From de761939cfd827dadef4e867ddb4b4e2c61e8322 Mon Sep 17 00:00:00 2001 From: Nate Williams Date: Fri, 23 Dec 1994 22:37:45 +0000 Subject: [PATCH] Updated version of gas which allows for link-time error reporting if used in conjustion with the new shlib 'ld' source. Note, if you use the new features both gas and ld must be updated. Obtained from: NetBSD --- gnu/usr.bin/as/Makefile | 14 +- gnu/usr.bin/as/app.c | 1085 ++++++++++------- gnu/usr.bin/as/as.h | 14 +- gnu/usr.bin/as/cond.c | 348 +++--- gnu/usr.bin/as/config/Makefile.i386 | 4 +- gnu/usr.bin/as/config/Makefile.sparc | 4 +- gnu/usr.bin/as/config/aout.h | 22 +- gnu/usr.bin/as/config/obj-aout.c | 71 +- gnu/usr.bin/as/config/obj-aout.h | 135 ++- gnu/usr.bin/as/config/tc-i386.c | 43 +- gnu/usr.bin/as/config/tc-i386.h | 9 +- gnu/usr.bin/as/config/tc-m68k.c | 32 +- gnu/usr.bin/as/config/tc-m68k.h | 8 +- gnu/usr.bin/as/config/tc-ns32k.c | 196 ++- gnu/usr.bin/as/config/tc-ns32k.h | 10 +- gnu/usr.bin/as/config/tc-sparc.c | 331 ++--- gnu/usr.bin/as/config/tc-sparc.h | 18 +- gnu/usr.bin/as/input-scrub.c | 526 ++++---- gnu/usr.bin/as/listing.c | 1686 +++++++++++++++----------- gnu/usr.bin/as/listing.h | 136 ++- gnu/usr.bin/as/messages.c | 676 +++++++---- gnu/usr.bin/as/opcode/m68k.h | 7 + gnu/usr.bin/as/opcode/sparc.h | 18 +- gnu/usr.bin/as/read.c | 51 +- gnu/usr.bin/as/read.h | 11 +- gnu/usr.bin/as/struc-symbol.h | 4 +- gnu/usr.bin/as/write.c | 13 +- 27 files changed, 3211 insertions(+), 2261 deletions(-) diff --git a/gnu/usr.bin/as/Makefile b/gnu/usr.bin/as/Makefile index fd4dc30f17cb..18e2db127707 100644 --- a/gnu/usr.bin/as/Makefile +++ b/gnu/usr.bin/as/Makefile @@ -1,5 +1,5 @@ # from: @(#)Makefile 6.1 (Berkeley) 3/3/91 -# $Id: Makefile,v 1.4 1994/08/28 17:43:37 bde Exp $ +# $Id: Makefile,v 1.5 1994/08/29 17:38:17 davidg Exp $ .include "config/Makefile.$(MACHINE)" @@ -25,8 +25,8 @@ SRCS+= app.c as.c atof-generic.c bignum-copy.c \ symbols.c version.c write.c xmalloc.c xrealloc.c \ obj-$(gas_objformat).c CFLAGS+= -I$(.CURDIR) ${ADDINCLUDE} -I$(.CURDIR)/config \ - -DPIC -DOLD_GAS -DSIGTY=void -Derror=as_fatal \ - -DSUB_SEGMENT_ALIGN=4 + -DOLD_GAS -DSIGTY=void -Derror=as_fatal \ + -DSUB_SEGMENT_ALIGN=4 -DFREEBSD_AOUT DPADD+= ${LIBGNUMALLOC} LDADD+= -lgnumalloc @@ -36,12 +36,12 @@ CONF_HEADERS= targ-cpu.h obj-format.h host.h targ-env.h beforedepend ${PROG}: ${CONF_HEADERS} -targ-cpu.h: Makefile config/Makefile.$(MACHINE) +targ-cpu.h: Makefile config/Makefile.$(MACHINE) $(.CURDIR)/config/tc-$(gas_target).h @cmp -s $(.CURDIR)/config/tc-$(gas_target).h targ-cpu.h || \ ( ${ECHO} "updating ${.TARGET}..." ; /bin/rm -f targ-cpu.h ; \ cp $(.CURDIR)/config/tc-$(gas_target).h targ-cpu.h ) -obj-format.h: Makefile config/Makefile.$(MACHINE) +obj-format.h: Makefile config/Makefile.$(MACHINE) $(.CURDIR)/config/obj-$(gas_objformat).h @cmp -s $(.CURDIR)/config/obj-$(gas_objformat).h obj-format.h || \ ( ${ECHO} "updating ${.TARGET}..." ; /bin/rm -f obj-format.h ; \ cp $(.CURDIR)/config/obj-$(gas_objformat).h obj-format.h ) @@ -52,7 +52,7 @@ config_hostfile= $(.CURDIR)/config/ho-$(gas_hosttype).h config_hostfile= $(.CURDIR)/config/ho-generic.h .endif -host.h: Makefile config/Makefile.$(MACHINE) +host.h: Makefile config/Makefile.$(MACHINE) $(config_hostfile) @cmp -s $(config_hostfile) host.h || \ ( ${ECHO} "updating ${.TARGET}..." ; /bin/rm -f host.h ; \ cp $(config_hostfile) host.h ) @@ -63,7 +63,7 @@ config_targenvfile= $(.CURDIR)/config/te-$(MACHINE).h config_targenvfile= $(.CURDIR)/config/te-generic.h .endif -targ-env.h: Makefile config/Makefile.$(MACHINE) +targ-env.h: Makefile config/Makefile.$(MACHINE) $(config_targenvfile) @cmp -s $(config_targenvfile) targ-env.h || \ ( ${ECHO} "updating ${.TARGET}..." ; /bin/rm -f targ-env.h ; \ cp $(config_targenvfile) targ-env.h ) diff --git a/gnu/usr.bin/as/app.c b/gnu/usr.bin/as/app.c index 4c89a77607a8..e1c029623c34 100644 --- a/gnu/usr.bin/as/app.c +++ b/gnu/usr.bin/as/app.c @@ -1,50 +1,44 @@ -/* Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. - - Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 - */ /* This is the Assembler Pre-Processor - Copyright (C) 1987 Free Software Foundation, Inc. - + Copyright (C) 1987, 1990, 1991, 1992, 1994 Free Software Foundation, Inc. + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 */ /* App, the assembler pre-processor. This pre-processor strips out excess spaces, turns single-quoted characters into a decimal constant, and turns - # into a .line \n.app-file pair. - This needs better error-handling. - */ + # into a .line \n.file + pair. This needs better error-handling. */ + #ifndef lint -static char rcsid[] = "$Id: app.c,v 1.3 1993/10/02 20:57:12 pk Exp $"; +static char rcsid[] = "$Id: app.c,v 1.2 1993/11/03 00:51:05 paul Exp $"; #endif #include -#include "as.h" /* For BAD_CASE() only */ +#include "as.h" /* For BAD_CASE() only */ -#if (__STDC__ != 1) && !defined(const) -#define const /* Nothing */ +#if (__STDC__ != 1) +#ifndef const +#define const /* empty */ +#endif #endif -static char lex[256]; -static char symbol_chars[] = - "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -/* These will go in BSS if not defined elsewhere, producing empty strings. */ -extern const char comment_chars[]; -extern const char line_comment_chars[]; -extern const char line_separator_chars[]; +static char lex[256]; +static const char symbol_chars[] = +"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; #define LEX_IS_SYMBOL_COMPONENT 1 #define LEX_IS_WHITESPACE 2 @@ -64,75 +58,98 @@ extern const char line_separator_chars[]; #define IS_LINE_COMMENT(c) (lex[c] == LEX_IS_LINE_COMMENT_START) #define IS_NEWLINE(c) (lex[c] == LEX_IS_NEWLINE) +static int process_escape PARAMS ((int)); + /* FIXME-soon: The entire lexer/parser thingy should be built statically at compile time rather than dynamically each and every time the assembler is run. xoxorich. */ -void do_scrub_begin() { - const char *p; - - lex[' '] = LEX_IS_WHITESPACE; - lex['\t'] = LEX_IS_WHITESPACE; - lex['\n'] = LEX_IS_NEWLINE; - lex[';'] = LEX_IS_LINE_SEPARATOR; - lex['"'] = LEX_IS_STRINGQUOTE; - lex['\''] = LEX_IS_ONECHAR_QUOTE; - lex[':'] = LEX_IS_COLON; - - /* Note that these override the previous defaults, e.g. if ';' - is a comment char, then it isn't a line separator. */ - for (p = symbol_chars; *p; ++p) { - lex[*p] = LEX_IS_SYMBOL_COMPONENT; - } /* declare symbol characters */ - - for (p = line_comment_chars; *p; p++) { - lex[*p] = LEX_IS_LINE_COMMENT_START; - } /* declare line comment chars */ - - for (p = comment_chars; *p; p++) { - lex[*p] = LEX_IS_COMMENT_START; - } /* declare comment chars */ - - for (p = line_separator_chars; *p; p++) { - lex[*p] = LEX_IS_LINE_SEPARATOR; - } /* declare line separators */ - - /* Only allow slash-star comments if slash is not in use */ - if (lex['/'] == 0) { - lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; - } - /* FIXME-soon. This is a bad hack but otherwise, we - can't do c-style comments when '/' is a line - comment char. xoxorich. */ - if (lex['*'] == 0) { - lex['*'] = LEX_IS_TWOCHAR_COMMENT_2ND; - } -} /* do_scrub_begin() */ +void +do_scrub_begin () +{ + const char *p; + + lex[' '] = LEX_IS_WHITESPACE; + lex['\t'] = LEX_IS_WHITESPACE; + lex['\n'] = LEX_IS_NEWLINE; + lex[';'] = LEX_IS_LINE_SEPARATOR; + lex['"'] = LEX_IS_STRINGQUOTE; +#ifndef TC_HPPA + lex['\''] = LEX_IS_ONECHAR_QUOTE; +#endif + lex[':'] = LEX_IS_COLON; + + + +#ifdef SINGLE_QUOTE_STRINGS + lex['\''] = LEX_IS_STRINGQUOTE; +#endif + + /* Note that these override the previous defaults, e.g. if ';' is a + comment char, then it isn't a line separator. */ + for (p = symbol_chars; *p; ++p) + { + lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT; + } /* declare symbol characters */ + + for (p = comment_chars; *p; p++) + { + lex[(unsigned char) *p] = LEX_IS_COMMENT_START; + } /* declare comment chars */ + + for (p = line_comment_chars; *p; p++) + { + lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START; + } /* declare line comment chars */ + + for (p = line_separator_chars; *p; p++) + { + lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR; + } /* declare line separators */ + + /* Only allow slash-star comments if slash is not in use */ + if (lex['/'] == 0) + { + lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; + } + /* FIXME-soon. This is a bad hack but otherwise, we can't do + c-style comments when '/' is a line comment char. xoxorich. */ + if (lex['*'] == 0) + { + lex['*'] = LEX_IS_TWOCHAR_COMMENT_2ND; + } +} /* do_scrub_begin() */ FILE *scrub_file; -int scrub_from_file() { - return getc(scrub_file); +int +scrub_from_file () +{ + return getc (scrub_file); } -void scrub_to_file(ch) -int ch; +void +scrub_to_file (ch) + int ch; { - ungetc(ch,scrub_file); -} /* scrub_to_file() */ + ungetc (ch, scrub_file); +} /* scrub_to_file() */ char *scrub_string; char *scrub_last_string; -int scrub_from_string() { - return scrub_string == scrub_last_string ? EOF : *scrub_string++; -} /* scrub_from_string() */ - -void scrub_to_string(ch) -int ch; +int +scrub_from_string () { - *--scrub_string=ch; -} /* scrub_to_string() */ + return scrub_string == scrub_last_string ? EOF : *scrub_string++; +} /* scrub_from_string() */ + +void +scrub_to_string (ch) + int ch; +{ + *--scrub_string = ch; +} /* scrub_to_string() */ /* Saved state of the scrubber */ static int state; @@ -146,394 +163,584 @@ static int add_newlines = 0; state at the time .include is interpreted is completely unrelated. That's why we have to save it all. */ -struct app_save { - int state; - int old_state; - char *out_string; - char out_buf[sizeof (out_buf)]; - int add_newlines; - char *scrub_string; - char *scrub_last_string; - FILE *scrub_file; -}; +struct app_save + { + int state; + int old_state; + char *out_string; + char out_buf[sizeof (out_buf)]; + int add_newlines; + char *scrub_string; + char *scrub_last_string; + FILE *scrub_file; + }; -char *app_push() { - register struct app_save *saved; - - saved = (struct app_save *) xmalloc(sizeof (*saved)); - saved->state = state; - saved->old_state = old_state; - saved->out_string = out_string; - memcpy(out_buf, saved->out_buf, sizeof(out_buf)); - saved->add_newlines = add_newlines; - saved->scrub_string = scrub_string; - saved->scrub_last_string = scrub_last_string; - saved->scrub_file = scrub_file; - - /* do_scrub_begin() is not useful, just wastes time. */ - return (char *)saved; +char * +app_push () +{ + register struct app_save *saved; + + saved = (struct app_save *) xmalloc (sizeof (*saved)); + saved->state = state; + saved->old_state = old_state; + saved->out_string = out_string; + memcpy (saved->out_buf, out_buf, sizeof (out_buf)); + saved->add_newlines = add_newlines; + saved->scrub_string = scrub_string; + saved->scrub_last_string = scrub_last_string; + saved->scrub_file = scrub_file; + + /* do_scrub_begin() is not useful, just wastes time. */ + return (char *) saved; } -void app_pop(arg) -char *arg; +void +app_pop (arg) + char *arg; { - register struct app_save *saved = (struct app_save *)arg; - - /* There is no do_scrub_end (). */ - state = saved->state; - old_state = saved->old_state; - out_string = saved->out_string; - memcpy(saved->out_buf, out_buf, sizeof (out_buf)); - add_newlines = saved->add_newlines; - scrub_string = saved->scrub_string; - scrub_last_string = saved->scrub_last_string; - scrub_file = saved->scrub_file; - - free (arg); -} /* app_pop() */ + register struct app_save *saved = (struct app_save *) arg; -int do_scrub_next_char(get,unget) -int (*get)(); -void (*unget)(); + /* There is no do_scrub_end (). */ + state = saved->state; + old_state = saved->old_state; + out_string = saved->out_string; + memcpy (out_buf, saved->out_buf, sizeof (out_buf)); + add_newlines = saved->add_newlines; + scrub_string = saved->scrub_string; + scrub_last_string = saved->scrub_last_string; + scrub_file = saved->scrub_file; + + free (arg); +} /* app_pop() */ + +/* @@ This assumes that \n &c are the same on host and target. This is not + necessarily true. */ +static int +process_escape (ch) + int ch; { - /*State 0: beginning of normal line + switch (ch) + { + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case '\'': + return '\''; + case '"': + return '\"'; + default: + return ch; + } +} +int +do_scrub_next_char (get, unget) + int (*get) (); + void (*unget) (); +{ + /*State 0: beginning of normal line 1: After first whitespace on line (flush more white) 2: After first non-white (opcode) on line (keep 1white) 3: after second white on line (into operands) (flush white) 4: after putting out a .line, put out digits 5: parsing a string, then go to old-state 6: putting out \ escape in a "d string. - 7: After putting out a .app-file, put out string. - 8: After putting out a .app-file string, flush until newline. - -1: output string in out_string and go to the state in old_state - -2: flush text until a '*' '/' is seen, then go to state old_state + 7: After putting out a .appfile, put out string. + 8: After putting out a .appfile string, flush until newline. + 9: After seeing symbol char in state 3 (keep 1white after symchar) + 10: After seeing whitespace in state 9 (keep white before symchar) + 11: After seeing a symbol character in state 0 (eg a label definition) + -1: output string in out_string and go to the state in old_state + -2: flush text until a '*' '/' is seen, then go to state old_state */ - - register int ch, ch2 = 0; - - switch (state) { - case -1: - ch= *out_string++; - if (*out_string == 0) { - state=old_state; - old_state=3; - } - return ch; - - case -2: - for (;;) { - do { - ch=(*get)(); - } while (ch != EOF && ch != '\n' && ch != '*'); - if (ch == '\n' || ch == EOF) - return ch; - - /* At this point, ch must be a '*' */ - while ( (ch=(*get)()) == '*' ){ - ; - } - if (ch == EOF || ch == '/') - break; - (*unget)(ch); - } - state=old_state; - return ' '; - - case 4: - ch=(*get)(); - if (ch == EOF || (ch >= '0' && ch <= '9')) - return ch; - else { - while (ch != EOF && IS_WHITESPACE(ch)) - ch=(*get)(); - if (ch == '"') { - (*unget)(ch); - out_string="\n.app-file "; - old_state=7; - state= -1; - return *out_string++; - } else { - while (ch != EOF && ch != '\n') - ch=(*get)(); - return ch; - } - } - - case 5: - ch=(*get)(); - if (ch == '"') { - state=old_state; - return '"'; - } else if (ch == '\\') { - state=6; - return ch; - } else if (ch == EOF) { - as_warn("End of file in string: inserted '\"'"); - state=old_state; - (*unget)('\n'); - return '"'; - } else { - return ch; - } - - case 6: - state=5; - ch=(*get)(); - switch (ch) { - /* This is neet. Turn "string - more string" into "string\n more string" - */ - case '\n': - (*unget)('n'); - add_newlines++; - return '\\'; - - case '"': - case '\\': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': + + /* I added states 9 and 10 because the MIPS ECOFF assembler uses + constructs like ``.loc 1 20''. This was turning into ``.loc + 120''. States 9 and 10 ensure that a space is never dropped in + between characters which could appear in a identifier. Ian + Taylor, ian@cygnus.com. + + I added state 11 so that something like "Lfoo add %r25,%r26,%r27" works + correctly on the PA (and any other target where colons are optional). + Jeff Law, law@cs.utah.edu. */ + + register int ch, ch2 = 0; + int not_cpp_line = 0; + + switch (state) + { + case -1: + ch = *out_string++; + if (*out_string == 0) + { + state = old_state; + old_state = 3; + } + return ch; + + case -2: + for (;;) + { + do + { + ch = (*get) (); + } + while (ch != EOF && ch != '\n' && ch != '*'); + if (ch == '\n' || ch == EOF) + return ch; + + /* At this point, ch must be a '*' */ + while ((ch = (*get) ()) == '*') + { + ; + } + if (ch == EOF || ch == '/') + break; + (*unget) (ch); + } + state = old_state; + return ' '; + + case 4: + ch = (*get) (); + if (ch == EOF || (ch >= '0' && ch <= '9')) + return ch; + else + { + while (ch != EOF && IS_WHITESPACE (ch)) + ch = (*get) (); + if (ch == '"') + { + (*unget) (ch); + out_string = "\n\t.appfile "; + old_state = 7; + state = -1; + return *out_string++; + } + else + { + while (ch != EOF && ch != '\n') + ch = (*get) (); + state = 0; + return ch; + } + } + + case 5: + ch = (*get) (); + if (lex[ch] == LEX_IS_STRINGQUOTE) + { + state = old_state; + return ch; + } +#ifndef NO_STRING_ESCAPES + else if (ch == '\\') + { + state = 6; + return ch; + } +#endif + else if (ch == EOF) + { + as_warn ("End of file in string: inserted '\"'"); + state = old_state; + (*unget) ('\n'); + return '"'; + } + else + { + return ch; + } + + case 6: + state = 5; + ch = (*get) (); + switch (ch) + { + /* Handle strings broken across lines, by turning '\n' into + '\\' and 'n'. */ + case '\n': + (*unget) ('n'); + add_newlines++; + return '\\'; + + case '"': + case '\\': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': #ifdef BACKSLASH_V - case 'v': + case 'v': #endif /* BACKSLASH_V */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - break; - -#ifdef ONLY_STANDARD_ESCAPES - default: - as_warn("Unknown escape '\\%c' in string: Ignored",ch); - break; -#else /* ONLY_STANDARD_ESCAPES */ - default: - /* Accept \x as x for any x */ - break; -#endif /* ONLY_STANDARD_ESCAPES */ - - case EOF: - as_warn("End of file in string: '\"' inserted"); - return '"'; - } - return ch; - - case 7: - ch=(*get)(); - state=5; - old_state=8; - return ch; - - case 8: - do ch= (*get)(); - while (ch != '\n'); - state=0; - return ch; - } - - /* OK, we are somewhere in states 0 through 4 */ - - /* flushchar: */ - ch=(*get)(); - recycle: - if (ch == EOF) { - if (state != 0) - as_warn("End of file not at end of a line: Newline inserted."); - return ch; - } - - switch (lex[ch]) { - case LEX_IS_WHITESPACE: - do ch=(*get)(); - while (ch != EOF && IS_WHITESPACE(ch)); - if (ch == EOF) - return ch; - if (IS_COMMENT(ch) || (state == 0 && IS_LINE_COMMENT(ch)) || ch == '/' || IS_LINE_SEPARATOR(ch)) { - goto recycle; - } - switch (state) { - case 0: state++; goto recycle; /* Punted leading sp */ - case 1: BAD_CASE(state); /* We can't get here */ - case 2: state++; (*unget)(ch); return ' '; /* Sp after opco */ - case 3: goto recycle; /* Sp in operands */ - default: BAD_CASE(state); - } - break; - - case LEX_IS_TWOCHAR_COMMENT_1ST: - ch2=(*get)(); - if (ch2 != EOF && lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND) { - for (;;) { - do { - ch2=(*get)(); - if (ch2 != EOF && IS_NEWLINE(ch2)) - add_newlines++; - } while (ch2 != EOF && - (lex[ch2] != LEX_IS_TWOCHAR_COMMENT_2ND)); - - while (ch2 != EOF && - (lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND)){ - ch2=(*get)(); - } - - if (ch2 == EOF - || lex[ch2] == LEX_IS_TWOCHAR_COMMENT_1ST) - break; - (*unget)(ch); - } - if (ch2 == EOF) - as_warn("End of file in multiline comment"); - - ch = ' '; - goto recycle; - } else { - if (ch2 != EOF) - (*unget)(ch2); - return ch; - } - break; - - case LEX_IS_STRINGQUOTE: - old_state=state; - state=5; - return ch; - -#ifndef IEEE_STYLE - case LEX_IS_ONECHAR_QUOTE: - ch=(*get)(); - if (ch == EOF) { - as_warn("End-of-file after a one-character quote; \000 inserted"); - ch=0; - } - sprintf(out_buf,"%d", (int)(unsigned char)ch); - - /* None of these 'x constants for us. We want 'x'. - */ - if ( (ch=(*get)()) != '\'' ) { -#ifdef REQUIRE_CHAR_CLOSE_QUOTE - as_warn("Missing close quote: (assumed)"); -#else - (*unget)(ch); -#endif - } - - old_state=state; - state= -1; - out_string=out_buf; - return *out_string++; -#endif - case LEX_IS_COLON: - if (state != 3) - state=0; - return ch; - - case LEX_IS_NEWLINE: - /* Roll out a bunch of newlines from inside comments, etc. */ - if (add_newlines) { - --add_newlines; - (*unget)(ch); - } - /* fall thru into... */ - - case LEX_IS_LINE_SEPARATOR: - state=0; - return ch; - - case LEX_IS_LINE_COMMENT_START: - if (state != 0) /* Not at start of line, act normal */ - goto de_fault; - - /* FIXME-someday: The two character comment stuff was badly - thought out. On i386, we want '/' as line comment start - AND we want C style comments. hence this hack. The - whole lexical process should be reworked. xoxorich. */ - - if (ch == '/' && (ch2 = (*get)()) == '*') { - state = -2; - return(do_scrub_next_char(get, unget)); - } else { - (*unget)(ch2); - } /* bad hack */ - - do ch=(*get)(); - while (ch != EOF && IS_WHITESPACE(ch)); - if (ch == EOF) { - as_warn("EOF in comment: Newline inserted"); - return '\n'; - } - if (ch<'0' || ch>'9') { - /* Non-numerics: Eat whole comment line */ - while (ch != EOF && !IS_NEWLINE(ch)) - ch=(*get)(); - if (ch == EOF) - as_warn("EOF in Comment: Newline inserted"); - state=0; - return '\n'; - } - /* Numerics begin comment. Perhaps CPP `# 123 "filename"' */ - (*unget)(ch); - old_state=4; - state= -1; - out_string=".line "; - return *out_string++; - - case LEX_IS_COMMENT_START: - do ch=(*get)(); - while (ch != EOF && !IS_NEWLINE(ch)); - if (ch == EOF) - as_warn("EOF in comment: Newline inserted"); - state=0; - return '\n'; - + case 'x': + case 'X': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + break; +#if defined(IGNORE_NONSTANDARD_ESCAPES) | defined(ONLY_STANDARD_ESCAPES) default: - de_fault: - /* Some relatively `normal' character. */ - if (state == 0) { - state=2; /* Now seeing opcode */ - return ch; - } else if (state == 1) { - state=2; /* Ditto */ - return ch; - } else { - return ch; /* Opcode or operands already */ - } + as_warn ("Unknown escape '\\%c' in string: Ignored", ch); + break; +#else /* ONLY_STANDARD_ESCAPES */ + default: + /* Accept \x as x for any x */ + break; +#endif /* ONLY_STANDARD_ESCAPES */ + + case EOF: + as_warn ("End of file in string: '\"' inserted"); + return '"'; } - return -1; + return ch; + + case 7: + ch = (*get) (); + state = 5; + old_state = 8; + return ch; + + case 8: + do + ch = (*get) (); + while (ch != '\n'); + state = 0; + return ch; + } + + /* OK, we are somewhere in states 0 through 4 or 9 through 11 */ + + /* flushchar: */ + ch = (*get) (); +recycle: + if (ch == EOF) + { + if (state != 0) + as_warn ("End of file not at end of a line: Newline inserted."); + return ch; + } + + switch (lex[ch]) + { + case LEX_IS_WHITESPACE: + do + /* Preserve a single whitespace character at the beginning of + a line. */ + if (state == 0) + { + state = 1; + return ch; + } + else + ch = (*get) (); + while (ch != EOF && IS_WHITESPACE (ch)); + if (ch == EOF) + return ch; + + if (IS_COMMENT (ch) + || (state == 0 && IS_LINE_COMMENT (ch)) + || ch == '/' + || IS_LINE_SEPARATOR (ch)) + { + /* cpp never outputs a leading space before the #, so try to + avoid being confused. */ + not_cpp_line = 1; + goto recycle; + } +#ifdef MRI + (*unget) (ch); /* Put back */ + return ' '; /* Always return one space at start of line */ +#endif + + /* If we're in state 2 or 11, we've seen a non-white character + followed by whitespace. If the next character is ':', this + is whitespace after a label name which we *must* ignore. */ + if ((state == 2 || state == 11) && lex[ch] == LEX_IS_COLON) + { + state = 1; + return ch; + } + + switch (state) + { + case 0: + state++; + goto recycle; /* Punted leading sp */ + case 1: + /* We can arrive here if we leave a leading whitespace character + at the beginning of a line. */ + goto recycle; + case 2: + state = 3; + (*unget) (ch); + return ' '; /* Sp after opco */ + case 3: + goto recycle; /* Sp in operands */ + case 9: + case 10: + state = 10; /* Sp after symbol char */ + goto recycle; + case 11: + state = 1; + (*unget) (ch); + return ' '; /* Sp after label definition. */ + default: + BAD_CASE (state); + } + break; + + case LEX_IS_TWOCHAR_COMMENT_1ST: + ch2 = (*get) (); + if (ch2 != EOF && lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND) + { + for (;;) + { + do + { + ch2 = (*get) (); + if (ch2 != EOF && IS_NEWLINE (ch2)) + add_newlines++; + } + while (ch2 != EOF && + (lex[ch2] != LEX_IS_TWOCHAR_COMMENT_2ND)); + + while (ch2 != EOF && + (lex[ch2] == LEX_IS_TWOCHAR_COMMENT_2ND)) + { + ch2 = (*get) (); + } + + if (ch2 == EOF + || lex[ch2] == LEX_IS_TWOCHAR_COMMENT_1ST) + break; + (*unget) (ch); + } + if (ch2 == EOF) + as_warn ("End of file in multiline comment"); + + ch = ' '; + goto recycle; + } + else + { + if (ch2 != EOF) + (*unget) (ch2); + if (state == 9 || state == 10) + state = 3; + return ch; + } + break; + + case LEX_IS_STRINGQUOTE: + if (state == 9 || state == 10) + old_state = 3; + else + old_state = state; + state = 5; + return ch; +#ifndef MRI +#ifndef IEEE_STYLE + case LEX_IS_ONECHAR_QUOTE: + ch = (*get) (); + if (ch == EOF) + { + as_warn ("End-of-file after a one-character quote; \\000 inserted"); + ch = 0; + } + if (ch == '\\') + { + ch = (*get) (); + ch = process_escape (ch); + } + sprintf (out_buf, "%d", (int) (unsigned char) ch); + + + /* None of these 'x constants for us. We want 'x'. */ + if ((ch = (*get) ()) != '\'') + { +#ifdef REQUIRE_CHAR_CLOSE_QUOTE + as_warn ("Missing close quote: (assumed)"); +#else + (*unget) (ch); +#endif + } + if (strlen (out_buf) == 1) + { + return out_buf[0]; + } + if (state == 9 || state == 10) + old_state = 3; + else + old_state = state; + state = -1; + out_string = out_buf; + return *out_string++; +#endif +#endif + case LEX_IS_COLON: + if (state == 9 || state == 10) + state = 3; + else if (state != 3) + state = 1; + return ch; + + case LEX_IS_NEWLINE: + /* Roll out a bunch of newlines from inside comments, etc. */ + if (add_newlines) + { + --add_newlines; + (*unget) (ch); + } + /* fall thru into... */ + + case LEX_IS_LINE_SEPARATOR: + state = 0; + return ch; + + case LEX_IS_LINE_COMMENT_START: + if (state == 0) /* Only comment at start of line. */ + { + /* FIXME-someday: The two character comment stuff was badly + thought out. On i386, we want '/' as line comment start + AND we want C style comments. hence this hack. The + whole lexical process should be reworked. xoxorich. */ + if (ch == '/') + { + ch2 = (*get) (); + if (ch2 == '*') + { + state = -2; + return (do_scrub_next_char (get, unget)); + } + else + { + (*unget) (ch2); + } + } /* bad hack */ + + if (ch != '#') + not_cpp_line = 1; + + do + ch = (*get) (); + while (ch != EOF && IS_WHITESPACE (ch)); + if (ch == EOF) + { + as_warn ("EOF in comment: Newline inserted"); + return '\n'; + } + if (ch < '0' || ch > '9' || not_cpp_line) + { + /* Non-numerics: Eat whole comment line */ + while (ch != EOF && !IS_NEWLINE (ch)) + ch = (*get) (); + if (ch == EOF) + as_warn ("EOF in Comment: Newline inserted"); + state = 0; + return '\n'; + } + /* Numerics begin comment. Perhaps CPP `# 123 "filename"' */ + (*unget) (ch); + old_state = 4; + state = -1; + out_string = "\t.appline "; + return *out_string++; + } + + /* We have a line comment character which is not at the start of + a line. If this is also a normal comment character, fall + through. Otherwise treat it as a default character. */ + if (strchr (comment_chars, ch) == NULL) + goto de_fault; + /* Fall through. */ + case LEX_IS_COMMENT_START: + do + ch = (*get) (); + while (ch != EOF && !IS_NEWLINE (ch)); + if (ch == EOF) + as_warn ("EOF in comment: Newline inserted"); + state = 0; + return '\n'; + + case LEX_IS_SYMBOL_COMPONENT: + if (state == 10) + { + /* This is a symbol character following another symbol + character, with whitespace in between. We skipped the + whitespace earlier, so output it now. */ + (*unget) (ch); + state = 3; + return ' '; + } + if (state == 3) + state = 9; + /* Fall through. */ + default: + de_fault: + /* Some relatively `normal' character. */ + if (state == 0) + { + state = 11; /* Now seeing label definition */ + return ch; + } + else if (state == 1) + { + state = 2; /* Ditto */ + return ch; + } + else if (state == 9) + { + if (lex[ch] != LEX_IS_SYMBOL_COMPONENT) + state = 3; + return ch; + } + else if (state == 10) + { + state = 3; + return ch; + } + else + { + return ch; /* Opcode or operands already */ + } + } + return -1; } #ifdef TEST -char comment_chars[] = "|"; -char line_comment_chars[] = "#"; +const char comment_chars[] = "|"; +const char line_comment_chars[] = "#"; -main() +main () { - int ch; - - app_begin(); - while ((ch=do_scrub_next_char(stdin)) != EOF) - putc(ch,stdout); + int ch; + + app_begin (); + while ((ch = do_scrub_next_char (stdin)) != EOF) + putc (ch, stdout); } -as_warn(str) -char *str; +as_warn (str) + char *str; { - fputs(str,stderr); - putc('\n',stderr); + fputs (str, stderr); + putc ('\n', stderr); } + #endif -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ - /* end of app.c */ diff --git a/gnu/usr.bin/as/as.h b/gnu/usr.bin/as/as.h index 7b1e27d2b1ad..10ea6049cf53 100644 --- a/gnu/usr.bin/as/as.h +++ b/gnu/usr.bin/as/as.h @@ -18,7 +18,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: as.h,v 1.3 1993/10/02 20:57:16 pk Exp $ + * $Id: as.h,v 1.2 1993/11/03 00:51:11 paul Exp $ */ #define GAS 1 @@ -46,6 +46,14 @@ #define __FILE__ "unknown" #endif /* __FILE__ */ +#ifndef PARAMS +#if __STDC__ != 1 +#define PARAMS(x) () +#else +#define PARAMS(x) x +#endif +#endif /*PARAMS */ + /* * I think this stuff is largely out of date. xoxorich. * @@ -335,8 +343,8 @@ int scrub_from_string(void); int seen_at_least_1_file(void); void app_pop(char *arg); void as_howmuch(FILE *stream); -void as_perror(char *gripe, char *filename); -void as_where(void); +void as_perror(const char *gripe, const char *filename); +void as_where(char **, unsigned int *); void bump_line_counters(void); void do_scrub_begin(void); void input_scrub_begin(void); diff --git a/gnu/usr.bin/as/cond.c b/gnu/usr.bin/as/cond.c index ad98201ad624..8e2ea4315eaf 100644 --- a/gnu/usr.bin/as/cond.c +++ b/gnu/usr.bin/as/cond.c @@ -1,24 +1,24 @@ /* cond.c - conditional assembly pseudo-ops, and .include - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - + Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$Id: cond.c,v 1.1 1993/10/02 20:57:20 pk Exp $"; +static char rcsid[] = "$Id: cond.c,v 1.1 1993/11/03 00:51:20 paul Exp $"; #endif #include "as.h" @@ -28,206 +28,186 @@ static char rcsid[] = "$Id: cond.c,v 1.1 1993/10/02 20:57:20 pk Exp $"; /* This is allocated to grow and shrink as .ifdef/.endif pairs are scanned. */ struct obstack cond_obstack; -struct file_line { - char *logical_file; - int logical_line; - char *physical_file; - int physical_line; -}; /* file_line */ +struct file_line +{ + char *file; + unsigned int line; +}; /* file_line */ /* This is what we push and pop. */ -struct conditional_frame { - struct file_line if_file_line; /* the source file & line number of the "if" */ - struct file_line else_file_line; /* the source file & line of the "else" */ - struct conditional_frame *previous_cframe; - int else_seen; /* have we seen an else yet? */ - int ignoring; /* if we are currently ignoring input. */ - int dead_tree; /* if a conditional at a higher level is ignoring input. */ -}; /* conditional_frame */ +struct conditional_frame + { + struct file_line if_file_line; /* the source file & line number of the "if" */ + struct file_line else_file_line; /* the source file & line of the "else" */ + struct conditional_frame *previous_cframe; + int else_seen; /* have we seen an else yet? */ + int ignoring; /* if we are currently ignoring input. */ + int dead_tree; /* if a conditional at a higher level is ignoring input. */ + }; /* conditional_frame */ -#if __STDC__ == 1 - -static void get_file_line(struct file_line *into); -static void initialize_cframe(struct conditional_frame *cframe); -static void set_file_line(struct file_line *from); - -#else - -static void get_file_line(); -static void initialize_cframe(); -static void set_file_line(); - -#endif +static void initialize_cframe PARAMS ((struct conditional_frame *cframe)); static struct conditional_frame *current_cframe = NULL; -void s_ifdef(arg) -int arg; +void +s_ifdef (arg) + int arg; { - register char *name; /* points to name of symbol */ - register struct symbol *symbolP; /* Points to symbol */ - struct conditional_frame cframe; - - SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ - name = input_line_pointer; - - if (!is_name_beginner(*name)) { - as_bad("invalid identifier for \".ifdef\""); - obstack_1grow(&cond_obstack, 0); - } else { - get_symbol_end(); - ++input_line_pointer; - symbolP = symbol_find(name); - - initialize_cframe(&cframe); - cframe.ignoring = cframe.dead_tree && !((symbolP != 0) ^ arg); - current_cframe = (struct conditional_frame *) obstack_copy(&cond_obstack, &cframe, sizeof(cframe)); - } /* if a valid identifyer name */ - - return; -} /* s_ifdef() */ + register char *name; /* points to name of symbol */ + register struct symbol *symbolP; /* Points to symbol */ + struct conditional_frame cframe; -void s_if(arg) -int arg; + SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ + name = input_line_pointer; + + if (!is_name_beginner (*name)) + { + as_bad ("invalid identifier for \".ifdef\""); + obstack_1grow (&cond_obstack, 0); + } + else + { + get_symbol_end (); + ++input_line_pointer; + symbolP = symbol_find (name); + + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || !((symbolP != 0) ^ arg); + current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe)); + } /* if a valid identifyer name */ + + return; +} /* s_ifdef() */ + +void +s_if (arg) + int arg; { - expressionS operand; - struct conditional_frame cframe; - - SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ - expr(0, &operand); - - if (operand.X_add_symbol != NULL - || operand.X_subtract_symbol != NULL) { - as_bad("non-constant expression in \".if\" statement"); - } /* bad condition */ - - /* If the above error is signaled, this will dispatch - using an undefined result. No big deal. */ - initialize_cframe(&cframe); - cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg); - current_cframe = (struct conditional_frame *) obstack_copy(&cond_obstack, &cframe, sizeof(cframe)); - return; -} /* s_if() */ + expressionS operand; + struct conditional_frame cframe; -void s_endif(arg) -int arg; + SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ + expression (&operand); + +#ifdef notyet + if (operand.X_op != O_constant) + as_bad ("non-constant expression in \".if\" statement"); +#else + if (operand.X_add_symbol != NULL || operand.X_subtract_symbol != NULL) { + as_bad("non-constant expression in \".if\" statement"); + } /* bad condition */ +#endif + + /* If the above error is signaled, this will dispatch + using an undefined result. No big deal. */ + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || !((operand.X_add_number != 0) ^ arg); + current_cframe = (struct conditional_frame *) obstack_copy (&cond_obstack, &cframe, sizeof (cframe)); + return; +} /* s_if() */ + +void +s_endif (arg) + int arg; { - struct conditional_frame *hold; - - if (current_cframe == NULL) { - as_bad("\".endif\" without \".if\""); - } else { - hold = current_cframe; - current_cframe = current_cframe->previous_cframe; - obstack_free(&cond_obstack, hold); - } /* if one pop too many */ - - return; -} /* s_endif() */ + struct conditional_frame *hold; -void s_else(arg) -int arg; + if (current_cframe == NULL) + { + as_bad ("\".endif\" without \".if\""); + } + else + { + hold = current_cframe; + current_cframe = current_cframe->previous_cframe; + obstack_free (&cond_obstack, hold); + } /* if one pop too many */ + + return; +} /* s_endif() */ + +void +s_else (arg) + int arg; { - if (current_cframe == NULL) { - as_bad(".else without matching .if - ignored"); - - } else if (current_cframe->else_seen) { - struct file_line hold; - as_bad("duplicate \"else\" - ignored"); - - get_file_line(&hold); - set_file_line(¤t_cframe->else_file_line); - as_bad("here is the previous \"else\"."); - set_file_line(¤t_cframe->if_file_line); - as_bad("here is the matching \".if\"."); - set_file_line(&hold); - - } else { - get_file_line(¤t_cframe->else_file_line); - - if (!current_cframe->dead_tree) { - current_cframe->ignoring = !current_cframe->ignoring; - } /* if not a dead tree */ - - current_cframe->else_seen = 1; - } /* if error else do it */ - - return; -} /* s_else() */ + if (current_cframe == NULL) + { + as_bad (".else without matching .if - ignored"); -void s_ifeqs(arg) -int arg; + } + else if (current_cframe->else_seen) + { + as_bad ("duplicate \"else\" - ignored"); + as_bad_where (current_cframe->else_file_line.file, + current_cframe->else_file_line.line, + "here is the previous \"else\""); + as_bad_where (current_cframe->if_file_line.file, + current_cframe->if_file_line.line, + "here is the previous \"if\""); + } + else + { + as_where (¤t_cframe->else_file_line.file, + ¤t_cframe->else_file_line.line); + + if (!current_cframe->dead_tree) + { + current_cframe->ignoring = !current_cframe->ignoring; + } /* if not a dead tree */ + + current_cframe->else_seen = 1; + } /* if error else do it */ + + return; +} /* s_else() */ + +void +s_ifeqs (arg) + int arg; { - as_bad("ifeqs not implemented."); - - return; -} /* s_ifeqs() */ + as_bad ("ifeqs not implemented."); -void s_end(arg) -int arg; + return; +} /* s_ifeqs() */ + +void +s_end (arg) + int arg; { - return; -} /* s_end() */ + return; +} /* s_end() */ -int ignore_input() { - char *ptr = obstack_next_free (&cond_obstack); - - /* We cannot ignore certain pseudo ops. */ - if (input_line_pointer[-1] == '.' - && ((input_line_pointer[0] == 'i' - && (!strncmp (input_line_pointer, "if", 2) - || !strncmp (input_line_pointer, "ifdef", 5) - || !strncmp (input_line_pointer, "ifndef", 6))) - || (input_line_pointer[0] == 'e' - && (!strncmp (input_line_pointer, "else", 4) - || !strncmp (input_line_pointer, "endif", 5))))) { - return 0; - } - - return((current_cframe != NULL) && (current_cframe->ignoring)); -} /* ignore_input() */ - -static void initialize_cframe(cframe) -struct conditional_frame *cframe; +int +ignore_input () { - memset(cframe, 0, sizeof(*cframe)); - get_file_line(&(cframe->if_file_line)); - cframe->previous_cframe = current_cframe; - cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring; - - return; -} /* initialize_cframe() */ + /* We cannot ignore certain pseudo ops. */ + if (input_line_pointer[-1] == '.' + && ((input_line_pointer[0] == 'i' + && (!strncmp (input_line_pointer, "if", 2) + || !strncmp (input_line_pointer, "ifdef", 5) + || !strncmp (input_line_pointer, "ifndef", 6))) + || (input_line_pointer[0] == 'e' + && (!strncmp (input_line_pointer, "else", 4) + || !strncmp (input_line_pointer, "endif", 5))))) + { + return 0; + } -static void get_file_line(into) -struct file_line *into; -{ - extern char *logical_input_file; - extern char *physical_input_file; - extern int logical_input_line; - extern int physical_input_line; - - into->logical_file = logical_input_file; - into->logical_line = logical_input_line; - into->physical_file = physical_input_file; - into->physical_line = physical_input_line; - - return; -} /* get_file_line() */ + return ((current_cframe != NULL) && (current_cframe->ignoring)); +} /* ignore_input() */ -static void set_file_line(from) -struct file_line *from; +static void +initialize_cframe (cframe) + struct conditional_frame *cframe; { - extern char *logical_input_file; - extern char *physical_input_file; - extern int logical_input_line; - extern int physical_input_line; - - logical_input_file = from->logical_file; - logical_input_line = from->logical_line; - physical_input_file = from->physical_file; - physical_input_line = from->physical_line; - return; -} /* set_file_line() */ + memset (cframe, 0, sizeof (*cframe)); + as_where (&cframe->if_file_line.file, + &cframe->if_file_line.line); + cframe->previous_cframe = current_cframe; + cframe->dead_tree = current_cframe != NULL && current_cframe->ignoring; + + return; +} /* initialize_cframe() */ /* * Local Variables: diff --git a/gnu/usr.bin/as/config/Makefile.i386 b/gnu/usr.bin/as/config/Makefile.i386 index bbae01707c5c..4cee91937bf9 100644 --- a/gnu/usr.bin/as/config/Makefile.i386 +++ b/gnu/usr.bin/as/config/Makefile.i386 @@ -1,5 +1,5 @@ # from: @(#)Makefile.i386 6.1 (Berkeley) 3/3/91 -# $Id: Makefile.i386,v 1.3 1993/10/02 20:58:21 pk Exp $ +# $Id: Makefile.i386,v 1.2 1993/11/03 00:52:58 paul Exp $ -CFLAGS+= -DNON_BROKEN_WORDS +CFLAGS+= -DNON_BROKEN_WORDS -DPIC SRCS+= tc-i386.c atof-ieee.c diff --git a/gnu/usr.bin/as/config/Makefile.sparc b/gnu/usr.bin/as/config/Makefile.sparc index c9d9af1455fa..6dc9658536f7 100644 --- a/gnu/usr.bin/as/config/Makefile.sparc +++ b/gnu/usr.bin/as/config/Makefile.sparc @@ -1,5 +1,5 @@ # from: @(#)Makefile.i386 6.1 (Berkeley) 3/3/91 -# $Id: Makefile.sparc,v 1.1 1993/10/02 20:58:22 pk Exp $ +# $Id: Makefile.sparc,v 1.1 1993/11/03 00:53:00 paul Exp $ -CFLAGS+= -DNON_BROKEN_WORDS +CFLAGS+= -DNON_BROKEN_WORDS -DPIC SRCS+= tc-sparc.c atof-ieee.c diff --git a/gnu/usr.bin/as/config/aout.h b/gnu/usr.bin/as/config/aout.h index 23b085adaaa1..fcc6a0ec3914 100644 --- a/gnu/usr.bin/as/config/aout.h +++ b/gnu/usr.bin/as/config/aout.h @@ -394,7 +394,13 @@ struct relocation_info { /* Address (within segment) to be relocated. */ int r_address; /* The meaning of r_symbolnum depends on r_extern. */ +#if defined(TC_NS32K) && !defined(TE_SEQUENT) + unsigned int r_symbolnum:22; + unsigned int r_copy:1; + unsigned int r_relative:1; +#else unsigned int r_symbolnum:24; +#endif /* Nonzero means value is a pc-relative offset and it should be relocated for changes in its own address as well as for changes in the symbol or section specified. */ @@ -409,19 +415,23 @@ struct relocation_info { r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS (the N_EXT bit may be set also, but signifies nothing). */ unsigned int r_extern:1; +#ifdef TC_NS32K +#ifdef TE_SEQUENT + unsigned int r_bsr:1; +#else + unsigned int r_jmptable:1; +#endif + unsigned int r_disp:2; + unsigned int r_baserel:1; +#else /* The next three bits are for SunOS shared libraries, and seem to be undocumented. */ unsigned int r_baserel:1; /* Linkage table relative */ unsigned int r_jmptable:1; /* pc-relative to jump table */ - -#ifdef TC_NS32K -#define r_bsr r_baserel -#define r_disp r_jmptable -#endif /* TC_NS32K */ - unsigned int r_relative:1; /* "relative relocation" */ /* unused */ unsigned int r_pad:1; /* Padding -- set to zero */ +#endif }; #endif /* CUSTOM_RELOC_FORMAT */ diff --git a/gnu/usr.bin/as/config/obj-aout.c b/gnu/usr.bin/as/config/obj-aout.c index 30eb2d150036..ceca490468d7 100644 --- a/gnu/usr.bin/as/config/obj-aout.c +++ b/gnu/usr.bin/as/config/obj-aout.c @@ -21,9 +21,7 @@ #include "obstack.h" -#ifndef NO_LISTING -#include "aout/stab_gnu.h" -#endif /* NO_LISTING */ +#include /* in: segT out: N_TYPE bits */ const short seg_N_TYPE[] = { @@ -44,21 +42,22 @@ const short seg_N_TYPE[] = { }; const segT N_TYPE_seg[N_TYPE+2] = { /* N_TYPE == 0x1E = 32-2 */ - SEG_UNKNOWN, /* N_UNDF == 0 */ - SEG_GOOF, - SEG_ABSOLUTE, /* N_ABS == 2 */ - SEG_GOOF, - SEG_TEXT, /* N_TEXT == 4 */ - SEG_GOOF, - SEG_DATA, /* N_DATA == 6 */ - SEG_GOOF, - SEG_BSS, /* N_BSS == 8 */ - SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, - SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ - SEG_GOOF, + SEG_UNKNOWN, SEG_GOOF, /* N_UNDF == 0 */ + SEG_ABSOLUTE, SEG_GOOF, /* N_ABS == 2 */ + SEG_TEXT, SEG_GOOF, /* N_TEXT == 4 */ + SEG_DATA, SEG_GOOF, /* N_DATA == 6 */ + SEG_BSS, SEG_GOOF, /* N_BSS == 8 */ + SEG_GOOF, SEG_GOOF, /* N_INDR == 0xa */ + SEG_GOOF, SEG_GOOF, /* 0xc */ + SEG_GOOF, SEG_GOOF, /* 0xe */ + SEG_GOOF, SEG_GOOF, /* 0x10 */ + SEG_REGISTER, SEG_GOOF, /* 0x12 (dummy N_REGISTER) */ + SEG_GOOF, SEG_GOOF, /* N_SETA == 0x14 */ + SEG_GOOF, SEG_GOOF, /* N_SETT == 0x16 */ + SEG_GOOF, SEG_GOOF, /* N_SETD == 0x18 */ + SEG_GOOF, SEG_GOOF, /* N_SETB == 0x1a */ + SEG_GOOF, SEG_GOOF, /* N_SETV == 0x1c */ + SEG_GOOF, SEG_GOOF, /* N_WARNING == 0x1e */ }; #if __STDC__ == 1 @@ -141,18 +140,18 @@ char **where; object_headers *headers; { tc_headers_hook(headers); - -#if defined(OLD_GAS) && defined(TC_I386) - /* I think that this old behaviour was wrong, but this lets me compare to the - previous gas. xoxorich. */ - md_number_to_chars(*where, headers->header.a_info, 2); - *where += 2; - md_number_to_chars(*where, 0, 2); - *where += 2; -#else /* not (TC_I386 && OLD_GAS) */ - md_number_to_chars(*where, headers->header.a_info, sizeof(headers->header.a_info)); + +#if defined(FREEBSD_AOUT) || defined(NETBSD_AOUT) + /* `a_info' (magic, mid, flags) is in network byte-order */ + (*where)[0] = ((char *)&headers->header.a_info)[0]; + (*where)[1] = ((char *)&headers->header.a_info)[1]; + (*where)[2] = ((char *)&headers->header.a_info)[2]; + (*where)[3] = ((char *)&headers->header.a_info)[3]; +#else + md_number_to_chars(*where, headers->header.a_info, + sizeof(headers->header.a_info)); +#endif *where += sizeof(headers->header.a_info); -#endif /* not (TC_I386 && OLD_GAS) */ #ifdef TE_HPUX md_number_to_chars(*where, 0, 4); *where += 4; /* a_spare1 */ @@ -514,11 +513,10 @@ object_headers *headers; || S_IS_EXTERNAL(symbolP) #endif /* TC_I960 */ || (S_GET_NAME(symbolP)[0] != '\001' && - (flagseen['L'] || ! S_LOCAL_NAME(symbolP) + (flagseen['L'] || ! S_LOCAL_NAME(symbolP)) #ifdef PIC - || flagseen['k'] && symbolP->sy_forceout + || (flagseen['k'] && symbolP->sy_forceout) #endif - ) ) ) #ifdef PIC @@ -627,11 +625,12 @@ char **where; void obj_pre_write_hook(headers) object_headers *headers; { - H_SET_DYNAMIC(headers, 0); - H_SET_VERSION(headers, 0); - H_SET_MACHTYPE(headers, AOUT_MACHTYPE); + H_SET_INFO(headers, + DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE, + AOUT_MACHTYPE, + AOUT_FLAGS, + AOUT_VERSION); - H_SET_MAGIC_NUMBER(headers, DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE); H_SET_ENTRY_POINT(headers, 0); tc_aout_pre_write_hook(headers); diff --git a/gnu/usr.bin/as/config/obj-aout.h b/gnu/usr.bin/as/config/obj-aout.h index af3d9b0fa124..3925911c53e4 100644 --- a/gnu/usr.bin/as/config/obj-aout.h +++ b/gnu/usr.bin/as/config/obj-aout.h @@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write - to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - * $Id: obj-aout.h,v 1.1 1993/11/03 00:53:50 paul Exp $ + to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: obj-aout.h,v 1.2 1993/11/30 20:57:40 jkh Exp $ */ @@ -30,10 +30,19 @@ #ifndef AOUT_MACHTYPE #define AOUT_MACHTYPE 0 -#endif /* AOUT_MACHTYPE */ +#endif + +#ifndef AOUT_VERSION +#define AOUT_VERSION 0 +#endif + +#ifndef AOUT_FLAGS +#define AOUT_FLAGS 0 +#endif extern const short seg_N_TYPE[]; extern const segT N_TYPE_seg[]; +#define N_REGISTER 0x12 /* Fake register type */ #ifndef DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE #define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (OMAGIC) @@ -136,30 +145,116 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ #define H_GET_STRING_SIZE(h) ((h)->string_table_size) #define H_GET_LINENO_SIZE(h) (0) +#if defined(FREEBSD_AOUT) || defined(NETBSD_AOUT) + +#if defined(FREEBSD_AOUT) +/* duplicate part of */ +#define H_GET_FLAGS(h) \ + ( (((h)->header.a_info)&0xffff) \ + ? ((h)->header.a_info >> 26) & 0x3f ) \ + : 0 \ + ) +#define H_GET_MACHTYPE(h) \ + ( (((h)->header.a_info)&0xffff) \ + ? ((h)->header.a_info >>16 ) & 0x3ff) \ + : 0 \ + ) + +#define H_GET_MAGIC_NUMBER(h) \ + ( (((h)->header.a_info)&0xffff) \ + ? ((h)->header.a_info & 0xffff) \ + : (ntohl(((h)->header.a_info))&0xffff) \ + ) + +#define H_SET_INFO(h,mag,mid,f,v) \ + ( (h)->header.a_info = \ + htonl( (((f)&0x3f)<<26) | (((mid)&0x03ff)<<16) | (((mag)&0xffff)) ) ) + +#endif /* FREEBSD_AOUT */ + +#if defined(NETBSD_AOUT) +/* SH*T, duplicate part of */ +#define H_GET_FLAGS(h) \ + ( (((h)->header.a_info)&0xffff0000) \ + ? ((ntohl(((h)->header.a_info))>>26)&0x3f) \ + : 0 \ + ) + +#define H_GET_MACHTYPE(h) \ + ( (((h)->header.a_info)&0xffff0000) \ + ? ((ntohl(((h)->header.a_info))>>16)&0x3ff) \ + : 0 \ + ) + +#define H_GET_MAGIC_NUMBER(h) \ + ( (((h)->header.a_info)&0xffff0000) \ + ? (ntohl(((h)->header.a_info))&0xffff) \ + : ((h)->header.a_info & 0xffff) \ + ) + +#define H_SET_INFO(h,mag,mid,f,v) \ + ( (h)->header.a_info = \ + htonl( (((f)&0x3f)<<26) | (((mid)&0x03ff)<<16) | (((mag)&0xffff)) ) ) + +#endif /* NETBSD_AOUT */ + +#define EX_DYNAMIC 0x20 +#define EX_PIC 0x10 +#undef AOUT_FLAGS +#define AOUT_FLAGS (flagseen['k'] ? EX_PIC : 0) + +#define H_GET_DYNAMIC(h) (H_GET_FLAGS(h) & EX_DYNAMIC) + +#define H_GET_VERSION(h) (0) + +#define H_SET_DYNAMIC(h,v) \ + H_SET_INFO(h, H_GET_MAGIC_NUMBER(h), H_GET_MACHTYPE(h), \ + (v)?(H_GET_FLAGS(h)|0x20):(H_GET_FLAGS(h)&(~0x20)), 0) + +#define H_SET_VERSION(h,v) + +#define H_SET_MACHTYPE(h,v) \ + H_SET_INFO(h, H_GET_MAGIC_NUMBER(h), (v), H_GET_FLAGS(h), 0) + +#define H_SET_MAGIC_NUMBER(h,v) \ + H_SET_INFO(h, (v), H_GET_MACHTYPE(h), H_GET_FLAGS(h), 0) + +#else /* !(FREEBSD_AOUT || NETBSD_AOUT) */ + #define H_GET_DYNAMIC(h) ((h)->header.a_info >> 31) #define H_GET_VERSION(h) (((h)->header.a_info >> 24) & 0x7f) #define H_GET_MACHTYPE(h) (((h)->header.a_info >> 16) & 0xff) #define H_GET_MAGIC_NUMBER(h) ((h)->header.a_info & 0xffff) -#define H_SET_DYNAMIC(h,v) ((h)->header.a_info = (((v) << 31) \ - | (H_GET_VERSION(h) << 24) \ - | (H_GET_MACHTYPE(h) << 16) \ - | (H_GET_MAGIC_NUMBER(h)))) +#define H_SET_DYNAMIC(h,v) ((h)->header.a_info = \ + (((v) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) -#define H_SET_VERSION(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ - | ((v) << 24) \ - | (H_GET_MACHTYPE(h) << 16) \ - | (H_GET_MAGIC_NUMBER(h)))) +#define H_SET_VERSION(h,v) ((h)->header.a_info = \ + ((H_GET_DYNAMIC(h) << 31) \ + | ((v) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) -#define H_SET_MACHTYPE(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ - | (H_GET_VERSION(h) << 24) \ - | ((v) << 16) \ - | (H_GET_MAGIC_NUMBER(h)))) +#define H_SET_MACHTYPE(h,v) ((h)->header.a_info = \ + ((H_GET_DYNAMIC(h) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | ((v) << 16) \ + | (H_GET_MAGIC_NUMBER(h)))) -#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = ((H_GET_DYNAMIC(h) << 31) \ - | (H_GET_VERSION(h) << 24) \ - | (H_GET_MACHTYPE(h) << 16) \ - | ((v)))) +#define H_SET_MAGIC_NUMBER(h,v) ((h)->header.a_info = \ + ((H_GET_DYNAMIC(h) << 31) \ + | (H_GET_VERSION(h) << 24) \ + | (H_GET_MACHTYPE(h) << 16) \ + | ((v)))) +#define H_SET_INFO(h,mag,mid,f,v) ((h)->header.a_info = \ + ((((f)==0x20) << 31) \ + | ((v) << 24) \ + | ((mid) << 16) \ + | ((mag))) ) +#endif /* FREEBSD_AOUT || NETBSD_AOUT */ #define H_SET_TEXT_SIZE(h,v) ((h)->header.a_text = md_section_align(SEG_TEXT, (v))) #define H_SET_DATA_SIZE(h,v) ((h)->header.a_data = md_section_align(SEG_DATA, (v))) diff --git a/gnu/usr.bin/as/config/tc-i386.c b/gnu/usr.bin/as/config/tc-i386.c index 84848d2ec233..caadb8a69244 100644 --- a/gnu/usr.bin/as/config/tc-i386.c +++ b/gnu/usr.bin/as/config/tc-i386.c @@ -25,7 +25,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: tc-i386.c,v 1.1 1993/11/03 00:54:23 paul Exp $"; +static char rcsid[] = "$Id: tc-i386.c,v 1.2 1993/11/30 20:57:41 jkh Exp $"; #endif #include "as.h" @@ -637,7 +637,7 @@ char *line; ordinal_names[i.operands]); return; } else break; /* we are done */ - } else if (! is_operand_char(*l)) { + } else if (! is_operand_char(*l) && ! is_space_char(*l)) { as_bad("invalid character %s in %s operand", output_invalid(*l), ordinal_names[i.operands]); @@ -1406,6 +1406,7 @@ char *operand_string; save_input_line_pointer = input_line_pointer; /* must advance op_string! */ input_line_pointer = ++op_string; + SKIP_WHITESPACE (); exp_seg = expression(exp); input_line_pointer = save_input_line_pointer; @@ -1647,18 +1648,42 @@ char *operand_string; /* missing expr becomes absolute 0 */ as_bad("missing or invalid displacement '%s' taken as 0", operand_string); - i.types[this_operand] |= (Disp|Abs); - exp->X_seg = SEG_ABSOLUTE; - exp->X_add_number = 0; - exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; + if (i.disp_reloc[this_operand] != NO_RELOC || !found_base_index_form || !i.base_reg) { + i.types[this_operand] |= (Disp|Abs); + exp->X_seg = SEG_ABSOLUTE; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_subtract_symbol = (symbolS *) 0; + } else { +#ifdef DEBUGxxx + printf("displacement removed in operand `%s'\n", operand_string); +#endif + i.disp_operands--; + i.disps[this_operand] = 0; + } break; case SEG_ABSOLUTE: - i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); + if (i.disp_reloc[this_operand] != NO_RELOC || !found_base_index_form || !i.base_reg || exp->X_add_symbol || exp->X_subtract_symbol || exp->X_add_number != 0) + i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); + else { +#ifdef DEBUGxxx + printf("displacement removed in operand `%s'\n", operand_string); +#endif + i.disp_operands--; + i.disps[this_operand] = 0; + } break; case SEG_TEXT: case SEG_DATA: case SEG_BSS: case SEG_UNKNOWN: /* must be 32 bit displacement (i.e. address) */ - i.types[this_operand] |= Disp32; + if (i.disp_reloc[this_operand] != NO_RELOC || !found_base_index_form || !i.base_reg || exp->X_add_symbol || exp->X_subtract_symbol || exp->X_add_number != 0) + i.types[this_operand] |= Disp32; + else { +#ifdef DEBUGxxx + printf("displacement removed in operand `%s'\n", operand_string); +#endif + i.disp_operands--; + i.disps[this_operand] = 0; + } break; default: goto seg_unimplemented; diff --git a/gnu/usr.bin/as/config/tc-i386.h b/gnu/usr.bin/as/config/tc-i386.h index b9ac3fe36bb6..1369d2b98df0 100644 --- a/gnu/usr.bin/as/config/tc-i386.h +++ b/gnu/usr.bin/as/config/tc-i386.h @@ -18,21 +18,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: tc-i386.h,v 1.1 1993/10/02 20:59:21 pk Exp $ + * $Id: tc-i386.h,v 1.1 1993/11/03 00:54:25 paul Exp $ */ #ifndef TC_I386 #define TC_I386 1 -#if 0 -#define AOUT_MACHTYPE 100 -#endif +#define AOUT_MACHTYPE 134 + #define REVERSE_SORT_RELOCS #define LOCAL_LABELS_FB -#define NO_LISTING - #define tc_coff_symbol_emit_hook(a) ; /* not used */ /* Local labels starts with .L */ diff --git a/gnu/usr.bin/as/config/tc-m68k.c b/gnu/usr.bin/as/config/tc-m68k.c index 2dac35b3bcbe..1aed016c7eed 100644 --- a/gnu/usr.bin/as/config/tc-m68k.c +++ b/gnu/usr.bin/as/config/tc-m68k.c @@ -1670,8 +1670,15 @@ char *instring; reloc_type = NO_RELOC; switch (opP->mode) { + int literal; + case IMMED: tmpreg=0x3c; /* 7.4 */ + if (*opP->con1->e_beg == ':') { + ++opP->con1->e_beg; + literal = 1; + } else + literal = 0; if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80); else nextword=nextword=get_num(opP->con1,0); if (isvar(opP->con1)) { @@ -1729,6 +1736,18 @@ char *instring; if (!baseo) break; + if (literal) { + if (seg(opP->con1) == SEG_BIG) + goto bignum; + while (baseo -= 2) { + addword(0); + addword(0); + } + addword(nextword>>16); + addword(nextword); + break; + } + /* We gotta put out some float */ if (seg(opP->con1) != SEG_BIG) { int_to_gen(nextword); @@ -1739,6 +1758,7 @@ char *instring; } /* Its BIG */ if (offs(opP->con1)>0) { as_warn("Bignum assumed to be binary bit-pattern"); + bignum: if (offs(opP->con1)>baseo) { as_warn("Bignum too big for %c format; truncated",s[1]); offs(opP->con1)=baseo; @@ -4014,18 +4034,6 @@ print_frags() } #endif -#ifdef DONTDEF -/*VARARGS1*/ -panic(format,args) -char *format; -{ - fputs("Internal error:",stderr); - _doprnt(format,&args,stderr); - (void)putc('\n',stderr); - as_where(); - abort(); -} -#endif /* We have no need to default values of symbols. */ diff --git a/gnu/usr.bin/as/config/tc-m68k.h b/gnu/usr.bin/as/config/tc-m68k.h index ce69252b963a..4ea748293542 100644 --- a/gnu/usr.bin/as/config/tc-m68k.h +++ b/gnu/usr.bin/as/config/tc-m68k.h @@ -23,15 +23,17 @@ * target processor specific header files. */ -#define TC_M68K 1 +#define MID_M68K 135 +#define MID_M68K4K 136 +#include -#define NO_LISTING +#define TC_M68K 1 #ifdef OLD_GAS #define REVERSE_SORT_RELOCS #endif /* OLD_GAS */ -#define AOUT_MACHTYPE 0x2 +#define AOUT_MACHTYPE MID_MACHINE #define LOCAL_LABELS_FB #define tc_crawl_symbol_chain(a) {;} /* not used */ diff --git a/gnu/usr.bin/as/config/tc-ns32k.c b/gnu/usr.bin/as/config/tc-ns32k.c index 02d86c442806..5843fe594a29 100644 --- a/gnu/usr.bin/as/config/tc-ns32k.c +++ b/gnu/usr.bin/as/config/tc-ns32k.c @@ -61,8 +61,8 @@ #define LINE_COMMENT_CHARS "#" #endif -char comment_chars[] = "#"; -char line_comment_chars[] = LINE_COMMENT_CHARS; +const char comment_chars[] = "#"; +const char line_comment_chars[] = LINE_COMMENT_CHARS; #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX) #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined */ #endif @@ -338,8 +338,8 @@ const relax_typeS md_relax_table[] = { { 1, 1, 0, 0 }, { 1, 1, 0, 0 }, - { (63), (-64), 1, IND(BRANCH,WORD) }, - { (8192), (-8192), 2, IND(BRANCH,DOUBLE) }, + { (63), (-64), 1, IND(BRANCH,WORD) }, + { (8191), (-8192), 2, IND(BRANCH,DOUBLE) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 } }; @@ -348,13 +348,23 @@ const relax_typeS md_relax_table[] = { Value is true if mode contains displacement. */ char disp_test[] = { 0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1, - 1,1,1,0,0,1,1,0, - 1,1,1,1,1,1,1,1 }; + 1,1,1,1,1,1,1,1, + 1,1,1,0,0,1,1,0, + 1,1,1,1,1,1,1,1 }; /* Array used to calculate max size of displacements */ char disp_size[] = { 4,1,2,0,4 }; + +#ifdef PIC +/* In pic-mode all external pc-relative references are jmpslot + references except references to __GLOBAL_OFFSET_TABLE_. */ +static symbolS *got_symbol; + +/* The size of got-offsets. */ +static int got_offset_size = 2; +#endif + #if __STDC__ == 1 @@ -821,7 +831,8 @@ char opcode_bit_ptr; pcrel=1; iif.instr_size+=suffixP[i] ? suffixP[i] : 4; IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0, - pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break; + pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1, 1); + break; case 'q': /* quick */ opcode_bit_ptr-=4; IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0, @@ -1024,10 +1035,10 @@ int recursive_level; */ void convert_iif() { int i; - int j; + bit_fixS *bit_fixP; fragS *inst_frag; char *inst_offset; - char **inst_opcode; + char *inst_opcode; char *memP; segT segment; int l; @@ -1036,39 +1047,50 @@ void convert_iif() { char type; char size = 0; int size_so_far = 0; /* used to calculate pcrel_adjust */ - int pcrel_symbols=0; /* kludge by jkp@hut.fi to make + int pcrel_symbols = 0;/* kludge by jkp@hut.fi to make movd _foo(pc),_bar(pc) work. It should be done with two frags for one insn, but I don't understand enough to make it work */ - - rem_size=iif.instr_size; - memP=frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */ - inst_opcode=memP; - inst_offset=(char*)(memP-frag_now->fr_literal); - inst_frag=frag_now; - for (i=0;ifr_literal); + inst_frag = frag_now; + for (i=0; i < IIF_ENTRIES; i++) { /* jkp kludge alert */ if (iif.iifP[i].type && iif.iifP[i].size == 0 && iif.iifP[i].pcrel) { - evaluate_expr(&exprP,(char*)iif.iifP[i].object); + evaluate_expr(&exprP, (char *)iif.iifP[i].object); if (exprP.X_add_symbol || exprP.X_subtract_symbol) pcrel_symbols++; } } for (i=0;ifx_bit_base) { /* expand fx_bit_base to point at opcode */ - iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode; + iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode; } case 8: /* bignum or doublefloat */ memset(memP, '\0', 8); case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */ - j=(unsigned long)iif.iifP[i].bit_fixP; + bit_fixP = iif.iifP[i].bit_fixP; switch (type) { case 1: /* the object is pure binary */ - if (j || iif.iifP[i].pcrel) { + if (bit_fixP || iif.iifP[i].pcrel) { fix_new_ns32k(frag_now, (long)(memP-frag_now->fr_literal), size, @@ -1078,8 +1100,9 @@ void convert_iif() { iif.iifP[i].pcrel, (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ iif.iifP[i].im_disp, - j, - iif.iifP[i].bsr); /* sequent hack */ + bit_fixP, + iif.iifP[i].bsr, /* sequent hack */ + reloc_mode); } else { /* good, just put them bytes out */ switch (iif.iifP[i].im_disp) { case 0: @@ -1126,7 +1149,7 @@ void convert_iif() { rem_size-=size; break; } - if (j || + if (bit_fixP || exprP.X_add_symbol || exprP.X_subtract_symbol || iif.iifP[i].pcrel) { /* fixit */ @@ -1142,8 +1165,9 @@ void convert_iif() { iif.iifP[i].pcrel, (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ iif.iifP[i].im_disp, - j, - iif.iifP[i].bsr); /* sequent hack */ + bit_fixP, + iif.iifP[i].bsr, /* sequent hack */ + reloc_mode); } else { /* good, just put them bytes out */ switch (iif.iifP[i].im_disp) { @@ -1171,6 +1195,13 @@ void convert_iif() { segment = evaluate_expr(&exprP, (char*)iif.iifP[i].object); if (((exprP.X_add_symbol || exprP.X_subtract_symbol) && !iif.iifP[i].pcrel) || pcrel_symbols >= 2 /*jkp*/) { /* OVE: hack, clamp to 4 bytes */ +#ifdef PIC + if (reloc_mode == RELOC_GLOB_DAT && got_offset_size == 2) { + size = 2; + /* rewind the bytes not used */ + obstack_blank_fast(&frags, -2); + } else +#endif size=4; /* we dont wan't to frag this, use 4 so it reaches */ fix_new_ns32k(frag_now, (long)(memP-frag_now->fr_literal), @@ -1181,7 +1212,8 @@ void convert_iif() { pcrel_symbols >= 2 ? iif.iifP[i].pcrel : 0, /*jkp*//* never iif.iifP[i].pcrel, */ (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/ 1, /* always iif.iifP[i].im_disp, */ - 0,0); + 0,0, + reloc_mode); memP+=size; rem_size-=4; break; /* exit this absolute hack */ @@ -1208,7 +1240,7 @@ void convert_iif() { IND(BRANCH,UNDEF), /* expecting the worst */ exprP.X_add_symbol, exprP.X_add_number, - (char*)inst_opcode, + inst_opcode, (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/ iif.iifP[i].bsr); /* sequent linker hack */ rem_size -= 4; @@ -1305,6 +1337,7 @@ int *sizeP; int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; + extern char *atof_ns32k(); char *t; switch (type) { @@ -1369,7 +1402,10 @@ char n; switch (n) { case 1: if (val < -64 || val > 63) +{ +fprintf(stderr, "val = %d\n", val); as_warn("Byte displacement out of range. line number not valid"); +} val &= 0x7f; #ifdef SHOW_NUM printf("%x ",val & 0xff); @@ -1502,38 +1538,75 @@ struct reloc_info_generic *ri; #ifdef OBJ_AOUT void tc_aout_fix_to_chars(where, fixP, segment_address_in_file) char *where; -struct fix *fixP; +fixS *fixP; relax_addressT segment_address_in_file; { /* * In: length of relocation (or of address) in chars: 1, 2 or 4. * Out: GNU LD relocation length code: 0, 1, or 2. */ - + static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 }; long r_symbolnum; - + int r_flags; + know(fixP->fx_addsy != NULL); md_number_to_chars(where, fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, 4); - + r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy) ? S_GET_TYPE(fixP->fx_addsy) : fixP->fx_addsy->sy_number); - - md_number_to_chars(where, - ((long)(r_symbolnum) - | (long)(fixP->fx_pcrel << 24) - | (long)(nbytes_r_length[fixP->fx_size] << 25) - | (long)((!S_IS_DEFINED(fixP->fx_addsy)) << 27) - | (long)(fixP->fx_bsr << 28) - | (long)(fixP->fx_im_disp << 29)), - 4); + r_flags = (fixP->fx_pcrel ? 1 : 0) + | ((nbytes_r_length[fixP->fx_size] & 3) << 1) + | (!S_IS_DEFINED(fixP->fx_addsy) ? 8 : 0) +#if defined(TE_SEQUENT) + | (fixP->fx_bsr ? 0x10 : 0) +#elif defined(PIC) + /* Undefined pc-relative relocations are of type jmpslot */ + | ((!S_IS_DEFINED(fixP->fx_addsy) + && fixP->fx_pcrel + && fixP->fx_addsy != got_symbol + && flagseen['k']) ? 0x10 : 0) +#endif + | (fixP->fx_im_disp & 3) << 5; +#ifdef PIC + switch (fixP->fx_r_type) { + case NO_RELOC: + break; + case RELOC_32: + if (flagseen['k'] && S_IS_EXTERNAL(fixP->fx_addsy)) { + r_symbolnum = fixP->fx_addsy->sy_number; + r_flags |= 8; /* set extern bit */ + } + break; + case RELOC_GLOB_DAT: + if (!fixP->fx_pcrel) { + r_flags |= 0x80; /* set baserel bit */ + r_symbolnum = fixP->fx_addsy->sy_number; + if (S_IS_EXTERNAL(fixP->fx_addsy)) + r_flags |= 8; + } + break; + case RELOC_RELATIVE: + /* should never happen */ + as_fatal("relocation botch"); + break; + } +#endif /* PIC */ + + where[4] = r_symbolnum & 0x0ff; + where[5] = (r_symbolnum >> 8) & 0x0ff; + where[6] = (r_symbolnum >> 16) & 0x0ff; + where[7] = r_flags; + return; } /* tc_aout_fix_to_chars() */ + + #endif /* OBJ_AOUT */ /* fast bitfiddling support */ @@ -1690,13 +1763,13 @@ register fragS *fragP; case IND(BRANCH,BYTE): ext = 1; break; - case IND(BRANCH,WORD): - ext = 2; + case IND(BRANCH,WORD): + ext = 2; break; - case IND(BRANCH,DOUBLE): - ext = 4; + case IND(BRANCH,DOUBLE): + ext = 4; break; - } + } if (ext) { md_number_to_disp(buffer_address, (long)disp, (int)ext); fragP->fr_fix += ext; @@ -1733,7 +1806,8 @@ segT segment; fragP->fr_pcrel_adjust, 1, 0, - fragP->fr_bsr); /*sequent hack */ + fragP->fr_bsr, /*sequent hack */ + NO_RELOC); fragP->fr_fix+=4; /* fragP->fr_opcode[1]=0xff; */ frag_wane(fragP); @@ -1805,7 +1879,16 @@ char ***vecP; while (**argP) (*argP)++; break; - + +#ifdef PIC + case 'K': + got_offset_size = 4; + break; + case 'k': + got_symbol = symbol_find_or_make("__GLOBAL_OFFSET_TABLE_"); + break; +#endif + default: return 0; } @@ -1845,7 +1928,7 @@ long add; /* Add mask, used for huffman prefix */ void fix_new_ns32k(frag, where, size, add_symbol, sub_symbol, offset, pcrel, - pcrel_adjust, im_disp, bit_fixP, bsr) + pcrel_adjust, im_disp, bit_fixP, bsr, r_type) fragS *frag; /* Which frag? */ int where; /* Where in that frag? */ int size; /* 1, 2 or 4 usually. */ @@ -1857,15 +1940,24 @@ char pcrel_adjust; /* not zero if adjustment of pcrel offset is needed */ char im_disp; /* true if the value to write is a displacement */ bit_fixS *bit_fixP; /* pointer at struct of bit_fix's, ignored if NULL */ char bsr; /* sequent-linker-hack: 1 when relocobject is a bsr */ +int r_type; /* Relocation type */ { +#ifdef PIC fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol, - offset, pcrel, NO_RELOC); - + offset, pcrel, r_type, NULL); +#else + fixS *fixP = fix_new(frag, where, size, add_symbol, sub_symbol, + offset, pcrel, r_type); +#endif /* PIC */ fixP->fx_pcrel_adjust = pcrel_adjust; fixP->fx_im_disp = im_disp; fixP->fx_bit_fixP = bit_fixP; fixP->fx_bsr = bsr; +#ifdef PIC + if (r_type == RELOC_GLOB_DAT) + add_symbol->sy_forceout = 1; +#endif /* PIC */ } /* fix_new_ns32k() */ /* We have no need to default values of symbols. */ diff --git a/gnu/usr.bin/as/config/tc-ns32k.h b/gnu/usr.bin/as/config/tc-ns32k.h index c3c09db56f5e..e66c21fdd506 100644 --- a/gnu/usr.bin/as/config/tc-ns32k.h +++ b/gnu/usr.bin/as/config/tc-ns32k.h @@ -17,9 +17,13 @@ along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef TC_NS32K +#define TC_NS32K 1 #include "bit_fix.h" -#define NO_LISTING +#define LOCAL_LABELS_FB + +#define AOUT_MACHTYPE 137 #define tc_aout_pre_write_hook(x) {;} /* not used */ #define tc_crawl_symbol_chain(a) {;} /* not used */ @@ -48,7 +52,8 @@ void fix_new_ns32k(fragS *frag, int pcrel_adjust, int im_disp, bit_fixS *bit_fixP, /* really bit_fixS */ - int bsr); + int bsr, + int r_type); #else /* not __STDC__ */ @@ -56,5 +61,6 @@ void fix_new_ns32k(); #endif /* not __STDC__ */ +#endif /* TC_NS32K */ /* end of tc-ns32k.h */ diff --git a/gnu/usr.bin/as/config/tc-sparc.c b/gnu/usr.bin/as/config/tc-sparc.c index ae5002701ca0..c503ab028a06 100644 --- a/gnu/usr.bin/as/config/tc-sparc.c +++ b/gnu/usr.bin/as/config/tc-sparc.c @@ -18,7 +18,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$Id: tc-sparc.c,v 1.1 1993/11/03 00:54:52 paul Exp $"; +static char rcsid[] = "$Id: tc-sparc.c,v 1.2 1993/12/12 17:02:13 jkh Exp $"; #endif #define cypress 1234 @@ -130,6 +130,34 @@ static void print_insn(); static int getExpression(); #endif /* not __STDC__ */ +static char *Reloc[] = { + "RELOC_8", + "RELOC_16", + "RELOC_32", + "RELOC_DISP8", + "RELOC_DISP16", + "RELOC_DISP32", + "RELOC_WDISP30", + "RELOC_WDISP22", + "RELOC_HI22", + "RELOC_22", + "RELOC_13", + "RELOC_LO10", + "RELOC_SFA_BASE", + "RELOC_SFA_OFF13", + "RELOC_BASE10", + "RELOC_BASE13", + "RELOC_BASE22", + "RELOC_PC10", + "RELOC_PC22", + "RELOC_JMP_TBL", + "RELOC_SEGOFF16", + "RELOC_GLOB_DAT", + "RELOC_JMP_SLOT", + "RELOC_RELATIVE", + "NO_RELOC" +}; + static char *expr_end; static int special_case; @@ -457,7 +485,8 @@ char *str; case SPECIAL_CASE_SET: special_case = 0; - know(the_insn.reloc == RELOC_HI22); + know(the_insn.reloc == RELOC_HI22 || + the_insn.reloc == RELOC_BASE22); /* See if "set" operand has no low-order bits; skip OR if so. */ if (the_insn.exp.X_seg == SEG_ABSOLUTE && ((the_insn.exp.X_add_number & 0x3FF) == 0)) @@ -473,7 +502,7 @@ char *str; the_insn.exp.X_subtract_symbol, the_insn.exp.X_add_number, the_insn.pcrel, - RELOC_LO10, + the_insn.reloc==RELOC_BASE22?RELOC_BASE10:RELOC_LO10, the_insn.exp.X_got_symbol); return; @@ -495,7 +524,7 @@ char *str; return; default: - as_fatal("failed sanity check."); + as_fatal("md_assemble: failed sanity check."); } } /* md_assemble() */ @@ -838,13 +867,14 @@ char *str; break; case 'h': /* high 22 bits */ -#ifdef PIC - the_insn.reloc = flagseen['k']? - RELOC_BASE22: - RELOC_HI22; -#else - the_insn.reloc = RELOC_HI22; -#endif + /* + * In the case of a `set' pseudo instruction + * we have an implied `%hi' operator. + */ + if (special_case == SPECIAL_CASE_SET) + the_insn.reloc = RELOC_HI22; + else + the_insn.reloc = RELOC_22; goto immediate; case 'l': /* 22 bit PC relative immediate */ @@ -853,13 +883,11 @@ char *str; goto immediate; case 'L': /* 30 bit immediate */ + the_insn.reloc = #ifdef PIC - the_insn.reloc = flagseen['k']? - RELOC_JMP_TBL: - RELOC_WDISP30; -#else - the_insn.reloc = RELOC_WDISP30; + flagseen['k']?RELOC_JMP_TBL: #endif + RELOC_WDISP30; the_insn.pcrel = 1; goto immediate; @@ -868,7 +896,7 @@ char *str; goto immediate; case 'i': /* 13 bit immediate */ - the_insn.reloc = RELOC_BASE13; + the_insn.reloc = RELOC_13; /*FALLTHROUGH */ @@ -877,6 +905,9 @@ char *str; s++; if (*s == '%') { if ((c = s[1]) == 'h' && s[2] == 'i') { + if (the_insn.reloc != RELOC_22) + as_bad( + "`%hi' in improper context"); the_insn.reloc = RELOC_HI22; s+=3; } else if (c == 'l' && s[2] == 'o') { @@ -921,8 +952,12 @@ char *str; } (void)getExpression(s); #ifdef PIC + /* + * Handle refs to __GLOBAL_OFFSET_TABLE_ + */ if (the_insn.exp.X_got_symbol) { switch(the_insn.reloc) { + case RELOC_22: case RELOC_HI22: the_insn.reloc = RELOC_PC22; the_insn.pcrel = 1; @@ -935,6 +970,23 @@ char *str; break; } } + + if (flagseen['k'] && the_insn.exp.X_add_symbol) { + switch (the_insn.reloc) { + case RELOC_LO10: + the_insn.reloc = RELOC_BASE10; + the_insn.exp.X_add_symbol->sy_forceout = 1; + break; + case RELOC_HI22: + the_insn.reloc = RELOC_BASE22; + the_insn.exp.X_add_symbol->sy_forceout = 1; + break; + case RELOC_13: + the_insn.reloc = RELOC_BASE13; + the_insn.exp.X_add_symbol->sy_forceout = 1; + break; + } + } #endif s = expr_end; continue; @@ -1012,7 +1064,7 @@ char *str; continue; default: - as_fatal("failed sanity check."); + as_fatal("sparc_ip: failed sanity check."); } /* switch on arg code */ break; } /* for each arg that we expect */ @@ -1072,17 +1124,6 @@ char *str; switch (seg = expression(&the_insn.exp)) { case SEG_ABSOLUTE: - switch (the_insn.reloc) { - case RELOC_LO10: - the_insn.exp.X_add_number &= ~(~(0) << 10); - break; - case RELOC_HI22: - the_insn.exp.X_add_number &= (~(0) << 10); - break; - default: - break; - } - break; case SEG_TEXT: case SEG_DATA: case SEG_BSS: @@ -1098,16 +1139,7 @@ char *str; input_line_pointer=save_in; return 1; } - switch (the_insn.reloc) { - case RELOC_BASE10: - case RELOC_BASE13: - case RELOC_BASE22: - if (the_insn.exp.X_add_symbol) - the_insn.exp.X_add_symbol->sy_forceout = 1; - break; - default: - break; - } + expr_end = input_line_pointer; input_line_pointer = save_in; return 0; @@ -1199,23 +1231,39 @@ int n; break; default: - as_fatal("failed sanity check."); + as_fatal("md_number_to_chars: failed sanity check."); } return; } /* md_number_to_chars() */ -static void reloc_check(val, bits) +static int reloc_check(val, bits, fixP) long val; int bits; +fixS *fixP /* For reporting errors */; { if (((val & (-1 << bits)) != 0) && ((val & (-1 << bits)) != (-1 << (bits - 0)))) { - as_warn("Relocation overflow. Value truncated."); + + long addr = fixP->fx_where + fixP->fx_frag->fr_address; + int ln; + char *fname; + + if (fixP->fx_frag->line) { + fname = fixP->fx_frag->line->file->filename; + ln = fixP->fx_frag->line->line; + } else { + fname = ""; + ln = -1; + } + + as_warn_where(fname, ln, + "Relocation (%s) overflow at %#x, value truncated.", + Reloc[fixP->fx_r_type], addr); } /* on overflow */ - return; } /* reloc_check() */ + /* Apply a fixS to the frags, now that we know the value it ought to hold. */ @@ -1224,20 +1272,9 @@ fixS *fixP; long val; { char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; - + long addr = fixP->fx_where + fixP->fx_frag->fr_address; + #if DEBUG_SPARC - static char *Reloc[] = { - "RELOC_8", "RELOC_16", "RELOC_32", - "RELOC_DISP8", "RELOC_DISP16", "RELOC_DISP32", - "RELOC_WDISP30", "RELOC_WDISP22", - "RELOC_HI22", - "RELOC_22", "RELOC_13", - "RELOC_LO10", "RELOC_SFA_BASE", "RELOC_SFA_OFF13", - "RELOC_BASE10", "RELOC_BASE13", "RELOC_BASE22", "RELOC_PC10", - "RELOC_PC22", "RELOC_JMP_TBL", "RELOC_SEGOFF16", - "RELOC_GLOB_DAT", "RELOC_JMP_SLOT", "RELOC_RELATIVE", - "NO_RELOC" - }; if (flagseen['D']) fprintf(stderr, "md_apply_fix: \"%s\" \"%s\", val %d -- %s\n", ((fixP->fx_addsy != NULL) @@ -1277,24 +1314,38 @@ long val; became ( ( 2 * addend ) + adjustment ). [and there should be no cases that reach here anyway. */ case RELOC_32: - buf[0] = 0; /* val >> 24; */ - buf[1] = 0; /* val >> 16; */ - buf[2] = 0; /* val >> 8; */ - buf[3] = 0; /* val; */ + if (fixP->fx_addsy == NULL) { + /* + * Ok, the remarks above do not hold if the + * expression has been reduced to a number. + */ + buf[0] = val >> 24; + buf[1] = val >> 16; + buf[2] = val >> 8; + buf[3] = val; + } else { + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + } break; -#if 0 - case RELOC_8: /* These don't seem to ever be needed. */ - case RELOC_16: - case RELOC_DISP8: - case RELOC_DISP16: - case RELOC_DISP32: -#endif - case RELOC_JMP_TBL: + if (!fixP->fx_addsy) { + val = (val >>= 2) + 1; + reloc_check(val, 30, fixP); + + buf[0] |= (val >> 24) & 0x3f; + buf[1]= (val >> 16); + buf[2] = val >> 8; + buf[3] = val; + } + break; + case RELOC_WDISP30: val = (val >>= 2) + 1; - reloc_check(val, 30); + reloc_check(val, 30, fixP); buf[0] |= (val >> 24) & 0x3f; buf[1]= (val >> 16); @@ -1302,76 +1353,89 @@ long val; buf[3] = val; break; - - case RELOC_HI22: - reloc_check(val >> 10, 22); + case RELOC_WDISP22: + val = (val >>= 2) + 1; + reloc_check(val, 22, fixP); + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + break; + + /* + * We should only use the RELOC_HI22 type as a result of the %hi + * operator (which is implicit in the case of the `set' pseudo op), + * This is NOT the same as using the `sethi' instruction, which merely + * puts the 22 bit operand into the high 22 bits of the destination + * register. + */ + case RELOC_22: + if (!fixP->fx_addsy) { + reloc_check(val, 22, fixP); + + buf[1] |= (val >> 16) & 0x3f; + buf[2] = val >> 8; + buf[3] = val; + } + break; + + case RELOC_HI22: + case RELOC_BASE22: if (!fixP->fx_addsy) { buf[1] |= (val >> 26) & 0x3f; buf[2] = val >> 18; buf[3] = val >> 10; } else { + if (flagseen['k'] && fixP->fx_r_type == RELOC_HI22) + as_warn("non-PIC access to %s", + S_GET_NAME(fixP->fx_addsy)); buf[2]=0; buf[3]=0; } break; - - case RELOC_PC22: - case RELOC_22: - reloc_check(val, 22); - - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val & 0xff; - break; - - case RELOC_13: - reloc_check(val, 13); - buf[2] = (val >> 8) & 0x1f; - buf[3] = val & 0xff; + case RELOC_13: + case RELOC_BASE13: + if (!fixP->fx_addsy) { + reloc_check(val, 13, fixP); + buf[2] |= (val >> 8) & 0x1f; + buf[3] = val; + } else { + buf[3]=0; + } break; - - - case RELOC_PC10: + case RELOC_LO10: case RELOC_BASE10: - reloc_check(val, 10); - if (!fixP->fx_addsy) { buf[2] |= (val >> 8) & 0x03; - buf[3] = val; - } else - buf[3]=0; + buf[3] = val & 0xff; + } else { + if (flagseen['k'] && fixP->fx_r_type == RELOC_LO10) + as_warn("non-PIC access to %s", + S_GET_NAME(fixP->fx_addsy)); + buf[3]=0; + } break; -#if 0 - case RELOC_SFA_BASE: - case RELOC_SFA_OFF13: -#endif - case RELOC_BASE13: - reloc_check(val, 13); - - buf[2] |= (val >> 8) & 0x1f; - buf[3] = val; - break; - - case RELOC_WDISP22: - val = (val >>= 2) + 1; - /* FALLTHROUGH */ - case RELOC_BASE22: - reloc_check(val, 22); - - buf[1] |= (val >> 16) & 0x3f; - buf[2] = val >> 8; - buf[3] = val; - break; - -#if 0 + case RELOC_PC10: case RELOC_PC22: - case RELOC_JMP_TBL: + if (fixP->fx_addsy != GOT_symbol) { + as_fatal("GOT"); + } + break; + +#if 0 + case RELOC_8: /* These don't seem to ever be needed. */ + case RELOC_16: + case RELOC_DISP8: + case RELOC_DISP16: + case RELOC_DISP32: case RELOC_SEGOFF16: - case RELOC_GLOB_DAT: + case RELOC_SFA_BASE: + case RELOC_SFA_OFF13: + + case RELOC_GLOB_DAT: /* These are output by linker only */ case RELOC_JMP_SLOT: case RELOC_RELATIVE: #endif @@ -1437,8 +1501,8 @@ relax_addressT segment_address_in_file; case RELOC_32: if (!S_IS_EXTERNAL(fixP->fx_addsy)) break; + r_extern = 1; r_index = fixP->fx_addsy->sy_number; - /*kflag = 1;*/ break; default: @@ -1518,33 +1582,6 @@ segT segtype; static void print_insn(insn) struct sparc_it *insn; { - static char *Reloc[] = { - "RELOC_8", - "RELOC_16", - "RELOC_32", - "RELOC_DISP8", - "RELOC_DISP16", - "RELOC_DISP32", - "RELOC_WDISP30", - "RELOC_WDISP22", - "RELOC_HI22", - "RELOC_22", - "RELOC_13", - "RELOC_LO10", - "RELOC_SFA_BASE", - "RELOC_SFA_OFF13", - "RELOC_BASE10", - "RELOC_BASE13", - "RELOC_BASE22", - "RELOC_PC10", - "RELOC_PC22", - "RELOC_JMP_TBL", - "RELOC_SEGOFF16", - "RELOC_GLOB_DAT", - "RELOC_JMP_SLOT", - "RELOC_RELATIVE", - "NO_RELOC" - }; if (insn->error) { fprintf(stderr, "ERROR: %s\n", insn->error); diff --git a/gnu/usr.bin/as/config/tc-sparc.h b/gnu/usr.bin/as/config/tc-sparc.h index 27355a70a822..f21baf1aa7fa 100644 --- a/gnu/usr.bin/as/config/tc-sparc.h +++ b/gnu/usr.bin/as/config/tc-sparc.h @@ -18,24 +18,22 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: tc-sparc.h,v 1.1 1993/10/02 20:59:41 pk Exp $ + * $Id: tc-sparc.h,v 1.1 1993/11/03 00:54:54 paul Exp $ */ #define TC_SPARC 1 -#define NO_LISTING #define LOCAL_LABELS_FB #define WORKING_DOT_WORD -#ifdef OBJ_BOUT -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | BMAGIC) /* Magic number for header */ -#else -#ifdef OBJ_AOUT -#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE ((0x103 << 16) | OMAGIC) /* Magic number for header */ -#endif /* OBJ_AOUT */ -#endif /* OBJ_BOUT */ +#ifdef __NetBSD__ +#define AOUT_MACHTYPE 138 +#endif -#define AOUT_MACHTYPE 3 +#ifdef sun +#define AOUT_MACHTYPE 3 +#define AOUT_VERSION 1 +#endif #define tc_headers_hook(a) {;} /* don't need it. */ #define tc_crawl_symbol_chain(a) {;} /* don't need it. */ diff --git a/gnu/usr.bin/as/input-scrub.c b/gnu/usr.bin/as/input-scrub.c index 73df1a2246b3..f914665bb0ba 100644 --- a/gnu/usr.bin/as/input-scrub.c +++ b/gnu/usr.bin/as/input-scrub.c @@ -1,27 +1,27 @@ /* input_scrub.c - Break up input buffers into whole numbers of lines. Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$Id: input-scrub.c,v 1.3 1993/10/02 20:57:39 pk Exp $"; +static char rcsid[] = "$Id: input-scrub.c,v 1.2 1993/11/03 00:51:51 paul Exp $"; #endif -#include /* Need this to make errno declaration right */ +#include /* Need this to make errno declaration right */ #include "as.h" #include "input-file.h" @@ -56,15 +56,15 @@ static char rcsid[] = "$Id: input-scrub.c,v 1.3 1993/10/02 20:57:39 pk Exp $"; #define BEFORE_SIZE (1) #define AFTER_SIZE (1) -static char * buffer_start; /*->1st char of full buffer area. */ -static char * partial_where; /*->after last full line in buffer. */ -static int partial_size; /* >= 0. Number of chars in partial line in buffer. */ +static char *buffer_start; /*->1st char of full buffer area. */ +static char *partial_where; /*->after last full line in buffer. */ +static int partial_size; /* >=0. Number of chars in partial line in buffer. */ static char save_source[AFTER_SIZE]; /* Because we need AFTER_STRING just after last */ /* full line, it clobbers 1st part of partial */ /* line. So we preserve 1st part of partial */ /* line here. */ -static int buffer_length; /* What is the largest size buffer that */ +static unsigned int buffer_length; /* What is the largest size buffer that */ /* input_file_give_next_buffer() could */ /* return to us? */ @@ -84,138 +84,144 @@ static char *next_saved_file; source line numbers. Whenever we open a file we must fill in physical_input_file. So if it is NULL we have not opened any files yet. */ -char *physical_input_file; -char *logical_input_file; +static char *physical_input_file; +static char *logical_input_file; -typedef unsigned int line_numberT; /* 1-origin line number in a source file. */ +typedef unsigned int line_numberT; /* 1-origin line number in a source file. */ /* A line ends in '\n' or eof. */ -line_numberT physical_input_line; -line_numberT logical_input_line; +static line_numberT physical_input_line; +static int logical_input_line; /* Struct used to save the state of the input handler during include files */ -struct input_save { - char *buffer_start; - char *partial_where; - int partial_size; - char save_source[AFTER_SIZE]; - int buffer_length; - char *physical_input_file; - char *logical_input_file; - line_numberT physical_input_line; - line_numberT logical_input_line; - char *next_saved_file; /* Chain of input_saves */ - char *input_file_save; /* Saved state of input routines */ - char *saved_position; /* Caller's saved position in buf */ -}; +struct input_save + { + char *buffer_start; + char *partial_where; + int partial_size; + char save_source[AFTER_SIZE]; + unsigned int buffer_length; + char *physical_input_file; + char *logical_input_file; + line_numberT physical_input_line; + int logical_input_line; + char *next_saved_file; /* Chain of input_saves */ + char *input_file_save; /* Saved state of input routines */ + char *saved_position; /* Caller's saved position in buf */ + }; -#if __STDC__ == 1 -static void as_1_char(unsigned int c, FILE *stream); -#else /* __STDC__ */ -static void as_1_char(); -#endif /* not __STDC__ */ +static char *input_scrub_push PARAMS ((char *saved_position)); +static char *input_scrub_pop PARAMS ((char *arg)); +static void as_1_char PARAMS ((unsigned int c, FILE * stream)); /* Push the state of input reading and scrubbing so that we can #include. The return value is a 'void *' (fudged for old compilers) to a save area, which can be restored by passing it to input_scrub_pop(). */ -char *input_scrub_push(saved_position) -char *saved_position; +static char * +input_scrub_push (saved_position) + char *saved_position; { - register struct input_save *saved; - - saved = (struct input_save *) xmalloc(sizeof *saved); - - saved->saved_position = saved_position; - saved->buffer_start = buffer_start; - saved->partial_where = partial_where; - saved->partial_size = partial_size; - saved->buffer_length = buffer_length; - saved->physical_input_file = physical_input_file; - saved->logical_input_file = logical_input_file; - saved->physical_input_line = physical_input_line; - saved->logical_input_line = logical_input_line; - memcpy(save_source, saved->save_source, sizeof(save_source)); - saved->next_saved_file = next_saved_file; - saved->input_file_save = input_file_push(); - - input_scrub_begin(); /* Reinitialize! */ - - return((char *) saved); -} /* input_scrub_push() */ + register struct input_save *saved; -char * - input_scrub_pop (arg) -char *arg; + saved = (struct input_save *) xmalloc (sizeof *saved); + + saved->saved_position = saved_position; + saved->buffer_start = buffer_start; + saved->partial_where = partial_where; + saved->partial_size = partial_size; + saved->buffer_length = buffer_length; + saved->physical_input_file = physical_input_file; + saved->logical_input_file = logical_input_file; + saved->physical_input_line = physical_input_line; + saved->logical_input_line = logical_input_line; + memcpy (saved->save_source, save_source, sizeof (save_source)); + saved->next_saved_file = next_saved_file; + saved->input_file_save = input_file_push (); + + input_file_begin (); /* Reinitialize! */ + logical_input_line = -1; + logical_input_file = (char *) NULL; + buffer_length = input_file_buffer_size (); + + buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); + + return ((char *) saved); +} /* input_scrub_push() */ + +static char * +input_scrub_pop (arg) + char *arg; { - register struct input_save *saved; - char *saved_position; - - input_scrub_end (); /* Finish off old buffer */ - - saved = (struct input_save *)arg; - - input_file_pop (saved->input_file_save); - saved_position = saved->saved_position; - buffer_start = saved->buffer_start; - buffer_length = saved->buffer_length; - physical_input_file = saved->physical_input_file; - logical_input_file = saved->logical_input_file; - physical_input_line = saved->physical_input_line; - logical_input_line = saved->logical_input_line; - partial_where = saved->partial_where; - partial_size = saved->partial_size; - next_saved_file = saved->next_saved_file; - memcpy(saved->save_source, save_source, sizeof (save_source)); - - free(arg); - return saved_position; + register struct input_save *saved; + char *saved_position; + + input_scrub_end (); /* Finish off old buffer */ + + saved = (struct input_save *) arg; + + input_file_pop (saved->input_file_save); + saved_position = saved->saved_position; + buffer_start = saved->buffer_start; + buffer_length = saved->buffer_length; + physical_input_file = saved->physical_input_file; + logical_input_file = saved->logical_input_file; + physical_input_line = saved->physical_input_line; + logical_input_line = saved->logical_input_line; + partial_where = saved->partial_where; + partial_size = saved->partial_size; + next_saved_file = saved->next_saved_file; + memcpy (save_source, saved->save_source, sizeof (save_source)); + + free (arg); + return saved_position; } - + void - input_scrub_begin () +input_scrub_begin () { - know(strlen(BEFORE_STRING) == BEFORE_SIZE); - know(strlen(AFTER_STRING) == AFTER_SIZE || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); - - input_file_begin (); - - buffer_length = input_file_buffer_size (); - - buffer_start = xmalloc((long)(BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); - memcpy(buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); - - /* Line number things. */ - logical_input_line = 0; - logical_input_file = (char *)NULL; - physical_input_file = NULL; /* No file read yet. */ - next_saved_file = NULL; /* At EOF, don't pop to any other file */ - do_scrub_begin(); + know (strlen (BEFORE_STRING) == BEFORE_SIZE); + know (strlen (AFTER_STRING) == AFTER_SIZE || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); + + input_file_begin (); + + buffer_length = input_file_buffer_size (); + + buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); + + /* Line number things. */ + logical_input_line = -1; + logical_input_file = (char *) NULL; + physical_input_file = NULL; /* No file read yet. */ + next_saved_file = NULL; /* At EOF, don't pop to any other file */ + do_scrub_begin (); } void - input_scrub_end () +input_scrub_end () { - if (buffer_start) - { - free (buffer_start); - buffer_start = 0; - input_file_end (); - } + if (buffer_start) + { + free (buffer_start); + buffer_start = 0; + input_file_end (); + } } /* Start reading input from a new file. */ char * /* Return start of caller's part of buffer. */ - input_scrub_new_file (filename) -char * filename; +input_scrub_new_file (filename) + char *filename; { - input_file_open (filename, !flagseen['f']); - physical_input_file = filename[0] ? filename : "{standard input}"; - physical_input_line = 0; - - partial_size = 0; - return (buffer_start + BEFORE_SIZE); + input_file_open (filename, !flagseen['f']); + physical_input_file = filename[0] ? filename : "{standard input}"; + physical_input_line = 0; + + partial_size = 0; + return (buffer_start + BEFORE_SIZE); } @@ -224,97 +230,66 @@ char * filename; input_scrub_new_file. */ char * - input_scrub_include_file (filename, position) -char *filename; -char *position; +input_scrub_include_file (filename, position) + char *filename; + char *position; { - next_saved_file = input_scrub_push(position); - return input_scrub_new_file (filename); + next_saved_file = input_scrub_push (position); + return input_scrub_new_file (filename); } void - input_scrub_close () +input_scrub_close () { - input_file_close (); + input_file_close (); } + char * - input_scrub_next_buffer (bufp) -char **bufp; +input_scrub_next_buffer (bufp) + char **bufp; { - register char * limit; /*->just after last char of buffer. */ - - *bufp = buffer_start + BEFORE_SIZE; - -#ifdef DONTDEF - if (preprocess) { - if (save_buffer) { - *bufp = save_buffer; - save_buffer = 0; - } - limit = input_file_give_next_buffer(buffer_start+BEFORE_SIZE); - if (!limit) { - partial_where = 0; - if (partial_size) - as_warn("Partial line at end of file ignored"); - return partial_where; - } - - if (partial_size) - memcpy(partial_where, save_source, (int) AFTER_SIZE); - do_scrub(partial_where, partial_size, - buffer_start + BEFORE_SIZE, - limit - (buffer_start + BEFORE_SIZE), - &out_string, &out_length); - limit=out_string + out_length; - for (p=limit;*--p != '\n';) - ; - p++; - if (p <= buffer_start+BEFORE_SIZE) - as_fatal("Source line too long. Please change file '%s' and re-make the assembler.", __FILE__); - - partial_where = p; - partial_size = limit-p; - memcpy(save_source, partial_where, (int) AFTER_SIZE); - memcpy(partial_where, AFTER_STRING, (int) AFTER_SIZE); - - save_buffer = *bufp; - *bufp = out_string; - - return partial_where; + register char *limit; /*->just after last char of buffer. */ + + *bufp = buffer_start + BEFORE_SIZE; + + if (partial_size) + { + memcpy (buffer_start + BEFORE_SIZE, partial_where, + (unsigned int) partial_size); + memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); + } + limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size); + if (limit) + { + register char *p; /* Find last newline. */ + + for (p = limit; *--p != '\n';);; + ++p; + if (p <= buffer_start + BEFORE_SIZE) + { + as_fatal ("Source line too long. Please change file %s then rebuild assembler.", __FILE__); } - - /* We're not preprocessing. Do the right thing */ -#endif - if (partial_size) { - memcpy(buffer_start + BEFORE_SIZE, partial_where, (int) partial_size); - memcpy(buffer_start + BEFORE_SIZE, save_source, (int) AFTER_SIZE); + partial_where = p; + partial_size = limit - p; + memcpy (save_source, partial_where, (int) AFTER_SIZE); + memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE); + } + else + { + partial_where = 0; + if (partial_size > 0) + { + as_warn ("Partial line at end of file ignored"); } - limit = input_file_give_next_buffer (buffer_start + BEFORE_SIZE + partial_size); - if (limit) { - register char * p; /* Find last newline. */ - - for (p = limit; *--p != '\n';) ;; - ++p; - if (p <= buffer_start + BEFORE_SIZE) { - as_fatal("Source line too long. Please change file %s then rebuild assembler.", __FILE__); - } - partial_where = p; - partial_size = limit - p; - memcpy(save_source, partial_where, (int) AFTER_SIZE); - memcpy(partial_where, AFTER_STRING, (int) AFTER_SIZE); - } else { - partial_where = 0; - if (partial_size > 0) { - as_warn("Partial line at end of file ignored"); - } - /* If we should pop to another file at EOF, do it. */ - if (next_saved_file) { - *bufp = input_scrub_pop (next_saved_file); /* Pop state */ - /* partial_where is now correct to return, since we popped it. */ - } + /* If we should pop to another file at EOF, do it. */ + if (next_saved_file) + { + *bufp = input_scrub_pop (next_saved_file); /* Pop state */ + /* partial_where is now correct to return, since we popped it. */ } - return(partial_where); -} /* input_scrub_next_buffer() */ + } + return (partial_where); +} /* input_scrub_next_buffer() */ /* * The remaining part of this file deals with line numbers, error @@ -323,66 +298,81 @@ char **bufp; int - seen_at_least_1_file () /* TRUE if we opened any file. */ +seen_at_least_1_file () /* TRUE if we opened any file. */ { - return (physical_input_file != NULL); + return (physical_input_file != NULL); } void - bump_line_counters () +bump_line_counters () { - ++ physical_input_line; - /* ++ logical_input_line; FIXME-now remove this. */ + ++physical_input_line; + if (logical_input_line >= 0) + ++logical_input_line; } /* * new_logical_line() * * Tells us what the new logical line number and file are. - * If the line_number is <0, we don't change the current logical line number. + * If the line_number is -1, we don't change the current logical line + * number. If it is -2, we decrement the logical line number (this is + * to support the .appfile pseudo-op inserted into the stream by + * do_scrub_next_char). * If the fname is NULL, we don't change the current logical file name. */ -void new_logical_line(fname, line_number) -char *fname; /* DON'T destroy it! We point to it! */ -int line_number; +void +new_logical_line (fname, line_number) + char *fname; /* DON'T destroy it! We point to it! */ + int line_number; { - if (fname) { - logical_input_file = fname; - } /* if we have a file name */ - - if (line_number >= 0) { - logical_input_line = line_number; - } /* if we have a line number */ -} /* new_logical_line() */ + if (fname) + { + logical_input_file = fname; + } /* if we have a file name */ + + if (line_number >= 0) + logical_input_line = line_number; + else if (line_number == -2 && logical_input_line > 0) + --logical_input_line; +} /* new_logical_line() */ /* * a s _ w h e r e () * - * Write a line to stderr locating where we are in reading - * input source files. - * As a sop to the debugger of AS, pretty-print the offending line. + * Return the current file name and line number. + * namep should be char * const *, but there are compilers which screw + * up declarations like that, and it's easier to avoid it. */ -void as_where() { - char *p; - line_numberT line; - extern char *myname; - - if (logical_input_file && (logical_input_line > 0)) { - p = logical_input_file; - line = logical_input_line; - } else { - p = physical_input_file; - line = physical_input_line; - } /* line number should match file name */ - - fprintf(stderr, "%s: %s:%u: ", myname, p, line); - - return; -} /* as_where() */ - - - +void +as_where (namep, linep) + char **namep; + unsigned int *linep; +{ + if (logical_input_file != NULL + && (linep == NULL || logical_input_line >= 0)) + { + *namep = logical_input_file; + if (linep != NULL) + *linep = logical_input_line; + } + else if (physical_input_file != NULL) + { + *namep = physical_input_file; + if (linep != NULL) + *linep = physical_input_line; + } + else + { + *namep = (char *) "*unknown*"; + if (linep != NULL) + *linep = 0; + } +} /* as_where() */ + + + /* * a s _ h o w m u c h () * @@ -391,46 +381,40 @@ void as_where() { * No free '\n' at end of line. */ void - as_howmuch (stream) -FILE * stream; /* Opened for write please. */ +as_howmuch (stream) + FILE *stream; /* Opened for write please. */ { - register char * p; /* Scan input line. */ - /* register char c; JF unused */ - - for (p = input_line_pointer - 1; * p != '\n'; --p) - { - } - ++ p; /* p->1st char of line. */ - for (; p <= input_line_pointer; p++) - { - /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */ - /* c = *p & 0xFF; JF unused */ - as_1_char(*p, stream); - } + register char *p; /* Scan input line. */ + /* register char c; JF unused */ + + for (p = input_line_pointer - 1; *p != '\n'; --p) + { + } + ++p; /* p->1st char of line. */ + for (; p <= input_line_pointer; p++) + { + /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */ + /* c = *p & 0xFF; JF unused */ + as_1_char ((unsigned char) *p, stream); + } } -static void as_1_char (c,stream) -unsigned int c; -FILE *stream; +static void +as_1_char (c, stream) + unsigned int c; + FILE *stream; { - if (c > 127) - { - (void)putc('%', stream); - c -= 128; - } - if (c < 32) - { - (void)putc('^', stream); - c += '@'; - } - (void)putc(c, stream); + if (c > 127) + { + (void) putc ('%', stream); + c -= 128; + } + if (c < 32) + { + (void) putc ('^', stream); + c += '@'; + } + (void) putc (c, stream); } -/* - * Local Variables: - * comment-column: 0 - * fill-column: 131 - * End: - */ - /* end of input_scrub.c */ diff --git a/gnu/usr.bin/as/listing.c b/gnu/usr.bin/as/listing.c index 2f8b1f02dc3d..df14a5e383d4 100644 --- a/gnu/usr.bin/as/listing.c +++ b/gnu/usr.bin/as/listing.c @@ -1,108 +1,108 @@ /* listing.c - mainting assembly listings Copyright (C) 1991, 1992 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - GAS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +This file is part of GAS, the GNU Assembler. + +GAS is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GAS is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GAS; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - Contributed by Steve Chamberlain - sac@cygnus.com - - - A listing page looks like: - - LISTING_HEADER sourcefilename pagenumber - TITLE LINE - SUBTITLE LINE - linenumber address data source - linenumber address data source - linenumber address data source - linenumber address data source - - If not overridden, the listing commands are: - - .title "stuff" - Put "stuff" onto the title line - .sbttl "stuff" - Put stuff onto the subtitle line - + Contributed by Steve Chamberlain + sac@cygnus.com + + + A listing page looks like: + + LISTING_HEADER sourcefilename pagenumber + TITLE LINE + SUBTITLE LINE + linenumber address data source + linenumber address data source + linenumber address data source + linenumber address data source + + If not overridden, the listing commands are: + + .title "stuff" + Put "stuff" onto the title line + .sbttl "stuff" + Put stuff onto the subtitle line + If these commands come within 10 lines of the top of the page, they will affect the page they are on, as well as any subsequent page - - .eject - Thow a page - .list - Increment the enable listing counter - .nolist - Decrement the enable listing counter - - .psize Y[,X] - Set the paper size to X wide and Y high. Setting a psize Y of - zero will suppress form feeds except where demanded by .eject - - If the counter goes below zero, listing is suppressed. - - - Listings are a maintained by read calling various listing_ - functions. What happens most is that the macro NO_LISTING is not - defined (from the Makefile), then the macro LISTING_NEWLINE expands - into a call to listing_newline. The call is done from read.c, every - time it sees a newline, and -l is on the command line. - - The function listing_newline remembers the frag associated with the - newline, and creates a new frag - note that this is wasteful, but not - a big deal, since listing slows things down a lot anyway. The - function also rememebers when the filename changes. - - When all the input has finished, and gas has had a chance to settle - down, the listing is output. This is done by running down the list of - frag/source file records, and opening the files as needed and printing - out the bytes and chars associated with them. - - The only things which the architecture can change about the listing - are defined in these macros: - - LISTING_HEADER The name of the architecture - LISTING_WORD_SIZE The make of the number of bytes in a word, this determines - the clumping of the output data. eg a value of - 2 makes words look like 1234 5678, whilst 1 - would make the same value look like 12 34 56 - 78 - LISTING_LHS_WIDTH Number of words of above size for the lhs - - LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs - for the second line - - LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation - LISTING_RHS_WIDTH Number of chars from the input file to print - on a line - */ + + .eject + Thow a page + .list + Increment the enable listing counter + .nolist + Decrement the enable listing counter + + .psize Y[,X] + Set the paper size to X wide and Y high. Setting a psize Y of + zero will suppress form feeds except where demanded by .eject + + If the counter goes below zero, listing is suppressed. + + + Listings are a maintained by read calling various listing_ + functions. What happens most is that the macro NO_LISTING is not + defined (from the Makefile), then the macro LISTING_NEWLINE expands + into a call to listing_newline. The call is done from read.c, every + time it sees a newline, and -l is on the command line. + + The function listing_newline remembers the frag associated with the + newline, and creates a new frag - note that this is wasteful, but not + a big deal, since listing slows things down a lot anyway. The + function also rememebers when the filename changes. + + When all the input has finished, and gas has had a chance to settle + down, the listing is output. This is done by running down the list of + frag/source file records, and opening the files as needed and printing + out the bytes and chars associated with them. + + The only things which the architecture can change about the listing + are defined in these macros: + + LISTING_HEADER The name of the architecture + LISTING_WORD_SIZE The make of the number of bytes in a word, this determines + the clumping of the output data. eg a value of + 2 makes words look like 1234 5678, whilst 1 + would make the same value look like 12 34 56 + 78 + LISTING_LHS_WIDTH Number of words of above size for the lhs + + LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs + for the second line + + LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation + LISTING_RHS_WIDTH Number of chars from the input file to print + on a line +*/ #ifndef lint -static char rcsid[] = "$Id: listing.c,v 1.1 1993/10/02 20:57:40 pk Exp $"; +static char rcsid[] = "$Id: listing.c,v 1.1 1993/11/03 00:51:54 paul Exp $"; #endif +#include + #include "as.h" - -#ifndef NO_LISTING - #include #include "input-file.h" -#include "targ-cpu.h" +#include "subsegs.h" +#ifndef NO_LISTING #ifndef LISTING_HEADER #define LISTING_HEADER "GAS LISTING" #endif @@ -118,732 +118,962 @@ static char rcsid[] = "$Id: listing.c,v 1.1 1993/10/02 20:57:40 pk Exp $"; #ifndef LISTING_RHS_WIDTH #define LISTING_RHS_WIDTH 100 #endif -#ifndef LISTING_LHS_CONT_LINES +#ifndef LISTING_LHS_CONT_LINES #define LISTING_LHS_CONT_LINES 4 #endif -/* This structure remembers which .s were used */ -typedef struct file_info_struct { - char *filename; - int linenum; - FILE *file; - struct file_info_struct *next; - int end_pending; -} file_info_type ; -/* this structure rememebrs which line from which file goes into which frag */ -typedef struct list_info_struct { - /* Frag which this line of source is nearest to */ - fragS *frag; - /* The actual line in the source file */ - unsigned int line; - /* Pointer to the file info struct for the file which this line - belongs to */ - file_info_type *file; - - /* Next in list */ - struct list_info_struct *next; - - - /* Pointer to the file info struct for the high level language - source line that belongs here */ - file_info_type *hll_file; - - /* High level language source line */ - int hll_line; - - - /* Pointer to any error message associated with this line */ - char *message; - - enum { - EDICT_NONE, - EDICT_SBTTL, - EDICT_TITLE, - EDICT_NOLIST, - EDICT_LIST, - EDICT_EJECT, - } edict; - char *edict_arg; -} list_info_type; - static struct list_info_struct *head; struct list_info_struct *listing_tail; extern int listing; -extern unsigned int physical_input_line; extern fragS *frag_now; + static int paper_width = 200; static int paper_height = 60; + /* this static array is used to keep the text of data to be printed - before the start of the line. It is stored so we can give a bit - more info on the next line. To much, and large initialized arrays - will use up lots of paper. */ + before the start of the line. + It is stored so we can give a bit more info on the next line. To much, and large + initialized arrays will use up lots of paper. + */ static char data_buffer[100]; static unsigned int data_buffer_size; + +/* Prototypes. */ +static void listing_message PARAMS ((const char *name, const char *message)); +static file_info_type *file_info PARAMS ((const char *file_name)); +static void new_frag PARAMS ((void)); +static char *buffer_line PARAMS ((file_info_type *file, + char *line, unsigned int size)); +static void listing_page PARAMS ((list_info_type *list)); +static unsigned int calc_hex PARAMS ((list_info_type *list)); +static void print_lines PARAMS ((list_info_type *list, + char *string, + unsigned int address)); +static void list_symbol_table PARAMS ((void)); +static void print_source PARAMS ((file_info_type *current_file, + list_info_type *list, + char *buffer, + unsigned int width)); +static int debugging_pseudo PARAMS ((char *line)); +static void listing_listing PARAMS ((char *name)); + + static void - listing_message(name, message) -char *name; -char *message; +listing_message (name, message) + const char *name; + const char *message; { - unsigned int l = strlen(name) + strlen(message) + 1; - char *n = malloc(l); - strcpy(n,name); - strcat(n,message); - if (listing_tail != (list_info_type *)NULL) { - listing_tail->message = n; - } - - return; -} /* lising_message() */ - -void - listing_warning(message) -char *message; -{ - listing_message("Warning:", message); + unsigned int l = strlen (name) + strlen (message) + 1; + char *n = (char *) xmalloc (l); + strcpy (n, name); + strcat (n, message); + if (listing_tail != (list_info_type *) NULL) + { + listing_tail->message = n; + } } void - listing_error(message) -char *message; +listing_warning (message) + const char *message; { - listing_message("Error:", message); + listing_message ("Warning:", message); } +void +listing_error (message) + const char *message; +{ + listing_message ("Error:", message); +} + + + + static file_info_type *file_info_head; static file_info_type * - file_info(file_name) -char *file_name; +file_info (file_name) + const char *file_name; { - /* Find an entry with this file name */ - file_info_type *p = file_info_head; - - while (p != (file_info_type *)NULL) { - if (strcmp(p->filename, file_name) == 0) - return(p); - p = p->next; - } - - /* Make new entry */ - - p = (file_info_type *) xmalloc(sizeof(file_info_type)); - p->next = file_info_head; - file_info_head = p; - p->filename = xmalloc(strlen(file_name)+1); - strcpy(p->filename, file_name); - p->linenum = 0; - p->end_pending = 0; - - p->file = fopen(p->filename,"r"); - return(p); -} /* file_info() */ + /* Find an entry with this file name */ + file_info_type *p = file_info_head; + while (p != (file_info_type *) NULL) + { + if (strcmp (p->filename, file_name) == 0) + return p; + p = p->next; + } -static void - new_frag() -{ - frag_wane(frag_now); - frag_new(0); + /* Make new entry */ + + p = (file_info_type *) xmalloc (sizeof (file_info_type)); + p->next = file_info_head; + file_info_head = p; + p->filename = xmalloc ((unsigned long) strlen (file_name) + 1); + strcpy (p->filename, file_name); + p->linenum = 0; + p->end_pending = 0; + + /* Do we really prefer binary mode for this?? */ +#define FOPEN_RB "r" + p->file = fopen (p->filename, FOPEN_RB); + if (p->file) + fgetc (p->file); + + return p; } -void - listing_newline(ps) -char *ps; + +static void +new_frag () { - char *s = ps; - extern char *file_name; - static unsigned int last_line = 0xffff ; - - - list_info_type *new; - if (physical_input_line != last_line) { - last_line = physical_input_line; - new_frag(); - - new = (list_info_type *) malloc(sizeof(list_info_type)); - new->frag = frag_now; - new->line = physical_input_line ; - new->file = file_info(file_name); - - if (listing_tail) { - listing_tail->next = new; - } else { - head = new; - } - - listing_tail = new; - new->next = (list_info_type *) NULL; - new->message = (char *) NULL; - new->edict = EDICT_NONE; - new->hll_file = (file_info_type*) NULL; - new->hll_line = 0; - new_frag(); + + frag_wane (frag_now); + frag_new (0); + +} + +void +listing_newline (ps) + char *ps; +{ + char *file; + unsigned int line; + static unsigned int last_line = 0xffff; + static char *last_file = NULL; + list_info_type *new; + + as_where (&file, &line); + if (line != last_line || last_file && file && strcmp(file, last_file)) + { + last_line = line; + last_file = file; + new_frag (); + + new = (list_info_type *) xmalloc (sizeof (list_info_type)); + new->frag = frag_now; + new->line = line; + new->file = file_info (file); + + if (listing_tail) + { + listing_tail->next = new; } + else + { + head = new; + } + listing_tail = new; + new->next = (list_info_type *) NULL; + new->message = (char *) NULL; + new->edict = EDICT_NONE; + new->hll_file = (file_info_type *) NULL; + new->hll_line = 0; + new_frag (); + } +} - return; -} /* listing_newline() */ +/* Attach all current frags to the previous line instead of the + current line. This is called by the MIPS backend when it discovers + that it needs to add some NOP instructions; the added NOP + instructions should go with the instruction that has the delay, not + with the new instruction. */ +void +listing_prev_line () +{ + list_info_type *l; + fragS *f; -/* This function returns the next source line from the file supplied, - truncated to size. It appends a fake line to the end of each input - file to make. */ + if (head == (list_info_type *) NULL + || head == listing_tail) + return; + + new_frag (); + + for (l = head; l->next != listing_tail; l = l->next) + ; + + for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) + if (f->line == listing_tail) + f->line = l; + + listing_tail->frag = frag_now; + new_frag (); +} + +/* + This function returns the next source line from the file supplied, + truncated to size. It appends a fake line to the end of each input + file to make +*/ static char * - buffer_line(file, line, size) -file_info_type *file; -char *line; -unsigned int size; +buffer_line (file, line, size) + file_info_type * file; + char *line; + unsigned int size; { - unsigned int count = 0; - int c; - - char *p = line; - - /* If we couldn't open the file, return an empty line */ - if (file->file == (FILE*) NULL) { - return(""); - } - - if (file->end_pending == 10) { - *p ++ = '\n'; - rewind(file->file); - file->linenum = 0; - file->end_pending = 0; - } - - c = fgetc(file->file); - size -= 1; /* leave room for null */ - - while (c != EOF && c != '\n') { - if (count < size) - *p++ = c; - count++; - - c = fgetc(file->file); - } - - if (c == EOF) { - file->end_pending ++; - *p++ = 'E'; - *p++ = 'O'; - *p++ = 'F'; - } - - file->linenum++; - *p++ = 0; - return(line); -} /* buffer_line() */ + unsigned int count = 0; + int c; -static char *fn; + char *p = line; + + /* If we couldn't open the file, return an empty line */ + if (file->file == (FILE *) NULL) + { + return ""; + } + + if (file->linenum == 0) + rewind (file->file); + + if (file->end_pending == 10) + { + *p++ = '\n'; + fseek (file->file, 0, 0); + file->linenum = 0; + file->end_pending = 0; + } + c = fgetc (file->file); + + + size -= 1; /* leave room for null */ + + while (c != EOF && c != '\n') + { + if (count < size) + *p++ = c; + count++; + + c = fgetc (file->file); + + } + if (c == EOF) + { + file->end_pending++; + *p++ = '.'; + *p++ = '.'; + *p++ = '.'; + } + file->linenum++; + *p++ = 0; + return line; +} + + +static const char *fn; static unsigned int eject; /* Eject pending */ -static unsigned int page; /* Current page number */ -static char *title; /* current title */ +static unsigned int page; /* Current page number */ +static char *title; /* current title */ static char *subtitle; /* current subtitle */ -static unsigned int on_page; /* number of lines printed on current page */ - -static void - listing_page(list) -list_info_type *list; -{ - /* Grope around, see if we can see a title or subtitle edict - coming up soon (we look down 10 lines of the page and see - if it's there). */ - - if ((eject || (on_page >= paper_height)) && paper_height != 0) { - unsigned int c = 10; - int had_title = 0; - int had_subtitle = 0; - - page++; - - while (c != 0 && list) { - if (list->edict == EDICT_SBTTL && !had_subtitle) { - had_subtitle = 1; - subtitle = list->edict_arg; - } - - if (list->edict == EDICT_TITLE && !had_title) { - had_title = 1; - title = list->edict_arg; - } - list = list->next; - --c; - } - - if (page > 1) { - printf("\f"); - } - - printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); - printf("%s\n", title); - printf("%s\n", subtitle); - on_page = 3; - eject = 0; - } - - return; -} /* listing_page() */ - - -static unsigned int - calc_hex(list) -list_info_type *list; -{ - list_info_type *first = list; - list_info_type *last = first; - unsigned int address = ~0; - - fragS *frag; - fragS *frag_ptr; - - unsigned int byte_in_frag = 0; - - int anything = 0; - - /* Find first frag which says it belongs to this line */ - frag = list->frag; - while (frag && frag->line != list) - frag = frag->fr_next; - - frag_ptr = frag; - - data_buffer_size = 0; - - /* Dump all the frags which belong to this line */ - while (frag_ptr != (fragS *)NULL && frag_ptr->line == first) { - /* Print as many bytes from the fixed part as is sensible */ - while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10) { - if (address == ~0) { - address = frag_ptr->fr_address; - } - - sprintf(data_buffer + data_buffer_size, "%02X", (frag_ptr->fr_literal[byte_in_frag]) & 0xff); - data_buffer_size += 2; - byte_in_frag++; - } - - /* Print as many bytes from the variable part as is sensible */ - while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset - && data_buffer_size < sizeof(data_buffer)-10) { - if (address == ~0) { - address = frag_ptr->fr_address; - } - data_buffer[data_buffer_size++] = '*'; - data_buffer[data_buffer_size++] = '*'; - - byte_in_frag++; - } - - frag_ptr = frag_ptr->fr_next; - } - - data_buffer[data_buffer_size++] = 0; - return address; -} /* calc_hex() */ - -static void - print_lines(list, string, address) -list_info_type *list; -char *string; -unsigned int address; -{ - unsigned int idx; - unsigned int nchars; - unsigned int lines; - unsigned int byte_in_word =0; - char *src = data_buffer; - - /* Print the stuff on the first line */ - listing_page(list); - nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH ; - - /* Print the hex for the first line */ - if (address == ~0) { - printf("% 4d ", list->line); - for (idx = 0; idx < nchars; idx++) - printf(" "); - - printf("\t%s\n", string ? string : ""); - on_page++; - listing_page(0); - } else { - if (had_errors()) { - printf("% 4d ???? ", list->line); - } else { - printf("% 4d %04x ", list->line, address); - } - - /* And the data to go along with it */ - idx = 0; - - while (*src && idx < nchars) { - printf("%c%c", src[0], src[1]); - src += 2; - byte_in_word++; - - if (byte_in_word == LISTING_WORD_SIZE) { - printf(" "); - idx++; - byte_in_word = 0; - } - idx+=2; - } - - for (;idx < nchars; idx++) - printf(" "); - - printf("\t%s\n", string ? string : ""); - on_page++; - listing_page(list); - if (list->message) { - printf("**** %s\n",list->message); - listing_page(list); - on_page++; - } - - for (lines = 0; lines < LISTING_LHS_CONT_LINES && *src; lines++) { - nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1; - idx = 0; - /* Print any more lines of data, but more compactly */ - printf("% 4d ", list->line); - - while (*src && idx < nchars) { - printf("%c%c", src[0], src[1]); - src+=2; - idx+=2; - byte_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) { - printf(" "); - idx++; - byte_in_word = 0; - } - } - - printf("\n"); - on_page++; - listing_page(list); - } - } -} /* print_lines() */ +static unsigned int on_page; /* number of lines printed on current page */ static void - list_symbol_table() +listing_page (list) + list_info_type *list; { - extern symbolS *symbol_rootP; - symbolS *ptr; - - eject = 1; - listing_page(0); - printf("DEFINED SYMBOLS\n"); - on_page++; - - for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) { - if (ptr->sy_frag->line) { - if (strlen(S_GET_NAME(ptr))) { - printf("%20s:%-5d %2d:%08x %s \n", - ptr->sy_frag->line->file->filename, - ptr->sy_frag->line->line, - S_GET_SEGMENT(ptr), - S_GET_VALUE(ptr), - S_GET_NAME(ptr)); - - on_page++; - listing_page(0); - } - } - - } - - printf("\n"); - on_page++; - listing_page(0); - printf("UNDEFINED SYMBOLS\n"); - on_page++; - listing_page(0); - - for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) { - if (ptr && strlen(S_GET_NAME(ptr)) != 0) { - if (ptr->sy_frag->line == 0) { - printf("%s\n", S_GET_NAME(ptr)); - on_page++; - listing_page(0); - } - } + /* Grope around, see if we can see a title or subtitle edict coming up + soon (we look down 10 lines of the page and see if it's there)*/ + if ((eject || (on_page >= paper_height)) && paper_height != 0) + { + unsigned int c = 10; + int had_title = 0; + int had_subtitle = 0; + + page++; + + while (c != 0 && list) + { + if (list->edict == EDICT_SBTTL && !had_subtitle) + { + had_subtitle = 1; + subtitle = list->edict_arg; + } + if (list->edict == EDICT_TITLE && !had_title) + { + had_title = 1; + title = list->edict_arg; + } + list = list->next; + c--; } - return; -} /* list_symbol_table() */ -void - print_source(current_file, list, buffer, width) -file_info_type *current_file; -list_info_type *list; -char *buffer; -unsigned int width; -{ - if (current_file->file) { - while (current_file->linenum < list->hll_line) { - char * p = buffer_line(current_file, buffer, width); - printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p); - on_page++; - listing_page(list); - } + if (page > 1) + { + printf ("\f"); } - - return; -} /* print_source() */ + + printf ("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); + printf ("%s\n", title); + printf ("%s\n", subtitle); + on_page = 3; + eject = 0; + } +} + + +static unsigned int +calc_hex (list) + list_info_type * list; +{ + list_info_type *first = list; + unsigned int address = (unsigned int) ~0; + + fragS *frag; + fragS *frag_ptr; + + unsigned int byte_in_frag; + + + /* Find first frag which says it belongs to this line */ + frag = list->frag; + while (frag && frag->line != list) + frag = frag->fr_next; + + frag_ptr = frag; + + data_buffer_size = 0; + + /* Dump all the frags which belong to this line */ + while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) + { + /* Print as many bytes from the fixed part as is sensible */ + byte_in_frag = 0; + while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10) + { + if (address == ~0) + { + address = frag_ptr->fr_address; + } + + sprintf (data_buffer + data_buffer_size, + "%02X", + (frag_ptr->fr_literal[byte_in_frag]) & 0xff); + data_buffer_size += 2; + byte_in_frag++; + } + { + unsigned int var_rep_max = byte_in_frag; + unsigned int var_rep_idx = byte_in_frag; + + /* Print as many bytes from the variable part as is sensible */ + while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset + && data_buffer_size < sizeof (data_buffer) - 10) + { + if (address == ~0) + { + address = frag_ptr->fr_address; + } + sprintf (data_buffer + data_buffer_size, + "%02X", + (frag_ptr->fr_literal[var_rep_idx]) & 0xff); +#if 0 + data_buffer[data_buffer_size++] = '*'; + data_buffer[data_buffer_size++] = '*'; +#endif + data_buffer_size += 2; + + var_rep_idx++; + byte_in_frag++; + + if (var_rep_idx >= frag_ptr->fr_var) + var_rep_idx = var_rep_max; + } + } + + frag_ptr = frag_ptr->fr_next; + } + data_buffer[data_buffer_size++] = 0; + return address; +} + + + + + + +static void +print_lines (list, string, address) + list_info_type *list; + char *string; + unsigned int address; +{ + unsigned int idx; + unsigned int nchars; + unsigned int lines; + unsigned int byte_in_word = 0; + char *src = data_buffer; + + /* Print the stuff on the first line */ + listing_page (list); + nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH; + /* Print the hex for the first line */ + if (address == ~0) + { + printf ("% 4d ", list->line); + for (idx = 0; idx < nchars; idx++) + printf (" "); + + printf ("\t%s\n", string ? string : ""); + on_page++; + listing_page (0); + + } + else + { + if (had_errors ()) + { + printf ("% 4d ???? ", list->line); + } + else + { + printf ("% 4d %04x ", list->line, address); + } + + /* And the data to go along with it */ + idx = 0; + + while (*src && idx < nchars) + { + printf ("%c%c", src[0], src[1]); + src += 2; + byte_in_word++; + if (byte_in_word == LISTING_WORD_SIZE) + { + printf (" "); + idx++; + byte_in_word = 0; + } + idx += 2; + } + + for (; idx < nchars; idx++) + printf (" "); + + printf ("\t%s\n", string ? string : ""); + on_page++; + listing_page (list); + if (list->message) + { + printf ("**** %s\n", list->message); + listing_page (list); + on_page++; + } + + for (lines = 0; + lines < LISTING_LHS_CONT_LINES + && *src; + lines++) + { + nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1; + idx = 0; + /* Print any more lines of data, but more compactly */ + printf ("% 4d ", list->line); + + while (*src && idx < nchars) + { + printf ("%c%c", src[0], src[1]); + src += 2; + idx += 2; + byte_in_word++; + if (byte_in_word == LISTING_WORD_SIZE) + { + printf (" "); + idx++; + byte_in_word = 0; + } + } + + printf ("\n"); + on_page++; + listing_page (list); + + } + + + } +} + + +static void +list_symbol_table () +{ + extern symbolS *symbol_rootP; + int got_some = 0; + + symbolS *ptr; + eject = 1; + listing_page (0); + + for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) + { + if (ptr->sy_frag->line) + { + if (S_GET_NAME (ptr)) + { + char buf[30]; + valueT val = S_GET_VALUE (ptr); + + /* @@ Note that this is dependent on the compilation options, + not solely on the target characteristics. */ + if (sizeof (val) == 4 && sizeof (int) == 4) + sprintf (buf, "%08lx", (unsigned long) val); +#if defined (BFD64) + else if (sizeof (val) > 4) + { + char buf1[30]; + sprintf_vma (buf1, val); + strcpy (buf, "00000000"); + strcpy (buf + 8 - strlen (buf1), buf1); + } +#endif + else + abort (); + + if (!got_some) + { + printf ("DEFINED SYMBOLS\n"); + on_page++; + got_some = 1; + } + + printf ("%20s:%-5d %s:%s %s\n", + ptr->sy_frag->line->file->filename, + ptr->sy_frag->line->line, + segment_name (S_GET_SEGMENT (ptr)), + buf, S_GET_NAME (ptr)); + + on_page++; + listing_page (0); + } + } + + } + if (!got_some) + { + printf ("NO DEFINED SYMBOLS\n"); + on_page++; + } + printf ("\n"); + on_page++; + listing_page (0); + + got_some = 0; + + for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) + { + if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) + { + if (ptr->sy_frag->line == 0 +#ifdef notyet + && S_GET_SEGMENT (ptr) != reg_section) +#else + && !S_IS_REGISTER(ptr)) +#endif + { + if (!got_some) + { + got_some = 1; + printf ("UNDEFINED SYMBOLS\n"); + on_page++; + listing_page (0); + } + printf ("%s\n", S_GET_NAME (ptr)); + on_page++; + listing_page (0); + } + } + } + if (!got_some) + { + printf ("NO UNDEFINED SYMBOLS\n"); + on_page++; + listing_page (0); + } +} + +static void +print_source (current_file, list, buffer, width) + file_info_type *current_file; + list_info_type *list; + char *buffer; + unsigned int width; +{ + if (current_file->file) + { + while (current_file->linenum < list->hll_line) + { + char *p = buffer_line (current_file, buffer, width); + printf ("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p); + on_page++; + listing_page (list); + } + } +} /* Sometimes the user doesn't want to be bothered by the debugging - records inserted by the compiler, see if the line is suspicioous */ + records inserted by the compiler, see if the line is suspicious */ static int - debugging_pseudo(line) -char *line; +debugging_pseudo (line) + char *line; { - while (isspace(*line)) - line++; - - if (*line != '.') return 0; - - line++; - - if (strncmp(line, "def",3) == 0) return 1; - if (strncmp(line, "val",3) == 0) return 1; - if (strncmp(line, "scl",3) == 0) return 1; - if (strncmp(line, "line",4) == 0) return 1; - if (strncmp(line, "endef",5) == 0) return 1; - if (strncmp(line, "ln",2) == 0) return 1; - if (strncmp(line, "type",4) == 0) return 1; - if (strncmp(line, "size",4) == 0) return 1; - if (strncmp(line, "dim",3) == 0) return 1; - if (strncmp(line, "tag",3) == 0) return 1; - - return(0); -} /* debugging_pseudo() */ + while (isspace (*line)) + line++; -void - listing_listing(name) -char *name; -{ - char *buffer; - char *message; - char *p; - file_info_type *current_hll_file = (file_info_type *) NULL; - int on_page = 0; - int show_listing = 1; - list_info_type *list = head; - unsigned int addr = 0; - unsigned int page = 1; - unsigned int prev = 0; - unsigned int width; - - buffer = malloc(LISTING_RHS_WIDTH); - eject = 1; - list = head; - - while (list != (list_info_type *)NULL && 0) { - if (list->next) - list->frag = list->next->frag; - list = list->next; - } - - list = head->next; - - while (list) { - width = LISTING_RHS_WIDTH > paper_width ? paper_width : LISTING_RHS_WIDTH; - - switch (list->edict) { - case EDICT_LIST: - show_listing++; - break; - case EDICT_NOLIST: - show_listing--; - break; - case EDICT_EJECT: - break; - case EDICT_NONE: - break; - case EDICT_TITLE: - title = list->edict_arg; - break; - case EDICT_SBTTL: - subtitle = list->edict_arg; - break; - default: - abort(); - } - - if (show_listing > 0) { - /* Scan down the list and print all the stuff which can be done - with this line (or lines) */ - message = 0; - - if (list->hll_file) { - current_hll_file = list->hll_file; - } - - if (current_hll_file && list->hll_line && listing & LISTING_HLL) { - print_source(current_hll_file, list, buffer, width); - } - - p = buffer_line(list->file, buffer, width); - - if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p))) { - print_lines(list, p, calc_hex(list)); - } - - if (list->edict == EDICT_EJECT) { - eject = 1; - } - } else { - - p = buffer_line(list->file, buffer, width); - } - - list = list->next; - } - free(buffer); -} /* listing_listing() */ + if (*line != '.') + return 0; -void - listing_print(name) -char *name; + line++; + + if (strncmp (line, "def", 3) == 0) + return 1; + if (strncmp (line, "val", 3) == 0) + return 1; + if (strncmp (line, "scl", 3) == 0) + return 1; + if (strncmp (line, "line", 4) == 0) + return 1; + if (strncmp (line, "endef", 5) == 0) + return 1; + if (strncmp (line, "ln", 2) == 0) + return 1; + if (strncmp (line, "type", 4) == 0) + return 1; + if (strncmp (line, "size", 4) == 0) + return 1; + if (strncmp (line, "dim", 3) == 0) + return 1; + if (strncmp (line, "tag", 3) == 0) + return 1; + + if (strncmp (line, "stabs", 5) == 0) + return 1; + if (strncmp (line, "stabn", 5) == 0) + return 1; + + return 0; + +} + +static void +listing_listing (name) + char *name; { - title = ""; - subtitle = ""; - - if (listing & LISTING_NOFORM) + list_info_type *list = head; + file_info_type *current_hll_file = (file_info_type *) NULL; + char *message; + char *buffer; + char *p; + int show_listing = 1; + unsigned int width; + + buffer = xmalloc (LISTING_RHS_WIDTH); + eject = 1; + list = head; + + while (list != (list_info_type *) NULL && 0) + { + if (list->next) + list->frag = list->next->frag; + list = list->next; + + } + + list = head->next; + + + while (list) + { + width = LISTING_RHS_WIDTH > paper_width ? paper_width : + LISTING_RHS_WIDTH; + + switch (list->edict) + { + case EDICT_LIST: + show_listing++; + break; + case EDICT_NOLIST: + show_listing--; + break; + case EDICT_EJECT: + break; + case EDICT_NONE: + break; + case EDICT_TITLE: + title = list->edict_arg; + break; + case EDICT_SBTTL: + subtitle = list->edict_arg; + break; + default: + abort (); + } + + if (show_listing > 0) + { + /* Scan down the list and print all the stuff which can be done + with this line (or lines). */ + message = 0; + + if (list->hll_file) { - paper_height = 0; + current_hll_file = list->hll_file; } - - if (listing & LISTING_LISTING) + + if (current_hll_file && list->hll_line && listing & LISTING_HLL) { - listing_listing(name); - + print_source (current_hll_file, list, buffer, width); } - if (listing & LISTING_SYMBOLS) + + while (list->file->file && + list->file->linenum < list->line && !list->file->end_pending) { + p = buffer_line (list->file, buffer, width); + + if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p))) + { + print_lines (list, p, calc_hex (list)); + } + } + + if (list->edict == EDICT_EJECT) { - list_symbol_table(); + eject = 1; } -} /* listing_print() */ + } + else + { + + while (list->file->file && + list->file->linenum < list->line && !list->file->end_pending) + p = buffer_line (list->file, buffer, width); + } + + list = list->next; + } + free (buffer); +} + +void +listing_print (name) + char *name; +{ + title = ""; + subtitle = ""; + + if (listing & LISTING_NOFORM) + { + paper_height = 0; + } + + if (listing & LISTING_LISTING) + { + listing_listing (name); + + } + if (listing & LISTING_SYMBOLS) + { + list_symbol_table (); + } +} void - listing_file(name) -char *name; +listing_file (name) + const char *name; { - fn = name; + fn = name; +} + +void +listing_eject (ignore) + int ignore; +{ + listing_tail->edict = EDICT_EJECT; +} + +void +listing_flags (ignore) + int ignore; +{ + while ((*input_line_pointer++) && (*input_line_pointer != '\n')) + input_line_pointer++; + +} + +void +listing_list (on) + int on; +{ + listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; +} + + +void +listing_psize (ignore) + int ignore; +{ + paper_height = get_absolute_expression (); + + if (paper_height < 0 || paper_height > 1000) + { + paper_height = 0; + as_warn ("strange paper height, set to no form"); + } + if (*input_line_pointer == ',') + { + input_line_pointer++; + paper_width = get_absolute_expression (); + } +} + + +void +listing_title (depth) + int depth; +{ + char *start; + char *ttl; + unsigned int length; + + SKIP_WHITESPACE (); + if (*input_line_pointer == '\"') + { + input_line_pointer++; + start = input_line_pointer; + + while (*input_line_pointer) + { + if (*input_line_pointer == '\"') + { + length = input_line_pointer - start; + ttl = xmalloc (length + 1); + memcpy (ttl, start, length); + ttl[length] = 0; + listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; + listing_tail->edict_arg = ttl; + input_line_pointer++; + demand_empty_rest_of_line (); + return; + } + else if (*input_line_pointer == '\n') + { + as_bad ("New line in title"); + demand_empty_rest_of_line (); + return; + } + else + { + input_line_pointer++; + } + } + } + else + { + as_bad ("expecting title in quotes"); + } +} + + + +void +listing_source_line (line) + unsigned int line; +{ + new_frag (); + listing_tail->hll_line = line; + new_frag (); + +} + +void +listing_source_file (file) + const char *file; +{ + if (listing_tail) + listing_tail->hll_file = file_info (file); +} + + + +#else + + +/* Dummy functions for when compiled without listing enabled */ + +void +listing_flags (ignore) + int ignore; +{ + s_ignore (0); } void - listing_eject() +listing_list (on) + int on; { - listing_tail->edict = EDICT_EJECT; - return; + s_ignore (0); +} + +void +listing_eject (ignore) + int ignore; +{ + s_ignore (0); +} + +void +listing_psize (ignore) + int ignore; +{ + s_ignore (0); +} + +void +listing_title (depth) + int depth; +{ + s_ignore (0); } void - listing_flags() +listing_file (name) + const char *name; { - + } -void - listing_list(on) -unsigned int on; +void +listing_newline (name) + char *name; { - listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; + } - -void - listing_psize() +void +listing_source_line (n) + unsigned int n; { - paper_height = get_absolute_expression(); - - if (paper_height < 0 || paper_height > 1000) { - paper_height = 0; - as_warn("strantge paper height, set to no form"); - } - - if (*input_line_pointer == ',') { - input_line_pointer++; - paper_width = get_absolute_expression(); - } - - return; -} /* listing_psize() */ - -void - listing_title(depth) -unsigned int depth; +} +void +listing_source_file (n) + const char *n; { - char *start; - char *title; - unsigned int length; - - SKIP_WHITESPACE(); - - if (*input_line_pointer == '\"') { - input_line_pointer++; - start = input_line_pointer; - - while (*input_line_pointer) { - if (*input_line_pointer == '\"') { - length = input_line_pointer - start; - title = malloc(length + 1); - memcpy(title, start, length); - title[length] = 0; - listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; - listing_tail->edict_arg = title; - input_line_pointer++; - demand_empty_rest_of_line(); - return; - } else if (*input_line_pointer == '\n') { - as_bad("New line in title"); - demand_empty_rest_of_line(); - return; - } else { - input_line_pointer++; - } - } - } else { - as_bad("expecting title in quotes"); - } - - return; -} /* listing_title() */ - - -void - listing_source_line(line) -unsigned int line; -{ - new_frag(); - listing_tail->hll_line = line; - new_frag(); - return; -} /* lising_source_line() */ - -void - listing_source_file(file) -char *file; -{ - listing_tail->hll_file = file_info(file); } -#endif /* not NO_LISTING */ - -/* end of listing.c */ +#endif diff --git a/gnu/usr.bin/as/listing.h b/gnu/usr.bin/as/listing.h index 37a8e8793c1f..2220c35eb4c2 100644 --- a/gnu/usr.bin/as/listing.h +++ b/gnu/usr.bin/as/listing.h @@ -1,27 +1,26 @@ /* This file is listing.h - Copyright (C) 1987-1992 Free Software Foundation, Inc. - + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* - * $Id: listing.h,v 1.1 1993/10/02 20:57:41 pk Exp $ + * $Id: listing.h,v 1.1 1993/11/03 00:51:56 paul Exp $ */ - - #ifndef __listing_h__ #define __listing_h__ @@ -34,61 +33,82 @@ #define LISTING_DEFAULT (LISTING_LISTING | LISTING_HLL | LISTING_SYMBOLS) #ifndef NO_LISTING - #define LISTING_NEWLINE() { if (listing) listing_newline(input_line_pointer); } - - -#if __STDC__ == 1 - -void listing_eject(void); -void listing_error(char *message); -void listing_file(char *name); -void listing_flags(void); -void listing_list(unsigned int on); -void listing_newline(char *ps); -void listing_print(char *name); -void listing_psize(void); -void listing_source_file(char *); -void listing_source_line(unsigned int); -void listing_title(unsigned int depth); -void listing_warning(char *message); -void listing_width(unsigned int x); - -#else /* not __STDC__ */ - -void listing_eject(); -void listing_error(); -void listing_file(); -void listing_flags(); -void listing_list(); -void listing_newline(); -void listing_print(); -void listing_psize(); -void listing_source_file(); -void listing_source_line(); -void listing_title(); -void listing_warning(); -void listing_width(); - -#endif /* not __STDC__ */ - -#else /* NO_LISTING */ - +#else #define LISTING_NEWLINE() {;} +#endif -/* Dummy functions for when compiled without listing enabled */ -#define listing_flags() {;} -#define listing_list() {;} -#define listing_eject() {;} -#define listing_psize() {;} -#define listing_title(depth) {;} -#define listing_file(name) {;} -#define listing_newline(name) {;} -#define listing_source_line(n) {;} -#define listing_source_file(n) {;} +/* This structure remembers which .s were used */ +typedef struct file_info_struct +{ + char *filename; + int linenum; + FILE *file; + struct file_info_struct *next; + int end_pending; -#endif /* NO_LISTING */ +} + +file_info_type; + + +/* this structure rememebrs which line from which file goes into which + frag */ +typedef struct list_info_struct +{ + /* Frag which this line of source is nearest to */ + fragS *frag; + /* The actual line in the source file */ + unsigned int line; + /* Pointer to the file info struct for the file which this line + belongs to */ + file_info_type *file; + + /* Next in list */ + struct list_info_struct *next; + + + /* Pointer to the file info struct for the high level language + source line that belongs here */ + file_info_type *hll_file; + + /* High level language source line */ + int hll_line; + + + /* Pointer to any error message associated with this line */ + char *message; + + enum + { + EDICT_NONE, + EDICT_SBTTL, + EDICT_TITLE, + EDICT_NOLIST, + EDICT_LIST, + EDICT_EJECT + } edict; + char *edict_arg; + +} + +list_info_type; + +void listing_eject PARAMS ((int)); +void listing_error PARAMS ((const char *message)); +void listing_file PARAMS ((const char *name)); +void listing_flags PARAMS ((int)); +void listing_list PARAMS ((int on)); +void listing_newline PARAMS ((char *ps)); +void listing_prev_line PARAMS ((void)); +void listing_print PARAMS ((char *name)); +void listing_psize PARAMS ((int)); +void listing_source_file PARAMS ((const char *)); +void listing_source_line PARAMS ((unsigned int)); +void listing_title PARAMS ((int depth)); +void listing_warning PARAMS ((const char *message)); +void listing_width PARAMS ((unsigned int x)); #endif /* __listing_h__ */ diff --git a/gnu/usr.bin/as/messages.c b/gnu/usr.bin/as/messages.c index b1ba3f764a2d..84ce61a620d1 100644 --- a/gnu/usr.bin/as/messages.c +++ b/gnu/usr.bin/as/messages.c @@ -1,31 +1,37 @@ /* messages.c - error reporter - Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc. - + This file is part of GAS, the GNU Assembler. - + GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$Id: messages.c,v 1.3 1993/10/02 20:57:45 pk Exp $"; +static char rcsid[] = "$Id: messages.c,v 1.2 1993/11/03 00:52:01 paul Exp $"; #endif -#include /* define stderr */ +#include #include #include "as.h" +#ifndef __STDC__ +#ifndef NO_STDARG +#define NO_STDARG +#endif +#endif + #ifndef NO_STDARG #include #else @@ -34,6 +40,12 @@ static char rcsid[] = "$Id: messages.c,v 1.3 1993/10/02 20:57:45 pk Exp $"; #endif /* NO_VARARGS */ #endif /* NO_STDARG */ +extern char *strerror (); + +static void as_show_where PARAMS ((void)); +static void as_warn_internal PARAMS ((char *, unsigned int, char *)); +static void as_bad_internal PARAMS ((char *, unsigned int, char *)); + /* * Despite the rest of the comments in this file, (FIXME-SOON), * here is the current scheme for error messages etc: @@ -72,346 +84,512 @@ static char rcsid[] = "$Id: messages.c,v 1.3 1993/10/02 20:57:45 pk Exp $"; * continues as though no error occurred. */ -/* - ERRORS - - JF: this is now bogus. We now print more standard error messages - that try to look like everyone else's. - - We print the error message 1st, beginning in column 1. - All ancillary info starts in column 2 on lines after the - key error text. - We try to print a location in logical and physical file - just after the main error text. - Caller then prints any appendices after that, begining all - lines with at least 1 space. - - Optionally, we may die. - There is no need for a trailing '\n' in your error text format - because we supply one. - - as_warn(fmt,args) Like fprintf(stderr,fmt,args) but also call errwhere(). - - as_fatal(fmt,args) Like as_warn() but exit with a fatal status. - - */ +static void +identify (file) + char *file; +{ + static int identified; + if (identified) + return; + identified++; -static int warning_count = 0; /* Count of number of warnings issued */ + if (!file) + { + unsigned int x; + as_where (&file, &x); + } -int had_warnings() { - return(warning_count); -} /* had_err() */ + fprintf (stderr, "%s: Assembler messages:\n", file); +} + +static int warning_count; /* Count of number of warnings issued */ + +int +had_warnings () +{ + return (warning_count); +} /* had_err() */ /* Nonzero if we've hit a 'bad error', and should not write an obj file, and exit with a nonzero error code */ -static int error_count = 0; +static int error_count; -int had_errors() { - return(error_count); -} /* had_errors() */ +int +had_errors () +{ + return (error_count); +} /* had_errors() */ +/* Print the current location to stderr. */ + +static void +as_show_where () +{ + char *file; + unsigned int line; + + as_where (&file, &line); + identify (file); + fprintf (stderr, "%s:%u: ", file, line); +} + /* * a s _ p e r r o r * * Like perror(3), but with more info. */ -void as_perror(gripe, filename) -char *gripe; /* Unpunctuated error theme. */ -char *filename; -{ -#ifndef HAVE_STRERROR - extern char *strerror(); -#endif /* HAVE_STRERROR */ - as_where(); - fprintf(stderr, gripe, filename); - fprintf(stderr, "%s.\n", strerror(errno)); - errno = 0; /* After reporting, clear it. */ -} /* as_perror() */ +void +as_perror (gripe, filename) + const char *gripe; /* Unpunctuated error theme. */ + const char *filename; +{ + const char *errtxt; + + as_show_where (); + fprintf (stderr, gripe, filename); +#ifdef BFD_ASSEMBLER + errtxt = bfd_errmsg (bfd_get_error ()); +#else + errtxt = strerror (errno); +#endif + fprintf (stderr, ": %s\n", errtxt); + errno = 0; +#ifdef BFD_ASSEMBLER + bfd_set_error (bfd_error_no_error); +#endif +} /* * a s _ t s k t s k () * - * Send to stderr a string (with bell) (JF: Bell is obnoxious!) as a warning, and locate warning + * Send to stderr a string as a warning, and locate warning * in input file(s). * Please only use this for when we have some recovery action. * Please explain in string (which may have '\n's) what recovery was done. */ #ifndef NO_STDARG -void as_tsktsk(Format) -const char *Format; +void +as_tsktsk (const char *format,...) { - va_list args; - - as_where(); - va_start(args, Format); - vfprintf(stderr, Format, args); - va_end(args); - (void) putc('\n', stderr); -} /* as_tsktsk() */ + va_list args; + + as_show_where (); + va_start (args, format); + vfprintf (stderr, format, args); + va_end (args); + (void) putc ('\n', stderr); +} /* as_tsktsk() */ + #else #ifndef NO_VARARGS -void as_tsktsk(Format,va_alist) -char *Format; -va_dcl +void +as_tsktsk (format, va_alist) + char *format; + va_dcl { - va_list args; - - as_where(); - va_start(args); - vfprintf(stderr, Format, args); - va_end(args); - (void) putc('\n', stderr); -} /* as_tsktsk() */ + va_list args; + + as_show_where (); + va_start (args); + vfprintf (stderr, format, args); + va_end (args); + (void) putc ('\n', stderr); +} /* as_tsktsk() */ + #else /*VARARGS1 */ -as_tsktsk(Format,args) -char *Format; +as_tsktsk (format, args) + char *format; { - as_where(); - _doprnt (Format, &args, stderr); - (void)putc ('\n', stderr); - /* as_where(); */ -} /* as_tsktsk */ + as_show_where (); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); +} /* as_tsktsk */ + #endif /* not NO_VARARGS */ #endif /* not NO_STDARG */ -#ifdef DONTDEF -void as_tsktsk(Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an) -char *format; +/* The common portion of as_warn and as_warn_where. */ + +static void +as_warn_internal (file, line, buffer) + char *file; + unsigned int line; + char *buffer; { - as_where(); - fprintf(stderr,Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an); - (void)putc('\n',stderr); -} /* as_tsktsk() */ + ++warning_count; + + if (file == NULL) + as_where (&file, &line); + + identify (file); + fprintf (stderr, "%s:%u: Warning: ", file, line); + fputs (buffer, stderr); + (void) putc ('\n', stderr); +#ifndef NO_LISTING + listing_warning (buffer); #endif +} + /* * a s _ w a r n () * - * Send to stderr a string (with bell) (JF: Bell is obnoxious!) as a warning, and locate warning + * Send to stderr a string as a warning, and locate warning * in input file(s). * Please only use this for when we have some recovery action. * Please explain in string (which may have '\n's) what recovery was done. */ -#ifndef NO_STDARG -void as_warn(Format) -const char *Format; -{ - va_list args; - char buffer[200]; - - if (!flagseen['W']) { - ++warning_count; - as_where(); - va_start(args, Format); - fprintf(stderr,"Warning: "); - vsprintf(buffer, Format, args); - fprintf(stderr, buffer); -#ifndef NO_LISTING - listing_warning(buffer); +#if 1 +#define flag_no_warnings (flagseen['W']) #endif - va_end(args); - (void) putc('\n', stderr); - } -} /* as_warn() */ + +#ifndef NO_STDARG +void +as_warn (const char *format,...) +{ + va_list args; + char buffer[200]; + + if (!flag_no_warnings) + { + va_start (args, format); + vsprintf (buffer, format, args); + va_end (args); + as_warn_internal ((char *) NULL, 0, buffer); + } +} /* as_warn() */ + #else #ifndef NO_VARARGS -void as_warn(Format,va_alist) -char *Format; -va_dcl +void +as_warn (format, va_alist) + char *format; + va_dcl { - va_list args; - char buffer[200]; - - if (!flagseen['W']) { - ++warning_count; - as_where(); - va_start(args); - fprintf(stderr,"Warning: "); - vsprintf(buffer, Format, args); - fprintf(stderr,buffer); -#ifndef NO_LISTING - listing_warning(buffer); -#endif - va_end(args); - (void) putc('\n', stderr); - } -} /* as_warn() */ + va_list args; + char buffer[200]; + + if (!flag_no_warnings) + { + va_start (args); + vsprintf (buffer, format, args); + va_end (args); + as_warn_internal ((char *) NULL, 0, buffer); + } +} /* as_warn() */ + #else /*VARARGS1 */ -as_warn(Format,args) -char *Format; +as_warn (format, args) + char *format; { - /* -W supresses warning messages. */ - if (! flagseen['W']) { - ++warning_count; - as_where(); - _doprnt (Format, &args, stderr); - (void)putc ('\n', stderr); - /* as_where(); */ - } -} /* as_warn() */ + if (!flag_no_warnings) + { + ++warning_count; + as_show_where (); + fprintf (stderr, "Warning: "); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); + } +} /* as_warn() */ + #endif /* not NO_VARARGS */ #endif /* not NO_STDARG */ -#ifdef DONTDEF -void as_warn(Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an) -char *format; +/* as_warn_where, like as_bad but the file name and line number are + passed in. Unfortunately, we have to repeat the function in order + to handle the varargs correctly and portably. */ + +#ifndef NO_STDARG +void +as_warn_where (char *file, unsigned int line, const char *format,...) { - if (!flagseen['W']) { - ++warning_count; - as_where(); - fprintf(stderr,Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an); - (void)putc('\n',stderr); - } -} /* as_warn() */ + va_list args; + char buffer[200]; + + if (!flag_no_warnings) + { + va_start (args, format); + vsprintf (buffer, format, args); + va_end (args); + as_warn_internal (file, line, buffer); + } +} /* as_warn() */ + +#else +#ifndef NO_VARARGS +void +as_warn_where (file, line, format, va_alist) + char *file; + unsigned int line; + char *format; + va_dcl +{ + va_list args; + char buffer[200]; + + if (!flag_no_warnings) + { + va_start (args); + vsprintf (buffer, format, args); + va_end (args); + as_warn_internal (file, line, buffer); + } +} /* as_warn() */ + +#else +/*VARARGS1 */ +as_warn_where (file, line, format, args) + char *file; + unsigned int line; + char *format; +{ + if (!flag_no_warnings) + { + ++warning_count; + identify (file); + fprintf (stderr, "%s:%u: Warning: ", file, line); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); + } +} /* as_warn() */ + +#endif /* not NO_VARARGS */ +#endif /* not NO_STDARG */ + +/* The common portion of as_bad and as_bad_where. */ + +static void +as_bad_internal (file, line, buffer) + char *file; + unsigned int line; + char *buffer; +{ + ++error_count; + + if (file == NULL) + as_where (&file, &line); + + identify (file); + fprintf (stderr, "%s:%u: Error: ", file, line); + fputs (buffer, stderr); + (void) putc ('\n', stderr); +#ifndef NO_LISTING + listing_error (buffer); #endif +} + /* * a s _ b a d () * - * Send to stderr a string (with bell) (JF: Bell is obnoxious!) as a warning, - * and locate warning in input file(s). + * Send to stderr a string as a warning, and locate warning in input file(s). * Please us when there is no recovery, but we want to continue processing * but not produce an object file. * Please explain in string (which may have '\n's) what recovery was done. */ #ifndef NO_STDARG -void as_bad(Format) -const char *Format; +void +as_bad (const char *format,...) { - va_list args; - char buffer[200]; - - ++error_count; - as_where(); - va_start(args, Format); - fprintf(stderr,"Error: "); - - vsprintf(buffer, Format, args); - fprintf(stderr,buffer); -#ifndef NO_LISTING - listing_error(buffer); -#endif - va_end(args); - (void) putc('\n', stderr); -} /* as_bad() */ + va_list args; + char buffer[200]; + + va_start (args, format); + vsprintf (buffer, format, args); + va_end (args); + + as_bad_internal ((char *) NULL, 0, buffer); +} + #else #ifndef NO_VARARGS -void as_bad(Format,va_alist) -char *Format; -va_dcl +void +as_bad (format, va_alist) + char *format; + va_dcl { - va_list args; - char buffer[200]; - - ++error_count; - as_where(); - va_start(args); - vsprintf(buffer, Format, args); - fprintf(stderr,buffer); -#ifndef NO_LISTING - listing_error(buffer); -#endif - - va_end(args); - (void) putc('\n', stderr); -} /* as_bad() */ + va_list args; + char buffer[200]; + + va_start (args); + vsprintf (buffer, format, args); + va_end (args); + + as_bad_internal ((char *) NULL, 0, buffer); +} + #else /*VARARGS1 */ -as_bad(Format,args) -char *Format; +as_bad (format, args) + char *format; { - ++error_count; - - as_where(); - fprintf(stderr,"Error: "); - _doprnt (Format, &args, stderr); - (void)putc ('\n', stderr); - /* as_where(); */ -} /* as_bad() */ + ++error_count; + + as_show_where (); + fprintf (stderr, "Error: "); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); +} /* as_bad() */ + #endif /* not NO_VARARGS */ #endif /* not NO_STDARG */ -#ifdef DONTDEF -void as_bad(Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an) -char *format; +/* as_bad_where, like as_bad but the file name and line number are + passed in. Unfortunately, we have to repeat the function in order + to handle the varargs correctly and portably. */ + +#ifndef NO_STDARG +void +as_bad_where (char *file, unsigned int line, const char *format,...) { - ++error_count; - as_where(); - fprintf(stderr,Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an); - (void)putc('\n',stderr); -} /* as_bad() */ -#endif + va_list args; + char buffer[200]; + + va_start (args, format); + vsprintf (buffer, format, args); + va_end (args); + + as_bad_internal (file, line, buffer); +} + +#else +#ifndef NO_VARARGS +void +as_bad_where (file, line, format, va_alist) + char *file; + unsigned int line; + char *format; + va_dcl +{ + va_list args; + char buffer[200]; + + va_start (args); + vsprintf (buffer, format, args); + va_end (args); + + as_bad_internal (file, line, buffer); +} + +#else +/*VARARGS1 */ +as_bad_where (file, line, format, args) + char *file; + unsigned int line; + char *format; +{ + ++error_count; + + identify (file); + fprintf (stderr, "%s:%u: Error: ", file, line); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); +} /* as_bad() */ + +#endif /* not NO_VARARGS */ +#endif /* not NO_STDARG */ /* * a s _ f a t a l () * - * Send to stderr a string (with bell) (JF: Bell is obnoxious!) as a fatal - * message, and locate stdsource in input file(s). + * Send to stderr a string as a fatal message, and print location of error in + * input file(s). * Please only use this for when we DON'T have some recovery action. * It exit()s with a warning status. */ #ifndef NO_STDARG -void as_fatal(Format) -const char *Format; +void +as_fatal (const char *format,...) { - va_list args; - - as_where(); - va_start(args, Format); - fprintf (stderr, "FATAL:"); - vfprintf(stderr, Format, args); - (void) putc('\n', stderr); - va_end(args); - exit(33); -} /* as_fatal() */ + va_list args; + + as_show_where (); + va_start (args, format); + fprintf (stderr, "Fatal error:"); + vfprintf (stderr, format, args); + (void) putc ('\n', stderr); + va_end (args); + exit (33); +} /* as_fatal() */ + #else #ifndef NO_VARARGS -void as_fatal(Format,va_alist) -char *Format; -va_dcl +void +as_fatal (format, va_alist) + char *format; + va_dcl { - va_list args; - - as_where(); - va_start(args); - fprintf (stderr, "FATAL:"); - vfprintf(stderr, Format, args); - (void) putc('\n', stderr); - va_end(args); - exit(33); -} /* as_fatal() */ + va_list args; + + as_show_where (); + va_start (args); + fprintf (stderr, "Fatal error:"); + vfprintf (stderr, format, args); + (void) putc ('\n', stderr); + va_end (args); + exit (33); +} /* as_fatal() */ + #else /*VARARGS1 */ -as_fatal(Format, args) -char *Format; +as_fatal (format, args) + char *format; { - as_where(); - fprintf(stderr,"FATAL:"); - _doprnt (Format, &args, stderr); - (void)putc ('\n', stderr); - /* as_where(); */ - exit(33); /* What is a good exit status? */ -} /* as_fatal() */ + as_show_where (); + fprintf (stderr, "Fatal error:"); + _doprnt (format, &args, stderr); + (void) putc ('\n', stderr); + exit (33); /* What is a good exit status? */ +} /* as_fatal() */ + #endif /* not NO_VARARGS */ #endif /* not NO_STDARG */ -#ifdef DONTDEF -void as_fatal(Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an) -char *Format; +void +fprint_value (file, val) + FILE *file; + valueT val; { - as_where(); - fprintf (stderr, "FATAL:"); - fprintf(stderr, Format,aa,ab,ac,ad,ae,af,ag,ah,ai,aj,ak,al,am,an); - (void) putc('\n', stderr); - exit(33); -} /* as_fatal() */ + if (sizeof (val) <= sizeof (long)) + { + fprintf (file, "%ld", val); + return; + } +#ifdef BFD_ASSEMBLER + if (sizeof (val) <= sizeof (bfd_vma)) + { + fprintf_vma (file, val); + return; + } #endif + abort (); +} + +void +sprint_value (buf, val) + char *buf; + valueT val; +{ + if (sizeof (val) <= sizeof (long)) + { + sprintf (buf, "%ld", val); + return; + } +#ifdef BFD_ASSEMBLER + if (sizeof (val) <= sizeof (bfd_vma)) + { + sprintf_vma (buf, val); + return; + } +#endif + abort (); +} /* end of messages.c */ diff --git a/gnu/usr.bin/as/opcode/m68k.h b/gnu/usr.bin/as/opcode/m68k.h index dda833769066..86ee7a98274c 100644 --- a/gnu/usr.bin/as/opcode/m68k.h +++ b/gnu/usr.bin/as/opcode/m68k.h @@ -1909,8 +1909,15 @@ struct m68k_opcode m68k_opcodes[] = {"jbsr", one(0060400), one(0177400), "Bg", m68000up }, {"jbsr", one(0047200), one(0177700), "!s", m68000up }, +#ifdef PIC +{"jbsr", one(0060400), one(0177400), "Bg ", m68020up }, +#endif /* PIC */ + {"jra", one(0060000), one(0177400), "Bg", m68000up }, {"jra", one(0047300), one(0177700), "!s", m68000up }, +#ifdef PIC +{"jra", one(0060000), one(0177400), "Bg ", m68000up }, +#endif /* PIC */ {"jhi", one(0061000), one(0177400), "Bg", m68000up }, {"jls", one(0061400), one(0177400), "Bg", m68000up }, diff --git a/gnu/usr.bin/as/opcode/sparc.h b/gnu/usr.bin/as/opcode/sparc.h index 3c52464e6a91..a7dbafb558fa 100644 --- a/gnu/usr.bin/as/opcode/sparc.h +++ b/gnu/usr.bin/as/opcode/sparc.h @@ -20,7 +20,7 @@ along with GAS or GDB; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: sparc.h,v 1.1 1993/10/02 21:00:55 pk Exp $ + * $Id: sparc.h,v 1.1 1993/11/03 00:56:11 paul Exp $ */ /* FIXME-someday: perhaps the ,a's and such should be embedded in the @@ -631,12 +631,25 @@ static const struct sparc_opcode sparc_opcodes[] = { { "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "1,i,d", 0, v8 }, { "udivcc", F3(2, 0x1e, 1), F3(~2, ~0x1e, ~1), "i,1,d", 0, v8 }, - { "call", F1(0x1), F1(~0x1), "L", F_DELAYED, v6 }, { "call", F1(0x1), F1(~0x1), "L,#", F_DELAYED, v6 }, { "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1", F_DELAYED, v6 }, /* jmpl rs1+%g0, %o7 */ { "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf)|ASI_RS2(~0), "1,#", F_DELAYED, v6 }, +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf), +"1+2", F_DELAYED, v6 }, /* jmpl rs1+rs2,%o7 */ +{ "call", F3(2, 0x38, 0)|RD(0xf), F3(~2, ~0x38, ~0)|RD(~0xf), +"1+2,#", F_DELAYED, v6 }, /* jmpl rs1+rs2,%o7 */ + +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), +"1+i", F_DELAYED, v6 }, /* jmpl rs1+i,%o7 */ +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), +"1+i,#", F_DELAYED, v6 }, /* jmpl rs1+i,%o7 */ +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), +"i+1", F_DELAYED, v6 }, /* jmpl i+rs1,%o7 */ +{ "call", F3(2, 0x38, 1)|RD(0xf), F3(~2, ~0x38, ~1)|RD(~0xf), +"i+1,#", F_DELAYED, v6 }, /* jmpl i+rs1,%o7 */ + /* Conditional instructions. Because this part of the table was such a mess earlier, I have @@ -668,6 +681,7 @@ cond ("ba", "ta", CONDA, F_ALIAS), /* for nothing */ cond ("bcc", "tcc", CONDCC, 0), cond ("bcs", "tcs", CONDCS, 0), cond ("be", "te", CONDE, 0), +cond ("beq", "teq", CONDE, F_ALIAS), /* for be */ cond ("bg", "tg", CONDG, 0), cond ("bgt", "tgt", CONDG, F_ALIAS), cond ("bge", "tge", CONDGE, 0), diff --git a/gnu/usr.bin/as/read.c b/gnu/usr.bin/as/read.c index cf3c416ea017..c23719bf4810 100644 --- a/gnu/usr.bin/as/read.c +++ b/gnu/usr.bin/as/read.c @@ -19,7 +19,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef lint -static char rcsid[] = "$Id: read.c,v 1.3 1993/11/30 20:55:43 jkh Exp $"; +static char rcsid[] = "$Id: read.c,v 1.4 1993/12/12 17:01:16 jkh Exp $"; #endif #define MASK_CHAR (0xFF) /* If your chars aren't 8 bits, you will @@ -185,7 +185,7 @@ void /* set up pseudo-op tables */ struct hash_control * - po_hash = NULL; /* use before set up: NULL->address error */ + po_hash = NULL; /* use before set up: NULL->address error */ static const pseudo_typeS potable[] = @@ -214,7 +214,8 @@ static const pseudo_typeS /* err */ /* extend */ { "extern", s_ignore, 0 }, /* We treat all undef as ext */ - { "app-file", s_app_file, 0 }, + { "appline", s_app_line, 0 }, + { "appfile", s_app_file, 1 }, { "file", s_app_file, 0 }, { "fill", s_fill, 0 }, { "float", float_cons, 'f' }, @@ -751,20 +752,58 @@ void demand_empty_rest_of_line(); } -void s_app_file() { +/* Handle the .appfile pseudo-op. This is automatically generated by + do_scrub_next_char when a preprocessor # line comment is seen with + a file name. This default definition may be overridden by the + object or CPU specific pseudo-ops. This function is also the + default definition for .file; the APPFILE argument is 1 for + .appfile, 0 for .file. */ + +void s_app_file(appfile) + int appfile; +{ register char *s; int length; /* Some assemblers tolerate immediately following '"' */ if ((s = demand_copy_string(&length)) != 0) { - new_logical_line(s, -1); + /* If this is a fake .appfile, a fake newline was inserted + * into the buffer. Passing -2 to new_logical_line tells it + * to account for it. + */ + new_logical_line (s, appfile ? -2 : -1); demand_empty_rest_of_line(); +#ifdef LISTING + if (listing) + listing_source_file (s); +#endif } #ifdef OBJ_COFF c_dot_file_symbol(s); #endif /* OBJ_COFF */ } /* s_app_file() */ +/* Handle the .appline pseudo-op. This is automatically generated by + do_scrub_next_char when a preprocessor # line comment is seen. + This default definition may be overridden by the object or CPU + specific pseudo-ops. */ + +void +s_app_line (ignore) + int ignore; +{ + int l; + + /* The given number is that of the next line. */ + l = get_absolute_expression () - 1; + new_logical_line ((char *) NULL, l); +#ifdef LISTING + if (listing) + listing_source_line (l); +#endif + demand_empty_rest_of_line (); +} + void s_fill() { long temp_repeat; long temp_size; @@ -1672,7 +1711,7 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */ #ifdef TC_NS32K fix_new_ns32k(frag_now, p - frag_now->fr_literal, nbytes, exp.X_add_symbol, exp.X_subtract_symbol, - exp.X_add_number, 0, 0, 2, 0, 0); + exp.X_add_number, 0, 0, 2, 0, 0, RELOC_32); #else #ifdef PIC fix_new(frag_now, p - frag_now->fr_literal, nbytes, diff --git a/gnu/usr.bin/as/read.h b/gnu/usr.bin/as/read.h index b03fbab824c3..fb77b3cb76d4 100644 --- a/gnu/usr.bin/as/read.h +++ b/gnu/usr.bin/as/read.h @@ -18,7 +18,7 @@ along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: read.h,v 1.2 1993/11/03 00:52:16 paul Exp $ + * $Id: read.h,v 1.3 1993/11/30 20:55:45 jkh Exp $ */ @@ -57,6 +57,11 @@ extern const char lex_type[]; #endif extern char is_end_of_line[]; +/* These are initialized by the CPU specific target files (tc-*.c). */ +extern const char comment_chars[]; +extern const char line_comment_chars[]; +extern const char line_separator_chars[]; + #if __STDC__ == 1 char *demand_copy_C_string(int *len_pointer); @@ -75,7 +80,8 @@ void read_begin(void); void s_abort(void); void s_align_bytes(int arg); void s_align_ptwo(void); -void s_app_file(void); +void s_app_file(int); +void s_app_line(int); void s_comm(void); void s_data(void); void s_else(int arg); @@ -116,6 +122,7 @@ void s_abort(); void s_align_bytes(); void s_align_ptwo(); void s_app_file(); +void s_app_line(); void s_comm(); void s_data(); void s_else(); diff --git a/gnu/usr.bin/as/struc-symbol.h b/gnu/usr.bin/as/struc-symbol.h index e0030cd1dd09..5ef4b3a6cf9d 100644 --- a/gnu/usr.bin/as/struc-symbol.h +++ b/gnu/usr.bin/as/struc-symbol.h @@ -17,7 +17,7 @@ along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - * $Id: struc-symbol.h,v 1.2 1993/11/03 00:52:18 paul Exp $ + * $Id: struc-symbol.h,v 1.3 1993/11/30 20:55:46 jkh Exp $ */ @@ -85,8 +85,6 @@ extern struct broken_word *broken_words; #define SEGMENT_TO_SYMBOL_TYPE(seg) (seg_N_TYPE[(int) (seg)]) extern const short seg_N_TYPE[]; /* subseg.c */ -#define N_REGISTER 30 /* Fake N_TYPE value for SEG_REGISTER */ - #ifdef SYMBOLS_NEED_BACKPOINTERS #if __STDC__ == 1 diff --git a/gnu/usr.bin/as/write.c b/gnu/usr.bin/as/write.c index dd139f7e82dc..33cc8d29bfd9 100644 --- a/gnu/usr.bin/as/write.c +++ b/gnu/usr.bin/as/write.c @@ -21,7 +21,7 @@ /* This thing should be set up to do byteordering correctly. But... */ #ifndef lint -static char rcsid[] = "$Id: write.c,v 1.4 1993/12/12 17:01:24 jkh Exp $"; +static char rcsid[] = "$Id: write.c,v 1.5 1994/02/20 16:06:12 rgrimes Exp $"; #endif #include "as.h" @@ -401,7 +401,7 @@ void write_object_file() lie->add, lie->sub, lie->addnum, - 0, 0, 2, 0, 0); + 0, 0, 2, 0, 0, NO_RELOC); #else /* TC_NS32K */ #ifdef PIC fix_new(lie->frag, lie->word_goes_here - lie->frag->fr_literal, @@ -1004,6 +1004,12 @@ segT this_segment_type; /* N_TYPE bits for segment. */ as_bad("callj to difference of 2 symbols"); } #endif /* TC_I960 */ +#ifdef PIC + if (flagseen['k'] && + S_IS_EXTERNAL(add_symbolP)) { + as_bad("Can't reduce difference of external symbols in PIC code"); + } +#endif add_number += S_GET_VALUE(add_symbolP) - S_GET_VALUE(sub_symbolP); @@ -1075,6 +1081,9 @@ segT this_segment_type; /* N_TYPE bits for segment. */ * even if defined here. */ if (!flagseen['k'] || +#ifdef TC_NS32K + fixP->fx_pcrel || +#endif (fixP->fx_r_type != RELOC_GLOB_DAT && #ifdef TC_I386 /* XXX - This must be rationalized */