From 5490489cbb3759f7de75f5b491d20620bedcd358 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 6 Dec 2014 08:41:27 +0000 Subject: [PATCH] binutils: build AS. git-svn-id: svn://kolibrios.org@5222 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/toolchain/binutils/gas/Makefile | 45 + contrib/toolchain/binutils/gas/app.c | 1473 +++ contrib/toolchain/binutils/gas/as | Bin 0 -> 1235004 bytes contrib/toolchain/binutils/gas/as.c | 1326 ++ contrib/toolchain/binutils/gas/as.h | 634 + contrib/toolchain/binutils/gas/asintl.h | 52 + contrib/toolchain/binutils/gas/atof-generic.c | 614 + contrib/toolchain/binutils/gas/bignum.h | 42 + contrib/toolchain/binutils/gas/bit_fix.h | 48 + .../toolchain/binutils/gas/compress-debug.c | 117 + .../toolchain/binutils/gas/compress-debug.h | 39 + contrib/toolchain/binutils/gas/cond.c | 577 + contrib/toolchain/binutils/gas/config.h | 363 + .../toolchain/binutils/gas/config/atof-ieee.c | 813 ++ .../binutils/gas/config/obj-coff-seh.c | 1018 ++ .../binutils/gas/config/obj-coff-seh.h | 205 + .../toolchain/binutils/gas/config/obj-coff.c | 1957 +++ .../toolchain/binutils/gas/config/obj-coff.h | 415 + .../binutils/gas/config/tc-i386-intel.c | 1005 ++ .../toolchain/binutils/gas/config/tc-i386.c | 10565 ++++++++++++++++ .../toolchain/binutils/gas/config/tc-i386.h | 342 + contrib/toolchain/binutils/gas/config/te-pe.h | 26 + contrib/toolchain/binutils/gas/depend.c | 208 + contrib/toolchain/binutils/gas/dw2gencfi.c | 2044 +++ contrib/toolchain/binutils/gas/dw2gencfi.h | 132 + contrib/toolchain/binutils/gas/dwarf2dbg.c | 1944 +++ contrib/toolchain/binutils/gas/dwarf2dbg.h | 116 + contrib/toolchain/binutils/gas/ecoff.c | 5244 ++++++++ contrib/toolchain/binutils/gas/ecoff.h | 113 + contrib/toolchain/binutils/gas/ehopt.c | 557 + contrib/toolchain/binutils/gas/expr.c | 2367 ++++ contrib/toolchain/binutils/gas/expr.h | 189 + contrib/toolchain/binutils/gas/flonum-copy.c | 71 + contrib/toolchain/binutils/gas/flonum-konst.c | 228 + contrib/toolchain/binutils/gas/flonum-mult.c | 188 + contrib/toolchain/binutils/gas/flonum.h | 102 + contrib/toolchain/binutils/gas/frags.c | 445 + contrib/toolchain/binutils/gas/frags.h | 160 + contrib/toolchain/binutils/gas/hash.c | 597 + contrib/toolchain/binutils/gas/hash.h | 89 + contrib/toolchain/binutils/gas/input-file.c | 259 + contrib/toolchain/binutils/gas/input-file.h | 66 + contrib/toolchain/binutils/gas/input-scrub.c | 523 + contrib/toolchain/binutils/gas/itbl-cpu.h | 1 + contrib/toolchain/binutils/gas/listing.c | 1660 +++ contrib/toolchain/binutils/gas/listing.h | 67 + contrib/toolchain/binutils/gas/literal.c | 96 + contrib/toolchain/binutils/gas/macro.c | 1382 ++ contrib/toolchain/binutils/gas/macro.h | 97 + contrib/toolchain/binutils/gas/messages.c | 440 + contrib/toolchain/binutils/gas/obj-format.h | 1 + contrib/toolchain/binutils/gas/obj.h | 87 + contrib/toolchain/binutils/gas/output-file.c | 74 + contrib/toolchain/binutils/gas/output-file.h | 26 + contrib/toolchain/binutils/gas/read.c | 6107 +++++++++ contrib/toolchain/binutils/gas/read.h | 193 + contrib/toolchain/binutils/gas/remap.c | 91 + contrib/toolchain/binutils/gas/sb.c | 237 + contrib/toolchain/binutils/gas/sb.h | 71 + contrib/toolchain/binutils/gas/stabs.c | 710 ++ contrib/toolchain/binutils/gas/struc-symbol.h | 159 + contrib/toolchain/binutils/gas/subsegs.c | 330 + contrib/toolchain/binutils/gas/subsegs.h | 117 + contrib/toolchain/binutils/gas/symbols.c | 3252 +++++ contrib/toolchain/binutils/gas/symbols.h | 216 + contrib/toolchain/binutils/gas/targ-cpu.h | 1 + contrib/toolchain/binutils/gas/targ-env.h | 1 + contrib/toolchain/binutils/gas/tc.h | 79 + contrib/toolchain/binutils/gas/write.c | 2868 +++++ contrib/toolchain/binutils/gas/write.h | 191 + 70 files changed, 55872 insertions(+) create mode 100644 contrib/toolchain/binutils/gas/Makefile create mode 100644 contrib/toolchain/binutils/gas/app.c create mode 100644 contrib/toolchain/binutils/gas/as create mode 100644 contrib/toolchain/binutils/gas/as.c create mode 100644 contrib/toolchain/binutils/gas/as.h create mode 100644 contrib/toolchain/binutils/gas/asintl.h create mode 100644 contrib/toolchain/binutils/gas/atof-generic.c create mode 100644 contrib/toolchain/binutils/gas/bignum.h create mode 100644 contrib/toolchain/binutils/gas/bit_fix.h create mode 100644 contrib/toolchain/binutils/gas/compress-debug.c create mode 100644 contrib/toolchain/binutils/gas/compress-debug.h create mode 100644 contrib/toolchain/binutils/gas/cond.c create mode 100644 contrib/toolchain/binutils/gas/config.h create mode 100644 contrib/toolchain/binutils/gas/config/atof-ieee.c create mode 100644 contrib/toolchain/binutils/gas/config/obj-coff-seh.c create mode 100644 contrib/toolchain/binutils/gas/config/obj-coff-seh.h create mode 100644 contrib/toolchain/binutils/gas/config/obj-coff.c create mode 100644 contrib/toolchain/binutils/gas/config/obj-coff.h create mode 100644 contrib/toolchain/binutils/gas/config/tc-i386-intel.c create mode 100644 contrib/toolchain/binutils/gas/config/tc-i386.c create mode 100644 contrib/toolchain/binutils/gas/config/tc-i386.h create mode 100644 contrib/toolchain/binutils/gas/config/te-pe.h create mode 100644 contrib/toolchain/binutils/gas/depend.c create mode 100644 contrib/toolchain/binutils/gas/dw2gencfi.c create mode 100644 contrib/toolchain/binutils/gas/dw2gencfi.h create mode 100644 contrib/toolchain/binutils/gas/dwarf2dbg.c create mode 100644 contrib/toolchain/binutils/gas/dwarf2dbg.h create mode 100644 contrib/toolchain/binutils/gas/ecoff.c create mode 100644 contrib/toolchain/binutils/gas/ecoff.h create mode 100644 contrib/toolchain/binutils/gas/ehopt.c create mode 100644 contrib/toolchain/binutils/gas/expr.c create mode 100644 contrib/toolchain/binutils/gas/expr.h create mode 100644 contrib/toolchain/binutils/gas/flonum-copy.c create mode 100644 contrib/toolchain/binutils/gas/flonum-konst.c create mode 100644 contrib/toolchain/binutils/gas/flonum-mult.c create mode 100644 contrib/toolchain/binutils/gas/flonum.h create mode 100644 contrib/toolchain/binutils/gas/frags.c create mode 100644 contrib/toolchain/binutils/gas/frags.h create mode 100644 contrib/toolchain/binutils/gas/hash.c create mode 100644 contrib/toolchain/binutils/gas/hash.h create mode 100644 contrib/toolchain/binutils/gas/input-file.c create mode 100644 contrib/toolchain/binutils/gas/input-file.h create mode 100644 contrib/toolchain/binutils/gas/input-scrub.c create mode 100644 contrib/toolchain/binutils/gas/itbl-cpu.h create mode 100644 contrib/toolchain/binutils/gas/listing.c create mode 100644 contrib/toolchain/binutils/gas/listing.h create mode 100644 contrib/toolchain/binutils/gas/literal.c create mode 100644 contrib/toolchain/binutils/gas/macro.c create mode 100644 contrib/toolchain/binutils/gas/macro.h create mode 100644 contrib/toolchain/binutils/gas/messages.c create mode 100644 contrib/toolchain/binutils/gas/obj-format.h create mode 100644 contrib/toolchain/binutils/gas/obj.h create mode 100644 contrib/toolchain/binutils/gas/output-file.c create mode 100644 contrib/toolchain/binutils/gas/output-file.h create mode 100644 contrib/toolchain/binutils/gas/read.c create mode 100644 contrib/toolchain/binutils/gas/read.h create mode 100644 contrib/toolchain/binutils/gas/remap.c create mode 100644 contrib/toolchain/binutils/gas/sb.c create mode 100644 contrib/toolchain/binutils/gas/sb.h create mode 100644 contrib/toolchain/binutils/gas/stabs.c create mode 100644 contrib/toolchain/binutils/gas/struc-symbol.h create mode 100644 contrib/toolchain/binutils/gas/subsegs.c create mode 100644 contrib/toolchain/binutils/gas/subsegs.h create mode 100644 contrib/toolchain/binutils/gas/symbols.c create mode 100644 contrib/toolchain/binutils/gas/symbols.h create mode 100644 contrib/toolchain/binutils/gas/targ-cpu.h create mode 100644 contrib/toolchain/binutils/gas/targ-env.h create mode 100644 contrib/toolchain/binutils/gas/tc.h create mode 100644 contrib/toolchain/binutils/gas/write.c create mode 100644 contrib/toolchain/binutils/gas/write.h diff --git a/contrib/toolchain/binutils/gas/Makefile b/contrib/toolchain/binutils/gas/Makefile new file mode 100644 index 0000000000..e17ebfd9bc --- /dev/null +++ b/contrib/toolchain/binutils/gas/Makefile @@ -0,0 +1,45 @@ + +LIB_DIR:= $(SDK_DIR)/lib + +CFLAGS_OPT = -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -U_MSC_VER -O2 +CFLAGS_OPT+= -fomit-frame-pointer -fno-ident -mno-ms-bitfields +CFLAGS_OPT+= -W -Wall -Wmissing-prototypes -Wno-format +CFLAGS = -c $(CFLAGS_OPT) + +INCLUDES= -I. -I../bfd -I./config -I../include -I../ +INCLUDES+= -I$(SDK_DIR)/sources/newlib/libc/include -I$(SDK_DIR)/sources/zlib + +DEFINES= -DHAVE_CONFIG_H -DLOCALEDIR='"/home/autobuild/tools/win32/share/locale"' + +LIBS= -lopcodes -lbfd -liberty -lz -lgcc -lc.dll -lapp + +LIBPATH:= -L$(LIB_DIR) -L/home/autobuild/tools/win32/mingw32/lib + +LDFLAGS = -static -nostdlib --stack 12582912 -T$(SDK_DIR)/sources/newlib/app.lds --image-base 0 + + +SRCS = \ + app.c as.c atof-generic.c compress-debug.c \ + cond.c depend.c dwarf2dbg.c dw2gencfi.c ecoff.c \ + ehopt.c expr.c flonum-copy.c flonum-konst.c \ + flonum-mult.c frags.c hash.c input-file.c \ + input-scrub.c listing.c literal.c macro.c \ + messages.c output-file.c read.c remap.c sb.c \ + stabs.c subsegs.c symbols.c write.c \ + config/atof-ieee.c config/obj-coff.c \ + config/tc-i386.c + +OBJS = $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))) + +# targets + +all: as + +as: $(OBJS) Makefile + $(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(OBJS) $(LIBS) + kos32-objcopy $@ -O binary + +%.o : %.c Makefile + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $< + + \ No newline at end of file diff --git a/contrib/toolchain/binutils/gas/app.c b/contrib/toolchain/binutils/gas/app.c new file mode 100644 index 0000000000..ec3a35ee86 --- /dev/null +++ b/contrib/toolchain/binutils/gas/app.c @@ -0,0 +1,1473 @@ +/* This is the Assembler Pre-Processor + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, 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 the # in # into a + .linefile. This needs better error-handling. */ + +#include "as.h" + +#if (__STDC__ != 1) +#ifndef const +#define const /* empty */ +#endif +#endif + +#ifdef H_TICK_HEX +int enable_h_tick_hex = 0; +#endif + +#ifdef TC_M68K +/* Whether we are scrubbing in m68k MRI mode. This is different from + flag_m68k_mri, because the two flags will be affected by the .mri + pseudo-op at different times. */ +static int scrub_m68k_mri; + +/* The pseudo-op which switches in and out of MRI mode. See the + comment in do_scrub_chars. */ +static const char mri_pseudo[] = ".mri 0"; +#else +#define scrub_m68k_mri 0 +#endif + +#if defined TC_ARM && defined OBJ_ELF +/* The pseudo-op for which we need to special-case `@' characters. + See the comment in do_scrub_chars. */ +static const char symver_pseudo[] = ".symver"; +static const char * symver_state; +#endif + +static char lex[256]; +static const char symbol_chars[] = +"$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +#define LEX_IS_SYMBOL_COMPONENT 1 +#define LEX_IS_WHITESPACE 2 +#define LEX_IS_LINE_SEPARATOR 3 +#define LEX_IS_COMMENT_START 4 +#define LEX_IS_LINE_COMMENT_START 5 +#define LEX_IS_TWOCHAR_COMMENT_1ST 6 +#define LEX_IS_STRINGQUOTE 8 +#define LEX_IS_COLON 9 +#define LEX_IS_NEWLINE 10 +#define LEX_IS_ONECHAR_QUOTE 11 +#ifdef TC_V850 +#define LEX_IS_DOUBLEDASH_1ST 12 +#endif +#ifdef TC_M32R +#define DOUBLEBAR_PARALLEL +#endif +#ifdef DOUBLEBAR_PARALLEL +#define LEX_IS_DOUBLEBAR_1ST 13 +#endif +#define LEX_IS_PARALLEL_SEPARATOR 14 +#ifdef H_TICK_HEX +#define LEX_IS_H 15 +#endif +#define IS_SYMBOL_COMPONENT(c) (lex[c] == LEX_IS_SYMBOL_COMPONENT) +#define IS_WHITESPACE(c) (lex[c] == LEX_IS_WHITESPACE) +#define IS_LINE_SEPARATOR(c) (lex[c] == LEX_IS_LINE_SEPARATOR) +#define IS_PARALLEL_SEPARATOR(c) (lex[c] == LEX_IS_PARALLEL_SEPARATOR) +#define IS_COMMENT(c) (lex[c] == LEX_IS_COMMENT_START) +#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 (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 (int m68k_mri ATTRIBUTE_UNUSED) +{ + const char *p; + int c; + + lex[' '] = LEX_IS_WHITESPACE; + lex['\t'] = LEX_IS_WHITESPACE; + lex['\r'] = LEX_IS_WHITESPACE; + lex['\n'] = LEX_IS_NEWLINE; + lex[':'] = LEX_IS_COLON; + +#ifdef TC_M68K + scrub_m68k_mri = m68k_mri; + + if (! m68k_mri) +#endif + { + lex['"'] = LEX_IS_STRINGQUOTE; + +#if ! defined (TC_HPPA) && ! defined (TC_I370) + /* I370 uses single-quotes to delimit integer, float constants. */ + lex['\''] = LEX_IS_ONECHAR_QUOTE; +#endif + +#ifdef SINGLE_QUOTE_STRINGS + lex['\''] = LEX_IS_STRINGQUOTE; +#endif + } + + /* Note: if any other character can be LEX_IS_STRINGQUOTE, the loop + in state 5 of do_scrub_chars must be changed. */ + + /* 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; + + for (c = 128; c < 256; ++c) + lex[c] = LEX_IS_SYMBOL_COMPONENT; + +#ifdef tc_symbol_chars + /* This macro permits the processor to specify all characters which + may appears in an operand. This will prevent the scrubber from + discarding meaningful whitespace in certain cases. The i386 + backend uses this to support prefixes, which can confuse the + scrubber as to whether it is parsing operands or opcodes. */ + for (p = tc_symbol_chars; *p; ++p) + lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT; +#endif + + /* The m68k backend wants to be able to change comment_chars. */ +#ifndef tc_comment_chars +#define tc_comment_chars comment_chars +#endif + for (p = tc_comment_chars; *p; p++) + lex[(unsigned char) *p] = LEX_IS_COMMENT_START; + + for (p = line_comment_chars; *p; p++) + lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START; + + for (p = line_separator_chars; *p; p++) + lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR; + +#ifdef tc_parallel_separator_chars + /* This macro permits the processor to specify all characters which + separate parallel insns on the same line. */ + for (p = tc_parallel_separator_chars; *p; p++) + lex[(unsigned char) *p] = LEX_IS_PARALLEL_SEPARATOR; +#endif + + /* Only allow slash-star comments if slash is not in use. + FIXME: This isn't right. We should always permit them. */ + if (lex['/'] == 0) + lex['/'] = LEX_IS_TWOCHAR_COMMENT_1ST; + +#ifdef TC_M68K + if (m68k_mri) + { + lex['\''] = LEX_IS_STRINGQUOTE; + lex[';'] = LEX_IS_COMMENT_START; + lex['*'] = LEX_IS_LINE_COMMENT_START; + /* The MRI documentation says '!' is LEX_IS_COMMENT_START, but + then it can't be used in an expression. */ + lex['!'] = LEX_IS_LINE_COMMENT_START; + } +#endif + +#ifdef TC_V850 + lex['-'] = LEX_IS_DOUBLEDASH_1ST; +#endif +#ifdef DOUBLEBAR_PARALLEL + lex['|'] = LEX_IS_DOUBLEBAR_1ST; +#endif +#ifdef TC_D30V + /* Must do this is we want VLIW instruction with "->" or "<-". */ + lex['-'] = LEX_IS_SYMBOL_COMPONENT; +#endif + +#ifdef H_TICK_HEX + if (enable_h_tick_hex) + { + lex['h'] = LEX_IS_H; + lex['H'] = LEX_IS_H; + } +#endif +} + +/* Saved state of the scrubber. */ +static int state; +static int old_state; +static char *out_string; +static char out_buf[20]; +static int add_newlines; +static char *saved_input; +static size_t saved_input_len; +static char input_buffer[32 * 1024]; +static const char *mri_state; +static char mri_last_ch; + +/* Data structure for saving the state of app across #include's. Note that + app is called asynchronously to the parsing of the .include's, so our + 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 * saved_input; + size_t saved_input_len; +#ifdef TC_M68K + int scrub_m68k_mri; +#endif + const char * mri_state; + char mri_last_ch; +#if defined TC_ARM && defined OBJ_ELF + const char * symver_state; +#endif +}; + +char * +app_push (void) +{ + 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; + if (saved_input == NULL) + saved->saved_input = NULL; + else + { + saved->saved_input = (char *) xmalloc (saved_input_len); + memcpy (saved->saved_input, saved_input, saved_input_len); + saved->saved_input_len = saved_input_len; + } +#ifdef TC_M68K + saved->scrub_m68k_mri = scrub_m68k_mri; +#endif + saved->mri_state = mri_state; + saved->mri_last_ch = mri_last_ch; +#if defined TC_ARM && defined OBJ_ELF + saved->symver_state = symver_state; +#endif + + /* do_scrub_begin() is not useful, just wastes time. */ + + state = 0; + saved_input = NULL; + add_newlines = 0; + + return (char *) saved; +} + +void +app_pop (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 (out_buf, saved->out_buf, sizeof (out_buf)); + add_newlines = saved->add_newlines; + if (saved->saved_input == NULL) + saved_input = NULL; + else + { + gas_assert (saved->saved_input_len <= sizeof (input_buffer)); + memcpy (input_buffer, saved->saved_input, saved->saved_input_len); + saved_input = input_buffer; + saved_input_len = saved->saved_input_len; + free (saved->saved_input); + } +#ifdef TC_M68K + scrub_m68k_mri = saved->scrub_m68k_mri; +#endif + mri_state = saved->mri_state; + mri_last_ch = saved->mri_last_ch; +#if defined TC_ARM && defined OBJ_ELF + symver_state = saved->symver_state; +#endif + + free (arg); +} + +/* @@ This assumes that \n &c are the same on host and target. This is not + necessarily true. */ + +static int +process_escape (int ch) +{ + 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; + } +} + +/* This function is called to process input characters. The GET + parameter is used to retrieve more input characters. GET should + set its parameter to point to a buffer, and return the length of + the buffer; it should return 0 at end of file. The scrubbed output + characters are put into the buffer starting at TOSTART; the TOSTART + buffer is TOLEN bytes in length. The function returns the number + of scrubbed characters put into TOSTART. This will be TOLEN unless + end of file was seen. This function is arranged as a state + machine, and saves its state so that it may return at any point. + This is the way the old code used to work. */ + +size_t +do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen) +{ + char *to = tostart; + char *toend = tostart + tolen; + char *from; + char *fromend; + size_t fromlen; + register int ch, ch2 = 0; + /* Character that started the string we're working on. */ + static char quotechar; + + /*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 .linefile, put out digits + 5: parsing a string, then go to old-state + 6: putting out \ escape in a "d string. + 7: no longer used + 8: no longer used + 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 +#ifdef TC_V850 + 12: After seeing a dash, looking for a second dash as a start + of comment. +#endif +#ifdef DOUBLEBAR_PARALLEL + 13: After seeing a vertical bar, looking for a second + vertical bar as a parallel expression separator. +#endif +#ifdef TC_PREDICATE_START_CHAR + 14: After seeing a predicate start character at state 0, looking + for a predicate end character as predicate. + 15: After seeing a predicate start character at state 1, looking + for a predicate end character as predicate. +#endif +#ifdef TC_Z80 + 16: After seeing an 'a' or an 'A' at the start of a symbol + 17: After seeing an 'f' or an 'F' in state 16 +#endif + */ + + /* 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 an 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. + + I added state 13 so that something like "cmp r1, r2 || trap #1" does not + get squashed into "cmp r1,r2||trap#1", with the all important space + between the 'trap' and the '#1' being eliminated. nickc@cygnus.com */ + + /* This macro gets the next input character. */ + +#define GET() \ + (from < fromend \ + ? * (unsigned char *) (from++) \ + : (saved_input = NULL, \ + fromlen = (*get) (input_buffer, sizeof input_buffer), \ + from = input_buffer, \ + fromend = from + fromlen, \ + (fromlen == 0 \ + ? EOF \ + : * (unsigned char *) (from++)))) + + /* This macro pushes a character back on the input stream. */ + +#define UNGET(uch) (*--from = (uch)) + + /* This macro puts a character into the output buffer. If this + character fills the output buffer, this macro jumps to the label + TOFULL. We use this rather ugly approach because we need to + handle two different termination conditions: EOF on the input + stream, and a full output buffer. It would be simpler if we + always read in the entire input stream before processing it, but + I don't want to make such a significant change to the assembler's + memory usage. */ + +#define PUT(pch) \ + do \ + { \ + *to++ = (pch); \ + if (to >= toend) \ + goto tofull; \ + } \ + while (0) + + if (saved_input != NULL) + { + from = saved_input; + fromend = from + saved_input_len; + } + else + { + fromlen = (*get) (input_buffer, sizeof input_buffer); + if (fromlen == 0) + return 0; + from = input_buffer; + fromend = from + fromlen; + } + + while (1) + { + /* The cases in this switch end with continue, in order to + branch back to the top of this while loop and generate the + next output character in the appropriate state. */ + switch (state) + { + case -1: + ch = *out_string++; + if (*out_string == '\0') + { + state = old_state; + old_state = 3; + } + PUT (ch); + continue; + + case -2: + for (;;) + { + do + { + ch = GET (); + + if (ch == EOF) + { + as_warn (_("end of file in comment")); + goto fromeof; + } + + if (ch == '\n') + PUT ('\n'); + } + while (ch != '*'); + + while ((ch = GET ()) == '*') + ; + + if (ch == EOF) + { + as_warn (_("end of file in comment")); + goto fromeof; + } + + if (ch == '/') + break; + + UNGET (ch); + } + + state = old_state; + UNGET (' '); + continue; + + case 4: + ch = GET (); + if (ch == EOF) + goto fromeof; + else if (ch >= '0' && ch <= '9') + PUT (ch); + else + { + while (ch != EOF && IS_WHITESPACE (ch)) + ch = GET (); + if (ch == '"') + { + quotechar = ch; + state = 5; + old_state = 3; + PUT (ch); + } + else + { + while (ch != EOF && ch != '\n') + ch = GET (); + state = 0; + PUT (ch); + } + } + continue; + + case 5: + /* We are going to copy everything up to a quote character, + with special handling for a backslash. We try to + optimize the copying in the simple case without using the + GET and PUT macros. */ + { + char *s; + ptrdiff_t len; + + for (s = from; s < fromend; s++) + { + ch = *s; + if (ch == '\\' + || ch == quotechar + || ch == '\n') + break; + } + len = s - from; + if (len > toend - to) + len = toend - to; + if (len > 0) + { + memcpy (to, from, len); + to += len; + from += len; + if (to >= toend) + goto tofull; + } + } + + ch = GET (); + if (ch == EOF) + { + /* This buffer is here specifically so + that the UNGET below will work. */ + static char one_char_buf[1]; + + as_warn (_("end of file in string; '%c' inserted"), quotechar); + state = old_state; + from = fromend = one_char_buf + 1; + fromlen = 1; + UNGET ('\n'); + PUT (quotechar); + } + else if (ch == quotechar) + { + state = old_state; + PUT (ch); + } +#ifndef NO_STRING_ESCAPES + else if (ch == '\\') + { + state = 6; + PUT (ch); + } +#endif + else if (scrub_m68k_mri && ch == '\n') + { + /* Just quietly terminate the string. This permits lines like + bne label loop if we haven't reach end yet. */ + state = old_state; + UNGET (ch); + PUT ('\''); + } + else + { + PUT (ch); + } + continue; + + 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++; + PUT ('\\'); + continue; + + case EOF: + as_warn (_("end of file in string; '%c' inserted"), quotechar); + PUT (quotechar); + continue; + + case '"': + case '\\': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + case 'x': + case 'X': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + break; + + default: +#ifdef ONLY_STANDARD_ESCAPES + as_warn (_("unknown escape '\\%c' in string; ignored"), ch); +#endif + break; + } + PUT (ch); + continue; + +#ifdef DOUBLEBAR_PARALLEL + case 13: + ch = GET (); + if (ch != '|') + abort (); + + /* Reset back to state 1 and pretend that we are parsing a + line from just after the first white space. */ + state = 1; + PUT ('|'); +#ifdef TC_TIC6X + /* "||^" is used for SPMASKed instructions. */ + ch = GET (); + if (ch == EOF) + goto fromeof; + else if (ch == '^') + PUT ('^'); + else + UNGET (ch); +#endif + continue; +#endif +#ifdef TC_Z80 + case 16: + /* We have seen an 'a' at the start of a symbol, look for an 'f'. */ + ch = GET (); + if (ch == 'f' || ch == 'F') + { + state = 17; + PUT (ch); + } + else + { + state = 9; + break; + } + case 17: + /* We have seen "af" at the start of a symbol, + a ' here is a part of that symbol. */ + ch = GET (); + state = 9; + if (ch == '\'') + /* Change to avoid warning about unclosed string. */ + PUT ('`'); + else if (ch != EOF) + UNGET (ch); + break; +#endif + } + + /* OK, we are somewhere in states 0 through 4 or 9 through 11. */ + + /* flushchar: */ + ch = GET (); + +#ifdef TC_PREDICATE_START_CHAR + if (ch == TC_PREDICATE_START_CHAR && (state == 0 || state == 1)) + { + state += 14; + PUT (ch); + continue; + } + else if (state == 14 || state == 15) + { + if (ch == TC_PREDICATE_END_CHAR) + { + state -= 14; + PUT (ch); + ch = GET (); + } + else + { + PUT (ch); + continue; + } + } +#endif + + recycle: + +#if defined TC_ARM && defined OBJ_ELF + /* We need to watch out for .symver directives. See the comment later + in this function. */ + if (symver_state == NULL) + { + if ((state == 0 || state == 1) && ch == symver_pseudo[0]) + symver_state = symver_pseudo + 1; + } + else + { + /* We advance to the next state if we find the right + character. */ + if (ch != '\0' && (*symver_state == ch)) + ++symver_state; + else if (*symver_state != '\0') + /* We did not get the expected character, or we didn't + get a valid terminating character after seeing the + entire pseudo-op, so we must go back to the beginning. */ + symver_state = NULL; + else + { + /* We've read the entire pseudo-op. If this is the end + of the line, go back to the beginning. */ + if (IS_NEWLINE (ch)) + symver_state = NULL; + } + } +#endif /* TC_ARM && OBJ_ELF */ + +#ifdef TC_M68K + /* We want to have pseudo-ops which control whether we are in + MRI mode or not. Unfortunately, since m68k MRI mode affects + the scrubber, that means that we need a special purpose + recognizer here. */ + if (mri_state == NULL) + { + if ((state == 0 || state == 1) + && ch == mri_pseudo[0]) + mri_state = mri_pseudo + 1; + } + else + { + /* We advance to the next state if we find the right + character, or if we need a space character and we get any + whitespace character, or if we need a '0' and we get a + '1' (this is so that we only need one state to handle + ``.mri 0'' and ``.mri 1''). */ + if (ch != '\0' + && (*mri_state == ch + || (*mri_state == ' ' + && lex[ch] == LEX_IS_WHITESPACE) + || (*mri_state == '0' + && ch == '1'))) + { + mri_last_ch = ch; + ++mri_state; + } + else if (*mri_state != '\0' + || (lex[ch] != LEX_IS_WHITESPACE + && lex[ch] != LEX_IS_NEWLINE)) + { + /* We did not get the expected character, or we didn't + get a valid terminating character after seeing the + entire pseudo-op, so we must go back to the + beginning. */ + mri_state = NULL; + } + else + { + /* We've read the entire pseudo-op. mips_last_ch is + either '0' or '1' indicating whether to enter or + leave MRI mode. */ + do_scrub_begin (mri_last_ch == '1'); + mri_state = NULL; + + /* We continue handling the character as usual. The + main gas reader must also handle the .mri pseudo-op + to control expression parsing and the like. */ + } + } +#endif + + if (ch == EOF) + { + if (state != 0) + { + as_warn (_("end of file not at end of a line; newline inserted")); + state = 0; + PUT ('\n'); + } + goto fromeof; + } + + switch (lex[ch]) + { + case LEX_IS_WHITESPACE: + do + { + ch = GET (); + } + while (ch != EOF && IS_WHITESPACE (ch)); + if (ch == EOF) + goto fromeof; + + if (state == 0) + { + /* Preserve a single whitespace character at the + beginning of a line. */ + state = 1; + UNGET (ch); + PUT (' '); + break; + } + +#ifdef KEEP_WHITE_AROUND_COLON + if (lex[ch] == LEX_IS_COLON) + { + /* Only keep this white if there's no white *after* the + colon. */ + ch2 = GET (); + if (ch2 != EOF) + UNGET (ch2); + if (!IS_WHITESPACE (ch2)) + { + state = 9; + UNGET (ch); + PUT (' '); + break; + } + } +#endif + if (IS_COMMENT (ch) + || ch == '/' + || IS_LINE_SEPARATOR (ch) + || IS_PARALLEL_SEPARATOR (ch)) + { + if (scrub_m68k_mri) + { + /* In MRI mode, we keep these spaces. */ + UNGET (ch); + PUT (' '); + break; + } + goto recycle; + } + + /* 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 + normally must ignore. In MRI mode, though, spaces are + not permitted between the label and the colon. */ + if ((state == 2 || state == 11) + && lex[ch] == LEX_IS_COLON + && ! scrub_m68k_mri) + { + state = 1; + PUT (ch); + break; + } + + switch (state) + { + 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; + if (to + 1 < toend) + { + /* Optimize common case by skipping UNGET/GET. */ + PUT (' '); /* Sp after opco */ + goto recycle; + } + UNGET (ch); + PUT (' '); + break; + case 3: +#ifndef TC_KEEP_OPERAND_SPACES + /* For TI C6X, we keep these spaces as they may separate + functional unit specifiers from operands. */ + if (scrub_m68k_mri) +#endif + { + /* In MRI mode, we keep these spaces. */ + UNGET (ch); + PUT (' '); + break; + } + goto recycle; /* Sp in operands */ + case 9: + case 10: +#ifndef TC_KEEP_OPERAND_SPACES + if (scrub_m68k_mri) +#endif + { + /* In MRI mode, we keep these spaces. */ + state = 3; + UNGET (ch); + PUT (' '); + break; + } + state = 10; /* Sp after symbol char */ + goto recycle; + case 11: + if (LABELS_WITHOUT_COLONS || flag_m68k_mri) + state = 1; + else + { + /* We know that ch is not ':', since we tested that + case above. Therefore this is not a label, so it + must be the opcode, and we've just seen the + whitespace after it. */ + state = 3; + } + UNGET (ch); + PUT (' '); /* Sp after label definition. */ + break; + default: + BAD_CASE (state); + } + break; + + case LEX_IS_TWOCHAR_COMMENT_1ST: + ch2 = GET (); + if (ch2 == '*') + { + for (;;) + { + do + { + ch2 = GET (); + if (ch2 != EOF && IS_NEWLINE (ch2)) + add_newlines++; + } + while (ch2 != EOF && ch2 != '*'); + + while (ch2 == '*') + ch2 = GET (); + + if (ch2 == EOF || ch2 == '/') + break; + + /* This UNGET will ensure that we count newlines + correctly. */ + UNGET (ch2); + } + + if (ch2 == EOF) + as_warn (_("end of file in multiline comment")); + + ch = ' '; + goto recycle; + } +#ifdef DOUBLESLASH_LINE_COMMENTS + else if (ch2 == '/') + { + do + { + ch = GET (); + } + while (ch != EOF && !IS_NEWLINE (ch)); + if (ch == EOF) + as_warn ("end of file in comment; newline inserted"); + state = 0; + PUT ('\n'); + break; + } +#endif + else + { + if (ch2 != EOF) + UNGET (ch2); + if (state == 9 || state == 10) + state = 3; + PUT (ch); + } + break; + + case LEX_IS_STRINGQUOTE: + quotechar = ch; + if (state == 10) + { + /* Preserve the whitespace in foo "bar". */ + UNGET (ch); + state = 3; + PUT (' '); + + /* PUT didn't jump out. We could just break, but we + know what will happen, so optimize a bit. */ + ch = GET (); + old_state = 3; + } + else if (state == 9) + old_state = 3; + else + old_state = state; + state = 5; + PUT (ch); + break; + +#ifndef IEEE_STYLE + case LEX_IS_ONECHAR_QUOTE: +#ifdef H_TICK_HEX + if (state == 9 && enable_h_tick_hex) + { + char c; + + c = GET (); + as_warn ("'%c found after symbol", c); + UNGET (c); + } +#endif + if (state == 10) + { + /* Preserve the whitespace in foo 'b'. */ + UNGET (ch); + state = 3; + PUT (' '); + break; + } + ch = GET (); + if (ch == EOF) + { + as_warn (_("end of file after a one-character quote; \\0 inserted")); + ch = 0; + } + if (ch == '\\') + { + ch = GET (); + if (ch == EOF) + { + as_warn (_("end of file in escape character")); + ch = '\\'; + } + else + 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 + if (ch != EOF) + UNGET (ch); +#endif + } + if (strlen (out_buf) == 1) + { + PUT (out_buf[0]); + break; + } + if (state == 9) + old_state = 3; + else + old_state = state; + state = -1; + out_string = out_buf; + PUT (*out_string++); + break; +#endif + + case LEX_IS_COLON: +#ifdef KEEP_WHITE_AROUND_COLON + state = 9; +#else + if (state == 9 || state == 10) + state = 3; + else if (state != 3) + state = 1; +#endif + PUT (ch); + break; + + case LEX_IS_NEWLINE: + /* Roll out a bunch of newlines from inside comments, etc. */ + if (add_newlines) + { + --add_newlines; + UNGET (ch); + } + /* Fall through. */ + + case LEX_IS_LINE_SEPARATOR: + state = 0; + PUT (ch); + break; + + case LEX_IS_PARALLEL_SEPARATOR: + state = 1; + PUT (ch); + break; + +#ifdef TC_V850 + case LEX_IS_DOUBLEDASH_1ST: + ch2 = GET (); + if (ch2 != '-') + { + if (ch2 != EOF) + UNGET (ch2); + goto de_fault; + } + /* Read and skip to end of line. */ + do + { + ch = GET (); + } + while (ch != EOF && ch != '\n'); + + if (ch == EOF) + as_warn (_("end of file in comment; newline inserted")); + + state = 0; + PUT ('\n'); + break; +#endif +#ifdef DOUBLEBAR_PARALLEL + case LEX_IS_DOUBLEBAR_1ST: + ch2 = GET (); + if (ch2 != EOF) + UNGET (ch2); + if (ch2 != '|') + goto de_fault; + + /* Handle '||' in two states as invoking PUT twice might + result in the first one jumping out of this loop. We'd + then lose track of the state and one '|' char. */ + state = 13; + PUT ('|'); + break; +#endif + case LEX_IS_LINE_COMMENT_START: + /* 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 == '*') + { + old_state = 3; + state = -2; + break; + } + else + { + UNGET (ch2); + } + } + + if (state == 0 || state == 1) /* Only comment at start of line. */ + { + int startch; + + startch = ch; + + do + { + ch = GET (); + } + while (ch != EOF && IS_WHITESPACE (ch)); + + if (ch == EOF) + { + as_warn (_("end of file in comment; newline inserted")); + PUT ('\n'); + break; + } + + if (ch < '0' || ch > '9' || state != 0 || startch != '#') + { + /* Not a cpp line. */ + while (ch != EOF && !IS_NEWLINE (ch)) + ch = GET (); + if (ch == EOF) + as_warn (_("end of file in comment; newline inserted")); + state = 0; + PUT ('\n'); + break; + } + /* Looks like `# 123 "filename"' from cpp. */ + UNGET (ch); + old_state = 4; + state = -1; + if (scrub_m68k_mri) + out_string = "\tlinefile "; + else + out_string = "\t.linefile "; + PUT (*out_string++); + break; + } + +#ifdef TC_D10V + /* All insns end in a char for which LEX_IS_SYMBOL_COMPONENT is true. + Trap is the only short insn that has a first operand that is + neither register nor label. + We must prevent exef0f ||trap #1 to degenerate to exef0f ||trap#1 . + We can't make '#' LEX_IS_SYMBOL_COMPONENT because it is + already LEX_IS_LINE_COMMENT_START. However, it is the + only character in line_comment_chars for d10v, hence we + can recognize it as such. */ + /* An alternative approach would be to reset the state to 1 when + we see '||', '<'- or '->', but that seems to be overkill. */ + if (state == 10) + PUT (' '); +#endif + /* 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 (tc_comment_chars, ch) == NULL + && (! scrub_m68k_mri + || (ch != '!' && ch != '*'))) + goto de_fault; + if (scrub_m68k_mri + && (ch == '!' || ch == '*' || ch == '#') + && state != 1 + && state != 10) + goto de_fault; + /* Fall through. */ + case LEX_IS_COMMENT_START: +#if defined TC_ARM && defined OBJ_ELF + /* On the ARM, `@' is the comment character. + Unfortunately this is also a special character in ELF .symver + directives (and .type, though we deal with those another way). + So we check if this line is such a directive, and treat + the character as default if so. This is a hack. */ + if ((symver_state != NULL) && (*symver_state == 0)) + goto de_fault; +#endif + +#ifdef TC_ARM + /* For the ARM, care is needed not to damage occurrences of \@ + by stripping the @ onwards. Yuck. */ + if (to > tostart && *(to - 1) == '\\') + /* Do not treat the @ as a start-of-comment. */ + goto de_fault; +#endif + +#ifdef WARN_COMMENTS + if (!found_comment) + as_where (&found_comment_file, &found_comment); +#endif + do + { + ch = GET (); + } + while (ch != EOF && !IS_NEWLINE (ch)); + if (ch == EOF) + as_warn (_("end of file in comment; newline inserted")); + state = 0; + PUT ('\n'); + break; + +#ifdef H_TICK_HEX + case LEX_IS_H: + /* Look for strings like H'[0-9A-Fa-f] and if found, replace + the H' with 0x to make them gas-style hex characters. */ + if (enable_h_tick_hex) + { + char quot; + + quot = GET (); + if (quot == '\'') + { + UNGET ('x'); + ch = '0'; + } + else + UNGET (quot); + } + /* FALL THROUGH */ +#endif + + 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; + PUT (' '); + break; + } + +#ifdef TC_Z80 + /* "af'" is a symbol containing '\''. */ + if (state == 3 && (ch == 'a' || ch == 'A')) + { + state = 16; + PUT (ch); + ch = GET (); + if (ch == 'f' || ch == 'F') + { + state = 17; + PUT (ch); + break; + } + else + { + state = 9; + if (ch == EOF || !IS_SYMBOL_COMPONENT (ch)) + { + if (ch != EOF) + UNGET (ch); + break; + } + } + } +#endif + if (state == 3) + state = 9; + + /* This is a common case. Quickly copy CH and all the + following symbol component or normal characters. */ + if (to + 1 < toend + && mri_state == NULL +#if defined TC_ARM && defined OBJ_ELF + && symver_state == NULL +#endif + ) + { + char *s; + ptrdiff_t len; + + for (s = from; s < fromend; s++) + { + int type; + + ch2 = *(unsigned char *) s; + type = lex[ch2]; + if (type != 0 + && type != LEX_IS_SYMBOL_COMPONENT) + break; + } + + if (s > from) + /* Handle the last character normally, for + simplicity. */ + --s; + + len = s - from; + + if (len > (toend - to) - 1) + len = (toend - to) - 1; + + if (len > 0) + { + PUT (ch); + memcpy (to, from, len); + to += len; + from += len; + if (to >= toend) + goto tofull; + ch = GET (); + } + } + + /* Fall through. */ + default: + de_fault: + /* Some relatively `normal' character. */ + if (state == 0) + { + state = 11; /* Now seeing label definition. */ + } + else if (state == 1) + { + state = 2; /* Ditto. */ + } + else if (state == 9) + { + if (!IS_SYMBOL_COMPONENT (ch)) + state = 3; + } + else if (state == 10) + { + if (ch == '\\') + { + /* Special handling for backslash: a backslash may + be the beginning of a formal parameter (of a + macro) following another symbol character, with + whitespace in between. If that is the case, we + output a space before the parameter. Strictly + speaking, correct handling depends upon what the + macro parameter expands into; if the parameter + expands into something which does not start with + an operand character, then we don't want to keep + the space. We don't have enough information to + make the right choice, so here we are making the + choice which is more likely to be correct. */ + if (to + 1 >= toend) + { + /* If we're near the end of the buffer, save the + character for the next time round. Otherwise + we'll lose our state. */ + UNGET (ch); + goto tofull; + } + *to++ = ' '; + } + + state = 3; + } + PUT (ch); + break; + } + } + + /*NOTREACHED*/ + + fromeof: + /* We have reached the end of the input. */ + return to - tostart; + + tofull: + /* The output buffer is full. Save any input we have not yet + processed. */ + if (fromend > from) + { + saved_input = from; + saved_input_len = fromend - from; + } + else + saved_input = NULL; + + return to - tostart; +} diff --git a/contrib/toolchain/binutils/gas/as b/contrib/toolchain/binutils/gas/as new file mode 100644 index 0000000000000000000000000000000000000000..befff57d2b3ebd94698158ecab3d518008b04174 GIT binary patch literal 1235004 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
  • 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

    M^-7U^$!Qs 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 z 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

      rK`E=cTX~ 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ξK>ZE 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 (7uh-HFXO$5DwvI~+pMs1A4eHc&MeB^ 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 (); +} + +const char * +default_emul_bfd_name (void) +{ + abort (); + return NULL; +} + +void +common_emul_init (void) +{ + this_format = this_emulation->format; + + if (this_emulation->leading_underscore == 2) + this_emulation->leading_underscore = this_format->dfl_leading_underscore; + + if (this_emulation->default_endian != 2) + target_big_endian = this_emulation->default_endian; + + if (this_emulation->fake_label_name == 0) + { + if (this_emulation->leading_underscore) + this_emulation->fake_label_name = "L0\001"; + else + /* What other parameters should we test? */ + this_emulation->fake_label_name = ".L0\001"; + } +} +#endif + +void +print_version_id (void) +{ + static int printed; + + if (printed) + return; + printed = 1; + + fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s\n"), + VERSION, TARGET_ALIAS, BFD_VERSION_STRING); +} + +static void +show_usage (FILE * stream) +{ + fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname); + + fprintf (stream, _("\ +Options:\n\ + -a[sub-option...] turn on listings\n\ + Sub-options [default hls]:\n\ + c omit false conditionals\n\ + d omit debugging directives\n\ + g include general info\n\ + h include high-level source\n\ + l include assembly\n\ + m include macro expansions\n\ + n omit forms processing\n\ + s include symbols\n\ + =FILE list to FILE (must be last sub-option)\n")); + + fprintf (stream, _("\ + --alternate initially turn on alternate macro syntax\n")); +#ifdef HAVE_ZLIB_H + fprintf (stream, _("\ + --compress-debug-sections\n\ + compress DWARF debug sections using zlib\n")); + fprintf (stream, _("\ + --nocompress-debug-sections\n\ + don't compress DWARF debug sections\n")); +#endif /* HAVE_ZLIB_H */ + fprintf (stream, _("\ + -D produce assembler debugging messages\n")); + fprintf (stream, _("\ + --debug-prefix-map OLD=NEW\n\ + map OLD to NEW in debug information\n")); + fprintf (stream, _("\ + --defsym SYM=VAL define symbol SYM to given value\n")); +#ifdef USE_EMULATIONS + { + int i; + char *def_em; + + fprintf (stream, "\ + --em=["); + for (i = 0; i < n_emulations - 1; i++) + fprintf (stream, "%s | ", emulations[i]->name); + fprintf (stream, "%s]\n", emulations[i]->name); + + def_em = getenv (EMULATION_ENVIRON); + if (!def_em) + def_em = DEFAULT_EMULATION; + fprintf (stream, _("\ + emulate output (default %s)\n"), def_em); + } +#endif +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF + fprintf (stream, _("\ + --execstack require executable stack for this object\n")); + fprintf (stream, _("\ + --noexecstack don't require executable stack for this object\n")); + fprintf (stream, _("\ + --size-check=[error|warning]\n\ + ELF .size directive check (default --size-check=error)\n")); +#endif + fprintf (stream, _("\ + -f skip whitespace and comment preprocessing\n")); + fprintf (stream, _("\ + -g --gen-debug generate debugging information\n")); + fprintf (stream, _("\ + --gstabs generate STABS debugging information\n")); + fprintf (stream, _("\ + --gstabs+ generate STABS debug info with GNU extensions\n")); + fprintf (stream, _("\ + --gdwarf-2 generate DWARF2 debugging information\n")); + fprintf (stream, _("\ + --gdwarf-sections generate per-function section names for DWARF line information\n")); + fprintf (stream, _("\ + --hash-size= set the hash table size close to \n")); + fprintf (stream, _("\ + --help show this message and exit\n")); + fprintf (stream, _("\ + --target-help show target specific options\n")); + fprintf (stream, _("\ + -I DIR add DIR to search list for .include directives\n")); + fprintf (stream, _("\ + -J don't warn about signed overflow\n")); + fprintf (stream, _("\ + -K warn when differences altered for long displacements\n")); + fprintf (stream, _("\ + -L,--keep-locals keep local symbols (e.g. starting with `L')\n")); + fprintf (stream, _("\ + -M,--mri assemble in MRI compatibility mode\n")); + fprintf (stream, _("\ + --MD FILE write dependency information in FILE (default none)\n")); + fprintf (stream, _("\ + -nocpp ignored\n")); + fprintf (stream, _("\ + -o OBJFILE name the object-file output OBJFILE (default a.out)\n")); + fprintf (stream, _("\ + -R fold data section into text section\n")); + fprintf (stream, _("\ + --reduce-memory-overheads \n\ + prefer smaller memory use at the cost of longer\n\ + assembly times\n")); + fprintf (stream, _("\ + --statistics print various measured statistics from execution\n")); + fprintf (stream, _("\ + --strip-local-absolute strip local absolute symbols\n")); + fprintf (stream, _("\ + --traditional-format Use same format as native assembler when possible\n")); + fprintf (stream, _("\ + --version print assembler version number and exit\n")); + fprintf (stream, _("\ + -W --no-warn suppress warnings\n")); + fprintf (stream, _("\ + --warn don't suppress warnings\n")); + fprintf (stream, _("\ + --fatal-warnings treat warnings as errors\n")); +#ifdef HAVE_ITBL_CPU + fprintf (stream, _("\ + --itbl INSTTBL extend instruction set to include instructions\n\ + matching the specifications defined in file INSTTBL\n")); +#endif + fprintf (stream, _("\ + -w ignored\n")); + fprintf (stream, _("\ + -X ignored\n")); + fprintf (stream, _("\ + -Z generate object file even after errors\n")); + fprintf (stream, _("\ + --listing-lhs-width set the width in words of the output data column of\n\ + the listing\n")); + fprintf (stream, _("\ + --listing-lhs-width2 set the width in words of the continuation lines\n\ + of the output data column; ignored if smaller than\n\ + the width of the first line\n")); + fprintf (stream, _("\ + --listing-rhs-width set the max width in characters of the lines from\n\ + the source file\n")); + fprintf (stream, _("\ + --listing-cont-lines set the maximum number of continuation lines used\n\ + for the output data column of the listing\n")); + fprintf (stream, _("\ + @FILE read options from FILE\n")); + + md_show_usage (stream); + + fputc ('\n', stream); + + if (REPORT_BUGS_TO[0] && stream == stdout) + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); +} + +/* Since it is easy to do here we interpret the special arg "-" + to mean "use stdin" and we set that argv[] pointing to "". + After we have munged argv[], the only things left are source file + name(s) and ""(s) denoting stdin. These file names are used + (perhaps more than once) later. + + check for new machine-dep cmdline options in + md_parse_option definitions in config/tc-*.c. */ + +static void +parse_args (int * pargc, char *** pargv) +{ + int old_argc; + int new_argc; + char ** old_argv; + char ** new_argv; + /* Starting the short option string with '-' is for programs that + expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. */ + char *shortopts; + extern const char *md_shortopts; + static const char std_shortopts[] = + { + '-', 'J', +#ifndef WORKING_DOT_WORD + /* -K is not meaningful if .word is not being hacked. */ + 'K', +#endif + 'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'g', ':',':', 'I', ':', 'o', ':', +#ifndef VMS + /* -v takes an argument on VMS, so we don't make it a generic + option. */ + 'v', +#endif + 'w', 'X', +#ifdef HAVE_ITBL_CPU + /* New option for extending instruction set (see also --itbl below). */ + 't', ':', +#endif + '\0' + }; + struct option *longopts; + extern struct option md_longopts[]; + extern size_t md_longopts_size; + /* Codes used for the long options with no short synonyms. */ + enum option_values + { + OPTION_HELP = OPTION_STD_BASE, + OPTION_NOCPP, + OPTION_STATISTICS, + OPTION_VERSION, + OPTION_DUMPCONFIG, + OPTION_VERBOSE, + OPTION_EMULATION, + OPTION_DEBUG_PREFIX_MAP, + OPTION_DEFSYM, + OPTION_LISTING_LHS_WIDTH, + OPTION_LISTING_LHS_WIDTH2, + OPTION_LISTING_RHS_WIDTH, + OPTION_LISTING_CONT_LINES, + OPTION_DEPFILE, + OPTION_GSTABS, + OPTION_GSTABS_PLUS, + OPTION_GDWARF2, + OPTION_GDWARF_SECTIONS, + OPTION_STRIP_LOCAL_ABSOLUTE, + OPTION_TRADITIONAL_FORMAT, + OPTION_WARN, + OPTION_TARGET_HELP, + OPTION_EXECSTACK, + OPTION_NOEXECSTACK, + OPTION_SIZE_CHECK, + OPTION_ALTERNATE, + OPTION_AL, + OPTION_HASH_TABLE_SIZE, + OPTION_REDUCE_MEMORY_OVERHEADS, + OPTION_WARN_FATAL, + OPTION_COMPRESS_DEBUG, + OPTION_NOCOMPRESS_DEBUG + /* When you add options here, check that they do + not collide with OPTION_MD_BASE. See as.h. */ + }; + + static const struct option std_longopts[] = + { + /* Note: commas are placed at the start of the line rather than + the end of the preceding line so that it is simpler to + selectively add and remove lines from this list. */ + {"alternate", no_argument, NULL, OPTION_ALTERNATE} + /* The entry for "a" is here to prevent getopt_long_only() from + considering that -a is an abbreviation for --alternate. This is + necessary because -a= is a valid switch but getopt would + normally reject it since --alternate does not take an argument. */ + ,{"a", optional_argument, NULL, 'a'} + /* Handle -al=. */ + ,{"al", optional_argument, NULL, OPTION_AL} + ,{"compress-debug-sections", no_argument, NULL, OPTION_COMPRESS_DEBUG} + ,{"nocompress-debug-sections", no_argument, NULL, OPTION_NOCOMPRESS_DEBUG} + ,{"debug-prefix-map", required_argument, NULL, OPTION_DEBUG_PREFIX_MAP} + ,{"defsym", required_argument, NULL, OPTION_DEFSYM} + ,{"dump-config", no_argument, NULL, OPTION_DUMPCONFIG} + ,{"emulation", required_argument, NULL, OPTION_EMULATION} +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF + ,{"execstack", no_argument, NULL, OPTION_EXECSTACK} + ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK} + ,{"size-check", required_argument, NULL, OPTION_SIZE_CHECK} +#endif + ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL} + ,{"gdwarf-2", no_argument, NULL, OPTION_GDWARF2} + /* GCC uses --gdwarf-2 but GAS uses to use --gdwarf2, + so we keep it here for backwards compatibility. */ + ,{"gdwarf2", no_argument, NULL, OPTION_GDWARF2} + ,{"gdwarf-sections", no_argument, NULL, OPTION_GDWARF_SECTIONS} + ,{"gen-debug", no_argument, NULL, 'g'} + ,{"gstabs", no_argument, NULL, OPTION_GSTABS} + ,{"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS} + ,{"hash-size", required_argument, NULL, OPTION_HASH_TABLE_SIZE} + ,{"help", no_argument, NULL, OPTION_HELP} +#ifdef HAVE_ITBL_CPU + /* New option for extending instruction set (see also -t above). + The "-t file" or "--itbl file" option extends the basic set of + valid instructions by reading "file", a text file containing a + list of instruction formats. The additional opcodes and their + formats are added to the built-in set of instructions, and + mnemonics for new registers may also be defined. */ + ,{"itbl", required_argument, NULL, 't'} +#endif + /* getopt allows abbreviations, so we do this to stop it from + treating -k as an abbreviation for --keep-locals. Some + ports use -k to enable PIC assembly. */ + ,{"keep-locals", no_argument, NULL, 'L'} + ,{"keep-locals", no_argument, NULL, 'L'} + ,{"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH} + ,{"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2} + ,{"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH} + ,{"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES} + ,{"MD", required_argument, NULL, OPTION_DEPFILE} + ,{"mri", no_argument, NULL, 'M'} + ,{"nocpp", no_argument, NULL, OPTION_NOCPP} + ,{"no-warn", no_argument, NULL, 'W'} + ,{"reduce-memory-overheads", no_argument, NULL, OPTION_REDUCE_MEMORY_OVERHEADS} + ,{"statistics", no_argument, NULL, OPTION_STATISTICS} + ,{"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE} + ,{"version", no_argument, NULL, OPTION_VERSION} + ,{"verbose", no_argument, NULL, OPTION_VERBOSE} + ,{"target-help", no_argument, NULL, OPTION_TARGET_HELP} + ,{"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT} + ,{"warn", no_argument, NULL, OPTION_WARN} + }; + + /* Construct the option lists from the standard list and the target + dependent list. Include space for an extra NULL option and + always NULL terminate. */ + shortopts = concat (std_shortopts, md_shortopts, (char *) NULL); + longopts = (struct option *) xmalloc (sizeof (std_longopts) + + md_longopts_size + sizeof (struct option)); + memcpy (longopts, std_longopts, sizeof (std_longopts)); + memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size); + memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size, + 0, sizeof (struct option)); + + /* Make a local copy of the old argv. */ + old_argc = *pargc; + old_argv = *pargv; + + /* Initialize a new argv that contains no options. */ + new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1)); + new_argv[0] = old_argv[0]; + new_argc = 1; + new_argv[new_argc] = NULL; + + while (1) + { + /* getopt_long_only is like getopt_long, but '-' as well as '--' can + indicate a long option. */ + int longind; + int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts, + &longind); + + if (optc == -1) + break; + + switch (optc) + { + default: + /* md_parse_option should return 1 if it recognizes optc, + 0 if not. */ + if (md_parse_option (optc, optarg) != 0) + break; + /* `-v' isn't included in the general short_opts list, so check for + it explicitly here before deciding we've gotten a bad argument. */ + if (optc == 'v') + { +#ifdef VMS + /* Telling getopt to treat -v's value as optional can result + in it picking up a following filename argument here. The + VMS code in md_parse_option can return 0 in that case, + but it has no way of pushing the filename argument back. */ + if (optarg && *optarg) + new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL; + else +#else + case 'v': +#endif + case OPTION_VERBOSE: + print_version_id (); + verbose = 1; + break; + } + else + as_bad (_("unrecognized option -%c%s"), optc, optarg ? optarg : ""); + /* Fall through. */ + + case '?': + exit (EXIT_FAILURE); + + case 1: /* File name. */ + if (!strcmp (optarg, "-")) + optarg = ""; + new_argv[new_argc++] = optarg; + new_argv[new_argc] = NULL; + break; + + case OPTION_TARGET_HELP: + md_show_usage (stdout); + exit (EXIT_SUCCESS); + + case OPTION_HELP: + show_usage (stdout); + exit (EXIT_SUCCESS); + + case OPTION_NOCPP: + break; + + case OPTION_STATISTICS: + flag_print_statistics = 1; + break; + + case OPTION_STRIP_LOCAL_ABSOLUTE: + flag_strip_local_absolute = 1; + break; + + case OPTION_TRADITIONAL_FORMAT: + flag_traditional_format = 1; + break; + + case OPTION_VERSION: + /* This output is intended to follow the GNU standards document. */ + printf (_("GNU assembler %s\n"), BFD_VERSION_STRING); + printf (_("Copyright 2013 Free Software Foundation, Inc.\n")); + printf (_("\ +This program is free software; you may redistribute it under the terms of\n\ +the GNU General Public License version 3 or later.\n\ +This program has absolutely no warranty.\n")); + printf (_("This assembler was configured for a target of `%s'.\n"), + TARGET_ALIAS); + exit (EXIT_SUCCESS); + + case OPTION_EMULATION: +#ifdef USE_EMULATIONS + if (strcmp (optarg, this_emulation->name)) + as_fatal (_("multiple emulation names specified")); +#else + as_fatal (_("emulations not handled in this configuration")); +#endif + break; + + case OPTION_DUMPCONFIG: + fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS); + fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL); + fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU); +#ifdef TARGET_OBJ_FORMAT + fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT); +#endif +#ifdef TARGET_FORMAT + fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT); +#endif + exit (EXIT_SUCCESS); + + case OPTION_COMPRESS_DEBUG: +#ifdef HAVE_ZLIB_H + flag_compress_debug = 1; +#else + as_warn (_("cannot compress debug sections (zlib not installed)")); +#endif /* HAVE_ZLIB_H */ + break; + + case OPTION_NOCOMPRESS_DEBUG: + flag_compress_debug = 0; + break; + + case OPTION_DEBUG_PREFIX_MAP: + add_debug_prefix_map (optarg); + break; + + case OPTION_DEFSYM: + { + char *s; + valueT i; + struct defsym_list *n; + + for (s = optarg; *s != '\0' && *s != '='; s++) + ; + if (*s == '\0') + as_fatal (_("bad defsym; format is --defsym name=value")); + *s++ = '\0'; + i = bfd_scan_vma (s, (const char **) NULL, 0); + n = (struct defsym_list *) xmalloc (sizeof *n); + n->next = defsyms; + n->name = optarg; + n->value = i; + defsyms = n; + } + break; + +#ifdef HAVE_ITBL_CPU + case 't': + { + /* optarg is the name of the file containing the instruction + formats, opcodes, register names, etc. */ + struct itbl_file_list *n; + + if (optarg == NULL) + { + as_warn (_("no file name following -t option")); + break; + } + + n = xmalloc (sizeof * n); + n->next = itbl_files; + n->name = optarg; + itbl_files = n; + + /* Parse the file and add the new instructions to our internal + table. If multiple instruction tables are specified, the + information from this table gets appended onto the existing + internal table. */ + itbl_files->name = xstrdup (optarg); + if (itbl_parse (itbl_files->name) != 0) + as_fatal (_("failed to read instruction table %s\n"), + itbl_files->name); + } + break; +#endif + + case OPTION_DEPFILE: + start_dependencies (optarg); + break; + + case 'g': + /* Some backends, eg Alpha and Mips, use the -g switch for their + own purposes. So we check here for an explicit -g and allow + the backend to decide if it wants to process it. */ + if ( old_argv[optind - 1][1] == 'g' + && md_parse_option (optc, optarg)) + continue; + + if (md_debug_format_selector) + debug_type = md_debug_format_selector (& use_gnu_debug_info_extensions); + else if (IS_ELF) + debug_type = DEBUG_DWARF2; + else + debug_type = DEBUG_STABS; + break; + + case OPTION_GSTABS_PLUS: + use_gnu_debug_info_extensions = 1; + /* Fall through. */ + case OPTION_GSTABS: + debug_type = DEBUG_STABS; + break; + + case OPTION_GDWARF2: + debug_type = DEBUG_DWARF2; + break; + + case OPTION_GDWARF_SECTIONS: + flag_dwarf_sections = TRUE; + break; + + case 'J': + flag_signed_overflow_ok = 1; + break; + +#ifndef WORKING_DOT_WORD + case 'K': + flag_warn_displacement = 1; + break; +#endif + case 'L': + flag_keep_locals = 1; + break; + + case OPTION_LISTING_LHS_WIDTH: + listing_lhs_width = atoi (optarg); + if (listing_lhs_width_second < listing_lhs_width) + listing_lhs_width_second = listing_lhs_width; + break; + case OPTION_LISTING_LHS_WIDTH2: + { + int tmp = atoi (optarg); + + if (tmp > listing_lhs_width) + listing_lhs_width_second = tmp; + } + break; + case OPTION_LISTING_RHS_WIDTH: + listing_rhs_width = atoi (optarg); + break; + case OPTION_LISTING_CONT_LINES: + listing_lhs_cont_lines = atoi (optarg); + break; + + case 'M': + flag_mri = 1; +#ifdef TC_M68K + flag_m68k_mri = 1; +#endif + break; + + case 'R': + flag_readonly_data_in_text = 1; + break; + + case 'W': + flag_no_warnings = 1; + break; + + case OPTION_WARN: + flag_no_warnings = 0; + flag_fatal_warnings = 0; + break; + + case OPTION_WARN_FATAL: + flag_no_warnings = 0; + flag_fatal_warnings = 1; + break; + +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF + case OPTION_EXECSTACK: + flag_execstack = 1; + flag_noexecstack = 0; + break; + + case OPTION_NOEXECSTACK: + flag_noexecstack = 1; + flag_execstack = 0; + break; + + case OPTION_SIZE_CHECK: + if (strcasecmp (optarg, "error") == 0) + flag_size_check = size_check_error; + else if (strcasecmp (optarg, "warning") == 0) + flag_size_check = size_check_warning; + else + as_fatal (_("Invalid --size-check= option: `%s'"), optarg); + break; +#endif + case 'Z': + flag_always_generate_output = 1; + break; + + case OPTION_AL: + listing |= LISTING_LISTING; + if (optarg) + listing_filename = xstrdup (optarg); + break; + + case OPTION_ALTERNATE: + optarg = old_argv [optind - 1]; + while (* optarg == '-') + optarg ++; + + if (strcmp (optarg, "alternate") == 0) + { + flag_macro_alternate = 1; + break; + } + optarg ++; + /* Fall through. */ + + case 'a': + if (optarg) + { + if (optarg != old_argv[optind] && optarg[-1] == '=') + --optarg; + + if (md_parse_option (optc, optarg) != 0) + break; + + while (*optarg) + { + switch (*optarg) + { + case 'c': + listing |= LISTING_NOCOND; + break; + case 'd': + listing |= LISTING_NODEBUG; + break; + case 'g': + listing |= LISTING_GENERAL; + break; + case 'h': + listing |= LISTING_HLL; + break; + case 'l': + listing |= LISTING_LISTING; + break; + case 'm': + listing |= LISTING_MACEXP; + break; + case 'n': + listing |= LISTING_NOFORM; + break; + case 's': + listing |= LISTING_SYMBOLS; + break; + case '=': + listing_filename = xstrdup (optarg + 1); + optarg += strlen (listing_filename); + break; + default: + as_fatal (_("invalid listing option `%c'"), *optarg); + break; + } + optarg++; + } + } + if (!listing) + listing = LISTING_DEFAULT; + break; + + case 'D': + /* DEBUG is implemented: it debugs different + things from other people's assemblers. */ + flag_debug = 1; + break; + + case 'f': + flag_no_comments = 1; + break; + + case 'I': + { /* Include file directory. */ + char *temp = xstrdup (optarg); + + add_include_dir (temp); + break; + } + + case 'o': + out_file_name = xstrdup (optarg); + break; + + case 'w': + break; + + case 'X': + /* -X means treat warnings as errors. */ + break; + + case OPTION_REDUCE_MEMORY_OVERHEADS: + /* The only change we make at the moment is to reduce + the size of the hash tables that we use. */ + set_gas_hash_table_size (4051); + break; + + case OPTION_HASH_TABLE_SIZE: + { + unsigned long new_size; + + new_size = strtoul (optarg, NULL, 0); + if (new_size) + set_gas_hash_table_size (new_size); + else + as_fatal (_("--hash-size needs a numeric argument")); + break; + } + } + } + + free (shortopts); + free (longopts); + + *pargc = new_argc; + *pargv = new_argv; + +#ifdef md_after_parse_args + md_after_parse_args (); +#endif +} + +static void +dump_statistics (void) +{ +#ifdef HAVE_SBRK + char *lim = (char *) sbrk (0); +#endif + long run_time = get_run_time () - start_time; + + fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"), + myname, run_time / 1000000, run_time % 1000000); +#ifdef HAVE_SBRK + fprintf (stderr, _("%s: data size %ld\n"), + myname, (long) (lim - start_sbrk)); +#endif + + subsegs_print_statistics (stderr); + write_print_statistics (stderr); + symbol_print_statistics (stderr); + read_print_statistics (stderr); + +#ifdef tc_print_statistics + tc_print_statistics (stderr); +#endif + +#ifdef obj_print_statistics + obj_print_statistics (stderr); +#endif +} + +static void +close_output_file (void) +{ + output_file_close (out_file_name); + if (!keep_it) + unlink_if_ordinary (out_file_name); +} + +/* The interface between the macro code and gas expression handling. */ + +static size_t +macro_expr (const char *emsg, size_t idx, sb *in, offsetT *val) +{ + char *hold; + expressionS ex; + + sb_terminate (in); + + hold = input_line_pointer; + input_line_pointer = in->ptr + idx; + expression_and_evaluate (&ex); + idx = input_line_pointer - in->ptr; + input_line_pointer = hold; + + if (ex.X_op != O_constant) + as_bad ("%s", emsg); + + *val = ex.X_add_number; + + return idx; +} + +/* Here to attempt 1 pass over each input file. + We scan argv[*] looking for filenames or exactly "" which is + shorthand for stdin. Any argv that is NULL is not a file-name. + We set need_pass_2 TRUE if, after this, we still have unresolved + expressions of the form (unknown value)+-(unknown value). + + Note the un*x semantics: there is only 1 logical input file, but it + may be a catenation of many 'physical' input files. */ + +static void +perform_an_assembly_pass (int argc, char ** argv) +{ + int saw_a_file = 0; +#ifndef OBJ_MACH_O + flagword applicable; +#endif + + need_pass_2 = 0; + +#ifndef OBJ_MACH_O + /* Create the standard sections, and those the assembler uses + internally. */ + text_section = subseg_new (TEXT_SECTION_NAME, 0); + data_section = subseg_new (DATA_SECTION_NAME, 0); + bss_section = subseg_new (BSS_SECTION_NAME, 0); + /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed + to have relocs, otherwise we don't find out in time. */ + applicable = bfd_applicable_section_flags (stdoutput); + bfd_set_section_flags (stdoutput, text_section, + applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC + | SEC_CODE | SEC_READONLY)); + bfd_set_section_flags (stdoutput, data_section, + applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC + | SEC_DATA)); + bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC); + seg_info (bss_section)->bss = 1; +#endif + subseg_new (BFD_ABS_SECTION_NAME, 0); + subseg_new (BFD_UND_SECTION_NAME, 0); + reg_section = subseg_new ("*GAS `reg' section*", 0); + expr_section = subseg_new ("*GAS `expr' section*", 0); + +#ifndef OBJ_MACH_O + subseg_set (text_section, 0); +#endif + + /* This may add symbol table entries, which requires having an open BFD, + and sections already created. */ + md_begin (); + +#ifdef USING_CGEN + gas_cgen_begin (); +#endif +#ifdef obj_begin + obj_begin (); +#endif + + /* Skip argv[0]. */ + argv++; + argc--; + + while (argc--) + { + if (*argv) + { /* Is it a file-name argument? */ + PROGRESS (1); + saw_a_file++; + /* argv->"" if stdin desired, else->filename. */ + read_a_source_file (*argv); + } + argv++; /* Completed that argv. */ + } + if (!saw_a_file) + read_a_source_file (""); +} + +#ifdef OBJ_ELF +static void +create_obj_attrs_section (void) +{ + segT s; + char *p; + offsetT size; + const char *name; + + size = bfd_elf_obj_attr_size (stdoutput); + if (size) + { + name = get_elf_backend_data (stdoutput)->obj_attrs_section; + if (!name) + name = ".gnu.attributes"; + s = subseg_new (name, 0); + elf_section_type (s) + = get_elf_backend_data (stdoutput)->obj_attrs_section_type; + bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA); + frag_now_fix (); + p = frag_more (size); + bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size); + } +} +#endif + + +int +main (int argc, char ** argv) +{ + char ** argv_orig = argv; + + int macro_strip_at; + + start_time = get_run_time (); +#ifdef HAVE_SBRK + start_sbrk = (char *) sbrk (0); +#endif + +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_MESSAGES, ""); +#endif +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + if (debug_memory) + chunksize = 64; + +#ifdef HOST_SPECIAL_INIT + HOST_SPECIAL_INIT (argc, argv); +#endif + + myname = argv[0]; + xmalloc_set_program_name (myname); + + expandargv (&argc, &argv); + + START_PROGRESS (myname, 0); + +#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME +#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out" +#endif + + out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME; + + hex_init (); + bfd_init (); + bfd_set_error_program_name (myname); + +#ifdef USE_EMULATIONS + select_emulation_mode (argc, argv); +#endif + + PROGRESS (1); + /* Call parse_args before any of the init/begin functions + so that switches like --hash-size can be honored. */ + parse_args (&argc, &argv); + symbol_begin (); + frag_init (); + subsegs_begin (); + read_begin (); + input_scrub_begin (); + expr_begin (); + + /* It has to be called after dump_statistics (). */ + xatexit (close_output_file); + + if (flag_print_statistics) + xatexit (dump_statistics); + + macro_strip_at = 0; +#ifdef TC_I960 + macro_strip_at = flag_mri; +#endif + + macro_init (flag_macro_alternate, flag_mri, macro_strip_at, macro_expr); + + PROGRESS (1); + + output_file_create (out_file_name); + gas_assert (stdoutput != 0); + + dot_symbol_init (); + +#ifdef tc_init_after_args + tc_init_after_args (); +#endif + + itbl_init (); + + dwarf2_init (); + + local_symbol_make (".gasversion.", absolute_section, + BFD_VERSION / 10000UL, &predefined_address_frag); + + /* Now that we have fully initialized, and have created the output + file, define any symbols requested by --defsym command line + arguments. */ + while (defsyms != NULL) + { + symbolS *sym; + struct defsym_list *next; + + sym = symbol_new (defsyms->name, absolute_section, defsyms->value, + &zero_address_frag); + /* Make symbols defined on the command line volatile, so that they + can be redefined inside a source file. This makes this assembler's + behaviour compatible with earlier versions, but it may not be + completely intuitive. */ + S_SET_VOLATILE (sym); + symbol_table_insert (sym); + next = defsyms->next; + free (defsyms); + defsyms = next; + } + + PROGRESS (1); + + /* Assemble it. */ + perform_an_assembly_pass (argc, argv); + + cond_finish_check (-1); + +#ifdef md_end + md_end (); +#endif + +#ifdef OBJ_ELF + if (IS_ELF) + create_obj_attrs_section (); +#endif + +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF + if ((flag_execstack || flag_noexecstack) + && OUTPUT_FLAVOR == bfd_target_elf_flavour) + { + segT gnustack; + + gnustack = subseg_new (".note.GNU-stack", 0); + bfd_set_section_flags (stdoutput, gnustack, + SEC_READONLY | (flag_execstack ? SEC_CODE : 0)); + + } +#endif + + /* If we've been collecting dwarf2 .debug_line info, either for + assembly debugging or on behalf of the compiler, emit it now. */ + dwarf2_finish (); + + /* If we constructed dwarf2 .eh_frame info, either via .cfi + directives from the user or by the backend, emit it now. */ + cfi_finish (); + + if (seen_at_least_1_file () + && (flag_always_generate_output || had_errors () == 0)) + keep_it = 1; + else + keep_it = 0; + + /* This used to be done at the start of write_object_file in + write.c, but that caused problems when doing listings when + keep_it was zero. This could probably be moved above md_end, but + I didn't want to risk the change. */ + subsegs_finish (); + + if (keep_it) + write_object_file (); + + fflush (stderr); + +#ifndef NO_LISTING + listing_print (listing_filename, argv_orig); +#endif + + if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0) + as_bad (_("%d warnings, treating warnings as errors"), had_warnings ()); + + if (had_errors () > 0 && ! flag_always_generate_output) + keep_it = 0; + + input_scrub_end (); + + END_PROGRESS (myname); + + /* Use xexit instead of return, because under VMS environments they + may not place the same interpretation on the value given. */ + if (had_errors () > 0) + xexit (EXIT_FAILURE); + + /* Only generate dependency file if assembler was successful. */ + print_dependencies (); + + xexit (EXIT_SUCCESS); +} diff --git a/contrib/toolchain/binutils/gas/as.h b/contrib/toolchain/binutils/gas/as.h new file mode 100644 index 0000000000..1fefee98fd --- /dev/null +++ b/contrib/toolchain/binutils/gas/as.h @@ -0,0 +1,634 @@ +/* as.h - global header file + Copyright 1987-2013 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef GAS +#define GAS 1 +/* I think this stuff is largely out of date. xoxorich. + + CAPITALISED names are #defined. + "lowercaseH" is #defined if "lowercase.h" has been #include-d. + "lowercaseT" is a typedef of "lowercase" objects. + "lowercaseP" is type "pointer to object of type 'lowercase'". + "lowercaseS" is typedef struct ... lowercaseS. + + #define DEBUG to enable all the "know" assertion tests. + #define SUSPECT when debugging hash code. + #define COMMON as "extern" for all modules except one, where you #define + COMMON as "". + If TEST is #defined, then we are testing a module: #define COMMON as "". */ + +#include "alloca-conf.h" + +/* Now, tend to the rest of the configuration. */ + +/* System include files first... */ +#include + +#ifdef STRING_WITH_STRINGS +#include +#include +#else +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +/* for size_t, pid_t */ +#include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif + +#include + +#include "getopt.h" +/* The first getopt value for machine-independent long options. + 150 isn't special; it's just an arbitrary non-ASCII char value. */ +#define OPTION_STD_BASE 150 +/* The first getopt value for machine-dependent long options. + 190 gives the standard options room to grow. */ +#define OPTION_MD_BASE 190 + +#ifdef DEBUG +#undef NDEBUG +#endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) +#define __PRETTY_FUNCTION__ ((char *) NULL) +#endif +#define gas_assert(P) \ + ((void) ((P) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0))) +#undef abort +#define abort() as_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) + +/* Now GNU header files... */ +#include "ansidecl.h" +#include "bfd.h" +#include "libiberty.h" + +/* Define the standard progress macros. */ +#include "progress.h" + +/* This doesn't get taken care of anywhere. */ +#ifndef __MWERKS__ /* Metrowerks C chokes on the "defined (inline)" */ +#if !defined (__GNUC__) && !defined (inline) +#define inline +#endif +#endif /* !__MWERKS__ */ + +/* Other stuff from config.h. */ +#ifdef NEED_DECLARATION_ENVIRON +extern char **environ; +#endif +#ifdef NEED_DECLARATION_ERRNO +extern int errno; +#endif +#ifdef NEED_DECLARATION_FFS +extern int ffs (int); +#endif +#ifdef NEED_DECLARATION_FREE +extern void free (); +#endif +#ifdef NEED_DECLARATION_MALLOC +extern void *malloc (); +extern void *realloc (); +#endif +#ifdef NEED_DECLARATION_STRSTR +extern char *strstr (); +#endif + +#if !HAVE_DECL_MEMPCPY +void *mempcpy(void *, const void *, size_t); +#endif + +#if !HAVE_DECL_VSNPRINTF +extern int vsnprintf(char *, size_t, const char *, va_list); +#endif + +/* This is needed for VMS. */ +#if ! defined (HAVE_UNLINK) && defined (HAVE_REMOVE) +#define unlink remove +#endif + +/* Hack to make "gcc -Wall" not complain about obstack macros. */ +#if !defined (memcpy) && !defined (bcopy) +#define bcopy(src,dest,size) memcpy (dest, src, size) +#endif + +/* Make Saber happier on obstack.h. */ +#ifdef SABER +#undef __PTR_TO_INT +#define __PTR_TO_INT(P) ((int) (P)) +#undef __INT_TO_PTR +#define __INT_TO_PTR(P) ((char *) (P)) +#endif + +#ifndef __LINE__ +#define __LINE__ "unknown" +#endif /* __LINE__ */ + +#ifndef __FILE__ +#define __FILE__ "unknown" +#endif /* __FILE__ */ + +#ifndef FOPEN_WB +#ifdef USE_BINARY_FOPEN +#include "fopen-bin.h" +#else +#include "fopen-same.h" +#endif +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free xfree + +#define xfree free + +#include "asintl.h" + +#define BAD_CASE(val) \ + { \ + as_fatal (_("Case value %ld unexpected at line %d of file \"%s\"\n"), \ + (long) val, __LINE__, __FILE__); \ + } + +#include "flonum.h" + +/* These are assembler-wide concepts */ + +extern bfd *stdoutput; +typedef bfd_vma addressT; +typedef bfd_signed_vma offsetT; + +/* Type of symbol value, etc. For use in prototypes. */ +typedef addressT valueT; + +#ifndef COMMON +#ifdef TEST +#define COMMON /* Declare our COMMONs storage here. */ +#else +#define COMMON extern /* Our commons live elsewhere. */ +#endif +#endif +/* COMMON now defined */ + +#ifndef ENABLE_CHECKING +#define ENABLE_CHECKING 0 +#endif + +#if ENABLE_CHECKING || defined (DEBUG) +#ifndef know +#define know(p) gas_assert(p) /* Verify our assumptions! */ +#endif /* not yet defined */ +#else +#define know(p) do {} while (0) /* know() checks are no-op.ed */ +#endif + +/* input_scrub.c */ + +/* Supplies sanitised buffers to read.c. + Also understands printing line-number part of error messages. */ + +/* subsegs.c Sub-segments. Also, segment(=expression type)s.*/ + +typedef asection *segT; +#define SEG_NORMAL(SEG) ( (SEG) != absolute_section \ + && (SEG) != undefined_section \ + && (SEG) != reg_section \ + && (SEG) != expr_section) +typedef int subsegT; + +/* What subseg we are accessing now? */ +COMMON subsegT now_subseg; + +/* Segment our instructions emit to. */ +COMMON segT now_seg; + +#define segment_name(SEG) bfd_get_section_name (stdoutput, SEG) + +extern segT reg_section, expr_section; +/* Shouldn't these be eliminated someday? */ +extern segT text_section, data_section, bss_section; +#define absolute_section bfd_abs_section_ptr +#define undefined_section bfd_und_section_ptr + +enum _relax_state +{ + /* Dummy frag used by listing code. */ + rs_dummy = 0, + + /* Variable chars to be repeated fr_offset times. + Fr_symbol unused. Used with fr_offset == 0 for a + constant length frag. */ + rs_fill, + + /* Align. The fr_offset field holds the power of 2 to which to + align. The fr_var field holds the number of characters in the + fill pattern. The fr_subtype field holds the maximum number of + bytes to skip when aligning, or 0 if there is no maximum. */ + rs_align, + + /* Align code. The fr_offset field holds the power of 2 to which + to align. This type is only generated by machine specific + code, which is normally responsible for handling the fill + pattern. The fr_subtype field holds the maximum number of + bytes to skip when aligning, or 0 if there is no maximum. */ + rs_align_code, + + /* Test for alignment. Like rs_align, but used by several targets + to warn if data is not properly aligned. */ + rs_align_test, + + /* Org: Fr_offset, fr_symbol: address. 1 variable char: fill + character. */ + rs_org, + +#ifndef WORKING_DOT_WORD + /* JF: gunpoint */ + rs_broken_word, +#endif + + /* Machine specific relaxable (or similarly alterable) instruction. */ + rs_machine_dependent, + + /* .space directive with expression operand that needs to be computed + later. Similar to rs_org, but different. + fr_symbol: operand + 1 variable char: fill character */ + rs_space, + + /* A DWARF leb128 value; only ELF uses this. The subtype is 0 for + unsigned, 1 for signed. */ + rs_leb128, + + /* Exception frame information which we may be able to optimize. */ + rs_cfa, + + /* Cross-fragment dwarf2 line number optimization. */ + rs_dwarf2dbg +}; + +typedef enum _relax_state relax_stateT; + +/* This type is used in prototypes, so it can't be a type that will be + widened for argument passing. */ +typedef unsigned int relax_substateT; + +/* Enough bits for address, but still an integer type. + Could be a problem, cross-assembling for 64-bit machines. */ +typedef addressT relax_addressT; + +struct relax_type +{ + /* Forward reach. Signed number. > 0. */ + offsetT rlx_forward; + /* Backward reach. Signed number. < 0. */ + offsetT rlx_backward; + + /* Bytes length of this address. */ + unsigned char rlx_length; + + /* Next longer relax-state. 0 means there is no 'next' relax-state. */ + relax_substateT rlx_more; +}; + +typedef struct relax_type relax_typeS; + +/* main program "as.c" (command arguments etc). */ + +COMMON unsigned char flag_no_comments; /* -f */ +COMMON unsigned char flag_debug; /* -D */ +COMMON unsigned char flag_signed_overflow_ok; /* -J */ +#ifndef WORKING_DOT_WORD +COMMON unsigned char flag_warn_displacement; /* -K */ +#endif + +/* True if local symbols should be retained. */ +COMMON int flag_keep_locals; /* -L */ + +/* True if we are assembling in MRI mode. */ +COMMON int flag_mri; + +/* Should the data section be made read-only and appended to the text + section? */ +COMMON unsigned char flag_readonly_data_in_text; /* -R */ + +/* True if warnings should be inhibited. */ +COMMON int flag_no_warnings; /* -W */ + +/* True if warnings count as errors. */ +COMMON int flag_fatal_warnings; /* --fatal-warnings */ + +/* True if we should attempt to generate output even if non-fatal errors + are detected. */ +COMMON unsigned char flag_always_generate_output; /* -Z */ + +/* This is true if the assembler should output time and space usage. */ +COMMON unsigned char flag_print_statistics; + +/* True if local absolute symbols are to be stripped. */ +COMMON int flag_strip_local_absolute; + +/* True if we should generate a traditional format object file. */ +COMMON int flag_traditional_format; + +/* TRUE if debug sections should be compressed. */ +COMMON int flag_compress_debug; + +/* TRUE if .note.GNU-stack section with SEC_CODE should be created */ +COMMON int flag_execstack; + +/* TRUE if .note.GNU-stack section with SEC_CODE should be created */ +COMMON int flag_noexecstack; + +/* name of emitted object file */ +COMMON char *out_file_name; + +/* name of file defining extensions to the basic instruction set */ +COMMON char *insttbl_file_name; + +/* TRUE if we need a second pass. */ +COMMON int need_pass_2; + +/* TRUE if we should do no relaxing, and + leave lots of padding. */ +COMMON int linkrelax; + +/* TRUE if we should produce a listing. */ +extern int listing; + +/* Type of debugging information we should generate. We currently support + stabs, ECOFF, and DWARF2. + + NOTE! This means debug information about the assembly source code itself + and _not_ about possible debug information from a high-level language. + This is especially relevant to DWARF2, since the compiler may emit line + number directives that the assembler resolves. */ + +enum debug_info_type +{ + DEBUG_UNSPECIFIED, + DEBUG_NONE, + DEBUG_STABS, + DEBUG_ECOFF, + DEBUG_DWARF, + DEBUG_DWARF2 +}; + +extern enum debug_info_type debug_type; +extern int use_gnu_debug_info_extensions; +COMMON bfd_boolean flag_dwarf_sections; + +/* Maximum level of macro nesting. */ +extern int max_macro_nest; + +/* Verbosity level. */ +extern int verbose; + +/* Obstack chunk size. Keep large for efficient space use, make small to + increase malloc calls for monitoring memory allocation. */ +extern int chunksize; + +struct _pseudo_type +{ + /* assembler mnemonic, lower case, no '.' */ + const char *poc_name; + /* Do the work */ + void (*poc_handler) (int); + /* Value to pass to handler */ + int poc_val; +}; + +typedef struct _pseudo_type pseudo_typeS; + +#if (__GNUC__ >= 2) && !defined(VMS) +/* for use with -Wformat */ + +#if __GNUC__ == 2 && __GNUC_MINOR__ < 6 +/* Support for double underscores in attribute names was added in gcc + 2.6, so avoid them if we are using an earlier version. */ +#define __printf__ printf +#define __format__ format +#endif + +#define PRINTF_LIKE(FCN) \ + void FCN (const char *format, ...) \ + __attribute__ ((__format__ (__printf__, 1, 2))) +#define PRINTF_WHERE_LIKE(FCN) \ + void FCN (char *file, unsigned int line, const char *format, ...) \ + __attribute__ ((__format__ (__printf__, 3, 4))) + +#else /* __GNUC__ < 2 || defined(VMS) */ + +#define PRINTF_LIKE(FCN) void FCN (const char *format, ...) +#define PRINTF_WHERE_LIKE(FCN) void FCN (char *file, \ + unsigned int line, \ + const char *format, ...) + +#endif /* __GNUC__ < 2 || defined(VMS) */ + +PRINTF_LIKE (as_bad); +PRINTF_LIKE (as_fatal) ATTRIBUTE_NORETURN; +PRINTF_LIKE (as_tsktsk); +PRINTF_LIKE (as_warn); +PRINTF_WHERE_LIKE (as_bad_where); +PRINTF_WHERE_LIKE (as_warn_where); + +void as_assert (const char *, int, const char *); +void as_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; +void sprint_value (char *, addressT); +int had_errors (void); +int had_warnings (void); +void as_warn_value_out_of_range (char *, offsetT, offsetT, offsetT, char *, unsigned); +void as_bad_value_out_of_range (char *, offsetT, offsetT, offsetT, char *, unsigned); +void print_version_id (void); +char * app_push (void); +char * atof_ieee (char *, int, LITTLENUM_TYPE *); +char * ieee_md_atof (int, char *, int *, bfd_boolean); +char * vax_md_atof (int, char *, int *); +char * input_scrub_include_file (char *, char *); +void input_scrub_insert_line (const char *); +void input_scrub_insert_file (char *); +char * input_scrub_new_file (char *); +char * input_scrub_next_buffer (char **bufp); +size_t do_scrub_chars (size_t (*get) (char *, size_t), char *, size_t); +int gen_to_words (LITTLENUM_TYPE *, int, long); +int had_err (void); +int ignore_input (void); +void cond_finish_check (int); +void cond_exit_macro (int); +int seen_at_least_1_file (void); +void app_pop (char *); +void as_where (char **, unsigned int *); +void bump_line_counters (void); +void do_scrub_begin (int); +void input_scrub_begin (void); +void input_scrub_close (void); +void input_scrub_end (void); +int new_logical_line (char *, int); +int new_logical_line_flags (char *, int, int); +void subsegs_begin (void); +void subseg_change (segT, int); +segT subseg_new (const char *, subsegT); +segT subseg_force_new (const char *, subsegT); +void subseg_set (segT, subsegT); +int subseg_text_p (segT); +int seg_not_empty_p (segT); +void start_dependencies (char *); +void register_dependency (char *); +void print_dependencies (void); +segT subseg_get (const char *, int); + +const char *remap_debug_filename (const char *); +void add_debug_prefix_map (const char *); + +struct expressionS; +struct fix; +typedef struct symbol symbolS; +typedef struct frag fragS; + +/* literal.c */ +valueT add_to_literal_pool (symbolS *, valueT, segT, int); + +int check_eh_frame (struct expressionS *, unsigned int *); +int eh_frame_estimate_size_before_relax (fragS *); +int eh_frame_relax_frag (fragS *); +void eh_frame_convert_frag (fragS *); +int generic_force_reloc (struct fix *); + +#include "expr.h" /* Before targ-*.h */ + +/* This one starts the chain of target dependant headers. */ +#include "targ-env.h" + +#ifdef OBJ_MAYBE_ELF +#define IS_ELF (OUTPUT_FLAVOR == bfd_target_elf_flavour) +#else +#ifdef OBJ_ELF +#define IS_ELF 1 +#else +#define IS_ELF 0 +#endif +#endif + +#include "write.h" +#include "frags.h" +#include "hash.h" +#include "read.h" +#include "symbols.h" + +#include "tc.h" +#include "obj.h" + +#ifdef USE_EMULATIONS +#include "emul.h" +#endif +#include "listing.h" + +#ifdef H_TICK_HEX +extern int enable_h_tick_hex; +#endif + +#ifdef TC_M68K +/* True if we are assembling in m68k MRI mode. */ +COMMON int flag_m68k_mri; +#define DOLLAR_AMBIGU flag_m68k_mri +#else +#define flag_m68k_mri 0 +#endif + +#ifdef WARN_COMMENTS +COMMON int warn_comment; +COMMON unsigned int found_comment; +COMMON char * found_comment_file; +#endif + +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF +/* If .size directive failure should be error or warning. */ +COMMON enum + { + size_check_error = 0, + size_check_warning + } +flag_size_check; +#endif + +#ifndef DOLLAR_AMBIGU +#define DOLLAR_AMBIGU 0 +#endif + +#ifndef NUMBERS_WITH_SUFFIX +#define NUMBERS_WITH_SUFFIX 0 +#endif + +#ifndef LOCAL_LABELS_DOLLAR +#define LOCAL_LABELS_DOLLAR 0 +#endif + +#ifndef LOCAL_LABELS_FB +#define LOCAL_LABELS_FB 0 +#endif + +#ifndef LABELS_WITHOUT_COLONS +#define LABELS_WITHOUT_COLONS 0 +#endif + +#ifndef NO_PSEUDO_DOT +#define NO_PSEUDO_DOT 0 +#endif + +#ifndef TEXT_SECTION_NAME +#define TEXT_SECTION_NAME ".text" +#define DATA_SECTION_NAME ".data" +#define BSS_SECTION_NAME ".bss" +#endif + +#ifndef OCTETS_PER_BYTE_POWER +#define OCTETS_PER_BYTE_POWER 0 +#endif +#ifndef OCTETS_PER_BYTE +#define OCTETS_PER_BYTE (1< + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifdef HAVE_LOCALE_H +# ifndef ENABLE_NLS + /* The Solaris version of locale.h always includes libintl.h. If we have + been configured with --disable-nls then ENABLE_NLS will not be defined + and the dummy definitions of bindtextdomain (et al) below will conflict + with the defintions in libintl.h. So we define these values to prevent + the bogus inclusion of libintl.h. */ +# define _LIBINTL_H +# define _LIBGETTEXT_H +# endif +# include +#endif + +#ifdef ENABLE_NLS +# include +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define gettext(Msgid) (Msgid) +# define dgettext(Domainname, Msgid) (Msgid) +# define dcgettext(Domainname, Msgid, Category) (Msgid) +# define textdomain(Domainname) while (0) /* nothing */ +# define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ +# define _(String) (String) +# define N_(String) (String) +#endif diff --git a/contrib/toolchain/binutils/gas/atof-generic.c b/contrib/toolchain/binutils/gas/atof-generic.c new file mode 100644 index 0000000000..40a9ff0492 --- /dev/null +++ b/contrib/toolchain/binutils/gas/atof-generic.c @@ -0,0 +1,614 @@ +/* atof_generic.c - turn a string of digits into a Flonum + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, + 2001, 2003, 2005, 2006, 2007, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "safe-ctype.h" + +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (1) +#endif + +#ifdef TRACE +static void flonum_print (const FLONUM_TYPE *); +#endif + +#define ASSUME_DECIMAL_MARK_IS_DOT + +/***********************************************************************\ + * * + * Given a string of decimal digits , with optional decimal * + * mark and optional decimal exponent (place value) of the * + * lowest_order decimal digit: produce a floating point * + * number. The number is 'generic' floating point: our * + * caller will encode it for a specific machine architecture. * + * * + * Assumptions * + * uses base (radix) 2 * + * this machine uses 2's complement binary integers * + * target flonums use " " " " * + * target flonums exponents fit in a long * + * * + \***********************************************************************/ + +/* + + Syntax: + + ::= + ::= '+' | '-' | {empty} + ::= + | + | + | + + ::= {empty} + | + + ::= | + ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' + ::= {one character from "string_of_decimal_exponent_marks"} + ::= {one character from "string_of_decimal_marks"} + + */ + +int +atof_generic (/* return pointer to just AFTER number we read. */ + char **address_of_string_pointer, + /* At most one per number. */ + const char *string_of_decimal_marks, + const char *string_of_decimal_exponent_marks, + FLONUM_TYPE *address_of_generic_floating_point_number) +{ + int return_value; /* 0 means OK. */ + char *first_digit; + unsigned int number_of_digits_before_decimal; + unsigned int number_of_digits_after_decimal; + long decimal_exponent; + unsigned int number_of_digits_available; + char digits_sign_char; + + /* + * Scan the input string, abstracting (1)digits (2)decimal mark (3) exponent. + * It would be simpler to modify the string, but we don't; just to be nice + * to caller. + * We need to know how many digits we have, so we can allocate space for + * the digits' value. + */ + + char *p; + char c; + int seen_significant_digit; + +#ifdef ASSUME_DECIMAL_MARK_IS_DOT + gas_assert (string_of_decimal_marks[0] == '.' + && string_of_decimal_marks[1] == 0); +#define IS_DECIMAL_MARK(c) ((c) == '.') +#else +#define IS_DECIMAL_MARK(c) (0 != strchr (string_of_decimal_marks, (c))) +#endif + + first_digit = *address_of_string_pointer; + c = *first_digit; + + if (c == '-' || c == '+') + { + digits_sign_char = c; + first_digit++; + } + else + digits_sign_char = '+'; + + switch (first_digit[0]) + { + case 'n': + case 'N': + if (!strncasecmp ("nan", first_digit, 3)) + { + address_of_generic_floating_point_number->sign = 0; + address_of_generic_floating_point_number->exponent = 0; + address_of_generic_floating_point_number->leader = + address_of_generic_floating_point_number->low; + *address_of_string_pointer = first_digit + 3; + return 0; + } + break; + + case 'i': + case 'I': + if (!strncasecmp ("inf", first_digit, 3)) + { + address_of_generic_floating_point_number->sign = + digits_sign_char == '+' ? 'P' : 'N'; + address_of_generic_floating_point_number->exponent = 0; + address_of_generic_floating_point_number->leader = + address_of_generic_floating_point_number->low; + + first_digit += 3; + if (!strncasecmp ("inity", first_digit, 5)) + first_digit += 5; + + *address_of_string_pointer = first_digit; + + return 0; + } + break; + } + + number_of_digits_before_decimal = 0; + number_of_digits_after_decimal = 0; + decimal_exponent = 0; + seen_significant_digit = 0; + for (p = first_digit; + (((c = *p) != '\0') + && (!c || !IS_DECIMAL_MARK (c)) + && (!c || !strchr (string_of_decimal_exponent_marks, c))); + p++) + { + if (ISDIGIT (c)) + { + if (seen_significant_digit || c > '0') + { + ++number_of_digits_before_decimal; + seen_significant_digit = 1; + } + else + { + first_digit++; + } + } + else + { + break; /* p -> char after pre-decimal digits. */ + } + } /* For each digit before decimal mark. */ + +#ifndef OLD_FLOAT_READS + /* Ignore trailing 0's after the decimal point. The original code here + * (ifdef'd out) does not do this, and numbers like + * 4.29496729600000000000e+09 (2**31) + * come out inexact for some reason related to length of the digit + * string. + */ + if (c && IS_DECIMAL_MARK (c)) + { + unsigned int zeros = 0; /* Length of current string of zeros */ + + for (p++; (c = *p) && ISDIGIT (c); p++) + { + if (c == '0') + { + zeros++; + } + else + { + number_of_digits_after_decimal += 1 + zeros; + zeros = 0; + } + } + } +#else + if (c && IS_DECIMAL_MARK (c)) + { + for (p++; + (((c = *p) != '\0') + && (!c || !strchr (string_of_decimal_exponent_marks, c))); + p++) + { + if (ISDIGIT (c)) + { + /* This may be retracted below. */ + number_of_digits_after_decimal++; + + if ( /* seen_significant_digit || */ c > '0') + { + seen_significant_digit = TRUE; + } + } + else + { + if (!seen_significant_digit) + { + number_of_digits_after_decimal = 0; + } + break; + } + } /* For each digit after decimal mark. */ + } + + while (number_of_digits_after_decimal + && first_digit[number_of_digits_before_decimal + + number_of_digits_after_decimal] == '0') + --number_of_digits_after_decimal; +#endif + + if (flag_m68k_mri) + { + while (c == '_') + c = *++p; + } + if (c && strchr (string_of_decimal_exponent_marks, c)) + { + char digits_exponent_sign_char; + + c = *++p; + if (flag_m68k_mri) + { + while (c == '_') + c = *++p; + } + if (c && strchr ("+-", c)) + { + digits_exponent_sign_char = c; + c = *++p; + } + else + { + digits_exponent_sign_char = '+'; + } + + for (; (c); c = *++p) + { + if (ISDIGIT (c)) + { + decimal_exponent = decimal_exponent * 10 + c - '0'; + /* + * BUG! If we overflow here, we lose! + */ + } + else + { + break; + } + } + + if (digits_exponent_sign_char == '-') + { + decimal_exponent = -decimal_exponent; + } + } + + *address_of_string_pointer = p; + + number_of_digits_available = + number_of_digits_before_decimal + number_of_digits_after_decimal; + return_value = 0; + if (number_of_digits_available == 0) + { + address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */ + address_of_generic_floating_point_number->leader + = -1 + address_of_generic_floating_point_number->low; + address_of_generic_floating_point_number->sign = digits_sign_char; + /* We have just concocted (+/-)0.0E0 */ + + } + else + { + int count; /* Number of useful digits left to scan. */ + + LITTLENUM_TYPE *digits_binary_low; + unsigned int precision; + unsigned int maximum_useful_digits; + unsigned int number_of_digits_to_use; + unsigned int more_than_enough_bits_for_digits; + unsigned int more_than_enough_littlenums_for_digits; + unsigned int size_of_digits_in_littlenums; + unsigned int size_of_digits_in_chars; + FLONUM_TYPE power_of_10_flonum; + FLONUM_TYPE digits_flonum; + + precision = (address_of_generic_floating_point_number->high + - address_of_generic_floating_point_number->low + + 1); /* Number of destination littlenums. */ + + /* Includes guard bits (two littlenums worth) */ + maximum_useful_digits = (((precision - 2)) + * ( (LITTLENUM_NUMBER_OF_BITS)) + * 1000000 / 3321928) + + 2; /* 2 :: guard digits. */ + + if (number_of_digits_available > maximum_useful_digits) + { + number_of_digits_to_use = maximum_useful_digits; + } + else + { + number_of_digits_to_use = number_of_digits_available; + } + + /* Cast these to SIGNED LONG first, otherwise, on systems with + LONG wider than INT (such as Alpha OSF/1), unsignedness may + cause unexpected results. */ + decimal_exponent += ((long) number_of_digits_before_decimal + - (long) number_of_digits_to_use); + + more_than_enough_bits_for_digits + = (number_of_digits_to_use * 3321928 / 1000000 + 1); + + more_than_enough_littlenums_for_digits + = (more_than_enough_bits_for_digits + / LITTLENUM_NUMBER_OF_BITS) + + 2; + + /* Compute (digits) part. In "12.34E56" this is the "1234" part. + Arithmetic is exact here. If no digits are supplied then this + part is a 0 valued binary integer. Allocate room to build up + the binary number as littlenums. We want this memory to + disappear when we leave this function. Assume no alignment + problems => (room for n objects) == n * (room for 1 + object). */ + + size_of_digits_in_littlenums = more_than_enough_littlenums_for_digits; + size_of_digits_in_chars = size_of_digits_in_littlenums + * sizeof (LITTLENUM_TYPE); + + digits_binary_low = (LITTLENUM_TYPE *) + alloca (size_of_digits_in_chars); + + memset ((char *) digits_binary_low, '\0', size_of_digits_in_chars); + + /* Digits_binary_low[] is allocated and zeroed. */ + + /* + * Parse the decimal digits as if * digits_low was in the units position. + * Emit a binary number into digits_binary_low[]. + * + * Use a large-precision version of: + * (((1st-digit) * 10 + 2nd-digit) * 10 + 3rd-digit ...) * 10 + last-digit + */ + + for (p = first_digit, count = number_of_digits_to_use; count; p++, --count) + { + c = *p; + if (ISDIGIT (c)) + { + /* + * Multiply by 10. Assume can never overflow. + * Add this digit to digits_binary_low[]. + */ + + long carry; + LITTLENUM_TYPE *littlenum_pointer; + LITTLENUM_TYPE *littlenum_limit; + + littlenum_limit = digits_binary_low + + more_than_enough_littlenums_for_digits + - 1; + + carry = c - '0'; /* char -> binary */ + + for (littlenum_pointer = digits_binary_low; + littlenum_pointer <= littlenum_limit; + littlenum_pointer++) + { + long work; + + work = carry + 10 * (long) (*littlenum_pointer); + *littlenum_pointer = work & LITTLENUM_MASK; + carry = work >> LITTLENUM_NUMBER_OF_BITS; + } + + if (carry != 0) + { + /* + * We have a GROSS internal error. + * This should never happen. + */ + as_fatal (_("failed sanity check")); + } + } + else + { + ++count; /* '.' doesn't alter digits used count. */ + } + } + + /* + * Digits_binary_low[] properly encodes the value of the digits. + * Forget about any high-order littlenums that are 0. + */ + while (digits_binary_low[size_of_digits_in_littlenums - 1] == 0 + && size_of_digits_in_littlenums >= 2) + size_of_digits_in_littlenums--; + + digits_flonum.low = digits_binary_low; + digits_flonum.high = digits_binary_low + size_of_digits_in_littlenums - 1; + digits_flonum.leader = digits_flonum.high; + digits_flonum.exponent = 0; + /* + * The value of digits_flonum . sign should not be important. + * We have already decided the output's sign. + * We trust that the sign won't influence the other parts of the number! + * So we give it a value for these reasons: + * (1) courtesy to humans reading/debugging + * these numbers so they don't get excited about strange values + * (2) in future there may be more meaning attached to sign, + * and what was + * harmless noise may become disruptive, ill-conditioned (or worse) + * input. + */ + digits_flonum.sign = '+'; + + { + /* + * Compute the mantssa (& exponent) of the power of 10. + * If successful, then multiply the power of 10 by the digits + * giving return_binary_mantissa and return_binary_exponent. + */ + + LITTLENUM_TYPE *power_binary_low; + int decimal_exponent_is_negative; + /* This refers to the "-56" in "12.34E-56". */ + /* FALSE: decimal_exponent is positive (or 0) */ + /* TRUE: decimal_exponent is negative */ + FLONUM_TYPE temporary_flonum; + LITTLENUM_TYPE *temporary_binary_low; + unsigned int size_of_power_in_littlenums; + unsigned int size_of_power_in_chars; + + size_of_power_in_littlenums = precision; + /* Precision has a built-in fudge factor so we get a few guard bits. */ + + decimal_exponent_is_negative = decimal_exponent < 0; + if (decimal_exponent_is_negative) + { + decimal_exponent = -decimal_exponent; + } + + /* From now on: the decimal exponent is > 0. Its sign is separate. */ + + size_of_power_in_chars = size_of_power_in_littlenums + * sizeof (LITTLENUM_TYPE) + 2; + + power_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars); + temporary_binary_low = (LITTLENUM_TYPE *) alloca (size_of_power_in_chars); + memset ((char *) power_binary_low, '\0', size_of_power_in_chars); + *power_binary_low = 1; + power_of_10_flonum.exponent = 0; + power_of_10_flonum.low = power_binary_low; + power_of_10_flonum.leader = power_binary_low; + power_of_10_flonum.high = power_binary_low + size_of_power_in_littlenums - 1; + power_of_10_flonum.sign = '+'; + temporary_flonum.low = temporary_binary_low; + temporary_flonum.high = temporary_binary_low + size_of_power_in_littlenums - 1; + /* + * (power) == 1. + * Space for temporary_flonum allocated. + */ + + /* + * ... + * + * WHILE more bits + * DO find next bit (with place value) + * multiply into power mantissa + * OD + */ + { + int place_number_limit; + /* Any 10^(2^n) whose "n" exceeds this */ + /* value will fall off the end of */ + /* flonum_XXXX_powers_of_ten[]. */ + int place_number; + const FLONUM_TYPE *multiplicand; /* -> 10^(2^n) */ + + place_number_limit = table_size_of_flonum_powers_of_ten; + + multiplicand = (decimal_exponent_is_negative + ? flonum_negative_powers_of_ten + : flonum_positive_powers_of_ten); + + for (place_number = 1;/* Place value of this bit of exponent. */ + decimal_exponent;/* Quit when no more 1 bits in exponent. */ + decimal_exponent >>= 1, place_number++) + { + if (decimal_exponent & 1) + { + if (place_number > place_number_limit) + { + /* The decimal exponent has a magnitude so great + that our tables can't help us fragment it. + Although this routine is in error because it + can't imagine a number that big, signal an + error as if it is the user's fault for + presenting such a big number. */ + return_value = ERROR_EXPONENT_OVERFLOW; + /* quit out of loop gracefully */ + decimal_exponent = 0; + } + else + { +#ifdef TRACE + printf ("before multiply, place_number = %d., power_of_10_flonum:\n", + place_number); + + flonum_print (&power_of_10_flonum); + (void) putchar ('\n'); +#endif +#ifdef TRACE + printf ("multiplier:\n"); + flonum_print (multiplicand + place_number); + (void) putchar ('\n'); +#endif + flonum_multip (multiplicand + place_number, + &power_of_10_flonum, &temporary_flonum); +#ifdef TRACE + printf ("after multiply:\n"); + flonum_print (&temporary_flonum); + (void) putchar ('\n'); +#endif + flonum_copy (&temporary_flonum, &power_of_10_flonum); +#ifdef TRACE + printf ("after copy:\n"); + flonum_print (&power_of_10_flonum); + (void) putchar ('\n'); +#endif + } /* If this bit of decimal_exponent was computable.*/ + } /* If this bit of decimal_exponent was set. */ + } /* For each bit of binary representation of exponent */ +#ifdef TRACE + printf ("after computing power_of_10_flonum:\n"); + flonum_print (&power_of_10_flonum); + (void) putchar ('\n'); +#endif + } + + } + + /* + * power_of_10_flonum is power of ten in binary (mantissa) , (exponent). + * It may be the number 1, in which case we don't NEED to multiply. + * + * Multiply (decimal digits) by power_of_10_flonum. + */ + + flonum_multip (&power_of_10_flonum, &digits_flonum, address_of_generic_floating_point_number); + /* Assert sign of the number we made is '+'. */ + address_of_generic_floating_point_number->sign = digits_sign_char; + + } + return return_value; +} + +#ifdef TRACE +static void +flonum_print (f) + const FLONUM_TYPE *f; +{ + LITTLENUM_TYPE *lp; + char littlenum_format[10]; + sprintf (littlenum_format, " %%0%dx", sizeof (LITTLENUM_TYPE) * 2); +#define print_littlenum(LP) (printf (littlenum_format, LP)) + printf ("flonum @%p %c e%ld", f, f->sign, f->exponent); + if (f->low < f->high) + for (lp = f->high; lp >= f->low; lp--) + print_littlenum (*lp); + else + for (lp = f->low; lp <= f->high; lp++) + print_littlenum (*lp); + printf ("\n"); + fflush (stdout); +} +#endif + +/* end of atof_generic.c */ diff --git a/contrib/toolchain/binutils/gas/bignum.h b/contrib/toolchain/binutils/gas/bignum.h new file mode 100644 index 0000000000..41c3559988 --- /dev/null +++ b/contrib/toolchain/binutils/gas/bignum.h @@ -0,0 +1,42 @@ +/* bignum.h-arbitrary precision integers + Copyright 1987, 1992, 2003, 2005, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/***********************************************************************\ + * * + * Arbitrary-precision integer arithmetic. * + * For speed, we work in groups of bits, even though this * + * complicates algorithms. * + * Each group of bits is called a 'littlenum'. * + * A bunch of littlenums representing a (possibly large) * + * integer is called a 'bignum'. * + * Bignums are >= 0. * + * * + \***********************************************************************/ + +#define LITTLENUM_NUMBER_OF_BITS (16) +#define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS) +#define LITTLENUM_MASK (0xFFFF) +#define LITTLENUM_SHIFT (1) +#define CHARS_PER_LITTLENUM (1 << LITTLENUM_SHIFT) +#ifndef BITS_PER_CHAR +#define BITS_PER_CHAR (8) +#endif + +typedef unsigned short LITTLENUM_TYPE; diff --git a/contrib/toolchain/binutils/gas/bit_fix.h b/contrib/toolchain/binutils/gas/bit_fix.h new file mode 100644 index 0000000000..a83bddc3f0 --- /dev/null +++ b/contrib/toolchain/binutils/gas/bit_fix.h @@ -0,0 +1,48 @@ +/* bit_fix.h + Copyright 1987, 1992, 2000, 2001, 2003, 2005, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* The bit_fix was implemented to support machines that need variables + to be inserted in bitfields other than 1, 2 and 4 bytes. + Furthermore it gives us a possibility to mask in bits in the symbol + when it's fixed in the objectcode and check the symbols limits. + + The or-mask is used to set the huffman bits in displacements for the + ns32k port. + The acbi, addqi, movqi, cmpqi instruction requires an assembler that + can handle bitfields. Ie. handle an expression, evaluate it and insert + the result in some bitfield. (eg: 5 bits in a short field of an opcode). */ + +#ifndef __bit_fix_h__ +#define __bit_fix_h__ + +struct bit_fix { + int fx_bit_size; /* Length of bitfield */ + int fx_bit_offset; /* Bit offset to bitfield */ + long fx_bit_base; /* Where do we apply the bitfix. + If this is zero, default is assumed. */ + long fx_bit_base_adj; /* Adjustment of base */ + long fx_bit_max; /* Signextended max for bitfield */ + long fx_bit_min; /* Signextended min for bitfield */ + long fx_bit_add; /* Or mask, used for huffman prefix */ +}; +typedef struct bit_fix bit_fixS; + +#endif /* __bit_fix_h__ */ diff --git a/contrib/toolchain/binutils/gas/compress-debug.c b/contrib/toolchain/binutils/gas/compress-debug.c new file mode 100644 index 0000000000..09076002d7 --- /dev/null +++ b/contrib/toolchain/binutils/gas/compress-debug.c @@ -0,0 +1,117 @@ +/* compress-debug.c - compress debug sections + Copyright 2010 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "config.h" +#include +#include "ansidecl.h" +#include "compress-debug.h" + +#ifdef HAVE_ZLIB_H +#include +#endif + +/* Initialize the compression engine. */ + +struct z_stream_s * +compress_init (void) +{ +#ifndef HAVE_ZLIB_H + return NULL; +#else + static struct z_stream_s strm; + + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + deflateInit (&strm, Z_DEFAULT_COMPRESSION); + return &strm; +#endif /* HAVE_ZLIB_H */ +} + +/* Stream the contents of a frag to the compression engine. Output + from the engine goes into the current frag on the obstack. */ + +int +compress_data (struct z_stream_s *strm ATTRIBUTE_UNUSED, + const char **next_in ATTRIBUTE_UNUSED, + int *avail_in ATTRIBUTE_UNUSED, + char **next_out ATTRIBUTE_UNUSED, + int *avail_out ATTRIBUTE_UNUSED) +{ +#ifndef HAVE_ZLIB_H + return -1; +#else + int out_size = 0; + int x; + + strm->next_in = (Bytef *) (*next_in); + strm->avail_in = *avail_in; + strm->next_out = (Bytef *) (*next_out); + strm->avail_out = *avail_out; + + x = deflate (strm, Z_NO_FLUSH); + if (x != Z_OK) + return -1; + + out_size = *avail_out - strm->avail_out; + *next_in = (char *) (strm->next_in); + *avail_in = strm->avail_in; + *next_out = (char *) (strm->next_out); + *avail_out = strm->avail_out; + + return out_size; +#endif /* HAVE_ZLIB_H */ +} + +/* Finish the compression and consume the remaining compressed output. + Returns -1 for error, 0 when done, 1 when more output buffer is + needed. */ + +int +compress_finish (struct z_stream_s *strm ATTRIBUTE_UNUSED, + char **next_out ATTRIBUTE_UNUSED, + int *avail_out ATTRIBUTE_UNUSED, + int *out_size ATTRIBUTE_UNUSED) +{ +#ifndef HAVE_ZLIB_H + return -1; +#else + int x; + + strm->avail_in = 0; + strm->next_out = (Bytef *) (*next_out); + strm->avail_out = *avail_out; + + x = deflate (strm, Z_FINISH); + + *out_size = *avail_out - strm->avail_out; + *next_out = (char *) (strm->next_out); + *avail_out = strm->avail_out; + + if (x == Z_STREAM_END) + { + deflateEnd (strm); + return 0; + } + if (strm->avail_out != 0) + return -1; + return 1; +#endif /* HAVE_ZLIB_H */ +} diff --git a/contrib/toolchain/binutils/gas/compress-debug.h b/contrib/toolchain/binutils/gas/compress-debug.h new file mode 100644 index 0000000000..9d821e9155 --- /dev/null +++ b/contrib/toolchain/binutils/gas/compress-debug.h @@ -0,0 +1,39 @@ +/* compress-debug.h - Header file for compressed debug sections. + Copyright 2010 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef COMPRESS_DEBUG_H +#define COMPRESS_DEBUG_H + +struct z_stream_s; + +/* Initialize the compression engine. */ +extern struct z_stream_s * +compress_init (void); + +/* Stream the contents of a frag to the compression engine. Output + from the engine goes into the current frag on the obstack. */ +extern int +compress_data (struct z_stream_s *, const char **, int *, char **, int *); + +/* Finish the compression and consume the remaining compressed output. */ +extern int +compress_finish (struct z_stream_s *, char **, int *, int *); + +#endif /* COMPRESS_DEBUG_H */ diff --git a/contrib/toolchain/binutils/gas/cond.c b/contrib/toolchain/binutils/gas/cond.c new file mode 100644 index 0000000000..c30912334f --- /dev/null +++ b/contrib/toolchain/binutils/gas/cond.c @@ -0,0 +1,577 @@ +/* cond.c - conditional assembly pseudo-ops, and .include + Copyright 1990, 1991, 1992, 1993, 1995, 1997, 1998, 2000, 2001, 2002, + 2003, 2005, 2006, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "sb.h" +#include "macro.h" + +#include "obstack.h" + +/* This is allocated to grow and shrink as .ifdef/.endif pairs are + scanned. */ +struct obstack cond_obstack; + +struct file_line { + char *file; + unsigned int line; +}; + +/* We push one of these structures for each .if, and pop it at the + .endif. */ + +struct conditional_frame { + /* The source file & line number of the "if". */ + struct file_line if_file_line; + /* The source file & line of the "else". */ + struct file_line else_file_line; + /* The previous conditional. */ + struct conditional_frame *previous_cframe; + /* Have we seen an else yet? */ + int else_seen; + /* Whether we are currently ignoring input. */ + int ignoring; + /* Whether a conditional at a higher level is ignoring input. + Set also when a branch of an "if .. elseif .." tree has matched + to prevent further matches. */ + int dead_tree; + /* Macro nesting level at which this conditional was created. */ + int macro_nest; +}; + +static void initialize_cframe (struct conditional_frame *cframe); +static char *get_mri_string (int, int *); + +static struct conditional_frame *current_cframe = NULL; + +/* Performs the .ifdef (test_defined == 1) and + the .ifndef (test_defined == 0) pseudo op. */ + +void +s_ifdef (int test_defined) +{ + /* Points to name of symbol. */ + char *name; + /* Points to symbol. */ + symbolS *symbolP; + struct conditional_frame cframe; + char c; + + /* Leading whitespace is part of operand. */ + SKIP_WHITESPACE (); + name = input_line_pointer; + + if (!is_name_beginner (*name)) + { + as_bad (_("invalid identifier for \".ifdef\"")); + obstack_1grow (&cond_obstack, 0); + ignore_rest_of_line (); + return; + } + + c = get_symbol_end (); + symbolP = symbol_find (name); + *input_line_pointer = c; + + initialize_cframe (&cframe); + + if (cframe.dead_tree) + cframe.ignoring = 1; + else + { + int is_defined; + + /* Use the same definition of 'defined' as .equiv so that a symbol + which has been referenced but not yet given a value/address is + considered to be undefined. */ + is_defined = + symbolP != NULL + && (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + && S_GET_SEGMENT (symbolP) != reg_section; + + cframe.ignoring = ! (test_defined ^ is_defined); + } + + current_cframe = ((struct conditional_frame *) + obstack_copy (&cond_obstack, &cframe, + sizeof (cframe))); + + if (LISTING_SKIP_COND () + && cframe.ignoring + && (cframe.previous_cframe == NULL + || ! cframe.previous_cframe->ignoring)) + listing_list (2); + + demand_empty_rest_of_line (); +} + +void +s_if (int arg) +{ + expressionS operand; + struct conditional_frame cframe; + int t; + char *stop = NULL; + char stopc; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + /* Leading whitespace is part of operand. */ + SKIP_WHITESPACE (); + + if (current_cframe != NULL && current_cframe->ignoring) + { + operand.X_add_number = 0; + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + } + else + { + expression_and_evaluate (&operand); + if (operand.X_op != O_constant) + as_bad (_("non-constant expression in \".if\" statement")); + } + + switch ((operatorT) arg) + { + case O_eq: t = operand.X_add_number == 0; break; + case O_ne: t = operand.X_add_number != 0; break; + case O_lt: t = operand.X_add_number < 0; break; + case O_le: t = operand.X_add_number <= 0; break; + case O_ge: t = operand.X_add_number >= 0; break; + case O_gt: t = operand.X_add_number > 0; break; + default: + abort (); + return; + } + + /* If the above error is signaled, this will dispatch + using an undefined result. No big deal. */ + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || ! t; + current_cframe = ((struct conditional_frame *) + obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); + + if (LISTING_SKIP_COND () + && cframe.ignoring + && (cframe.previous_cframe == NULL + || ! cframe.previous_cframe->ignoring)) + listing_list (2); + + if (flag_mri) + mri_comment_end (stop, stopc); + + demand_empty_rest_of_line (); +} + +/* Performs the .ifb (test_blank == 1) and + the .ifnb (test_blank == 0) pseudo op. */ + +void +s_ifb (int test_blank) +{ + struct conditional_frame cframe; + + initialize_cframe (&cframe); + + if (cframe.dead_tree) + cframe.ignoring = 1; + else + { + int is_eol; + + SKIP_WHITESPACE (); + is_eol = is_end_of_line[(unsigned char) *input_line_pointer]; + cframe.ignoring = (test_blank == !is_eol); + } + + current_cframe = ((struct conditional_frame *) + obstack_copy (&cond_obstack, &cframe, + sizeof (cframe))); + + if (LISTING_SKIP_COND () + && cframe.ignoring + && (cframe.previous_cframe == NULL + || ! cframe.previous_cframe->ignoring)) + listing_list (2); + + ignore_rest_of_line (); +} + +/* Get a string for the MRI IFC or IFNC pseudo-ops. */ + +static char * +get_mri_string (int terminator, int *len) +{ + char *ret; + char *s; + + SKIP_WHITESPACE (); + s = ret = input_line_pointer; + if (*input_line_pointer == '\'') + { + ++s; + ++input_line_pointer; + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + { + *s++ = *input_line_pointer++; + if (s[-1] == '\'') + { + if (*input_line_pointer != '\'') + break; + ++input_line_pointer; + } + } + SKIP_WHITESPACE (); + } + else + { + while (*input_line_pointer != terminator + && ! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + s = input_line_pointer; + while (s > ret && (s[-1] == ' ' || s[-1] == '\t')) + --s; + } + + *len = s - ret; + return ret; +} + +/* The MRI IFC and IFNC pseudo-ops. */ + +void +s_ifc (int arg) +{ + char *stop = NULL; + char stopc; + char *s1, *s2; + int len1, len2; + int res; + struct conditional_frame cframe; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + s1 = get_mri_string (',', &len1); + + if (*input_line_pointer != ',') + as_bad (_("bad format for ifc or ifnc")); + else + ++input_line_pointer; + + s2 = get_mri_string (';', &len2); + + res = len1 == len2 && strncmp (s1, s2, len1) == 0; + + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || ! (res ^ arg); + current_cframe = ((struct conditional_frame *) + obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); + + if (LISTING_SKIP_COND () + && cframe.ignoring + && (cframe.previous_cframe == NULL + || ! cframe.previous_cframe->ignoring)) + listing_list (2); + + if (flag_mri) + mri_comment_end (stop, stopc); + + demand_empty_rest_of_line (); +} + +void +s_elseif (int arg) +{ + if (current_cframe == NULL) + { + as_bad (_("\".elseif\" without matching \".if\"")); + } + else if (current_cframe->else_seen) + { + as_bad (_("\".elseif\" after \".else\"")); + 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); + + current_cframe->dead_tree |= !current_cframe->ignoring; + current_cframe->ignoring = current_cframe->dead_tree; + } + + if (current_cframe == NULL || current_cframe->ignoring) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + + if (current_cframe == NULL) + return; + } + else + { + expressionS operand; + int t; + + /* Leading whitespace is part of operand. */ + SKIP_WHITESPACE (); + + expression_and_evaluate (&operand); + if (operand.X_op != O_constant) + as_bad (_("non-constant expression in \".elseif\" statement")); + + switch ((operatorT) arg) + { + case O_eq: t = operand.X_add_number == 0; break; + case O_ne: t = operand.X_add_number != 0; break; + case O_lt: t = operand.X_add_number < 0; break; + case O_le: t = operand.X_add_number <= 0; break; + case O_ge: t = operand.X_add_number >= 0; break; + case O_gt: t = operand.X_add_number > 0; break; + default: + abort (); + return; + } + + current_cframe->ignoring = current_cframe->dead_tree || ! t; + } + + if (LISTING_SKIP_COND () + && (current_cframe->previous_cframe == NULL + || ! current_cframe->previous_cframe->ignoring)) + { + if (! current_cframe->ignoring) + listing_list (1); + else + listing_list (2); + } + + demand_empty_rest_of_line (); +} + +void +s_endif (int arg ATTRIBUTE_UNUSED) +{ + struct conditional_frame *hold; + + if (current_cframe == NULL) + { + as_bad (_("\".endif\" without \".if\"")); + } + else + { + if (LISTING_SKIP_COND () + && current_cframe->ignoring + && (current_cframe->previous_cframe == NULL + || ! current_cframe->previous_cframe->ignoring)) + listing_list (1); + + hold = current_cframe; + current_cframe = current_cframe->previous_cframe; + obstack_free (&cond_obstack, hold); + } /* if one pop too many */ + + if (flag_mri) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + } + + demand_empty_rest_of_line (); +} + +void +s_else (int arg ATTRIBUTE_UNUSED) +{ + if (current_cframe == NULL) + { + as_bad (_("\".else\" without matching \".if\"")); + } + else if (current_cframe->else_seen) + { + as_bad (_("duplicate \".else\"")); + 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); + + current_cframe->ignoring = + current_cframe->dead_tree | !current_cframe->ignoring; + + if (LISTING_SKIP_COND () + && (current_cframe->previous_cframe == NULL + || ! current_cframe->previous_cframe->ignoring)) + { + if (! current_cframe->ignoring) + listing_list (1); + else + listing_list (2); + } + + current_cframe->else_seen = 1; + } + + if (flag_mri) + { + while (! is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + } + + demand_empty_rest_of_line (); +} + +void +s_ifeqs (int arg) +{ + char *s1, *s2; + int len1, len2; + int res; + struct conditional_frame cframe; + + s1 = demand_copy_C_string (&len1); + + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_(".ifeqs syntax error")); + ignore_rest_of_line (); + return; + } + + ++input_line_pointer; + + s2 = demand_copy_C_string (&len2); + + res = len1 == len2 && strncmp (s1, s2, len1) == 0; + + initialize_cframe (&cframe); + cframe.ignoring = cframe.dead_tree || ! (res ^ arg); + current_cframe = ((struct conditional_frame *) + obstack_copy (&cond_obstack, &cframe, sizeof (cframe))); + + if (LISTING_SKIP_COND () + && cframe.ignoring + && (cframe.previous_cframe == NULL + || ! cframe.previous_cframe->ignoring)) + listing_list (2); + + demand_empty_rest_of_line (); +} + +int +ignore_input (void) +{ + char *s; + + s = input_line_pointer; + + if (NO_PSEUDO_DOT || flag_m68k_mri) + { + if (s[-1] != '.') + --s; + } + else + { + if (s[-1] != '.') + return (current_cframe != NULL) && (current_cframe->ignoring); + } + + /* We cannot ignore certain pseudo ops. */ + if (((s[0] == 'i' + || s[0] == 'I') + && (!strncasecmp (s, "if", 2) + || !strncasecmp (s, "ifdef", 5) + || !strncasecmp (s, "ifndef", 6))) + || ((s[0] == 'e' + || s[0] == 'E') + && (!strncasecmp (s, "else", 4) + || !strncasecmp (s, "endif", 5) + || !strncasecmp (s, "endc", 4)))) + return 0; + + return (current_cframe != NULL) && (current_cframe->ignoring); +} + +static void +initialize_cframe (struct conditional_frame *cframe) +{ + 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; + cframe->macro_nest = macro_nest; +} + +/* Give an error if a conditional is unterminated inside a macro or + the assembly as a whole. If NEST is non negative, we are being + called because of the end of a macro expansion. If NEST is + negative, we are being called at the of the input files. */ + +void +cond_finish_check (int nest) +{ + if (current_cframe != NULL && current_cframe->macro_nest >= nest) + { + if (nest >= 0) + as_bad (_("end of macro inside conditional")); + else + as_bad (_("end of file inside conditional")); + as_bad_where (current_cframe->if_file_line.file, + current_cframe->if_file_line.line, + _("here is the start of the unterminated conditional")); + if (current_cframe->else_seen) + as_bad_where (current_cframe->else_file_line.file, + current_cframe->else_file_line.line, + _("here is the \"else\" of the unterminated conditional")); + } +} + +/* This function is called when we exit out of a macro. We assume + that any conditionals which began within the macro are correctly + nested, and just pop them off the stack. */ + +void +cond_exit_macro (int nest) +{ + while (current_cframe != NULL && current_cframe->macro_nest >= nest) + { + struct conditional_frame *hold; + + hold = current_cframe; + current_cframe = current_cframe->previous_cframe; + obstack_free (&cond_obstack, hold); + } +} diff --git a/contrib/toolchain/binutils/gas/config.h b/contrib/toolchain/binutils/gas/config.h new file mode 100644 index 0000000000..04a37b0b68 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config.h @@ -0,0 +1,363 @@ +/* config.h. Generated from config.in by configure. */ +/* config.in. Generated from configure.in by autoheader. */ + +/* Check that config.h is #included before system headers + (this works only for glibc, but that should be enough). */ +#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__CONFIG_H__) +# error config.h must be #included before system headers +#endif +#define __CONFIG_H__ 1 + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* Define if using AIX 5.2 value for C_WEAKEXT. */ +/* #undef AIX_WEAK_SUPPORT */ + +/* assert broken? */ +/* #undef BROKEN_ASSERT */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Compiling cross-assembler? */ +/* #undef CROSS_COMPILE */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Default architecture. */ +#define DEFAULT_ARCH "i386" + +/* Default CRIS architecture. */ +/* #undef DEFAULT_CRIS_ARCH */ + +/* Default emulation. */ +#define DEFAULT_EMULATION "" + +/* Supported emulations. */ +#define EMULATIONS + +/* Define if you want run-time sanity checks. */ +/* #undef ENABLE_CHECKING */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +/* #undef ENABLE_NLS */ + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +/* #undef HAVE_ALLOCA_H */ + +/* Define to 1 if you have the declaration of `free', and to 0 if you don't. + */ +#define HAVE_DECL_FREE 1 + +/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't. + */ +#define HAVE_DECL_GETENV 1 + +/* Is the prototype for getopt in in the expected format? */ +#define HAVE_DECL_GETOPT 1 + +/* Define to 1 if you have the declaration of `malloc', and to 0 if you don't. + */ +#define HAVE_DECL_MALLOC 1 + +/* Define to 1 if you have the declaration of `mempcpy', and to 0 if you + don't. */ +#define HAVE_DECL_MEMPCPY 0 + +/* Define to 1 if you have the declaration of `realloc', and to 0 if you + don't. */ +#define HAVE_DECL_REALLOC 1 + +/* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't. + */ +#define HAVE_DECL_STPCPY 0 + +/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't. + */ +#define HAVE_DECL_STRSTR 1 + +/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you + don't. */ +#define HAVE_DECL_VSNPRINTF 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if your file defines LC_MESSAGES. */ +/* #undef HAVE_LC_MESSAGES */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `remove' function. */ +#define HAVE_REMOVE + +/* Define to 1 if you have the `sbrk' function. */ +/* #undef HAVE_SBRK */ + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if has struct stat.st_mtim.tv_nsec */ +/* #undef HAVE_ST_MTIM_TV_NSEC */ + +/* Define if has struct stat.st_mtim.tv_sec */ +/* #undef HAVE_ST_MTIM_TV_SEC */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if has struct tm.tm_gmtoff. */ +/* #undef HAVE_TM_GMTOFF */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unlink' function. */ +#define HAVE_UNLINK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ZLIB_H 1 + +/* Using i386 COFF? */ +#define I386COFF 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Using m68k COFF? */ +/* #undef M68KCOFF */ + +/* Using m88k COFF? */ +/* #undef M88KCOFF */ + +/* Default CPU for MIPS targets. */ +/* #undef MIPS_CPU_STRING_DEFAULT */ + +/* Generate 64-bit code by default on MIPS targets. */ +/* #undef MIPS_DEFAULT_64BIT */ + +/* Choose a default ABI for MIPS targets. */ +/* #undef MIPS_DEFAULT_ABI */ + +/* Define if environ is not declared in system header files. */ +/* #undef NEED_DECLARATION_ENVIRON */ + +/* Define if errno is not declared in system header files. */ +/* #undef NEED_DECLARATION_ERRNO */ + +/* Define if ffs is not declared in system header files. */ +#define NEED_DECLARATION_FFS 1 + +/* Define if free is not declared in system header files. */ +/* #undef NEED_DECLARATION_FREE */ + +/* Define if malloc is not declared in system header files. */ +/* #undef NEED_DECLARATION_MALLOC */ + +/* Define if sbrk is not declared in system header files. */ +#define NEED_DECLARATION_SBRK 1 + +/* Define if strstr is not declared in system header files. */ +/* #undef NEED_DECLARATION_STRSTR */ + +/* a.out support? */ +/* #undef OBJ_MAYBE_AOUT */ + +/* b.out support? */ +/* #undef OBJ_MAYBE_BOUT */ + +/* COFF support? */ +/* #undef OBJ_MAYBE_COFF */ + +/* ECOFF support? */ +/* #undef OBJ_MAYBE_ECOFF */ + +/* ELF support? */ +/* #undef OBJ_MAYBE_ELF */ + +/* generic support? */ +/* #undef OBJ_MAYBE_GENERIC */ + +/* SOM support? */ +/* #undef OBJ_MAYBE_SOM */ + +/* Name of package */ +#define PACKAGE "gas" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define if defaulting to ELF on SCO 5. */ +/* #undef SCO_ELF */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Using strict COFF? */ +/* #undef STRICTCOFF */ + +/* Define if you can safely include both and . */ +#define STRING_WITH_STRINGS 1 + +/* Target alias. */ +#define TARGET_ALIAS "mingw32" + +/* Define as 1 if big endian. */ +/* #undef TARGET_BYTES_BIG_ENDIAN */ + +/* Canonical target. */ +#define TARGET_CANONICAL "i686-pc-mingw32" + +/* Target CPU. */ +#define TARGET_CPU "i686" + +/* Target OS. */ +#define TARGET_OS "mingw32" + +/* Define if default target is PowerPC Solaris. */ +/* #undef TARGET_SOLARIS_COMMENT */ + +/* Define if target is Symbian OS. */ +/* #undef TARGET_SYMBIAN */ + +/* Target vendor. */ +#define TARGET_VENDOR "pc" + +/* Use b modifier when opening binary files? */ +#define USE_BINARY_FOPEN 1 + +/* Use emulation support? */ +/* #undef USE_EMULATIONS */ + +/* Allow use of E_MIPS_ABI_O32 on MIPS targets. */ +/* #undef USE_E_MIPS_ABI_O32 */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Using cgen code? */ +/* #undef USING_CGEN */ + +/* Version number of package */ +#define VERSION "2.24" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +/* #undef YYTEXT_POINTER */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/contrib/toolchain/binutils/gas/config/atof-ieee.c b/contrib/toolchain/binutils/gas/config/atof-ieee.c new file mode 100644 index 0000000000..32e57076a4 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/atof-ieee.c @@ -0,0 +1,813 @@ +/* atof_ieee.c - turn a Flonum into an IEEE floating point number + Copyright 1987, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2005, + 2007, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" + +/* Flonums returned here. */ +extern FLONUM_TYPE generic_floating_point_number; + +extern const char EXP_CHARS[]; +/* Precision in LittleNums. */ +/* Don't count the gap in the m68k extended precision format. */ +#define MAX_PRECISION 5 +#define F_PRECISION 2 +#define D_PRECISION 4 +#define X_PRECISION 5 +#define P_PRECISION 5 + +/* Length in LittleNums of guard bits. */ +#define GUARD 2 + +#ifndef TC_LARGEST_EXPONENT_IS_NORMAL +#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) 0 +#endif + +static const unsigned long mask[] = +{ + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, + 0xffffffff, +}; + +static int bits_left_in_littlenum; +static int littlenums_left; +static LITTLENUM_TYPE *littlenum_pointer; + +static int +next_bits (int number_of_bits) +{ + int return_value; + + if (!littlenums_left) + return 0; + + if (number_of_bits >= bits_left_in_littlenum) + { + return_value = mask[bits_left_in_littlenum] & *littlenum_pointer; + number_of_bits -= bits_left_in_littlenum; + return_value <<= number_of_bits; + + if (--littlenums_left) + { + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits; + --littlenum_pointer; + return_value |= + (*littlenum_pointer >> bits_left_in_littlenum) + & mask[number_of_bits]; + } + } + else + { + bits_left_in_littlenum -= number_of_bits; + return_value = + mask[number_of_bits] & (*littlenum_pointer >> bits_left_in_littlenum); + } + return return_value; +} + +/* Num had better be less than LITTLENUM_NUMBER_OF_BITS. */ + +static void +unget_bits (int num) +{ + if (!littlenums_left) + { + ++littlenum_pointer; + ++littlenums_left; + bits_left_in_littlenum = num; + } + else if (bits_left_in_littlenum + num > LITTLENUM_NUMBER_OF_BITS) + { + bits_left_in_littlenum = + num - (LITTLENUM_NUMBER_OF_BITS - bits_left_in_littlenum); + ++littlenum_pointer; + ++littlenums_left; + } + else + bits_left_in_littlenum += num; +} + +static void +make_invalid_floating_point_number (LITTLENUM_TYPE *words) +{ + as_bad (_("cannot create floating-point number")); + /* Zero the leftmost bit. */ + words[0] = (LITTLENUM_TYPE) ((unsigned) -1) >> 1; + words[1] = (LITTLENUM_TYPE) -1; + words[2] = (LITTLENUM_TYPE) -1; + words[3] = (LITTLENUM_TYPE) -1; + words[4] = (LITTLENUM_TYPE) -1; + words[5] = (LITTLENUM_TYPE) -1; +} + +/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to + figure out any alignment problems and to conspire for the + bytes/word to be emitted in the right order. Bigendians beware! */ + +/* Note that atof-ieee always has X and P precisions enabled. it is up + to md_atof to filter them out if the target machine does not support + them. */ + +/* Returns pointer past text consumed. */ + +char * +atof_ieee (char *str, /* Text to convert to binary. */ + int what_kind, /* 'd', 'f', 'x', 'p'. */ + LITTLENUM_TYPE *words) /* Build the binary here. */ +{ + /* Extra bits for zeroed low-order bits. + The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ + static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; + char *return_value; + /* Number of 16-bit words in the format. */ + int precision; + long exponent_bits; + FLONUM_TYPE save_gen_flonum; + + /* We have to save the generic_floating_point_number because it + contains storage allocation about the array of LITTLENUMs where + the value is actually stored. We will allocate our own array of + littlenums below, but have to restore the global one on exit. */ + save_gen_flonum = generic_floating_point_number; + + return_value = str; + generic_floating_point_number.low = bits + MAX_PRECISION; + generic_floating_point_number.high = NULL; + generic_floating_point_number.leader = NULL; + generic_floating_point_number.exponent = 0; + generic_floating_point_number.sign = '\0'; + + /* Use more LittleNums than seems necessary: the highest flonum may + have 15 leading 0 bits, so could be useless. */ + + memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); + + switch (what_kind) + { + case 'f': + case 'F': + case 's': + case 'S': + precision = F_PRECISION; + exponent_bits = 8; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + precision = D_PRECISION; + exponent_bits = 11; + break; + + case 'x': + case 'X': + case 'e': + case 'E': + precision = X_PRECISION; + exponent_bits = 15; + break; + + case 'p': + case 'P': + precision = P_PRECISION; + exponent_bits = -1; + break; + + default: + make_invalid_floating_point_number (words); + return (NULL); + } + + generic_floating_point_number.high + = generic_floating_point_number.low + precision - 1 + GUARD; + + if (atof_generic (&return_value, ".", EXP_CHARS, + &generic_floating_point_number)) + { + make_invalid_floating_point_number (words); + return NULL; + } + gen_to_words (words, precision, exponent_bits); + + /* Restore the generic_floating_point_number's storage alloc (and + everything else). */ + generic_floating_point_number = save_gen_flonum; + + return return_value; +} + +/* Turn generic_floating_point_number into a real float/double/extended. */ + +int +gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits) +{ + int return_value = 0; + + long exponent_1; + long exponent_2; + long exponent_3; + long exponent_4; + int exponent_skippage; + LITTLENUM_TYPE word1; + LITTLENUM_TYPE *lp; + LITTLENUM_TYPE *words_end; + + words_end = words + precision; +#ifdef TC_M68K + if (precision == X_PRECISION) + /* On the m68k the extended precision format has a gap of 16 bits + between the exponent and the mantissa. */ + words_end++; +#endif + + if (generic_floating_point_number.low > generic_floating_point_number.leader) + { + /* 0.0e0 seen. */ + if (generic_floating_point_number.sign == '+') + words[0] = 0x0000; + else + words[0] = 0x8000; + memset (&words[1], '\0', + (words_end - words - 1) * sizeof (LITTLENUM_TYPE)); + return return_value; + } + + /* NaN: Do the right thing. */ + if (generic_floating_point_number.sign == 0) + { + if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) + as_warn (_("NaNs are not supported by this target\n")); + if (precision == F_PRECISION) + { + words[0] = 0x7fff; + words[1] = 0xffff; + } + else if (precision == X_PRECISION) + { +#ifdef TC_M68K + words[0] = 0x7fff; + words[1] = 0; + words[2] = 0xffff; + words[3] = 0xffff; + words[4] = 0xffff; + words[5] = 0xffff; +#else /* ! TC_M68K */ +#ifdef TC_I386 + words[0] = 0xffff; + words[1] = 0xc000; + words[2] = 0; + words[3] = 0; + words[4] = 0; +#else /* ! TC_I386 */ + abort (); +#endif /* ! TC_I386 */ +#endif /* ! TC_M68K */ + } + else + { + words[0] = 0x7fff; + words[1] = 0xffff; + words[2] = 0xffff; + words[3] = 0xffff; + } + return return_value; + } + else if (generic_floating_point_number.sign == 'P') + { + if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) + as_warn (_("Infinities are not supported by this target\n")); + + /* +INF: Do the right thing. */ + if (precision == F_PRECISION) + { + words[0] = 0x7f80; + words[1] = 0; + } + else if (precision == X_PRECISION) + { +#ifdef TC_M68K + words[0] = 0x7fff; + words[1] = 0; + words[2] = 0; + words[3] = 0; + words[4] = 0; + words[5] = 0; +#else /* ! TC_M68K */ +#ifdef TC_I386 + words[0] = 0x7fff; + words[1] = 0x8000; + words[2] = 0; + words[3] = 0; + words[4] = 0; +#else /* ! TC_I386 */ + abort (); +#endif /* ! TC_I386 */ +#endif /* ! TC_M68K */ + } + else + { + words[0] = 0x7ff0; + words[1] = 0; + words[2] = 0; + words[3] = 0; + } + return return_value; + } + else if (generic_floating_point_number.sign == 'N') + { + if (TC_LARGEST_EXPONENT_IS_NORMAL (precision)) + as_warn (_("Infinities are not supported by this target\n")); + + /* Negative INF. */ + if (precision == F_PRECISION) + { + words[0] = 0xff80; + words[1] = 0x0; + } + else if (precision == X_PRECISION) + { +#ifdef TC_M68K + words[0] = 0xffff; + words[1] = 0; + words[2] = 0; + words[3] = 0; + words[4] = 0; + words[5] = 0; +#else /* ! TC_M68K */ +#ifdef TC_I386 + words[0] = 0xffff; + words[1] = 0x8000; + words[2] = 0; + words[3] = 0; + words[4] = 0; +#else /* ! TC_I386 */ + abort (); +#endif /* ! TC_I386 */ +#endif /* ! TC_M68K */ + } + else + { + words[0] = 0xfff0; + words[1] = 0x0; + words[2] = 0x0; + words[3] = 0x0; + } + return return_value; + } + + /* The floating point formats we support have: + Bit 15 is sign bit. + Bits 14:n are excess-whatever exponent. + Bits n-1:0 (if any) are most significant bits of fraction. + Bits 15:0 of the next word(s) are the next most significant bits. + + So we need: number of bits of exponent, number of bits of + mantissa. */ + bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS; + littlenum_pointer = generic_floating_point_number.leader; + littlenums_left = (1 + + generic_floating_point_number.leader + - generic_floating_point_number.low); + + /* Seek (and forget) 1st significant bit. */ + for (exponent_skippage = 0; !next_bits (1); ++exponent_skippage); + exponent_1 = (generic_floating_point_number.exponent + + generic_floating_point_number.leader + + 1 + - generic_floating_point_number.low); + + /* Radix LITTLENUM_RADIX, point just higher than + generic_floating_point_number.leader. */ + exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS; + + /* Radix 2. */ + exponent_3 = exponent_2 - exponent_skippage; + + /* Forget leading zeros, forget 1st bit. */ + exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2); + + /* Offset exponent. */ + lp = words; + + /* Word 1. Sign, exponent and perhaps high bits. */ + word1 = ((generic_floating_point_number.sign == '+') + ? 0 + : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); + + /* Assume 2's complement integers. */ + if (exponent_4 <= 0) + { + int prec_bits; + int num_bits; + + unget_bits (1); + num_bits = -exponent_4; + prec_bits = + LITTLENUM_NUMBER_OF_BITS * precision - (exponent_bits + 1 + num_bits); +#ifdef TC_I386 + if (precision == X_PRECISION && exponent_bits == 15) + { + /* On the i386 a denormalized extended precision float is + shifted down by one, effectively decreasing the exponent + bias by one. */ + prec_bits -= 1; + num_bits += 1; + } +#endif + + if (num_bits >= LITTLENUM_NUMBER_OF_BITS - exponent_bits) + { + /* Bigger than one littlenum. */ + num_bits -= (LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits; + *lp++ = word1; + if (num_bits + exponent_bits + 1 + > precision * LITTLENUM_NUMBER_OF_BITS) + { + /* Exponent overflow. */ + make_invalid_floating_point_number (words); + return return_value; + } +#ifdef TC_M68K + if (precision == X_PRECISION && exponent_bits == 15) + *lp++ = 0; +#endif + while (num_bits >= LITTLENUM_NUMBER_OF_BITS) + { + num_bits -= LITTLENUM_NUMBER_OF_BITS; + *lp++ = 0; + } + if (num_bits) + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - (num_bits)); + } + else + { + if (precision == X_PRECISION && exponent_bits == 15) + { + *lp++ = word1; +#ifdef TC_M68K + *lp++ = 0; +#endif + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS - num_bits); + } + else + { + word1 |= next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) + - (exponent_bits + num_bits)); + *lp++ = word1; + } + } + while (lp < words_end) + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); + + /* Round the mantissa up, but don't change the number. */ + if (next_bits (1)) + { + --lp; + if (prec_bits >= LITTLENUM_NUMBER_OF_BITS) + { + int n = 0; + int tmp_bits; + + n = 0; + tmp_bits = prec_bits; + while (tmp_bits > LITTLENUM_NUMBER_OF_BITS) + { + if (lp[n] != (LITTLENUM_TYPE) - 1) + break; + --n; + tmp_bits -= LITTLENUM_NUMBER_OF_BITS; + } + if (tmp_bits > LITTLENUM_NUMBER_OF_BITS + || (lp[n] & mask[tmp_bits]) != mask[tmp_bits] + || (prec_bits != (precision * LITTLENUM_NUMBER_OF_BITS + - exponent_bits - 1) +#ifdef TC_I386 + /* An extended precision float with only the integer + bit set would be invalid. That must be converted + to the smallest normalized number. */ + && !(precision == X_PRECISION + && prec_bits == (precision * LITTLENUM_NUMBER_OF_BITS + - exponent_bits - 2)) +#endif + )) + { + unsigned long carry; + + for (carry = 1; carry && (lp >= words); lp--) + { + carry = *lp + carry; + *lp = carry; + carry >>= LITTLENUM_NUMBER_OF_BITS; + } + } + else + { + /* This is an overflow of the denormal numbers. We + need to forget what we have produced, and instead + generate the smallest normalized number. */ + lp = words; + word1 = ((generic_floating_point_number.sign == '+') + ? 0 + : (1 << (LITTLENUM_NUMBER_OF_BITS - 1))); + word1 |= (1 + << ((LITTLENUM_NUMBER_OF_BITS - 1) + - exponent_bits)); + *lp++ = word1; +#ifdef TC_I386 + /* Set the integer bit in the extended precision format. + This cannot happen on the m68k where the mantissa + just overflows into the integer bit above. */ + if (precision == X_PRECISION) + *lp++ = 1 << (LITTLENUM_NUMBER_OF_BITS - 1); +#endif + while (lp < words_end) + *lp++ = 0; + } + } + else + *lp += 1; + } + + return return_value; + } + else if ((unsigned long) exponent_4 > mask[exponent_bits] + || (! TC_LARGEST_EXPONENT_IS_NORMAL (precision) + && (unsigned long) exponent_4 == mask[exponent_bits])) + { + /* Exponent overflow. Lose immediately. */ + + /* We leave return_value alone: admit we read the + number, but return a floating exception + because we can't encode the number. */ + make_invalid_floating_point_number (words); + return return_value; + } + else + { + word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits)) + | next_bits ((LITTLENUM_NUMBER_OF_BITS - 1) - exponent_bits); + } + + *lp++ = word1; + + /* X_PRECISION is special: on the 68k, it has 16 bits of zero in the + middle. Either way, it is then followed by a 1 bit. */ + if (exponent_bits == 15 && precision == X_PRECISION) + { +#ifdef TC_M68K + *lp++ = 0; +#endif + *lp++ = (1 << (LITTLENUM_NUMBER_OF_BITS - 1) + | next_bits (LITTLENUM_NUMBER_OF_BITS - 1)); + } + + /* The rest of the words are just mantissa bits. */ + while (lp < words_end) + *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS); + + if (next_bits (1)) + { + unsigned long carry; + /* Since the NEXT bit is a 1, round UP the mantissa. + The cunning design of these hidden-1 floats permits + us to let the mantissa overflow into the exponent, and + it 'does the right thing'. However, we lose if the + highest-order bit of the lowest-order word flips. + Is that clear? */ + + /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2) + Please allow at least 1 more bit in carry than is in a LITTLENUM. + We need that extra bit to hold a carry during a LITTLENUM carry + propagation. Another extra bit (kept 0) will assure us that we + don't get a sticky sign bit after shifting right, and that + permits us to propagate the carry without any masking of bits. + #endif */ + for (carry = 1, lp--; carry; lp--) + { + carry = *lp + carry; + *lp = carry; + carry >>= LITTLENUM_NUMBER_OF_BITS; + if (lp == words) + break; + } + if (precision == X_PRECISION && exponent_bits == 15) + { + /* Extended precision numbers have an explicit integer bit + that we may have to restore. */ + if (lp == words) + { +#ifdef TC_M68K + /* On the m68k there is a gap of 16 bits. We must + explicitly propagate the carry into the exponent. */ + words[0] += words[1]; + words[1] = 0; + lp++; +#endif + /* Put back the integer bit. */ + lp[1] |= 1 << (LITTLENUM_NUMBER_OF_BITS - 1); + } + } + if ((word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) + { + /* We leave return_value alone: admit we read the number, + but return a floating exception because we can't encode + the number. */ + *words &= ~(1 << (LITTLENUM_NUMBER_OF_BITS - 1)); + } + } + return return_value; +} + +#ifdef TEST +char * +print_gen (gen) + FLONUM_TYPE *gen; +{ + FLONUM_TYPE f; + LITTLENUM_TYPE arr[10]; + double dv; + float fv; + static char sbuf[40]; + + if (gen) + { + f = generic_floating_point_number; + generic_floating_point_number = *gen; + } + gen_to_words (&arr[0], 4, 11); + memcpy (&dv, &arr[0], sizeof (double)); + sprintf (sbuf, "%x %x %x %x %.14G ", arr[0], arr[1], arr[2], arr[3], dv); + gen_to_words (&arr[0], 2, 8); + memcpy (&fv, &arr[0], sizeof (float)); + sprintf (sbuf + strlen (sbuf), "%x %x %.12g\n", arr[0], arr[1], fv); + + if (gen) + generic_floating_point_number = f; + + return (sbuf); +} +#endif + +extern const char FLT_CHARS[]; +#define MAX_LITTLENUMS 6 + +/* This is a utility function called from various tc-*.c files. It + is here in order to reduce code duplication. + + Turn a string at input_line_pointer into a floating point constant + of type TYPE (a character found in the FLT_CHARS macro), and store + it as LITTLENUMS in the bytes buffer LITP. The number of chars + emitted is stored in *SIZEP. BIG_WORDIAN is TRUE if the littlenums + should be emitted most significant littlenum first. + + An error message is returned, or a NULL pointer if everything went OK. */ + +char * +ieee_md_atof (int type, + char *litP, + int *sizeP, + bfd_boolean big_wordian) +{ + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + int prec = 0; + + if (strchr (FLT_CHARS, type) != NULL) + { + switch (type) + { + case 'f': + case 'F': + case 's': + case 'S': + prec = F_PRECISION; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = D_PRECISION; + break; + + case 't': + case 'T': + prec = X_PRECISION; + type = 'x'; /* This is what atof_ieee() understands. */ + break; + + case 'x': + case 'X': + case 'p': + case 'P': +#ifdef TC_M68K + /* Note: on the m68k there is a gap of 16 bits (one littlenum) + between the exponent and mantissa. Hence the precision is + 6 and not 5. */ + prec = P_PRECISION + 1; +#else + prec = P_PRECISION; +#endif + break; + + default: + break; + } + } + /* The 'f' and 'd' types are always recognised, even if the target has + not put them into the FLT_CHARS macro. This is because the 'f' type + can come from the .dc.s, .dcb.s, .float or .single pseudo-ops and the + 'd' type from the .dc.d, .dbc.d or .double pseudo-ops. + + The 'x' type is not implicitly recongised however, even though it can + be generated by the .dc.x and .dbc.x pseudo-ops because not all targets + can support floating point values that big. ie the target has to + explicitly allow them by putting them into FLT_CHARS. */ + else if (type == 'f') + prec = F_PRECISION; + else if (type == 'd') + prec = D_PRECISION; + + if (prec == 0) + { + *sizeP = 0; + return _("Unrecognized or unsupported floating point constant"); + } + + gas_assert (prec <= MAX_LITTLENUMS); + + t = atof_ieee (input_line_pointer, type, words); + if (t) + input_line_pointer = t; + + *sizeP = prec * sizeof (LITTLENUM_TYPE); + + if (big_wordian) + { + for (wordP = words; prec --;) + { + md_number_to_chars (litP, (valueT) (* wordP ++), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + } + else + { + for (wordP = words + prec; prec --;) + { + md_number_to_chars (litP, (valueT) (* -- wordP), sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + } + + return NULL; +} diff --git a/contrib/toolchain/binutils/gas/config/obj-coff-seh.c b/contrib/toolchain/binutils/gas/config/obj-coff-seh.c new file mode 100644 index 0000000000..83e8cb669c --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/obj-coff-seh.c @@ -0,0 +1,1018 @@ +/* seh pdata/xdata coff object file format + Copyright 2009, 2010 + Free Software Foundation, Inc. + + This file is part of GAS. + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "obj-coff-seh.h" + + +/* Private segment collection list. */ +struct seh_seg_list { + segT seg; + int subseg; + char *seg_name; +}; + +/* Local data. */ +static seh_context *seh_ctx_cur = NULL; + +static struct hash_control *seh_hash; + +static struct seh_seg_list *x_segcur = NULL; +static struct seh_seg_list *p_segcur = NULL; + +static void write_function_xdata (seh_context *); +static void write_function_pdata (seh_context *); + + +/* Build based on segment the derived .pdata/.xdata + segment name containing origin segment's postfix name part. */ +static char * +get_pxdata_name (segT seg, const char *base_name) +{ + const char *name,*dollar, *dot; + char *sname; + + name = bfd_get_section_name (stdoutput, seg); + + dollar = strchr (name, '$'); + dot = strchr (name + 1, '.'); + + if (!dollar && !dot) + name = ""; + else if (!dollar) + name = dot; + else if (!dot) + name = dollar; + else if (dot < dollar) + name = dot; + else + name = dollar; + + sname = concat (base_name, name, NULL); + + return sname; +} + +/* Allocate a seh_seg_list structure. */ +static struct seh_seg_list * +alloc_pxdata_item (segT seg, int subseg, char *name) +{ + struct seh_seg_list *r; + + r = (struct seh_seg_list *) + xmalloc (sizeof (struct seh_seg_list) + strlen (name)); + r->seg = seg; + r->subseg = subseg; + r->seg_name = name; + return r; +} + +/* Generate pdata/xdata segment with same linkonce properties + of based segment. */ +static segT +make_pxdata_seg (segT cseg, char *name) +{ + segT save_seg = now_seg; + int save_subseg = now_subseg; + segT r; + flagword flags; + + r = subseg_new (name, 0); + /* Check if code segment is marked as linked once. */ + flags = bfd_get_section_flags (stdoutput, cseg) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE + | SEC_LINK_DUPLICATES_SAME_CONTENTS); + + /* Add standard section flags. */ + flags |= SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA; + + /* Apply possibly linked once flags to new generated segment, too. */ + if (!bfd_set_section_flags (stdoutput, r, flags)) + as_bad (_("bfd_set_section_flags: %s"), + bfd_errmsg (bfd_get_error ())); + + /* Restore to previous segment. */ + subseg_set (save_seg, save_subseg); + return r; +} + +static void +seh_hash_insert (const char *name, struct seh_seg_list *item) +{ + const char *error_string; + + if ((error_string = hash_jam (seh_hash, name, (char *) item))) + as_fatal (_("Inserting \"%s\" into structure table failed: %s"), + name, error_string); +} + +static struct seh_seg_list * +seh_hash_find (char *name) +{ + return (struct seh_seg_list *) hash_find (seh_hash, name); +} + +static struct seh_seg_list * +seh_hash_find_or_make (segT cseg, const char *base_name) +{ + struct seh_seg_list *item; + char *name; + + /* Initialize seh_hash once. */ + if (!seh_hash) + seh_hash = hash_new (); + + name = get_pxdata_name (cseg, base_name); + + item = seh_hash_find (name); + if (!item) + { + item = alloc_pxdata_item (make_pxdata_seg (cseg, name), 0, name); + + seh_hash_insert (item->seg_name, item); + } + else + free (name); + + return item; +} + +/* Check if current segment has same name. */ +static int +seh_validate_seg (const char *directive) +{ + const char *cseg_name, *nseg_name; + if (seh_ctx_cur->code_seg == now_seg) + return 1; + cseg_name = bfd_get_section_name (stdoutput, seh_ctx_cur->code_seg); + nseg_name = bfd_get_section_name (stdoutput, now_seg); + as_bad (_("%s used in segment '%s' instead of expected '%s'"), + directive, nseg_name, cseg_name); + ignore_rest_of_line (); + return 0; +} + +static void +switch_xdata (int subseg, segT code_seg) +{ + x_segcur = seh_hash_find_or_make (code_seg, ".xdata"); + + subseg_set (x_segcur->seg, subseg); +} + +static void +switch_pdata (segT code_seg) +{ + p_segcur = seh_hash_find_or_make (code_seg, ".pdata"); + + subseg_set (p_segcur->seg, p_segcur->subseg); +} + +/* Parsing routines. */ + +/* Return the style of SEH unwind info to generate. */ + +static seh_kind +seh_get_target_kind (void) +{ + if (!stdoutput) + return seh_kind_unknown; + switch (bfd_get_arch (stdoutput)) + { + case bfd_arch_arm: + case bfd_arch_powerpc: + case bfd_arch_sh: + return seh_kind_arm; + case bfd_arch_i386: + switch (bfd_get_mach (stdoutput)) + { + case bfd_mach_x86_64: + case bfd_mach_x86_64_intel_syntax: + return seh_kind_x64; + default: + break; + } + /* FALL THROUGH. */ + case bfd_arch_mips: + return seh_kind_mips; + case bfd_arch_ia64: + /* Should return seh_kind_x64. But not implemented yet. */ + return seh_kind_unknown; + default: + break; + } + return seh_kind_unknown; +} + +/* Verify that we're in the context of a seh_proc. */ + +static int +verify_context (const char *directive) +{ + if (seh_ctx_cur == NULL) + { + as_bad (_("%s used outside of .seh_proc block"), directive); + ignore_rest_of_line (); + return 0; + } + return 1; +} + +/* Similar, except we also verify the appropriate target. */ + +static int +verify_context_and_target (const char *directive, seh_kind target) +{ + if (seh_get_target_kind () != target) + { + as_warn (_("%s ignored for this target"), directive); + ignore_rest_of_line (); + return 0; + } + return verify_context (directive); +} + +/* Skip whitespace and a comma. Error if the comma is not seen. */ + +static int +skip_whitespace_and_comma (int required) +{ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + return 1; + } + else if (required) + { + as_bad (_("missing separator")); + ignore_rest_of_line (); + } + else + demand_empty_rest_of_line (); + return 0; +} + +/* Mark current context to use 32-bit instruction (arm). */ + +static void +obj_coff_seh_32 (int what) +{ + if (!verify_context_and_target ((what ? ".seh_32" : ".seh_no32"), + seh_kind_arm)) + return; + + seh_ctx_cur->use_instruction_32 = (what ? 1 : 0); + demand_empty_rest_of_line (); +} + +/* Set for current context the handler and optional data (arm). */ + +static void +obj_coff_seh_eh (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context_and_target (".seh_eh", seh_kind_arm)) + return; + + /* Write block to .text if exception handler is set. */ + seh_ctx_cur->handler_written = 1; + emit_expr (&seh_ctx_cur->handler, 4); + emit_expr (&seh_ctx_cur->handler_data, 4); + + demand_empty_rest_of_line (); +} + +/* Set for current context the default handler (x64). */ + +static void +obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) +{ + char *symbol_name; + char name_end; + + if (!verify_context (".seh_handler")) + return; + + if (*input_line_pointer == 0 || *input_line_pointer == '\n') + { + as_bad (_(".seh_handler requires a handler")); + demand_empty_rest_of_line (); + return; + } + + SKIP_WHITESPACE (); + + if (*input_line_pointer == '@') + { + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + + seh_ctx_cur->handler.X_op = O_constant; + seh_ctx_cur->handler.X_add_number = 0; + + if (strcasecmp (symbol_name, "@0") == 0 + || strcasecmp (symbol_name, "@null") == 0) + ; + else if (strcasecmp (symbol_name, "@1") == 0) + seh_ctx_cur->handler.X_add_number = 1; + else + as_bad (_("unknown constant value '%s' for handler"), symbol_name); + + *input_line_pointer = name_end; + } + else + expression (&seh_ctx_cur->handler); + + seh_ctx_cur->handler_data.X_op = O_constant; + seh_ctx_cur->handler_data.X_add_number = 0; + seh_ctx_cur->handler_flags = 0; + + if (!skip_whitespace_and_comma (0)) + return; + + if (seh_get_target_kind () == seh_kind_x64) + { + do + { + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + + if (strcasecmp (symbol_name, "@unwind") == 0) + seh_ctx_cur->handler_flags |= UNW_FLAG_UHANDLER; + else if (strcasecmp (symbol_name, "@except") == 0) + seh_ctx_cur->handler_flags |= UNW_FLAG_EHANDLER; + else + as_bad (_(".seh_handler constant '%s' unknown"), symbol_name); + + *input_line_pointer = name_end; + } + while (skip_whitespace_and_comma (0)); + } + else + { + expression (&seh_ctx_cur->handler_data); + demand_empty_rest_of_line (); + + if (seh_ctx_cur->handler_written) + as_warn (_(".seh_handler after .seh_eh is ignored")); + } +} + +/* Switch to subsection for handler data for exception region (x64). */ + +static void +obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context_and_target (".seh_handlerdata", seh_kind_x64)) + return; + demand_empty_rest_of_line (); + + switch_xdata (seh_ctx_cur->subsection + 1, seh_ctx_cur->code_seg); +} + +/* Mark end of current context. */ + +static void +do_seh_endproc (void) +{ + seh_ctx_cur->end_addr = symbol_temp_new_now (); + + write_function_xdata (seh_ctx_cur); + write_function_pdata (seh_ctx_cur); + seh_ctx_cur = NULL; +} + +static void +obj_coff_seh_endproc (int what ATTRIBUTE_UNUSED) +{ + demand_empty_rest_of_line (); + if (seh_ctx_cur == NULL) + { + as_bad (_(".seh_endproc used without .seh_proc")); + return; + } + seh_validate_seg (".seh_endproc"); + do_seh_endproc (); +} + +/* Mark begin of new context. */ + +static void +obj_coff_seh_proc (int what ATTRIBUTE_UNUSED) +{ + char *symbol_name; + char name_end; + + if (seh_ctx_cur != NULL) + { + as_bad (_("previous SEH entry not closed (missing .seh_endproc)")); + do_seh_endproc (); + } + + if (*input_line_pointer == 0 || *input_line_pointer == '\n') + { + as_bad (_(".seh_proc requires function label name")); + demand_empty_rest_of_line (); + return; + } + + seh_ctx_cur = XCNEW (seh_context); + + seh_ctx_cur->code_seg = now_seg; + + if (seh_get_target_kind () == seh_kind_x64) + { + x_segcur = seh_hash_find_or_make (seh_ctx_cur->code_seg, ".xdata"); + seh_ctx_cur->subsection = x_segcur->subseg; + x_segcur->subseg += 2; + } + + SKIP_WHITESPACE (); + + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + seh_ctx_cur->func_name = xstrdup (symbol_name); + *input_line_pointer = name_end; + + demand_empty_rest_of_line (); + + seh_ctx_cur->start_addr = symbol_temp_new_now (); +} + +/* Mark end of prologue for current context. */ + +static void +obj_coff_seh_endprologue (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context (".seh_endprologue") + || !seh_validate_seg (".seh_endprologue")) + return; + demand_empty_rest_of_line (); + + if (seh_ctx_cur->endprologue_addr != NULL) + as_warn (_("duplicate .seh_endprologue in .seh_proc block")); + else + seh_ctx_cur->endprologue_addr = symbol_temp_new_now (); +} + +/* End-of-file hook. */ + +void +obj_coff_seh_do_final (void) +{ + if (seh_ctx_cur != NULL) + { + as_bad (_("open SEH entry at end of file (missing .cfi_endproc)")); + do_seh_endproc (); + } +} + +/* Enter a prologue element into current context (x64). */ + +static void +seh_x64_make_prologue_element (int code, int info, offsetT off) +{ + seh_prologue_element *n; + + if (seh_ctx_cur == NULL) + return; + if (seh_ctx_cur->elems_count == seh_ctx_cur->elems_max) + { + seh_ctx_cur->elems_max += 8; + seh_ctx_cur->elems = XRESIZEVEC (seh_prologue_element, + seh_ctx_cur->elems, + seh_ctx_cur->elems_max); + } + + n = &seh_ctx_cur->elems[seh_ctx_cur->elems_count++]; + n->code = code; + n->info = info; + n->off = off; + n->pc_addr = symbol_temp_new_now (); +} + +/* Helper to read a register name from input stream (x64). */ + +static int +seh_x64_read_reg (const char *directive, int kind) +{ + static const char * const int_regs[16] = + { "rax", "rcx", "rdx", "rbx", "rsp", "rbp","rsi","rdi", + "r8","r9","r10","r11","r12","r13","r14","r15" }; + static const char * const xmm_regs[16] = + { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10","xmm11","xmm12","xmm13","xmm14","xmm15" }; + + const char * const *regs = NULL; + char name_end; + char *symbol_name = NULL; + int i; + + switch (kind) + { + case 0: + case 1: + regs = int_regs; + break; + case 2: + regs = xmm_regs; + break; + default: + abort (); + } + + SKIP_WHITESPACE (); + if (*input_line_pointer == '%') + ++input_line_pointer; + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + + for (i = 0; i < 16; i++) + if (! strcasecmp (regs[i], symbol_name)) + break; + + *input_line_pointer = name_end; + + /* Error if register not found, or EAX used as a frame pointer. */ + if (i == 16 || (kind == 0 && i == 0)) + { + as_bad (_("invalid register for %s"), directive); + return -1; + } + + return i; +} + +/* Add a register push-unwind token to the current context. */ + +static void +obj_coff_seh_pushreg (int what ATTRIBUTE_UNUSED) +{ + int reg; + + if (!verify_context_and_target (".seh_pushreg", seh_kind_x64) + || !seh_validate_seg (".seh_pushreg")) + return; + + reg = seh_x64_read_reg (".seh_pushreg", 1); + demand_empty_rest_of_line (); + + if (reg < 0) + return; + + seh_x64_make_prologue_element (UWOP_PUSH_NONVOL, reg, 0); +} + +/* Add a register frame-unwind token to the current context. */ + +static void +obj_coff_seh_pushframe (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context_and_target (".seh_pushframe", seh_kind_x64) + || !seh_validate_seg (".seh_pushframe")) + return; + demand_empty_rest_of_line (); + + seh_x64_make_prologue_element (UWOP_PUSH_MACHFRAME, 0, 0); +} + +/* Add a register save-unwind token to current context. */ + +static void +obj_coff_seh_save (int what) +{ + const char *directive = (what == 1 ? ".seh_savereg" : ".seh_savexmm"); + int code, reg, scale; + offsetT off; + + if (!verify_context_and_target (directive, seh_kind_x64) + || !seh_validate_seg (directive)) + return; + + reg = seh_x64_read_reg (directive, what); + + if (!skip_whitespace_and_comma (1)) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg < 0) + return; + if (off < 0) + { + as_bad (_("%s offset is negative"), directive); + return; + } + + scale = (what == 1 ? 8 : 16); + + if ((off & (scale - 1)) == 0 && off <= (offsetT) (0xffff * scale)) + { + code = (what == 1 ? UWOP_SAVE_NONVOL : UWOP_SAVE_XMM128); + off /= scale; + } + else if (off < (offsetT) 0xffffffff) + code = (what == 1 ? UWOP_SAVE_NONVOL_FAR : UWOP_SAVE_XMM128_FAR); + else + { + as_bad (_("%s offset out of range"), directive); + return; + } + + seh_x64_make_prologue_element (code, reg, off); +} + +/* Add a stack-allocation token to current context. */ + +static void +obj_coff_seh_stackalloc (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + int code, info; + + if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64) + || !seh_validate_seg (".seh_stackalloc")) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (off == 0) + return; + if (off < 0) + { + as_bad (_(".seh_stackalloc offset is negative")); + return; + } + + if ((off & 7) == 0 && off <= 128) + code = UWOP_ALLOC_SMALL, info = (off - 8) >> 3, off = 0; + else if ((off & 7) == 0 && off <= (offsetT) (0xffff * 8)) + code = UWOP_ALLOC_LARGE, info = 0, off >>= 3; + else if (off <= (offsetT) 0xffffffff) + code = UWOP_ALLOC_LARGE, info = 1; + else + { + as_bad (_(".seh_stackalloc offset out of range")); + return; + } + + seh_x64_make_prologue_element (code, info, off); +} + +/* Add a frame-pointer token to current context. */ + +static void +obj_coff_seh_setframe (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + int reg; + + if (!verify_context_and_target (".seh_setframe", seh_kind_x64) + || !seh_validate_seg (".seh_setframe")) + return; + + reg = seh_x64_read_reg (".seh_setframe", 0); + + if (!skip_whitespace_and_comma (1)) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg < 0) + return; + if (off < 0) + as_bad (_(".seh_setframe offset is negative")); + else if (off > 240) + as_bad (_(".seh_setframe offset out of range")); + else if (off & 15) + as_bad (_(".seh_setframe offset not a multiple of 16")); + else if (seh_ctx_cur->framereg != 0) + as_bad (_("duplicate .seh_setframe in current .seh_proc")); + else + { + seh_ctx_cur->framereg = reg; + seh_ctx_cur->frameoff = off; + seh_x64_make_prologue_element (UWOP_SET_FPREG, 0, 0); + } +} + +/* Data writing routines. */ + +/* Output raw integers in 1, 2, or 4 bytes. */ + +static inline void +out_one (int byte) +{ + FRAG_APPEND_1_CHAR (byte); +} + +static inline void +out_two (int data) +{ + md_number_to_chars (frag_more (2), data, 2); +} + +static inline void +out_four (int data) +{ + md_number_to_chars (frag_more (4), data, 4); +} + +/* Write out prologue data for x64. */ + +static void +seh_x64_write_prologue_data (const seh_context *c) +{ + int i; + + /* We have to store in reverse order. */ + for (i = c->elems_count - 1; i >= 0; --i) + { + const seh_prologue_element *e = c->elems + i; + expressionS exp; + + /* First comes byte offset in code. */ + exp.X_op = O_subtract; + exp.X_add_symbol = e->pc_addr; + exp.X_op_symbol = c->start_addr; + exp.X_add_number = 0; + emit_expr (&exp, 1); + + /* Second comes code+info packed into a byte. */ + out_one ((e->info << 4) | e->code); + + switch (e->code) + { + case UWOP_PUSH_NONVOL: + case UWOP_ALLOC_SMALL: + case UWOP_SET_FPREG: + case UWOP_PUSH_MACHFRAME: + /* These have no extra data. */ + break; + + case UWOP_ALLOC_LARGE: + if (e->info) + { + case UWOP_SAVE_NONVOL_FAR: + case UWOP_SAVE_XMM128_FAR: + /* An unscaled 4 byte offset. */ + out_four (e->off); + break; + } + /* FALLTHRU */ + + case UWOP_SAVE_NONVOL: + case UWOP_SAVE_XMM128: + /* A scaled 2 byte offset. */ + out_two (e->off); + break; + + default: + abort (); + } + } +} + +static int +seh_x64_size_prologue_data (const seh_context *c) +{ + int i, ret = 0; + + for (i = c->elems_count - 1; i >= 0; --i) + switch (c->elems[i].code) + { + case UWOP_PUSH_NONVOL: + case UWOP_ALLOC_SMALL: + case UWOP_SET_FPREG: + case UWOP_PUSH_MACHFRAME: + ret += 1; + break; + + case UWOP_SAVE_NONVOL: + case UWOP_SAVE_XMM128: + ret += 2; + break; + + case UWOP_SAVE_NONVOL_FAR: + case UWOP_SAVE_XMM128_FAR: + ret += 3; + break; + + case UWOP_ALLOC_LARGE: + ret += (c->elems[i].info ? 3 : 2); + break; + + default: + abort (); + } + + return ret; +} + +/* Write out the xdata information for one function (x64). */ + +static void +seh_x64_write_function_xdata (seh_context *c) +{ + int flags, count_unwind_codes; + expressionS exp; + + /* Set 4-byte alignment. */ + frag_align (2, 0, 0); + + c->xdata_addr = symbol_temp_new_now (); + flags = c->handler_flags; + count_unwind_codes = seh_x64_size_prologue_data (c); + + /* ubyte:3 version, ubyte:5 flags. */ + out_one ((flags << 3) | 1); + + /* Size of prologue. */ + if (c->endprologue_addr) + { + exp.X_op = O_subtract; + exp.X_add_symbol = c->endprologue_addr; + exp.X_op_symbol = c->start_addr; + exp.X_add_number = 0; + emit_expr (&exp, 1); + } + else + out_one (0); + + /* Number of slots (i.e. shorts) in the unwind codes array. */ + if (count_unwind_codes > 255) + as_fatal (_("too much unwind data in this .seh_proc")); + out_one (count_unwind_codes); + + /* ubyte:4 frame-reg, ubyte:4 frame-reg-offset. */ + /* Note that frameoff is already a multiple of 16, and therefore + the offset is already both scaled and shifted into place. */ + out_one (c->frameoff | c->framereg); + + seh_x64_write_prologue_data (c); + + /* We need to align prologue data. */ + if (count_unwind_codes & 1) + out_two (0); + + if (flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) + { + /* Force the use of segment-relative relocations instead of absolute + valued expressions. Don't adjust for constants (e.g. NULL). */ + if (c->handler.X_op == O_symbol) + c->handler.X_op = O_symbol_rva; + emit_expr (&c->handler, 4); + } + + /* Handler data will be tacked in here by subsections. */ +} + +/* Write out xdata for one function. */ + +static void +write_function_xdata (seh_context *c) +{ + segT save_seg = now_seg; + int save_subseg = now_subseg; + + /* MIPS, SH, ARM don't have xdata. */ + if (seh_get_target_kind () != seh_kind_x64) + return; + + switch_xdata (c->subsection, c->code_seg); + + seh_x64_write_function_xdata (c); + + subseg_set (save_seg, save_subseg); +} + +/* Write pdata section data for one function (arm). */ + +static void +seh_arm_write_function_pdata (seh_context *c) +{ + expressionS exp; + unsigned int prol_len = 0, func_len = 0; + unsigned int val; + + /* Start address of the function. */ + exp.X_op = O_symbol; + exp.X_add_symbol = c->start_addr; + exp.X_add_number = 0; + emit_expr (&exp, 4); + + exp.X_op = O_subtract; + exp.X_add_symbol = c->end_addr; + exp.X_op_symbol = c->start_addr; + exp.X_add_number = 0; + if (resolve_expression (&exp) && exp.X_op == O_constant) + func_len = exp.X_add_number; + else + as_bad (_(".seh_endproc in a different section from .seh_proc")); + + if (c->endprologue_addr) + { + exp.X_op = O_subtract; + exp.X_add_symbol = c->endprologue_addr; + exp.X_op_symbol = c->start_addr; + exp.X_add_number = 0; + + if (resolve_expression (&exp) && exp.X_op == O_constant) + prol_len = exp.X_add_number; + else + as_bad (_(".seh_endprologue in a different section from .seh_proc")); + } + + /* Both function and prologue are in units of instructions. */ + func_len >>= (c->use_instruction_32 ? 2 : 1); + prol_len >>= (c->use_instruction_32 ? 2 : 1); + + /* Assemble the second word of the pdata. */ + val = prol_len & 0xff; + val |= (func_len & 0x3fffff) << 8; + if (c->use_instruction_32) + val |= 0x40000000U; + if (c->handler_written) + val |= 0x80000000U; + out_four (val); +} + +/* Write out pdata for one function. */ + +static void +write_function_pdata (seh_context *c) +{ + expressionS exp; + segT save_seg = now_seg; + int save_subseg = now_subseg; + memset (&exp, 0, sizeof (expressionS)); + switch_pdata (c->code_seg); + + switch (seh_get_target_kind ()) + { + case seh_kind_x64: + exp.X_op = O_symbol_rva; + exp.X_add_number = 0; + + exp.X_add_symbol = c->start_addr; + emit_expr (&exp, 4); + exp.X_op = O_symbol_rva; + exp.X_add_number = 0; + exp.X_add_symbol = c->end_addr; + emit_expr (&exp, 4); + exp.X_op = O_symbol_rva; + exp.X_add_number = 0; + exp.X_add_symbol = c->xdata_addr; + emit_expr (&exp, 4); + break; + + case seh_kind_mips: + exp.X_op = O_symbol; + exp.X_add_number = 0; + + exp.X_add_symbol = c->start_addr; + emit_expr (&exp, 4); + exp.X_add_symbol = c->end_addr; + emit_expr (&exp, 4); + + emit_expr (&c->handler, 4); + emit_expr (&c->handler_data, 4); + + exp.X_add_symbol = (c->endprologue_addr + ? c->endprologue_addr + : c->start_addr); + emit_expr (&exp, 4); + break; + + case seh_kind_arm: + seh_arm_write_function_pdata (c); + break; + + default: + abort (); + } + + subseg_set (save_seg, save_subseg); +} diff --git a/contrib/toolchain/binutils/gas/config/obj-coff-seh.h b/contrib/toolchain/binutils/gas/config/obj-coff-seh.h new file mode 100644 index 0000000000..71c803f257 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/obj-coff-seh.h @@ -0,0 +1,205 @@ +/* seh pdata/xdata coff object file format + Copyright 2009, 2010, 2012 + Free Software Foundation, Inc. + + This file is part of GAS. + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Short overview: + There are at the moment three different function entry formats preset. + The first is the MIPS one. The second version + is for ARM, PPC, SH3, and SH4 mainly for Windows CE. + The third is the IA64 and x64 version. Note, the IA64 isn't implemented yet, + but to find information about it, please see specification about IA64 on + http://download.intel.com/design/Itanium/Downloads/245358.pdf file. + + The first version has just entries in the pdata section: BeginAddress, + EndAddress, ExceptionHandler, HandlerData, and PrologueEndAddress. Each + value is a pointer to the corresponding data and has size of 4 bytes. + + The second variant has the following entries in the pdata section. + BeginAddress, PrologueLength (8 bits), EndAddress (22 bits), + Use-32-bit-instruction (1 bit), and Exception-Handler-Exists (1 bit). + If the FunctionLength is zero, or the Exception-Handler-Exists bit + is true, a PDATA_EH block is placed directly before function entry. + + The third version has a function entry block of BeginAddress (RVA), + EndAddress (RVA), and UnwindData (RVA). The description of the + prologue, excepetion-handler, and additional SEH data is stored + within the UNWIND_DATA field in the xdata section. + + The pseudos: + .seh_proc + .seh_endprologue + .seh_handler [,@unwind][,@except] (x64) + .seh_handler [,] (others) + .seh_handlerdata + .seh_eh + .seh_32/.seh_no32 + .seh_endproc + .seh_setframe , + .seh_stackalloc + .seh_pushreg + .seh_savereg + .seh_savexmm + .seh_pushframe +*/ + +/* architecture specific pdata/xdata handling. */ +#define SEH_CMDS \ + {"seh_proc", obj_coff_seh_proc, 0}, \ + {"seh_endproc", obj_coff_seh_endproc, 0}, \ + {"seh_pushreg", obj_coff_seh_pushreg, 0}, \ + {"seh_savereg", obj_coff_seh_save, 1}, \ + {"seh_savexmm", obj_coff_seh_save, 2}, \ + {"seh_pushframe", obj_coff_seh_pushframe, 0}, \ + {"seh_endprologue", obj_coff_seh_endprologue, 0}, \ + {"seh_setframe", obj_coff_seh_setframe, 0}, \ + {"seh_stackalloc", obj_coff_seh_stackalloc, 0}, \ + {"seh_eh", obj_coff_seh_eh, 0}, \ + {"seh_32", obj_coff_seh_32, 1}, \ + {"seh_no32", obj_coff_seh_32, 0}, \ + {"seh_handler", obj_coff_seh_handler, 0}, \ + {"seh_handlerdata", obj_coff_seh_handlerdata, 0}, + +/* Type definitions. */ + +typedef struct seh_prologue_element +{ + int code; + int info; + offsetT off; + symbolS *pc_addr; +} seh_prologue_element; + +typedef struct seh_context +{ + struct seh_context *next; + + /* Initial code-segment. */ + segT code_seg; + /* Function name. */ + char *func_name; + /* BeginAddress. */ + symbolS *start_addr; + /* EndAddress. */ + symbolS *end_addr; + /* Unwind data. */ + symbolS *xdata_addr; + /* PrologueEnd. */ + symbolS *endprologue_addr; + /* ExceptionHandler. */ + expressionS handler; + /* ExceptionHandlerData. (arm, mips) */ + expressionS handler_data; + + /* ARM .seh_eh directive seen. */ + int handler_written; + + /* WinCE specific data. */ + int use_instruction_32; + /* Was record already processed. */ + int done; + + /* x64 flags for the xdata header. */ + int handler_flags; + int subsection; + + /* x64 framereg and frame offset information. */ + int framereg; + int frameoff; + + /* Information about x64 specific unwind data fields. */ + int elems_count; + int elems_max; + seh_prologue_element *elems; +} seh_context; + +typedef enum seh_kind { + seh_kind_unknown = 0, + seh_kind_mips = 1, /* Used for MIPS and x86 pdata generation. */ + seh_kind_arm = 2, /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_EH) generation. */ + seh_kind_x64 = 3 /* Used for IA64 and x64 pdata/xdata generation. */ +} seh_kind; + +/* Forward declarations. */ +static void obj_coff_seh_stackalloc (int); +static void obj_coff_seh_setframe (int); +static void obj_coff_seh_endprologue (int); +static void obj_coff_seh_save (int); +static void obj_coff_seh_pushreg (int); +static void obj_coff_seh_pushframe (int); +static void obj_coff_seh_endproc (int); +static void obj_coff_seh_eh (int); +static void obj_coff_seh_32 (int); +static void obj_coff_seh_proc (int); +static void obj_coff_seh_handler (int); +static void obj_coff_seh_handlerdata (int); + +#define UNDSEC bfd_und_section_ptr + +/* Check if x64 UNW_... macros are already defined. */ +#ifndef PEX64_FLAG_NHANDLER +/* We can't include here coff/pe.h header. So we have to copy macros + from coff/pe.h here. */ +#define PEX64_UNWCODE_CODE(VAL) ((VAL) & 0xf) +#define PEX64_UNWCODE_INFO(VAL) (((VAL) >> 4) & 0xf) + +/* The unwind info. */ +#define UNW_FLAG_NHANDLER 0 +#define UNW_FLAG_EHANDLER 1 +#define UNW_FLAG_UHANDLER 2 +#define UNW_FLAG_FHANDLER 3 +#define UNW_FLAG_CHAININFO 4 + +#define UNW_FLAG_MASK 0x1f + +/* The unwind codes. */ +#define UWOP_PUSH_NONVOL 0 +#define UWOP_ALLOC_LARGE 1 +#define UWOP_ALLOC_SMALL 2 +#define UWOP_SET_FPREG 3 +#define UWOP_SAVE_NONVOL 4 +#define UWOP_SAVE_NONVOL_FAR 5 +#define UWOP_SAVE_XMM 6 +#define UWOP_SAVE_XMM_FAR 7 +#define UWOP_SAVE_XMM128 8 +#define UWOP_SAVE_XMM128_FAR 9 +#define UWOP_PUSH_MACHFRAME 10 + +#define PEX64_UWI_VERSION(VAL) ((VAL) & 7) +#define PEX64_UWI_FLAGS(VAL) (((VAL) >> 3) & 0x1f) +#define PEX64_UWI_FRAMEREG(VAL) ((VAL) & 0xf) +#define PEX64_UWI_FRAMEOFF(VAL) (((VAL) >> 4) & 0xf) +#define PEX64_UWI_SIZEOF_UWCODE_ARRAY(VAL) \ + ((((VAL) + 1) & ~1) * 2) + +#define PEX64_OFFSET_TO_UNWIND_CODE 0x4 + +#define PEX64_OFFSET_TO_HANDLER_RVA (COUNTOFUNWINDCODES) \ + (PEX64_OFFSET_TO_UNWIND_CODE + \ + PEX64_UWI_SIZEOF_UWCODE_ARRAY(COUNTOFUNWINDCODES)) + +#define PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) \ + (PEX64_OFFSET_TO_HANDLER_RVA(COUNTOFUNWINDCODES) + 4) + +#define PEX64_SCOPE_ENTRY(COUNTOFUNWINDCODES, IDX) \ + (PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) + \ + PEX64_SCOPE_ENTRY_SIZE * (IDX)) + +#endif + diff --git a/contrib/toolchain/binutils/gas/config/obj-coff.c b/contrib/toolchain/binutils/gas/config/obj-coff.c new file mode 100644 index 0000000000..dbe2f079e8 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/obj-coff.c @@ -0,0 +1,1957 @@ +/* coff object file format + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 + Free Software Foundation, Inc. + + This file is part of GAS. + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#define OBJ_HEADER "obj-coff.h" + +#include "as.h" +#include "safe-ctype.h" +#include "obstack.h" +#include "subsegs.h" +#include "struc-symbol.h" + +#ifdef TE_PE +#include "coff/pe.h" +#endif + +#ifdef OBJ_XCOFF +#include "coff/xcoff.h" +#endif + +#define streq(a,b) (strcmp ((a), (b)) == 0) +#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) + +/* I think this is probably always correct. */ +#ifndef KEEP_RELOC_INFO +#define KEEP_RELOC_INFO +#endif + +/* obj_coff_section will use this macro to set a new section's + attributes when a directive has no valid flags or the "w" flag is + used. This default should be appropriate for most. */ +#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES +#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA) +#endif + +/* This is used to hold the symbol built by a sequence of pseudo-ops + from .def and .endef. */ +static symbolS *def_symbol_in_progress; +#ifdef TE_PE +/* PE weak alternate symbols begin with this string. */ +static const char weak_altprefix[] = ".weak."; +#endif /* TE_PE */ + +#include "obj-coff-seh.c" + +typedef struct + { + unsigned long chunk_size; + unsigned long element_size; + unsigned long size; + char *data; + unsigned long pointer; + } +stack; + + +/* Stack stuff. */ + +static stack * +stack_init (unsigned long chunk_size, + unsigned long element_size) +{ + stack *st; + + st = malloc (sizeof (* st)); + if (!st) + return NULL; + st->data = malloc (chunk_size); + if (!st->data) + { + free (st); + return NULL; + } + st->pointer = 0; + st->size = chunk_size; + st->chunk_size = chunk_size; + st->element_size = element_size; + return st; +} + +static char * +stack_push (stack *st, char *element) +{ + if (st->pointer + st->element_size >= st->size) + { + st->size += st->chunk_size; + if ((st->data = xrealloc (st->data, st->size)) == NULL) + return NULL; + } + memcpy (st->data + st->pointer, element, st->element_size); + st->pointer += st->element_size; + return st->data + st->pointer; +} + +static char * +stack_pop (stack *st) +{ + if (st->pointer < st->element_size) + { + st->pointer = 0; + return NULL; + } + st->pointer -= st->element_size; + return st->data + st->pointer; +} + +/* Maintain a list of the tagnames of the structures. */ + +static struct hash_control *tag_hash; + +static void +tag_init (void) +{ + tag_hash = hash_new (); +} + +static void +tag_insert (const char *name, symbolS *symbolP) +{ + const char *error_string; + + if ((error_string = hash_jam (tag_hash, name, (char *) symbolP))) + as_fatal (_("Inserting \"%s\" into structure table failed: %s"), + name, error_string); +} + +static symbolS * +tag_find (char *name) +{ + return (symbolS *) hash_find (tag_hash, name); +} + +static symbolS * +tag_find_or_make (char *name) +{ + symbolS *symbolP; + + if ((symbolP = tag_find (name)) == NULL) + { + symbolP = symbol_new (name, undefined_section, + 0, &zero_address_frag); + + tag_insert (S_GET_NAME (symbolP), symbolP); + symbol_table_insert (symbolP); + } + + return symbolP; +} + +/* We accept the .bss directive to set the section for backward + compatibility with earlier versions of gas. */ + +static void +obj_coff_bss (int ignore ATTRIBUTE_UNUSED) +{ + if (*input_line_pointer == '\n') + subseg_new (".bss", get_absolute_expression ()); + else + s_lcomm (0); +} + +#ifdef TE_PE +/* Called from read.c:s_comm after we've parsed .comm symbol, size. + Parse a possible alignment value. */ + +static symbolS * +obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) +{ + addressT align = 0; + + if (*input_line_pointer == ',') + { + align = parse_align (0); + if (align == (addressT) -1) + return NULL; + } + + S_SET_VALUE (symbolP, size); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, bfd_com_section_ptr); + + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; + + /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE. + Instead we must add a note to the .drectve section. */ + if (align) + { + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + flagword oldflags; + asection *sec; + size_t pfxlen, numlen; + char *frag; + char numbuff[20]; + + sec = subseg_new (".drectve", 0); + oldflags = bfd_get_section_flags (stdoutput, sec); + if (oldflags == SEC_NO_FLAGS) + { + if (!bfd_set_section_flags (stdoutput, sec, + TC_COFF_SECTION_DEFAULT_ATTRIBUTES)) + as_warn (_("error setting flags for \"%s\": %s"), + bfd_section_name (stdoutput, sec), + bfd_errmsg (bfd_get_error ())); + } + + /* Emit a string. Note no NUL-termination. */ + pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1; + numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align); + frag = frag_more (pfxlen + numlen); + (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP)); + memcpy (frag + pfxlen, numbuff, numlen); + /* Restore original subseg. */ + subseg_set (current_seg, current_subseg); + } + + return symbolP; +} + +static void +obj_coff_comm (int ignore ATTRIBUTE_UNUSED) +{ + s_comm_internal (ignore, obj_coff_common_parse); +} +#endif /* TE_PE */ + +#define GET_FILENAME_STRING(X) \ + ((char *) (&((X)->sy_symbol.ost_auxent->x_file.x_n.x_offset))[1]) + +/* @@ Ick. */ +static segT +fetch_coff_debug_section (void) +{ + static segT debug_section; + + if (!debug_section) + { + const asymbol *s; + + s = bfd_make_debug_symbol (stdoutput, NULL, 0); + gas_assert (s != 0); + debug_section = s->section; + } + return debug_section; +} + +void +SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val) +{ + combined_entry_type *entry, *p; + + entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; + p = coffsymbol (symbol_get_bfdsym (val))->native; + entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p; + entry->fix_end = 1; +} + +static void +SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val) +{ + combined_entry_type *entry, *p; + + entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; + p = coffsymbol (symbol_get_bfdsym (val))->native; + entry->u.auxent.x_sym.x_tagndx.p = p; + entry->fix_tag = 1; +} + +static int +S_GET_DATA_TYPE (symbolS *sym) +{ + return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type; +} + +int +S_SET_DATA_TYPE (symbolS *sym, int val) +{ + coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val; + return val; +} + +int +S_GET_STORAGE_CLASS (symbolS *sym) +{ + return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass; +} + +int +S_SET_STORAGE_CLASS (symbolS *sym, int val) +{ + coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val; + return val; +} + +/* Merge a debug symbol containing debug information into a normal symbol. */ + +static void +c_symbol_merge (symbolS *debug, symbolS *normal) +{ + S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug)); + S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); + + if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) + /* Take the most we have. */ + S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); + + if (S_GET_NUMBER_AUXILIARY (debug) > 0) + /* Move all the auxiliary information. */ + memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug), + (S_GET_NUMBER_AUXILIARY (debug) + * sizeof (*SYM_AUXINFO (debug)))); + + /* Move the debug flags. */ + SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); +} + +void +c_dot_file_symbol (const char *filename, int appfile ATTRIBUTE_UNUSED) +{ + symbolS *symbolP; + + /* BFD converts filename to a .file symbol with an aux entry. It + also handles chaining. */ + symbolP = symbol_new (filename, bfd_abs_section_ptr, 0, &zero_address_frag); + + S_SET_STORAGE_CLASS (symbolP, C_FILE); + S_SET_NUMBER_AUXILIARY (symbolP, 1); + + symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING; + +#ifndef NO_LISTING + { + extern int listing; + + if (listing) + listing_source_file (filename); + } +#endif + + /* Make sure that the symbol is first on the symbol chain. */ + if (symbol_rootP != symbolP) + { + symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); + symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); + } +} + +/* Line number handling. */ + +struct line_no +{ + struct line_no *next; + fragS *frag; + alent l; +}; + +int coff_line_base; + +/* Symbol of last function, which we should hang line#s off of. */ +static symbolS *line_fsym; + +#define in_function() (line_fsym != 0) +#define clear_function() (line_fsym = 0) +#define set_function(F) (line_fsym = (F), coff_add_linesym (F)) + + +void +coff_obj_symbol_new_hook (symbolS *symbolP) +{ + long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); + char * s = xmalloc (sz); + + memset (s, 0, sz); + coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s; + + S_SET_DATA_TYPE (symbolP, T_NULL); + S_SET_STORAGE_CLASS (symbolP, 0); + S_SET_NUMBER_AUXILIARY (symbolP, 0); + + if (S_IS_STRING (symbolP)) + SF_SET_STRING (symbolP); + + if (S_IS_LOCAL (symbolP)) + SF_SET_LOCAL (symbolP); +} + +void +coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP) +{ + long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); + combined_entry_type * s = xmalloc (sz); + + memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz); + coffsymbol (symbol_get_bfdsym (newsymP))->native = s; + + SF_SET (newsymP, SF_GET (orgsymP)); +} + + +/* Handle .ln directives. */ + +static symbolS *current_lineno_sym; +static struct line_no *line_nos; +/* FIXME: Blindly assume all .ln directives will be in the .text section. */ +int coff_n_line_nos; + +static void +add_lineno (fragS * frag, addressT offset, int num) +{ + struct line_no * new_line = xmalloc (sizeof (* new_line)); + + if (!current_lineno_sym) + abort (); + +#ifndef OBJ_XCOFF + /* The native aix assembler accepts negative line number. */ + + if (num <= 0) + { + /* Zero is used as an end marker in the file. */ + as_warn (_("Line numbers must be positive integers\n")); + num = 1; + } +#endif /* OBJ_XCOFF */ + new_line->next = line_nos; + new_line->frag = frag; + new_line->l.line_number = num; + new_line->l.u.offset = offset; + line_nos = new_line; + coff_n_line_nos++; +} + +void +coff_add_linesym (symbolS *sym) +{ + if (line_nos) + { + coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno = + (alent *) line_nos; + coff_n_line_nos++; + line_nos = 0; + } + current_lineno_sym = sym; +} + +static void +obj_coff_ln (int appline) +{ + int l; + + if (! appline && def_symbol_in_progress != NULL) + { + as_warn (_(".ln pseudo-op inside .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } + + l = get_absolute_expression (); + + /* If there is no lineno symbol, treat a .ln + directive as if it were a .appline directive. */ + if (appline || current_lineno_sym == NULL) + new_logical_line ((char *) NULL, l - 1); + else + add_lineno (frag_now, frag_now_fix (), l); + +#ifndef NO_LISTING + { + extern int listing; + + if (listing) + { + if (! appline) + l += coff_line_base - 1; + listing_source_line (l); + } + } +#endif + + demand_empty_rest_of_line (); +} + +/* .loc is essentially the same as .ln; parse it for assembler + compatibility. */ + +static void +obj_coff_loc (int ignore ATTRIBUTE_UNUSED) +{ + int lineno; + + /* FIXME: Why do we need this check? We need it for ECOFF, but why + do we need it for COFF? */ + if (now_seg != text_section) + { + as_warn (_(".loc outside of .text")); + demand_empty_rest_of_line (); + return; + } + + if (def_symbol_in_progress != NULL) + { + as_warn (_(".loc pseudo-op inside .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } + + /* Skip the file number. */ + SKIP_WHITESPACE (); + get_absolute_expression (); + SKIP_WHITESPACE (); + + lineno = get_absolute_expression (); + +#ifndef NO_LISTING + { + extern int listing; + + if (listing) + { + lineno += coff_line_base - 1; + listing_source_line (lineno); + } + } +#endif + + demand_empty_rest_of_line (); + + add_lineno (frag_now, frag_now_fix (), lineno); +} + +/* Handle the .ident pseudo-op. */ + +static void +obj_coff_ident (int ignore ATTRIBUTE_UNUSED) +{ + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + +#ifdef TE_PE + { + segT sec; + + /* We could put it in .comment, but that creates an extra section + that shouldn't be loaded into memory, which requires linker + changes... For now, until proven otherwise, use .rdata. */ + sec = subseg_new (".rdata$zzz", 0); + bfd_set_section_flags (stdoutput, sec, + ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA) + & bfd_applicable_section_flags (stdoutput))); + } +#else + subseg_new (".comment", 0); +#endif + + stringer (8 + 1); + subseg_set (current_seg, current_subseg); +} + +/* Handle .def directives. + + One might ask : why can't we symbol_new if the symbol does not + already exist and fill it with debug information. Because of + the C_EFCN special symbol. It would clobber the value of the + function symbol before we have a chance to notice that it is + a C_EFCN. And a second reason is that the code is more clear this + way. (at least I think it is :-). */ + +#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') +#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ + *input_line_pointer == '\t') \ + input_line_pointer++; + +static void +obj_coff_def (int what ATTRIBUTE_UNUSED) +{ + char name_end; /* Char after the end of name. */ + char *symbol_name; /* Name of the debug symbol. */ + char *symbol_name_copy; /* Temporary copy of the name. */ + unsigned int symbol_name_length; + + if (def_symbol_in_progress != NULL) + { + as_warn (_(".def pseudo-op used inside of .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } + + SKIP_WHITESPACES (); + + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + symbol_name_length = strlen (symbol_name); + symbol_name_copy = xmalloc (symbol_name_length + 1); + strcpy (symbol_name_copy, symbol_name); +#ifdef tc_canonicalize_symbol_name + symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy); +#endif + + /* Initialize the new symbol. */ + def_symbol_in_progress = symbol_make (symbol_name_copy); + symbol_set_frag (def_symbol_in_progress, &zero_address_frag); + S_SET_VALUE (def_symbol_in_progress, 0); + + if (S_IS_STRING (def_symbol_in_progress)) + SF_SET_STRING (def_symbol_in_progress); + + *input_line_pointer = name_end; + + demand_empty_rest_of_line (); +} + +static void +obj_coff_endef (int ignore ATTRIBUTE_UNUSED) +{ + symbolS *symbolP = NULL; + + if (def_symbol_in_progress == NULL) + { + as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } + + /* Set the section number according to storage class. */ + switch (S_GET_STORAGE_CLASS (def_symbol_in_progress)) + { + case C_STRTAG: + case C_ENTAG: + case C_UNTAG: + SF_SET_TAG (def_symbol_in_progress); + /* Fall through. */ + case C_FILE: + case C_TPDEF: + SF_SET_DEBUG (def_symbol_in_progress); + S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ()); + break; + + case C_EFCN: + SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */ + /* Fall through. */ + case C_BLOCK: + SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */ + /* Fall through. */ + case C_FCN: + { + const char *name; + + S_SET_SEGMENT (def_symbol_in_progress, text_section); + + name = S_GET_NAME (def_symbol_in_progress); + if (name[0] == '.' && name[2] == 'f' && name[3] == '\0') + { + switch (name[1]) + { + case 'b': + /* .bf */ + if (! in_function ()) + as_warn (_("`%s' symbol without preceding function"), name); + /* Will need relocating. */ + SF_SET_PROCESS (def_symbol_in_progress); + clear_function (); + break; +#ifdef TE_PE + case 'e': + /* .ef */ + /* The MS compilers output the actual endline, not the + function-relative one... we want to match without + changing the assembler input. */ + SA_SET_SYM_LNNO (def_symbol_in_progress, + (SA_GET_SYM_LNNO (def_symbol_in_progress) + + coff_line_base)); + break; +#endif + } + } + } + break; + +#ifdef C_AUTOARG + case C_AUTOARG: +#endif /* C_AUTOARG */ + case C_AUTO: + case C_REG: + case C_ARG: + case C_REGPARM: + case C_FIELD: + + /* According to the COFF documentation: + + http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html + + A special section number (-2) marks symbolic debugging symbols, + including structure/union/enumeration tag names, typedefs, and + the name of the file. A section number of -1 indicates that the + symbol has a value but is not relocatable. Examples of + absolute-valued symbols include automatic and register variables, + function arguments, and .eos symbols. + + But from Ian Lance Taylor: + + http://sources.redhat.com/ml/binutils/2000-08/msg00202.html + + the actual tools all marked them as section -1. So the GNU COFF + assembler follows historical COFF assemblers. + + However, it causes problems for djgpp + + http://sources.redhat.com/ml/binutils/2000-08/msg00210.html + + By defining STRICTCOFF, a COFF port can make the assembler to + follow the documented behavior. */ +#ifdef STRICTCOFF + case C_MOS: + case C_MOE: + case C_MOU: + case C_EOS: +#endif + SF_SET_DEBUG (def_symbol_in_progress); + S_SET_SEGMENT (def_symbol_in_progress, absolute_section); + break; + +#ifndef STRICTCOFF + case C_MOS: + case C_MOE: + case C_MOU: + case C_EOS: + S_SET_SEGMENT (def_symbol_in_progress, absolute_section); + break; +#endif + + case C_EXT: + case C_WEAKEXT: +#ifdef TE_PE + case C_NT_WEAK: +#endif + case C_STAT: + case C_LABEL: + /* Valid but set somewhere else (s_comm, s_lcomm, colon). */ + break; + + default: + case C_USTATIC: + case C_EXTDEF: + case C_ULABEL: + as_warn (_("unexpected storage class %d"), + S_GET_STORAGE_CLASS (def_symbol_in_progress)); + break; + } + + /* Now that we have built a debug symbol, try to find if we should + merge with an existing symbol or not. If a symbol is C_EFCN or + absolute_section or untagged SEG_DEBUG it never merges. We also + don't merge labels, which are in a different namespace, nor + symbols which have not yet been defined since they are typically + unique, nor do we merge tags with non-tags. */ + + /* Two cases for functions. Either debug followed by definition or + definition followed by debug. For definition first, we will + merge the debug symbol into the definition. For debug first, the + lineno entry MUST point to the definition function or else it + will point off into space when obj_crawl_symbol_chain() merges + the debug symbol into the real symbol. Therefor, let's presume + the debug symbol is a real function reference. */ + + /* FIXME-SOON If for some reason the definition label/symbol is + never seen, this will probably leave an undefined symbol at link + time. */ + + if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN + || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL + || (streq (bfd_get_section_name (stdoutput, + S_GET_SEGMENT (def_symbol_in_progress)), + "*DEBUG*") + && !SF_GET_TAG (def_symbol_in_progress)) + || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section + || ! symbol_constant_p (def_symbol_in_progress) + || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL + || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)) + { + /* If it already is at the end of the symbol list, do nothing */ + if (def_symbol_in_progress != symbol_lastP) + { + symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); + symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, + &symbol_lastP); + } + } + else + { + /* This symbol already exists, merge the newly created symbol + into the old one. This is not mandatory. The linker can + handle duplicate symbols correctly. But I guess that it save + a *lot* of space if the assembly file defines a lot of + symbols. [loic] */ + + /* The debug entry (def_symbol_in_progress) is merged into the + previous definition. */ + + c_symbol_merge (def_symbol_in_progress, symbolP); + symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); + + def_symbol_in_progress = symbolP; + + if (SF_GET_FUNCTION (def_symbol_in_progress) + || SF_GET_TAG (def_symbol_in_progress) + || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT) + { + /* For functions, and tags, and static symbols, the symbol + *must* be where the debug symbol appears. Move the + existing symbol to the current place. */ + /* If it already is at the end of the symbol list, do nothing. */ + if (def_symbol_in_progress != symbol_lastP) + { + symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); + symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); + } + } + } + + if (SF_GET_TAG (def_symbol_in_progress)) + { + symbolS *oldtag; + + oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress)); + if (oldtag == NULL || ! SF_GET_TAG (oldtag)) + tag_insert (S_GET_NAME (def_symbol_in_progress), + def_symbol_in_progress); + } + + if (SF_GET_FUNCTION (def_symbol_in_progress)) + { + set_function (def_symbol_in_progress); + SF_SET_PROCESS (def_symbol_in_progress); + + if (symbolP == NULL) + /* That is, if this is the first time we've seen the + function. */ + symbol_table_insert (def_symbol_in_progress); + + } + + def_symbol_in_progress = NULL; + demand_empty_rest_of_line (); +} + +static void +obj_coff_dim (int ignore ATTRIBUTE_UNUSED) +{ + int d_index; + + if (def_symbol_in_progress == NULL) + { + as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored.")); + demand_empty_rest_of_line (); + return; + } + + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); + + for (d_index = 0; d_index < DIMNUM; d_index++) + { + SKIP_WHITESPACES (); + SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index, + get_absolute_expression ()); + + switch (*input_line_pointer) + { + case ',': + input_line_pointer++; + break; + + default: + as_warn (_("badly formed .dim directive ignored")); + /* Fall through. */ + case '\n': + case ';': + d_index = DIMNUM; + break; + } + } + + demand_empty_rest_of_line (); +} + +static void +obj_coff_line (int ignore ATTRIBUTE_UNUSED) +{ + int this_base; + + if (def_symbol_in_progress == NULL) + { + /* Probably stabs-style line? */ + obj_coff_ln (0); + return; + } + + this_base = get_absolute_expression (); + if (streq (".bf", S_GET_NAME (def_symbol_in_progress))) + coff_line_base = this_base; + + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); + SA_SET_SYM_LNNO (def_symbol_in_progress, this_base); + + demand_empty_rest_of_line (); + +#ifndef NO_LISTING + if (streq (".bf", S_GET_NAME (def_symbol_in_progress))) + { + extern int listing; + + if (listing) + listing_source_line ((unsigned int) this_base); + } +#endif +} + +static void +obj_coff_size (int ignore ATTRIBUTE_UNUSED) +{ + if (def_symbol_in_progress == NULL) + { + as_warn (_(".size pseudo-op used outside of .def/.endef ignored.")); + demand_empty_rest_of_line (); + return; + } + + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); + SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); + demand_empty_rest_of_line (); +} + +static void +obj_coff_scl (int ignore ATTRIBUTE_UNUSED) +{ + if (def_symbol_in_progress == NULL) + { + as_warn (_(".scl pseudo-op used outside of .def/.endef ignored.")); + demand_empty_rest_of_line (); + return; + } + + S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); + demand_empty_rest_of_line (); +} + +static void +obj_coff_tag (int ignore ATTRIBUTE_UNUSED) +{ + char *symbol_name; + char name_end; + + if (def_symbol_in_progress == NULL) + { + as_warn (_(".tag pseudo-op used outside of .def/.endef ignored.")); + demand_empty_rest_of_line (); + return; + } + + S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); + symbol_name = input_line_pointer; + name_end = get_symbol_end (); + +#ifdef tc_canonicalize_symbol_name + symbol_name = tc_canonicalize_symbol_name (symbol_name); +#endif + + /* Assume that the symbol referred to by .tag is always defined. + This was a bad assumption. I've added find_or_make. xoxorich. */ + SA_SET_SYM_TAGNDX (def_symbol_in_progress, + tag_find_or_make (symbol_name)); + if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) + as_warn (_("tag not found for .tag %s"), symbol_name); + + SF_SET_TAGGED (def_symbol_in_progress); + *input_line_pointer = name_end; + + demand_empty_rest_of_line (); +} + +static void +obj_coff_type (int ignore ATTRIBUTE_UNUSED) +{ + if (def_symbol_in_progress == NULL) + { + as_warn (_(".type pseudo-op used outside of .def/.endef ignored.")); + demand_empty_rest_of_line (); + return; + } + + S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ()); + + if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) && + S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF) + SF_SET_FUNCTION (def_symbol_in_progress); + + demand_empty_rest_of_line (); +} + +static void +obj_coff_val (int ignore ATTRIBUTE_UNUSED) +{ + if (def_symbol_in_progress == NULL) + { + as_warn (_(".val pseudo-op used outside of .def/.endef ignored.")); + demand_empty_rest_of_line (); + return; + } + + if (is_name_beginner (*input_line_pointer)) + { + char *symbol_name = input_line_pointer; + char name_end = get_symbol_end (); + +#ifdef tc_canonicalize_symbol_name + symbol_name = tc_canonicalize_symbol_name (symbol_name); +#endif + if (streq (symbol_name, ".")) + { + /* If the .val is != from the .def (e.g. statics). */ + symbol_set_frag (def_symbol_in_progress, frag_now); + S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ()); + } + else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name)) + { + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = symbol_find_or_make (symbol_name); + exp.X_op_symbol = NULL; + exp.X_add_number = 0; + symbol_set_value_expression (def_symbol_in_progress, &exp); + + /* If the segment is undefined when the forward reference is + resolved, then copy the segment id from the forward + symbol. */ + SF_SET_GET_SEGMENT (def_symbol_in_progress); + + /* FIXME: gcc can generate address expressions here in + unusual cases (search for "obscure" in sdbout.c). We + just ignore the offset here, thus generating incorrect + debugging information. We ignore the rest of the line + just below. */ + } + /* Otherwise, it is the name of a non debug symbol and its value + will be calculated later. */ + *input_line_pointer = name_end; + } + else + { + S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ()); + } + + demand_empty_rest_of_line (); +} + +#ifdef TE_PE + +/* Return nonzero if name begins with weak alternate symbol prefix. */ + +static int +weak_is_altname (const char * name) +{ + return strneq (name, weak_altprefix, sizeof (weak_altprefix) - 1); +} + +/* Return the name of the alternate symbol + name corresponding to a weak symbol's name. */ + +static const char * +weak_name2altname (const char * name) +{ + char *alt_name; + + alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name)); + strcpy (alt_name, weak_altprefix); + return strcat (alt_name, name); +} + +/* Return the name of the weak symbol corresponding to an + alternate symbol. */ + +static const char * +weak_altname2name (const char * name) +{ + gas_assert (weak_is_altname (name)); + return xstrdup (name + 6); +} + +/* Make a weak symbol name unique by + appending the name of an external symbol. */ + +static const char * +weak_uniquify (const char * name) +{ + char *ret; + const char * unique = ""; + +#ifdef TE_PE + if (an_external_name != NULL) + unique = an_external_name; +#endif + gas_assert (weak_is_altname (name)); + + ret = xmalloc (strlen (name) + strlen (unique) + 2); + strcpy (ret, name); + strcat (ret, "."); + strcat (ret, unique); + return ret; +} + +void +pecoff_obj_set_weak_hook (symbolS *symbolP) +{ + symbolS *alternateP; + + /* See _Microsoft Portable Executable and Common Object + File Format Specification_, section 5.5.3. + Create a symbol representing the alternate value. + coff_frob_symbol will set the value of this symbol from + the value of the weak symbol itself. */ + S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); + S_SET_NUMBER_AUXILIARY (symbolP, 1); + SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY); + + alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP))); + S_SET_EXTERNAL (alternateP); + S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK); + + SA_SET_SYM_TAGNDX (symbolP, alternateP); +} + +void +pecoff_obj_clear_weak_hook (symbolS *symbolP) +{ + symbolS *alternateP; + + S_SET_STORAGE_CLASS (symbolP, 0); + SA_SET_SYM_FSIZE (symbolP, 0); + + alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP))); + S_CLEAR_EXTERNAL (alternateP); +} + +#endif /* TE_PE */ + +/* Handle .weak. This is a GNU extension in formats other than PE. */ + +static void +obj_coff_weak (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + int c; + symbolS *symbolP; + + do + { + name = input_line_pointer; + c = get_symbol_end (); + if (*name == 0) + { + as_warn (_("badly formed .weak directive ignored")); + ignore_rest_of_line (); + return; + } + c = 0; + symbolP = symbol_find_or_make (name); + *input_line_pointer = c; + SKIP_WHITESPACE (); + S_SET_WEAK (symbolP); + + if (c == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + if (*input_line_pointer == '\n') + c = '\n'; + } + + } + while (c == ','); + + demand_empty_rest_of_line (); +} + +void +coff_obj_read_begin_hook (void) +{ + /* These had better be the same. Usually 18 bytes. */ + know (sizeof (SYMENT) == sizeof (AUXENT)); + know (SYMESZ == AUXESZ); + tag_init (); +} + +symbolS *coff_last_function; +#ifndef OBJ_XCOFF +static symbolS *coff_last_bf; +#endif + +void +coff_frob_symbol (symbolS *symp, int *punt) +{ + static symbolS *last_tagP; + static stack *block_stack; + static symbolS *set_end; + symbolS *next_set_end = NULL; + + if (symp == &abs_symbol) + { + *punt = 1; + return; + } + + if (current_lineno_sym) + coff_add_linesym (NULL); + + if (!block_stack) + block_stack = stack_init (512, sizeof (symbolS*)); + +#ifdef TE_PE + if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK + && ! S_IS_WEAK (symp) + && weak_is_altname (S_GET_NAME (symp))) + { + /* This is a weak alternate symbol. All processing of + PECOFFweak symbols is done here, through the alternate. */ + symbolS *weakp = symbol_find_noref (weak_altname2name + (S_GET_NAME (symp)), 1); + + gas_assert (weakp); + gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1); + + if (! S_IS_WEAK (weakp)) + { + /* The symbol was turned from weak to strong. Discard altname. */ + *punt = 1; + return; + } + else if (symbol_equated_p (weakp)) + { + /* The weak symbol has an alternate specified; symp is unneeded. */ + S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); + SA_SET_SYM_TAGNDX (weakp, + symbol_get_value_expression (weakp)->X_add_symbol); + + S_CLEAR_EXTERNAL (symp); + *punt = 1; + return; + } + else + { + /* The weak symbol has been assigned an alternate value. + Copy this value to symp, and set symp as weakp's alternate. */ + if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK) + { + S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp)); + S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); + } + + if (S_IS_DEFINED (weakp)) + { + /* This is a defined weak symbol. Copy value information + from the weak symbol itself to the alternate symbol. */ + symbol_set_value_expression (symp, + symbol_get_value_expression (weakp)); + symbol_set_frag (symp, symbol_get_frag (weakp)); + S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp)); + } + else + { + /* This is an undefined weak symbol. + Define the alternate symbol to zero. */ + S_SET_VALUE (symp, 0); + S_SET_SEGMENT (symp, absolute_section); + } + + S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp))); + S_SET_STORAGE_CLASS (symp, C_EXT); + + S_SET_VALUE (weakp, 0); + S_SET_SEGMENT (weakp, undefined_section); + } + } +#else /* TE_PE */ + if (S_IS_WEAK (symp)) + S_SET_STORAGE_CLASS (symp, C_WEAKEXT); +#endif /* TE_PE */ + + if (!S_IS_DEFINED (symp) + && !S_IS_WEAK (symp) + && S_GET_STORAGE_CLASS (symp) != C_STAT) + S_SET_STORAGE_CLASS (symp, C_EXT); + + if (!SF_GET_DEBUG (symp)) + { + symbolS * real; + + if (!SF_GET_LOCAL (symp) + && !SF_GET_STATICS (symp) + && S_GET_STORAGE_CLASS (symp) != C_LABEL + && symbol_constant_p (symp) + && (real = symbol_find_noref (S_GET_NAME (symp), 1)) + && S_GET_STORAGE_CLASS (real) == C_NULL + && real != symp) + { + c_symbol_merge (symp, real); + *punt = 1; + return; + } + + if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp)) + { + gas_assert (S_GET_VALUE (symp) == 0); + if (S_IS_WEAKREFD (symp)) + *punt = 1; + else + S_SET_EXTERNAL (symp); + } + else if (S_GET_STORAGE_CLASS (symp) == C_NULL) + { + if (S_GET_SEGMENT (symp) == text_section + && symp != seg_info (text_section)->sym) + S_SET_STORAGE_CLASS (symp, C_LABEL); + else + S_SET_STORAGE_CLASS (symp, C_STAT); + } + + if (SF_GET_PROCESS (symp)) + { + if (S_GET_STORAGE_CLASS (symp) == C_BLOCK) + { + if (streq (S_GET_NAME (symp), ".bb")) + stack_push (block_stack, (char *) &symp); + else + { + symbolS *begin; + + begin = *(symbolS **) stack_pop (block_stack); + if (begin == 0) + as_warn (_("mismatched .eb")); + else + next_set_end = begin; + } + } + + if (coff_last_function == 0 && SF_GET_FUNCTION (symp) + && S_IS_DEFINED (symp)) + { + union internal_auxent *auxp; + + coff_last_function = symp; + if (S_GET_NUMBER_AUXILIARY (symp) < 1) + S_SET_NUMBER_AUXILIARY (symp, 1); + auxp = SYM_AUXENT (symp); + memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0, + sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen)); + } + + if (S_GET_STORAGE_CLASS (symp) == C_EFCN + && S_IS_DEFINED (symp)) + { + if (coff_last_function == 0) + as_fatal (_("C_EFCN symbol for %s out of scope"), + S_GET_NAME (symp)); + SA_SET_SYM_FSIZE (coff_last_function, + (long) (S_GET_VALUE (symp) + - S_GET_VALUE (coff_last_function))); + next_set_end = coff_last_function; + coff_last_function = 0; + } + } + + if (S_IS_EXTERNAL (symp)) + S_SET_STORAGE_CLASS (symp, C_EXT); + else if (SF_GET_LOCAL (symp)) + *punt = 1; + + if (SF_GET_FUNCTION (symp)) + symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION; + } + + /* Double check weak symbols. */ + if (S_IS_WEAK (symp) && S_IS_COMMON (symp)) + as_bad (_("Symbol `%s' can not be both weak and common"), + S_GET_NAME (symp)); + + if (SF_GET_TAG (symp)) + last_tagP = symp; + else if (S_GET_STORAGE_CLASS (symp) == C_EOS) + next_set_end = last_tagP; + +#ifdef OBJ_XCOFF + /* This is pretty horrible, but we have to set *punt correctly in + order to call SA_SET_SYM_ENDNDX correctly. */ + if (! symbol_used_in_reloc_p (symp) + && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0 + || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp)) + && ! symbol_get_tc (symp)->output + && S_GET_STORAGE_CLASS (symp) != C_FILE))) + *punt = 1; +#endif + + if (set_end != (symbolS *) NULL + && ! *punt + && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0 + || (S_IS_DEFINED (symp) + && ! S_IS_COMMON (symp) + && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp))))) + { + SA_SET_SYM_ENDNDX (set_end, symp); + set_end = NULL; + } + + if (next_set_end != NULL) + { + if (set_end != NULL) + as_warn (_("Warning: internal error: forgetting to set endndx of %s"), + S_GET_NAME (set_end)); + set_end = next_set_end; + } + +#ifndef OBJ_XCOFF + if (! *punt + && S_GET_STORAGE_CLASS (symp) == C_FCN + && streq (S_GET_NAME (symp), ".bf")) + { + if (coff_last_bf != NULL) + SA_SET_SYM_ENDNDX (coff_last_bf, symp); + coff_last_bf = symp; + } +#endif + if (coffsymbol (symbol_get_bfdsym (symp))->lineno) + { + int i; + struct line_no *lptr; + alent *l; + + lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; + for (i = 0; lptr; lptr = lptr->next) + i++; + lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; + + /* We need i entries for line numbers, plus 1 for the first + entry which BFD will override, plus 1 for the last zero + entry (a marker for BFD). */ + l = xmalloc ((i + 2) * sizeof (* l)); + coffsymbol (symbol_get_bfdsym (symp))->lineno = l; + l[i + 1].line_number = 0; + l[i + 1].u.sym = NULL; + for (; i > 0; i--) + { + if (lptr->frag) + lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE; + l[i] = lptr->l; + lptr = lptr->next; + } + } +} + +void +coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void * x ATTRIBUTE_UNUSED) +{ + symbolS *secsym; + segment_info_type *seginfo = seg_info (sec); + int nlnno, nrelocs = 0; + + /* RS/6000 gas creates a .debug section manually in ppc_frob_file in + tc-ppc.c. Do not get confused by it. */ + if (seginfo == NULL) + return; + + if (streq (sec->name, ".text")) + nlnno = coff_n_line_nos; + else + nlnno = 0; + { + /* @@ Hope that none of the fixups expand to more than one reloc + entry... */ + fixS *fixp = seginfo->fix_root; + while (fixp) + { + if (! fixp->fx_done) + nrelocs++; + fixp = fixp->fx_next; + } + } + if (bfd_get_section_size (sec) == 0 + && nrelocs == 0 + && nlnno == 0 + && sec != text_section + && sec != data_section + && sec != bss_section) + return; + + secsym = section_symbol (sec); + /* This is an estimate; we'll plug in the real value using + SET_SECTION_RELOCS later */ + SA_SET_SCN_NRELOC (secsym, nrelocs); + SA_SET_SCN_NLINNO (secsym, nlnno); +} + +void +coff_frob_file_after_relocs (void) +{ + bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL); +} + +/* Implement the .section pseudo op: + .section name {, "flags"} + ^ ^ + | +--- optional flags: 'b' for bss + | 'i' for info + +-- section name 'l' for lib + 'n' for noload + 'o' for over + 'w' for data + 'd' (apparently m88k for data) + 'e' for exclude + 'x' for text + 'r' for read-only data + 's' for shared data (PE) + 'y' for noread + '0' - '9' for power-of-two alignment (GNU extension). + But if the argument is not a quoted string, treat it as a + subsegment number. + + Note the 'a' flag is silently ignored. This allows the same + .section directive to be parsed in both ELF and COFF formats. */ + +void +obj_coff_section (int ignore ATTRIBUTE_UNUSED) +{ + /* Strip out the section name. */ + char *section_name; + char c; + int alignment = -1; + char *name; + unsigned int exp; + flagword flags, oldflags; + asection *sec; + + if (flag_mri) + { + char type; + + s_mri_sect (&type); + return; + } + + section_name = input_line_pointer; + c = get_symbol_end (); + + name = xmalloc (input_line_pointer - section_name + 1); + strcpy (name, section_name); + + *input_line_pointer = c; + + SKIP_WHITESPACE (); + + exp = 0; + flags = SEC_NO_FLAGS; + + if (*input_line_pointer == ',') + { + ++input_line_pointer; + SKIP_WHITESPACE (); + if (*input_line_pointer != '"') + exp = get_absolute_expression (); + else + { + unsigned char attr; + int readonly_removed = 0; + int load_removed = 0; + + while (attr = *++input_line_pointer, + attr != '"' + && ! is_end_of_line[attr]) + { + if (ISDIGIT (attr)) + { + alignment = attr - '0'; + continue; + } + switch (attr) + { + case 'e': + /* Exclude section from linking. */ + flags |= SEC_EXCLUDE; + break; + + case 'b': + /* Uninitialised data section. */ + flags |= SEC_ALLOC; + flags &=~ SEC_LOAD; + break; + + case 'n': + /* Section not loaded. */ + flags &=~ SEC_LOAD; + flags |= SEC_NEVER_LOAD; + load_removed = 1; + break; + + case 's': + /* Shared section. */ + flags |= SEC_COFF_SHARED; + /* Fall through. */ + case 'd': + /* Data section. */ + flags |= SEC_DATA; + if (! load_removed) + flags |= SEC_LOAD; + flags &=~ SEC_READONLY; + break; + + case 'w': + /* Writable section. */ + flags &=~ SEC_READONLY; + readonly_removed = 1; + break; + + case 'a': + /* Ignore. Here for compatibility with ELF. */ + break; + + case 'r': /* Read-only section. Implies a data section. */ + readonly_removed = 0; + /* Fall through. */ + case 'x': /* Executable section. */ + /* If we are setting the 'x' attribute or if the 'r' + attribute is being used to restore the readonly status + of a code section (eg "wxr") then set the SEC_CODE flag, + otherwise set the SEC_DATA flag. */ + flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA); + if (! load_removed) + flags |= SEC_LOAD; + /* Note - the READONLY flag is set here, even for the 'x' + attribute in order to be compatible with the MSVC + linker. */ + if (! readonly_removed) + flags |= SEC_READONLY; + break; + + case 'y': + flags |= SEC_COFF_NOREAD | SEC_READONLY; + break; + + case 'i': /* STYP_INFO */ + case 'l': /* STYP_LIB */ + case 'o': /* STYP_OVER */ + as_warn (_("unsupported section attribute '%c'"), attr); + break; + + default: + as_warn (_("unknown section attribute '%c'"), attr); + break; + } + } + if (attr == '"') + ++input_line_pointer; + } + } + + sec = subseg_new (name, (subsegT) exp); + + if (alignment >= 0) + sec->alignment_power = alignment; + + oldflags = bfd_get_section_flags (stdoutput, sec); + if (oldflags == SEC_NO_FLAGS) + { + /* Set section flags for a new section just created by subseg_new. + Provide a default if no flags were parsed. */ + if (flags == SEC_NO_FLAGS) + flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES; + +#ifdef COFF_LONG_SECTION_NAMES + /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce + sections so adjust_reloc_syms in write.c will correctly handle + relocs which refer to non-local symbols in these sections. */ + if (strneq (name, ".gnu.linkonce", sizeof (".gnu.linkonce") - 1)) + flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; +#endif + + if (! bfd_set_section_flags (stdoutput, sec, flags)) + as_warn (_("error setting flags for \"%s\": %s"), + bfd_section_name (stdoutput, sec), + bfd_errmsg (bfd_get_error ())); + } + else if (flags != SEC_NO_FLAGS) + { + /* This section's attributes have already been set. Warn if the + attributes don't match. */ + flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE + | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD + | SEC_COFF_NOREAD); + if ((flags ^ oldflags) & matchflags) + as_warn (_("Ignoring changed section attributes for %s"), name); + } + + demand_empty_rest_of_line (); +} + +void +coff_adjust_symtab (void) +{ + if (symbol_rootP == NULL + || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) + c_dot_file_symbol ("fake", 0); +} + +void +coff_frob_section (segT sec) +{ + segT strsec; + char *p; + fragS *fragp; + bfd_vma n_entries; + + /* The COFF back end in BFD requires that all section sizes be + rounded up to multiples of the corresponding section alignments, + supposedly because standard COFF has no other way of encoding alignment + for sections. If your COFF flavor has a different way of encoding + section alignment, then skip this step, as TICOFF does. */ + bfd_vma size = bfd_get_section_size (sec); +#if !defined(TICOFF) + bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER; + bfd_vma mask = ((bfd_vma) 1 << align_power) - 1; + + if (size & mask) + { + bfd_vma new_size; + fragS *last; + + new_size = (size + mask) & ~mask; + bfd_set_section_size (stdoutput, sec, new_size); + + /* If the size had to be rounded up, add some padding in + the last non-empty frag. */ + fragp = seg_info (sec)->frchainP->frch_root; + last = seg_info (sec)->frchainP->frch_last; + while (fragp->fr_next != last) + fragp = fragp->fr_next; + last->fr_address = size; + fragp->fr_offset += new_size - size; + } +#endif + + /* If the section size is non-zero, the section symbol needs an aux + entry associated with it, indicating the size. We don't know + all the values yet; coff_frob_symbol will fill them in later. */ +#ifndef TICOFF + if (size != 0 + || sec == text_section + || sec == data_section + || sec == bss_section) +#endif + { + symbolS *secsym = section_symbol (sec); + unsigned char sclass = C_STAT; + +#ifdef OBJ_XCOFF + if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING) + sclass = C_DWARF; +#endif + S_SET_STORAGE_CLASS (secsym, sclass); + S_SET_NUMBER_AUXILIARY (secsym, 1); + SF_SET_STATICS (secsym); + SA_SET_SCN_SCNLEN (secsym, size); + } + /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */ +#ifndef STAB_SECTION_NAME +#define STAB_SECTION_NAME ".stab" +#endif +#ifndef STAB_STRING_SECTION_NAME +#define STAB_STRING_SECTION_NAME ".stabstr" +#endif + if (! streq (STAB_STRING_SECTION_NAME, sec->name)) + return; + + strsec = sec; + sec = subseg_get (STAB_SECTION_NAME, 0); + /* size is already rounded up, since other section will be listed first */ + size = bfd_get_section_size (strsec); + + n_entries = bfd_get_section_size (sec) / 12 - 1; + + /* Find first non-empty frag. It should be large enough. */ + fragp = seg_info (sec)->frchainP->frch_root; + while (fragp && fragp->fr_fix == 0) + fragp = fragp->fr_next; + gas_assert (fragp != 0 && fragp->fr_fix >= 12); + + /* Store the values. */ + p = fragp->fr_literal; + bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6); + bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8); +} + +void +obj_coff_init_stab_section (segT seg) +{ + char *file; + char *p; + char *stabstr_name; + unsigned int stroff; + + /* Make space for this first symbol. */ + p = frag_more (12); + /* Zero it out. */ + memset (p, 0, 12); + as_where (&file, (unsigned int *) NULL); + stabstr_name = xmalloc (strlen (seg->name) + 4); + strcpy (stabstr_name, seg->name); + strcat (stabstr_name, "str"); + stroff = get_stab_string_offset (file, stabstr_name); + know (stroff == 1); + md_number_to_chars (p, stroff, 4); +} + +#ifdef DEBUG +const char * s_get_name (symbolS *); + +const char * +s_get_name (symbolS *s) +{ + return ((s == NULL) ? "(NULL)" : S_GET_NAME (s)); +} + +void symbol_dump (void); + +void +symbol_dump (void) +{ + symbolS *symbolP; + + for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) + printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"), + (unsigned long) symbolP, + S_GET_NAME (symbolP), + (long) S_GET_DATA_TYPE (symbolP), + S_GET_STORAGE_CLASS (symbolP), + (int) S_GET_SEGMENT (symbolP)); +} + +#endif /* DEBUG */ + +const pseudo_typeS coff_pseudo_table[] = +{ + {"ABORT", s_abort, 0}, + {"appline", obj_coff_ln, 1}, + /* We accept the .bss directive for backward compatibility with + earlier versions of gas. */ + {"bss", obj_coff_bss, 0}, +#ifdef TE_PE + /* PE provides an enhanced version of .comm with alignment. */ + {"comm", obj_coff_comm, 0}, +#endif /* TE_PE */ + {"def", obj_coff_def, 0}, + {"dim", obj_coff_dim, 0}, + {"endef", obj_coff_endef, 0}, + {"ident", obj_coff_ident, 0}, + {"line", obj_coff_line, 0}, + {"ln", obj_coff_ln, 0}, + {"scl", obj_coff_scl, 0}, + {"sect", obj_coff_section, 0}, + {"sect.s", obj_coff_section, 0}, + {"section", obj_coff_section, 0}, + {"section.s", obj_coff_section, 0}, + /* FIXME: We ignore the MRI short attribute. */ + {"size", obj_coff_size, 0}, + {"tag", obj_coff_tag, 0}, + {"type", obj_coff_type, 0}, + {"val", obj_coff_val, 0}, + {"version", s_ignore, 0}, + {"loc", obj_coff_loc, 0}, + {"optim", s_ignore, 0}, /* For sun386i cc (?) */ + {"weak", obj_coff_weak, 0}, +#if defined TC_TIC4X + /* The tic4x uses sdef instead of def. */ + {"sdef", obj_coff_def, 0}, +#endif +#if defined(SEH_CMDS) + SEH_CMDS +#endif + {NULL, NULL, 0} +}; + + +/* Support for a COFF emulation. */ + +static void +coff_pop_insert (void) +{ + pop_insert (coff_pseudo_table); +} + +static int +coff_separate_stab_sections (void) +{ + return 1; +} + +const struct format_ops coff_format_ops = +{ + bfd_target_coff_flavour, + 0, /* dfl_leading_underscore */ + 1, /* emit_section_symbols */ + 0, /* begin */ + c_dot_file_symbol, + coff_frob_symbol, + 0, /* frob_file */ + 0, /* frob_file_before_adjust */ + 0, /* frob_file_before_fix */ + coff_frob_file_after_relocs, + 0, /* s_get_size */ + 0, /* s_set_size */ + 0, /* s_get_align */ + 0, /* s_set_align */ + 0, /* s_get_other */ + 0, /* s_set_other */ + 0, /* s_get_desc */ + 0, /* s_set_desc */ + 0, /* s_get_type */ + 0, /* s_set_type */ + 0, /* copy_symbol_attributes */ + 0, /* generate_asm_lineno */ + 0, /* process_stab */ + coff_separate_stab_sections, + obj_coff_init_stab_section, + 0, /* sec_sym_ok_for_reloc */ + coff_pop_insert, + 0, /* ecoff_set_ext */ + coff_obj_read_begin_hook, + coff_obj_symbol_new_hook, + coff_obj_symbol_clone_hook, + coff_adjust_symtab +}; diff --git a/contrib/toolchain/binutils/gas/config/obj-coff.h b/contrib/toolchain/binutils/gas/config/obj-coff.h new file mode 100644 index 0000000000..ff5548eab4 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/obj-coff.h @@ -0,0 +1,415 @@ +/* coff object file format + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 + Free Software Foundation, Inc. + + This file is part of GAS. + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef OBJ_FORMAT_H +#define OBJ_FORMAT_H + +#define OBJ_COFF 1 + +#include "targ-cpu.h" + +/* This internal_lineno crap is to stop namespace pollution from the + bfd internal coff headerfile. */ +#define internal_lineno bfd_internal_lineno +#include "coff/internal.h" +#undef internal_lineno + +/* CPU-specific setup: */ + +#ifdef TC_ARM +#include "coff/arm.h" +#ifndef TARGET_FORMAT +#define TARGET_FORMAT "coff-arm" +#endif +#endif + +#ifdef TC_PPC +#ifdef TE_PE +#include "coff/powerpc.h" +#else +#include "coff/rs6000.h" +#endif +#endif + +#ifdef TC_SPARC +#include "coff/sparc.h" +#endif + +#ifdef TC_I386 +#ifdef TE_PEP +#include "coff/x86_64.h" +#else +#include "coff/i386.h" +#endif + +#ifndef TARGET_FORMAT +#ifdef TE_PEP +#define TARGET_FORMAT "coff-x86-64" +#else +#define TARGET_FORMAT "coff-i386" +#endif +#endif +#endif + +#ifdef TC_M68K +#include "coff/m68k.h" +#ifndef TARGET_FORMAT +#define TARGET_FORMAT "coff-m68k" +#endif +#endif + +#ifdef TC_OR32 +#include "coff/or32.h" +#define TARGET_FORMAT "coff-or32-big" +#endif + +#ifdef TC_I960 +#include "coff/i960.h" +#define TARGET_FORMAT "coff-Intel-little" +#endif + +#ifdef TC_Z80 +#include "coff/z80.h" +#define TARGET_FORMAT "coff-z80" +#endif + +#ifdef TC_Z8K +#include "coff/z8k.h" +#define TARGET_FORMAT "coff-z8k" +#endif + +#ifdef TC_H8300 +#include "coff/h8300.h" +#define TARGET_FORMAT "coff-h8300" +#endif + +#ifdef TC_H8500 +#include "coff/h8500.h" +#define TARGET_FORMAT "coff-h8500" +#endif + +#ifdef TC_SH + +#ifdef TE_PE +#define COFF_WITH_PE +#endif + +#include "coff/sh.h" + +#ifdef TE_PE +#define TARGET_FORMAT "pe-shl" +#else + +#define TARGET_FORMAT \ + (!target_big_endian \ + ? (sh_small ? "coff-shl-small" : "coff-shl") \ + : (sh_small ? "coff-sh-small" : "coff-sh")) + +#endif +#endif + +#ifdef TC_MIPS +#define COFF_WITH_PE +#include "coff/mipspe.h" +#undef TARGET_FORMAT +#define TARGET_FORMAT "pe-mips" +#endif + +#ifdef TC_TIC30 +#include "coff/tic30.h" +#define TARGET_FORMAT "coff-tic30" +#endif + +#ifdef TC_TIC4X +#include "coff/tic4x.h" +#define TARGET_FORMAT "coff2-tic4x" +#endif + +#ifdef TC_TIC54X +#include "coff/tic54x.h" +#define TARGET_FORMAT "coff1-c54x" +#endif + +#ifdef TC_MCORE +#include "coff/mcore.h" +#ifndef TARGET_FORMAT +#define TARGET_FORMAT "pe-mcore" +#endif +#endif + +#ifdef TE_PE +#define obj_set_weak_hook pecoff_obj_set_weak_hook +#define obj_clear_weak_hook pecoff_obj_clear_weak_hook +#endif + +#ifndef OBJ_COFF_MAX_AUXENTRIES +#define OBJ_COFF_MAX_AUXENTRIES 1 +#endif + +#define obj_symbol_new_hook coff_obj_symbol_new_hook +#define obj_symbol_clone_hook coff_obj_symbol_clone_hook +#define obj_read_begin_hook coff_obj_read_begin_hook + +#include "bfd/libcoff.h" + +#define OUTPUT_FLAVOR bfd_target_coff_flavour + +/* Alter the field names, for now, until we've fixed up the other + references to use the new name. */ +#ifdef TC_I960 +#define TC_SYMFIELD_TYPE symbolS * +#define sy_tc bal +#endif + +#define OBJ_SYMFIELD_TYPE unsigned long +#define sy_obj sy_obj_flags + +/* We can't use the predefined section symbols in bfd/section.c, as + COFF symbols have extra fields. See bfd/libcoff.h:coff_symbol_type. */ +#ifndef obj_sec_sym_ok_for_reloc +#define obj_sec_sym_ok_for_reloc(SEC) ((SEC)->owner != 0) +#endif + +#define SYM_AUXENT(S) \ + (&coffsymbol (symbol_get_bfdsym (S))->native[1].u.auxent) +#define SYM_AUXINFO(S) \ + (&coffsymbol (symbol_get_bfdsym (S))->native[1]) + +/* The number of auxiliary entries. */ +#define S_GET_NUMBER_AUXILIARY(s) \ + (coffsymbol (symbol_get_bfdsym (s))->native->u.syment.n_numaux) +/* The number of auxiliary entries. */ +#define S_SET_NUMBER_AUXILIARY(s, v) (S_GET_NUMBER_AUXILIARY (s) = (v)) + +/* True if a symbol name is in the string table, i.e. its length is > 8. */ +#define S_IS_STRING(s) (strlen (S_GET_NAME (s)) > 8 ? 1 : 0) + +/* Auxiliary entry macros. SA_ stands for symbol auxiliary. */ +/* Omit the tv related fields. */ +/* Accessors. */ + +#define SA_GET_SYM_TAGNDX(s) (SYM_AUXENT (s)->x_sym.x_tagndx.l) +#define SA_GET_SYM_LNNO(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno) +#define SA_GET_SYM_SIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size) +#define SA_GET_SYM_FSIZE(s) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize) +#define SA_GET_SYM_LNNOPTR(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr) +#define SA_GET_SYM_ENDNDX(s) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_endndx) +#define SA_GET_SYM_DIMEN(s,i) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)]) +#define SA_GET_FILE_FNAME(s) (SYM_AUXENT (s)->x_file.x_fname) +#define SA_GET_SCN_SCNLEN(s) (SYM_AUXENT (s)->x_scn.x_scnlen) +#define SA_GET_SCN_NRELOC(s) (SYM_AUXENT (s)->x_scn.x_nreloc) +#define SA_GET_SCN_NLINNO(s) (SYM_AUXENT (s)->x_scn.x_nlinno) + +#define SA_SET_SYM_LNNO(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_lnno = (v)) +#define SA_SET_SYM_SIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_lnsz.x_size = (v)) +#define SA_SET_SYM_FSIZE(s,v) (SYM_AUXENT (s)->x_sym.x_misc.x_fsize = (v)) +#define SA_SET_SYM_LNNOPTR(s,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_fcn.x_lnnoptr = (v)) +#define SA_SET_SYM_DIMEN(s,i,v) (SYM_AUXENT (s)->x_sym.x_fcnary.x_ary.x_dimen[(i)] = (v)) +#define SA_SET_FILE_FNAME(s,v) strncpy (SYM_AUXENT (s)->x_file.x_fname, (v), FILNMLEN) +#define SA_SET_SCN_SCNLEN(s,v) (SYM_AUXENT (s)->x_scn.x_scnlen = (v)) +#define SA_SET_SCN_NRELOC(s,v) (SYM_AUXENT (s)->x_scn.x_nreloc = (v)) +#define SA_SET_SCN_NLINNO(s,v) (SYM_AUXENT (s)->x_scn.x_nlinno = (v)) + +/* Internal use only definitions. SF_ stands for symbol flags. + + These values can be assigned to sy_symbol.ost_flags field of a symbolS. + + You'll break i960 if you shift the SYSPROC bits anywhere else. for + more on the balname/callname hack, see tc-i960.h. b.out is done + differently. */ + +#define SF_I960_MASK 0x000001ff /* Bits 0-8 are used by the i960 port. */ +#define SF_SYSPROC 0x0000003f /* bits 0-5 are used to store the sysproc number. */ +#define SF_IS_SYSPROC 0x00000040 /* bit 6 marks symbols that are sysprocs. */ +#define SF_BALNAME 0x00000080 /* bit 7 marks BALNAME symbols. */ +#define SF_CALLNAME 0x00000100 /* bit 8 marks CALLNAME symbols. */ + +#define SF_NORMAL_MASK 0x0000ffff /* bits 12-15 are general purpose. */ + +#define SF_STATICS 0x00001000 /* Mark the .text & all symbols. */ +#define SF_DEFINED 0x00002000 /* Symbol is defined in this file. */ +#define SF_STRING 0x00004000 /* Symbol name length > 8. */ +#define SF_LOCAL 0x00008000 /* Symbol must not be emitted. */ + +#define SF_DEBUG_MASK 0xffff0000 /* bits 16-31 are debug info. */ + +#define SF_FUNCTION 0x00010000 /* The symbol is a function. */ +#define SF_PROCESS 0x00020000 /* Process symbol before write. */ +#define SF_TAGGED 0x00040000 /* Is associated with a tag. */ +#define SF_TAG 0x00080000 /* Is a tag. */ +#define SF_DEBUG 0x00100000 /* Is in debug or abs section. */ +#define SF_GET_SEGMENT 0x00200000 /* Get the section of the forward symbol. */ +/* All other bits are unused. */ + +/* Accessors. */ +#define SF_GET(s) (* symbol_get_obj (s)) +#define SF_GET_DEBUG(s) (symbol_get_bfdsym (s)->flags & BSF_DEBUGGING) +#define SF_SET_DEBUG(s) (symbol_get_bfdsym (s)->flags |= BSF_DEBUGGING) +#define SF_GET_NORMAL_FIELD(s) (SF_GET (s) & SF_NORMAL_MASK) +#define SF_GET_DEBUG_FIELD(s) (SF_GET (s) & SF_DEBUG_MASK) +#define SF_GET_FILE(s) (SF_GET (s) & SF_FILE) +#define SF_GET_STATICS(s) (SF_GET (s) & SF_STATICS) +#define SF_GET_DEFINED(s) (SF_GET (s) & SF_DEFINED) +#define SF_GET_STRING(s) (SF_GET (s) & SF_STRING) +#define SF_GET_LOCAL(s) (SF_GET (s) & SF_LOCAL) +#define SF_GET_FUNCTION(s) (SF_GET (s) & SF_FUNCTION) +#define SF_GET_PROCESS(s) (SF_GET (s) & SF_PROCESS) +#define SF_GET_TAGGED(s) (SF_GET (s) & SF_TAGGED) +#define SF_GET_TAG(s) (SF_GET (s) & SF_TAG) +#define SF_GET_GET_SEGMENT(s) (SF_GET (s) & SF_GET_SEGMENT) +#define SF_GET_I960(s) (SF_GET (s) & SF_I960_MASK) /* Used by i960. */ +#define SF_GET_BALNAME(s) (SF_GET (s) & SF_BALNAME) /* Used by i960. */ +#define SF_GET_CALLNAME(s) (SF_GET (s) & SF_CALLNAME) /* Used by i960. */ +#define SF_GET_IS_SYSPROC(s) (SF_GET (s) & SF_IS_SYSPROC) /* Used by i960. */ +#define SF_GET_SYSPROC(s) (SF_GET (s) & SF_SYSPROC) /* Used by i960. */ + +/* Modifiers. */ +#define SF_SET(s,v) (SF_GET (s) = (v)) +#define SF_SET_NORMAL_FIELD(s,v)(SF_GET (s) |= ((v) & SF_NORMAL_MASK)) +#define SF_SET_DEBUG_FIELD(s,v) (SF_GET (s) |= ((v) & SF_DEBUG_MASK)) +#define SF_SET_FILE(s) (SF_GET (s) |= SF_FILE) +#define SF_SET_STATICS(s) (SF_GET (s) |= SF_STATICS) +#define SF_SET_DEFINED(s) (SF_GET (s) |= SF_DEFINED) +#define SF_SET_STRING(s) (SF_GET (s) |= SF_STRING) +#define SF_SET_LOCAL(s) (SF_GET (s) |= SF_LOCAL) +#define SF_CLEAR_LOCAL(s) (SF_GET (s) &= ~SF_LOCAL) +#define SF_SET_FUNCTION(s) (SF_GET (s) |= SF_FUNCTION) +#define SF_SET_PROCESS(s) (SF_GET (s) |= SF_PROCESS) +#define SF_SET_TAGGED(s) (SF_GET (s) |= SF_TAGGED) +#define SF_SET_TAG(s) (SF_GET (s) |= SF_TAG) +#define SF_SET_GET_SEGMENT(s) (SF_GET (s) |= SF_GET_SEGMENT) +#define SF_SET_I960(s,v) (SF_GET (s) |= ((v) & SF_I960_MASK)) /* Used by i960. */ +#define SF_SET_BALNAME(s) (SF_GET (s) |= SF_BALNAME) /* Used by i960. */ +#define SF_SET_CALLNAME(s) (SF_GET (s) |= SF_CALLNAME) /* Used by i960. */ +#define SF_SET_IS_SYSPROC(s) (SF_GET (s) |= SF_IS_SYSPROC) /* Used by i960. */ +#define SF_SET_SYSPROC(s,v) (SF_GET (s) |= ((v) & SF_SYSPROC)) /* Used by i960. */ + + +/* Line number handling. */ +extern int text_lineno_number; +extern int coff_line_base; +extern int coff_n_line_nos; +extern symbolS *coff_last_function; + +#define obj_emit_lineno(WHERE, LINE, FILE_START) abort () +#define obj_app_file(name, app) c_dot_file_symbol (name, app) +#define obj_frob_symbol(S,P) coff_frob_symbol (S, & P) +#define obj_frob_section(S) coff_frob_section (S) +#define obj_frob_file_after_relocs() coff_frob_file_after_relocs () +#ifndef obj_adjust_symtab +#define obj_adjust_symtab() coff_adjust_symtab () +#endif + +/* Forward the segment of a forwarded symbol, handle assignments that + just copy symbol values, etc. */ +#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES +#ifndef TE_I386AIX +#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest, src) \ + (SF_GET_GET_SEGMENT (dest) \ + ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \ + : 0) +#else +#define OBJ_COPY_SYMBOL_ATTRIBUTES(dest, src) \ + (SF_GET_GET_SEGMENT (dest) && S_GET_SEGMENT (dest) == SEG_UNKNOWN \ + ? (S_SET_SEGMENT (dest, S_GET_SEGMENT (src)), 0) \ + : 0) +#endif +#endif + +/* Sanity check. */ + +#ifdef TC_I960 +#ifndef C_LEAFSTAT +hey ! Where is the C_LEAFSTAT definition ? i960 - coff support is depending on it. +#endif /* no C_LEAFSTAT */ +#endif /* TC_I960 */ + +extern const pseudo_typeS coff_pseudo_table[]; + +#ifndef obj_pop_insert +#define obj_pop_insert() pop_insert (coff_pseudo_table) +#endif + +/* In COFF, if a symbol is defined using .def/.val SYM/.endef, it's OK + to redefine the symbol later on. This can happen if C symbols use + a prefix, and a symbol is defined both with and without the prefix, + as in start/_start/__start in gcc/libgcc1-test.c. */ +#define RESOLVE_SYMBOL_REDEFINITION(sym) \ +(SF_GET_GET_SEGMENT (sym) \ + ? (sym->sy_frag = frag_now, \ + S_SET_VALUE (sym, frag_now_fix ()), \ + S_SET_SEGMENT (sym, now_seg), \ + 0) \ + : 0) + +/* Stabs in a coff file go into their own section. */ +#define SEPARATE_STAB_SECTIONS 1 + +/* We need 12 bytes at the start of the section to hold some initial + information. */ +#define INIT_STAB_SECTION(seg) obj_coff_init_stab_section (seg) + +/* Store the number of relocations in the section aux entry. */ +#define SET_SECTION_RELOCS(sec, relocs, n) \ + SA_SET_SCN_NRELOC (section_symbol (sec), n) + +#define obj_app_file(name, app) c_dot_file_symbol (name, app) + +extern int S_SET_DATA_TYPE (symbolS *, int); +extern int S_SET_STORAGE_CLASS (symbolS *, int); +extern int S_GET_STORAGE_CLASS (symbolS *); +extern void SA_SET_SYM_ENDNDX (symbolS *, symbolS *); +extern void coff_add_linesym (symbolS *); +extern void c_dot_file_symbol (const char *, int); +extern void coff_frob_symbol (symbolS *, int *); +extern void coff_adjust_symtab (void); +extern void coff_frob_section (segT); +extern void coff_adjust_section_syms (bfd *, asection *, void *); +extern void coff_frob_file_after_relocs (void); +extern void coff_obj_symbol_new_hook (symbolS *); +extern void coff_obj_symbol_clone_hook (symbolS *, symbolS *); +extern void coff_obj_read_begin_hook (void); +#ifdef TE_PE +extern void pecoff_obj_set_weak_hook (symbolS *); +extern void pecoff_obj_clear_weak_hook (symbolS *); +#endif +extern void obj_coff_section (int); +extern segT obj_coff_add_segment (const char *); +extern void obj_coff_section (int); +extern void c_dot_file_symbol (const char *, int); +extern segT s_get_segment (symbolS *); +#ifndef tc_coff_symbol_emit_hook +extern void tc_coff_symbol_emit_hook (symbolS *); +#endif +extern void obj_coff_pe_handle_link_once (void); +extern void obj_coff_init_stab_section (segT); +extern void c_section_header (struct internal_scnhdr *, + char *, long, long, long, long, + long, long, long, long); +extern void obj_coff_seh_do_final (void); + +#ifndef obj_coff_generate_pdata +#define obj_coff_generate_pdata obj_coff_seh_do_final +#endif + + +#endif /* OBJ_FORMAT_H */ diff --git a/contrib/toolchain/binutils/gas/config/tc-i386-intel.c b/contrib/toolchain/binutils/gas/config/tc-i386-intel.c new file mode 100644 index 0000000000..22594bce91 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/tc-i386-intel.c @@ -0,0 +1,1005 @@ +/* tc-i386.c -- Assemble Intel syntax code for ix86/x86-64 + Copyright 2009, 2010 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +static struct + { + operatorT op_modifier; /* Operand modifier. */ + int is_mem; /* 1 if operand is memory reference. */ + int is_indirect; /* 1 if operand is indirect reference. */ + int has_offset; /* 1 if operand has offset. */ + unsigned int in_offset; /* >=1 if processing operand of offset. */ + unsigned int in_bracket; /* >=1 if processing operand in brackets. */ + unsigned int in_scale; /* >=1 if processing multipication operand + * in brackets. */ + i386_operand_type reloc_types; /* Value obtained from lex_got(). */ + const reg_entry *base; /* Base register (if any). */ + const reg_entry *index; /* Index register (if any). */ + offsetT scale_factor; /* Accumulated scale factor. */ + symbolS *seg; + } +intel_state; + +/* offset X_add_symbol */ +#define O_offset O_md32 +/* offset X_add_symbol */ +#define O_short O_md31 +/* near ptr X_add_symbol */ +#define O_near_ptr O_md30 +/* far ptr X_add_symbol */ +#define O_far_ptr O_md29 +/* byte ptr X_add_symbol */ +#define O_byte_ptr O_md28 +/* word ptr X_add_symbol */ +#define O_word_ptr O_md27 +/* dword ptr X_add_symbol */ +#define O_dword_ptr O_md26 +/* qword ptr X_add_symbol */ +#define O_qword_ptr O_md25 +/* oword ptr X_add_symbol */ +#define O_oword_ptr O_md24 +/* fword ptr X_add_symbol */ +#define O_fword_ptr O_md23 +/* tbyte ptr X_add_symbol */ +#define O_tbyte_ptr O_md22 +/* xmmword ptr X_add_symbol */ +#define O_xmmword_ptr O_md21 +/* ymmword ptr X_add_symbol */ +#define O_ymmword_ptr O_md20 +/* zmmword ptr X_add_symbol */ +#define O_zmmword_ptr O_md19 + +static struct + { + const char *name; + operatorT op; + unsigned int operands; + } +const i386_operators[] = + { + { "and", O_bit_and, 2 }, + { "eq", O_eq, 2 }, + { "ge", O_ge, 2 }, + { "gt", O_gt, 2 }, + { "le", O_le, 2 }, + { "lt", O_lt, 2 }, + { "mod", O_modulus, 2 }, + { "ne", O_ne, 2 }, + { "not", O_bit_not, 1 }, + { "offset", O_offset, 1 }, + { "or", O_bit_inclusive_or, 2 }, + { "shl", O_left_shift, 2 }, + { "short", O_short, 1 }, + { "shr", O_right_shift, 2 }, + { "xor", O_bit_exclusive_or, 2 }, + { NULL, O_illegal, 0 } + }; + +static struct + { + const char *name; + operatorT op; + unsigned short sz[3]; + } +const i386_types[] = + { +#define I386_TYPE(t, n) { #t, O_##t##_ptr, { n, n, n } } + I386_TYPE(byte, 1), + I386_TYPE(word, 2), + I386_TYPE(dword, 4), + I386_TYPE(fword, 6), + I386_TYPE(qword, 8), + I386_TYPE(tbyte, 10), + I386_TYPE(oword, 16), + I386_TYPE(xmmword, 16), + I386_TYPE(ymmword, 32), + I386_TYPE(zmmword, 64), +#undef I386_TYPE + { "near", O_near_ptr, { 0xff04, 0xff02, 0xff08 } }, + { "far", O_far_ptr, { 0xff06, 0xff05, 0xff06 } }, + { NULL, O_illegal, { 0, 0, 0 } } + }; + +operatorT i386_operator (const char *name, unsigned int operands, char *pc) +{ + unsigned int j; + + if (!intel_syntax) + return O_absent; + + if (!name) + { + if (operands != 2) + return O_illegal; + switch (*input_line_pointer) + { + case ':': + ++input_line_pointer; + return O_full_ptr; + case '[': + ++input_line_pointer; + return O_index; + case '@': + if (this_operand >= 0 && i.reloc[this_operand] == NO_RELOC) + { + int adjust = 0; + char *gotfree_input_line = lex_got (&i.reloc[this_operand], + &adjust, + &intel_state.reloc_types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); + + if (!gotfree_input_line) + break; + free (gotfree_input_line); + *input_line_pointer++ = '+'; + memset (input_line_pointer, '0', adjust - 1); + input_line_pointer[adjust - 1] = ' '; + return O_add; + } + break; + } + return O_illegal; + } + + for (j = 0; i386_operators[j].name; ++j) + if (strcasecmp (i386_operators[j].name, name) == 0) + { + if (i386_operators[j].operands + && i386_operators[j].operands != operands) + return O_illegal; + return i386_operators[j].op; + } + + for (j = 0; i386_types[j].name; ++j) + if (strcasecmp (i386_types[j].name, name) == 0) + break; + if (i386_types[j].name && *pc == ' ') + { + char *pname = ++input_line_pointer; + char c = get_symbol_end (); + + if (strcasecmp (pname, "ptr") == 0) + { + pname[-1] = *pc; + *pc = c; + if (intel_syntax > 0 || operands != 1) + return O_illegal; + return i386_types[j].op; + } + + *input_line_pointer = c; + input_line_pointer = pname - 1; + } + + return O_absent; +} + +static int i386_intel_parse_name (const char *name, expressionS *e) +{ + unsigned int j; + + if (! strcmp (name, "$")) + { + current_location (e); + return 1; + } + + for (j = 0; i386_types[j].name; ++j) + if (strcasecmp(i386_types[j].name, name) == 0) + { + e->X_op = O_constant; + e->X_add_number = i386_types[j].sz[flag_code]; + e->X_add_symbol = NULL; + e->X_op_symbol = NULL; + return 1; + } + + return 0; +} + +static INLINE int i386_intel_check (const reg_entry *rreg, + const reg_entry *base, + const reg_entry *iindex) +{ + if ((this_operand >= 0 + && rreg != i.op[this_operand].regs) + || base != intel_state.base + || iindex != intel_state.index) + { + as_bad (_("invalid use of register")); + return 0; + } + return 1; +} + +static INLINE void i386_intel_fold (expressionS *e, symbolS *sym) +{ + expressionS *exp = symbol_get_value_expression (sym); + if (S_GET_SEGMENT (sym) == absolute_section) + { + offsetT val = e->X_add_number; + + *e = *exp; + e->X_add_number += val; + } + else + { + if (exp->X_op == O_symbol + && strcmp (S_GET_NAME (exp->X_add_symbol), + GLOBAL_OFFSET_TABLE_NAME) == 0) + sym = exp->X_add_symbol; + e->X_add_symbol = sym; + e->X_op_symbol = NULL; + e->X_op = O_symbol; + } +} + +static int +i386_intel_simplify_register (expressionS *e) +{ + int reg_num; + + if (this_operand < 0 || intel_state.in_offset) + { + as_bad (_("invalid use of register")); + return 0; + } + + if (e->X_op == O_register) + reg_num = e->X_add_number; + else + reg_num = e->X_md - 1; + + if (!intel_state.in_bracket) + { + if (i.op[this_operand].regs) + { + as_bad (_("invalid use of register")); + return 0; + } + if (i386_regtab[reg_num].reg_type.bitfield.sreg3 + && i386_regtab[reg_num].reg_num == RegFlat) + { + as_bad (_("invalid use of pseudo-register")); + return 0; + } + i.op[this_operand].regs = i386_regtab + reg_num; + } + else if (!intel_state.index + && (i386_regtab[reg_num].reg_type.bitfield.regxmm + || i386_regtab[reg_num].reg_type.bitfield.regymm + || i386_regtab[reg_num].reg_type.bitfield.regzmm)) + intel_state.index = i386_regtab + reg_num; + else if (!intel_state.base && !intel_state.in_scale) + intel_state.base = i386_regtab + reg_num; + else if (!intel_state.index) + { + if (intel_state.in_scale + || i386_regtab[reg_num].reg_type.bitfield.baseindex) + intel_state.index = i386_regtab + reg_num; + else + { + /* Convert base to index and make ESP/RSP the base. */ + intel_state.index = intel_state.base; + intel_state.base = i386_regtab + reg_num; + } + } + else + { + /* esp is invalid as index */ + intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM; + } + return 2; +} + +static int i386_intel_simplify (expressionS *); + +static INLINE int i386_intel_simplify_symbol(symbolS *sym) +{ + int ret = i386_intel_simplify (symbol_get_value_expression (sym)); + + if (ret == 2) + { + S_SET_SEGMENT(sym, absolute_section); + ret = 1; + } + return ret; +} + +static int i386_intel_simplify (expressionS *e) +{ + const reg_entry *the_reg = (this_operand >= 0 + ? i.op[this_operand].regs : NULL); + const reg_entry *base = intel_state.base; + const reg_entry *state_index = intel_state.index; + int ret; + + if (!intel_syntax) + return 1; + + switch (e->X_op) + { + case O_index: + if (e->X_add_symbol) + { + if (!i386_intel_simplify_symbol (e->X_add_symbol) + || !i386_intel_check(the_reg, intel_state.base, + intel_state.index)) + return 0; + } + if (!intel_state.in_offset) + ++intel_state.in_bracket; + ret = i386_intel_simplify_symbol (e->X_op_symbol); + if (!intel_state.in_offset) + --intel_state.in_bracket; + if (!ret) + return 0; + if (e->X_add_symbol) + e->X_op = O_add; + else + i386_intel_fold (e, e->X_op_symbol); + break; + + case O_offset: + intel_state.has_offset = 1; + ++intel_state.in_offset; + ret = i386_intel_simplify_symbol (e->X_add_symbol); + --intel_state.in_offset; + if (!ret || !i386_intel_check(the_reg, base, state_index)) + return 0; + i386_intel_fold (e, e->X_add_symbol); + return ret; + + case O_byte_ptr: + case O_word_ptr: + case O_dword_ptr: + case O_fword_ptr: + case O_qword_ptr: + case O_tbyte_ptr: + case O_oword_ptr: + case O_xmmword_ptr: + case O_ymmword_ptr: + case O_zmmword_ptr: + case O_near_ptr: + case O_far_ptr: + if (intel_state.op_modifier == O_absent) + intel_state.op_modifier = e->X_op; + /* FALLTHROUGH */ + case O_short: + if (symbol_get_value_expression (e->X_add_symbol)->X_op + == O_register) + { + as_bad (_("invalid use of register")); + return 0; + } + if (!i386_intel_simplify_symbol (e->X_add_symbol)) + return 0; + i386_intel_fold (e, e->X_add_symbol); + break; + + case O_full_ptr: + if (symbol_get_value_expression (e->X_op_symbol)->X_op + == O_register) + { + as_bad (_("invalid use of register")); + return 0; + } + if (!i386_intel_simplify_symbol (e->X_op_symbol) + || !i386_intel_check(the_reg, intel_state.base, + intel_state.index)) + return 0; + if (!intel_state.in_offset) + intel_state.seg = e->X_add_symbol; + i386_intel_fold (e, e->X_op_symbol); + break; + + case O_multiply: + if (this_operand >= 0 && intel_state.in_bracket) + { + expressionS *scale = NULL; + + if (intel_state.index) + --scale; + + if (!intel_state.in_scale++) + intel_state.scale_factor = 1; + + ret = i386_intel_simplify_symbol (e->X_add_symbol); + if (ret && !scale && intel_state.index) + scale = symbol_get_value_expression (e->X_op_symbol); + + if (ret) + ret = i386_intel_simplify_symbol (e->X_op_symbol); + if (ret && !scale && intel_state.index) + scale = symbol_get_value_expression (e->X_add_symbol); + + if (ret && scale && (scale + 1)) + { + resolve_expression (scale); + if (scale->X_op != O_constant + || intel_state.index->reg_type.bitfield.reg16) + scale->X_add_number = 0; + intel_state.scale_factor *= scale->X_add_number; + } + + --intel_state.in_scale; + if (!ret) + return 0; + + if (!intel_state.in_scale) + switch (intel_state.scale_factor) + { + case 1: + i.log2_scale_factor = 0; + break; + case 2: + i.log2_scale_factor = 1; + break; + case 4: + i.log2_scale_factor = 2; + break; + case 8: + i.log2_scale_factor = 3; + break; + default: + /* esp is invalid as index */ + intel_state.index = i386_regtab + REGNAM_EAX + ESP_REG_NUM; + break; + } + + break; + } + goto fallthrough; + + case O_register: + ret = i386_intel_simplify_register (e); + if (ret == 2) + { + gas_assert (e->X_add_number < (unsigned short) -1); + e->X_md = (unsigned short) e->X_add_number + 1; + e->X_op = O_constant; + e->X_add_number = 0; + } + return ret; + + case O_constant: + if (e->X_md) + return i386_intel_simplify_register (e); + + /* FALLTHROUGH */ + default: +fallthrough: + if (e->X_add_symbol + && !i386_intel_simplify_symbol (e->X_add_symbol)) + return 0; + if (e->X_op == O_add || e->X_op == O_subtract) + { + base = intel_state.base; + state_index = intel_state.index; + } + if (!i386_intel_check (the_reg, base, state_index) + || (e->X_op_symbol + && !i386_intel_simplify_symbol (e->X_op_symbol)) + || !i386_intel_check (the_reg, + (e->X_op != O_add + ? base : intel_state.base), + (e->X_op != O_add + ? state_index : intel_state.index))) + return 0; + break; + } + + if (this_operand >= 0 + && e->X_op == O_symbol + && !intel_state.in_offset) + { + segT seg = S_GET_SEGMENT (e->X_add_symbol); + + if (seg != absolute_section + && seg != reg_section + && seg != expr_section) + intel_state.is_mem |= 2 - !intel_state.in_bracket; + } + + return 1; +} + +int i386_need_index_operator (void) +{ + return intel_syntax < 0; +} + +static int +i386_intel_operand (char *operand_string, int got_a_float) +{ + char *saved_input_line_pointer, *buf; + segT exp_seg; + expressionS exp, *expP; + char suffix = 0; + int ret; + + /* Handle vector immediates. */ + if (RC_SAE_immediate (operand_string)) + return 1; + + /* Initialize state structure. */ + intel_state.op_modifier = O_absent; + intel_state.is_mem = 0; + intel_state.is_indirect = 0; + intel_state.has_offset = 0; + intel_state.base = NULL; + intel_state.index = NULL; + intel_state.seg = NULL; + operand_type_set (&intel_state.reloc_types, ~0); + gas_assert (!intel_state.in_offset); + gas_assert (!intel_state.in_bracket); + gas_assert (!intel_state.in_scale); + + saved_input_line_pointer = input_line_pointer; + input_line_pointer = buf = xstrdup (operand_string); + + intel_syntax = -1; + memset (&exp, 0, sizeof(exp)); + exp_seg = expression (&exp); + ret = i386_intel_simplify (&exp); + intel_syntax = 1; + + SKIP_WHITESPACE (); + + /* Handle vector operations. */ + if (*input_line_pointer == '{') + { + char *end = check_VecOperations (input_line_pointer, NULL); + if (end) + input_line_pointer = end; + else + ret = 0; + } + + if (!is_end_of_line[(unsigned char) *input_line_pointer]) + { + as_bad (_("junk `%s' after expression"), input_line_pointer); + ret = 0; + } + else if (exp.X_op == O_illegal || exp.X_op == O_absent) + { + as_bad (_("invalid expression")); + ret = 0; + } + else if (!intel_state.has_offset + && input_line_pointer > buf + && *(input_line_pointer - 1) == ']') + { + intel_state.is_mem |= 1; + intel_state.is_indirect = 1; + } + + input_line_pointer = saved_input_line_pointer; + free (buf); + + gas_assert (!intel_state.in_offset); + gas_assert (!intel_state.in_bracket); + gas_assert (!intel_state.in_scale); + + if (!ret) + return 0; + + if (intel_state.op_modifier != O_absent + && current_templates->start->base_opcode != 0x8d /* lea */) + { + i.types[this_operand].bitfield.unspecified = 0; + + switch (intel_state.op_modifier) + { + case O_byte_ptr: + i.types[this_operand].bitfield.byte = 1; + suffix = BYTE_MNEM_SUFFIX; + break; + + case O_word_ptr: + i.types[this_operand].bitfield.word = 1; + if ((current_templates->start->name[0] == 'l' + && current_templates->start->name[2] == 's' + && current_templates->start->name[3] == 0) + || current_templates->start->base_opcode == 0x62 /* bound */) + suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ + else if (got_a_float == 2) /* "fi..." */ + suffix = SHORT_MNEM_SUFFIX; + else + suffix = WORD_MNEM_SUFFIX; + break; + + case O_dword_ptr: + i.types[this_operand].bitfield.dword = 1; + if ((current_templates->start->name[0] == 'l' + && current_templates->start->name[2] == 's' + && current_templates->start->name[3] == 0) + || current_templates->start->base_opcode == 0x62 /* bound */) + suffix = WORD_MNEM_SUFFIX; + else if (flag_code == CODE_16BIT + && (current_templates->start->opcode_modifier.jump + || current_templates->start->opcode_modifier.jumpdword)) + suffix = LONG_DOUBLE_MNEM_SUFFIX; + else if (got_a_float == 1) /* "f..." */ + suffix = SHORT_MNEM_SUFFIX; + else + suffix = LONG_MNEM_SUFFIX; + break; + + case O_fword_ptr: + i.types[this_operand].bitfield.fword = 1; + if (current_templates->start->name[0] == 'l' + && current_templates->start->name[2] == 's' + && current_templates->start->name[3] == 0) + suffix = LONG_MNEM_SUFFIX; + else if (!got_a_float) + { + if (flag_code == CODE_16BIT) + add_prefix (DATA_PREFIX_OPCODE); + suffix = LONG_DOUBLE_MNEM_SUFFIX; + } + else + suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ + break; + + case O_qword_ptr: + i.types[this_operand].bitfield.qword = 1; + if (current_templates->start->base_opcode == 0x62 /* bound */ + || got_a_float == 1) /* "f..." */ + suffix = LONG_MNEM_SUFFIX; + else + suffix = QWORD_MNEM_SUFFIX; + break; + + case O_tbyte_ptr: + i.types[this_operand].bitfield.tbyte = 1; + if (got_a_float == 1) + suffix = LONG_DOUBLE_MNEM_SUFFIX; + else + suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */ + break; + + case O_oword_ptr: + case O_xmmword_ptr: + i.types[this_operand].bitfield.xmmword = 1; + suffix = XMMWORD_MNEM_SUFFIX; + break; + + case O_ymmword_ptr: + i.types[this_operand].bitfield.ymmword = 1; + suffix = YMMWORD_MNEM_SUFFIX; + break; + + case O_zmmword_ptr: + i.types[this_operand].bitfield.zmmword = 1; + suffix = ZMMWORD_MNEM_SUFFIX; + break; + + case O_far_ptr: + suffix = LONG_DOUBLE_MNEM_SUFFIX; + /* FALLTHROUGH */ + case O_near_ptr: + if (!current_templates->start->opcode_modifier.jump + && !current_templates->start->opcode_modifier.jumpdword) + suffix = got_a_float /* so it will cause an error */ + ? BYTE_MNEM_SUFFIX + : LONG_DOUBLE_MNEM_SUFFIX; + break; + + default: + BAD_CASE (intel_state.op_modifier); + break; + } + + if (!i.suffix) + i.suffix = suffix; + else if (i.suffix != suffix) + { + as_bad (_("conflicting operand size modifiers")); + return 0; + } + } + + /* Operands for jump/call need special consideration. */ + if (current_templates->start->opcode_modifier.jump + || current_templates->start->opcode_modifier.jumpdword + || current_templates->start->opcode_modifier.jumpintersegment) + { + if (i.op[this_operand].regs + || intel_state.base + || intel_state.index + || intel_state.is_mem > 1) + i.types[this_operand].bitfield.jumpabsolute = 1; + else + switch (intel_state.op_modifier) + { + case O_near_ptr: + if (intel_state.seg) + i.types[this_operand].bitfield.jumpabsolute = 1; + else + intel_state.is_mem = 1; + break; + case O_far_ptr: + case O_absent: + if (!intel_state.seg) + { + intel_state.is_mem = 1; + if (intel_state.op_modifier == O_absent) + { + if (intel_state.is_indirect == 1) + i.types[this_operand].bitfield.jumpabsolute = 1; + break; + } + as_bad (_("cannot infer the segment part of the operand")); + return 0; + } + else if (S_GET_SEGMENT (intel_state.seg) == reg_section) + i.types[this_operand].bitfield.jumpabsolute = 1; + else + { + i386_operand_type types; + + if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS) + { + as_bad (_("at most %d immediate operands are allowed"), + MAX_IMMEDIATE_OPERANDS); + return 0; + } + expP = &im_expressions[i.imm_operands++]; + memset (expP, 0, sizeof(*expP)); + expP->X_op = O_symbol; + expP->X_add_symbol = intel_state.seg; + i.op[this_operand].imms = expP; + + resolve_expression (expP); + operand_type_set (&types, ~0); + if (!i386_finalize_immediate (S_GET_SEGMENT (intel_state.seg), + expP, types, operand_string)) + return 0; + if (i.operands < MAX_OPERANDS) + { + this_operand = i.operands++; + i.types[this_operand].bitfield.unspecified = 1; + } + if (suffix == LONG_DOUBLE_MNEM_SUFFIX) + i.suffix = 0; + intel_state.seg = NULL; + intel_state.is_mem = 0; + } + break; + default: + i.types[this_operand].bitfield.jumpabsolute = 1; + break; + } + if (i.types[this_operand].bitfield.jumpabsolute) + intel_state.is_mem |= 1; + } + else if (intel_state.seg) + intel_state.is_mem |= 1; + + if (i.op[this_operand].regs) + { + i386_operand_type temp; + + /* Register operand. */ + if (intel_state.base || intel_state.index || intel_state.seg) + { + as_bad (_("invalid operand")); + return 0; + } + + temp = i.op[this_operand].regs->reg_type; + temp.bitfield.baseindex = 0; + i.types[this_operand] = operand_type_or (i.types[this_operand], + temp); + i.types[this_operand].bitfield.unspecified = 0; + ++i.reg_operands; + } + else if (intel_state.base + || intel_state.index + || intel_state.seg + || intel_state.is_mem) + { + /* Memory operand. */ + if ((int) i.mem_operands + >= 2 - !current_templates->start->opcode_modifier.isstring) + { + /* Handle + + call 0x9090,0x90909090 + lcall 0x9090,0x90909090 + jmp 0x9090,0x90909090 + ljmp 0x9090,0x90909090 + */ + + if ((current_templates->start->opcode_modifier.jumpintersegment + || current_templates->start->opcode_modifier.jumpdword + || current_templates->start->opcode_modifier.jump) + && this_operand == 1 + && intel_state.seg == NULL + && i.mem_operands == 1 + && i.disp_operands == 1 + && intel_state.op_modifier == O_absent) + { + /* Try to process the first operand as immediate, */ + this_operand = 0; + if (i386_finalize_immediate (exp_seg, i.op[0].imms, + intel_state.reloc_types, + NULL)) + { + this_operand = 1; + expP = &im_expressions[0]; + i.op[this_operand].imms = expP; + *expP = exp; + + /* Try to process the second operand as immediate, */ + if (i386_finalize_immediate (exp_seg, expP, + intel_state.reloc_types, + NULL)) + { + i.mem_operands = 0; + i.disp_operands = 0; + i.imm_operands = 2; + i.types[0].bitfield.mem = 0; + i.types[0].bitfield.disp16 = 0; + i.types[0].bitfield.disp32 = 0; + i.types[0].bitfield.disp32s = 0; + return 1; + } + } + } + + as_bad (_("too many memory references for `%s'"), + current_templates->start->name); + return 0; + } + + expP = &disp_expressions[i.disp_operands]; + memcpy (expP, &exp, sizeof(exp)); + resolve_expression (expP); + + if (expP->X_op != O_constant + || expP->X_add_number + || (!intel_state.base + && !intel_state.index)) + { + i.op[this_operand].disps = expP; + i.disp_operands++; + + if (flag_code == CODE_64BIT) + { + i.types[this_operand].bitfield.disp32 = 1; + if (!i.prefix[ADDR_PREFIX]) + { + i.types[this_operand].bitfield.disp64 = 1; + i.types[this_operand].bitfield.disp32s = 1; + } + } + else if (!i.prefix[ADDR_PREFIX] ^ (flag_code == CODE_16BIT)) + i.types[this_operand].bitfield.disp32 = 1; + else + i.types[this_operand].bitfield.disp16 = 1; + +#if defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) + /* + * exp_seg is used only for verification in + * i386_finalize_displacement, and we can end up seeing reg_section + * here - but we know we removed all registers from the expression + * (or error-ed on any remaining ones) in i386_intel_simplify. I + * consider the check in i386_finalize_displacement bogus anyway, in + * particular because it doesn't allow for expr_section, so I'd + * rather see that check (and the similar one in + * i386_finalize_immediate) use SEG_NORMAL(), but not being an a.out + * expert I can't really say whether that would have other bad side + * effects. + */ + if (OUTPUT_FLAVOR == bfd_target_aout_flavour + && exp_seg == reg_section) + exp_seg = expP->X_op != O_constant ? undefined_section + : absolute_section; +#endif + + if (!i386_finalize_displacement (exp_seg, expP, + intel_state.reloc_types, + operand_string)) + return 0; + } + + if (intel_state.base || intel_state.index) + i.types[this_operand].bitfield.baseindex = 1; + + if (intel_state.seg) + { + for (;;) + { + expP = symbol_get_value_expression (intel_state.seg); + if (expP->X_op != O_full_ptr) + break; + intel_state.seg = expP->X_add_symbol; + } + if (expP->X_op != O_register) + { + as_bad (_("segment register name expected")); + return 0; + } + if (!i386_regtab[expP->X_add_number].reg_type.bitfield.sreg2 + && !i386_regtab[expP->X_add_number].reg_type.bitfield.sreg3) + { + as_bad (_("invalid use of register")); + return 0; + } + switch (i386_regtab[expP->X_add_number].reg_num) + { + case 0: i.seg[i.mem_operands] = &es; break; + case 1: i.seg[i.mem_operands] = &cs; break; + case 2: i.seg[i.mem_operands] = &ss; break; + case 3: i.seg[i.mem_operands] = &ds; break; + case 4: i.seg[i.mem_operands] = &fs; break; + case 5: i.seg[i.mem_operands] = &gs; break; + case RegFlat: i.seg[i.mem_operands] = NULL; break; + } + } + + /* Swap base and index in 16-bit memory operands like + [si+bx]. Since i386_index_check is also used in AT&T + mode we have to do that here. */ + if (intel_state.base + && intel_state.index + && intel_state.base->reg_type.bitfield.reg16 + && intel_state.index->reg_type.bitfield.reg16 + && intel_state.base->reg_num >= 6 + && intel_state.index->reg_num < 6) + { + i.base_reg = intel_state.index; + i.index_reg = intel_state.base; + } + else + { + i.base_reg = intel_state.base; + i.index_reg = intel_state.index; + } + + if (!i386_index_check (operand_string)) + return 0; + + i.types[this_operand].bitfield.mem = 1; + ++i.mem_operands; + } + else + { + /* Immediate. */ + if (i.imm_operands >= MAX_IMMEDIATE_OPERANDS) + { + as_bad (_("at most %d immediate operands are allowed"), + MAX_IMMEDIATE_OPERANDS); + return 0; + } + + expP = &im_expressions[i.imm_operands++]; + i.op[this_operand].imms = expP; + *expP = exp; + + return i386_finalize_immediate (exp_seg, expP, intel_state.reloc_types, + operand_string); + } + + return 1; +} diff --git a/contrib/toolchain/binutils/gas/config/tc-i386.c b/contrib/toolchain/binutils/gas/config/tc-i386.c new file mode 100644 index 0000000000..3c423da7a8 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/tc-i386.c @@ -0,0 +1,10565 @@ +/* tc-i386.c -- Assemble code for the Intel 80386 + Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, + 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Intel 80386 machine specific gas. + Written by Eliot Dresselhaus (eliot@mgm.mit.edu). + x86_64 support by Jan Hubicka (jh@suse.cz) + VIA PadLock support by Michal Ludvig (mludvig@suse.cz) + Bugs & suggestions are completely welcome. This is free software. + Please help us make it better. */ + +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "dwarf2dbg.h" +#include "dw2gencfi.h" +#include "elf/x86-64.h" +#include "opcodes/i386-init.h" + +#ifndef REGISTER_WARNINGS +#define REGISTER_WARNINGS 1 +#endif + +#ifndef INFER_ADDR_PREFIX +#define INFER_ADDR_PREFIX 1 +#endif + +#ifndef DEFAULT_ARCH +#define DEFAULT_ARCH "i386" +#endif + +#ifndef INLINE +#if __GNUC__ >= 2 +#define INLINE __inline__ +#else +#define INLINE +#endif +#endif + +/* Prefixes will be emitted in the order defined below. + WAIT_PREFIX must be the first prefix since FWAIT is really is an + instruction, and so must come before any prefixes. + The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX, + REP_PREFIX/HLE_PREFIX, LOCK_PREFIX. */ +#define WAIT_PREFIX 0 +#define SEG_PREFIX 1 +#define ADDR_PREFIX 2 +#define DATA_PREFIX 3 +#define REP_PREFIX 4 +#define HLE_PREFIX REP_PREFIX +#define BND_PREFIX REP_PREFIX +#define LOCK_PREFIX 5 +#define REX_PREFIX 6 /* must come last. */ +#define MAX_PREFIXES 7 /* max prefixes per opcode */ + +/* we define the syntax here (modulo base,index,scale syntax) */ +#define REGISTER_PREFIX '%' +#define IMMEDIATE_PREFIX '$' +#define ABSOLUTE_PREFIX '*' + +/* these are the instruction mnemonic suffixes in AT&T syntax or + memory operand size in Intel syntax. */ +#define WORD_MNEM_SUFFIX 'w' +#define BYTE_MNEM_SUFFIX 'b' +#define SHORT_MNEM_SUFFIX 's' +#define LONG_MNEM_SUFFIX 'l' +#define QWORD_MNEM_SUFFIX 'q' +#define XMMWORD_MNEM_SUFFIX 'x' +#define YMMWORD_MNEM_SUFFIX 'y' +#define ZMMWORD_MNEM_SUFFIX 'z' +/* Intel Syntax. Use a non-ascii letter since since it never appears + in instructions. */ +#define LONG_DOUBLE_MNEM_SUFFIX '\1' + +#define END_OF_INSN '\0' + +/* + 'templates' is for grouping together 'template' structures for opcodes + of the same name. This is only used for storing the insns in the grand + ole hash table of insns. + The templates themselves start at START and range up to (but not including) + END. + */ +typedef struct +{ + const insn_template *start; + const insn_template *end; +} +templates; + +/* 386 operand encoding bytes: see 386 book for details of this. */ +typedef struct +{ + unsigned int regmem; /* codes register or memory operand */ + unsigned int reg; /* codes register operand (or extended opcode) */ + unsigned int mode; /* how to interpret regmem & reg */ +} +modrm_byte; + +/* x86-64 extension prefix. */ +typedef int rex_byte; + +/* 386 opcode byte to code indirect addressing. */ +typedef struct +{ + unsigned base; + unsigned index; + unsigned scale; +} +sib_byte; + +/* x86 arch names, types and features */ +typedef struct +{ + const char *name; /* arch name */ + unsigned int len; /* arch string length */ + enum processor_type type; /* arch type */ + i386_cpu_flags flags; /* cpu feature flags */ + unsigned int skip; /* show_arch should skip this. */ + unsigned int negated; /* turn off indicated flags. */ +} +arch_entry; + +static void update_code_flag (int, int); +static void set_code_flag (int); +static void set_16bit_gcc_code_flag (int); +static void set_intel_syntax (int); +static void set_intel_mnemonic (int); +static void set_allow_index_reg (int); +static void set_check (int); +static void set_cpu_arch (int); +#ifdef TE_PE +static void pe_directive_secrel (int); +#endif +static void signed_cons (int); +static char *output_invalid (int c); +static int i386_finalize_immediate (segT, expressionS *, i386_operand_type, + const char *); +static int i386_finalize_displacement (segT, expressionS *, i386_operand_type, + const char *); +static int i386_att_operand (char *); +static int i386_intel_operand (char *, int); +static int i386_intel_simplify (expressionS *); +static int i386_intel_parse_name (const char *, expressionS *); +static const reg_entry *parse_register (char *, char **); +static char *parse_insn (char *, char *); +static char *parse_operands (char *, const char *); +static void swap_operands (void); +static void swap_2_operands (int, int); +static void optimize_imm (void); +static void optimize_disp (void); +static const insn_template *match_template (void); +static int check_string (void); +static int process_suffix (void); +static int check_byte_reg (void); +static int check_long_reg (void); +static int check_qword_reg (void); +static int check_word_reg (void); +static int finalize_imm (void); +static int process_operands (void); +static const seg_entry *build_modrm_byte (void); +static void output_insn (void); +static void output_imm (fragS *, offsetT); +static void output_disp (fragS *, offsetT); +#ifndef I386COFF +static void s_bss (int); +#endif +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) +static void handle_large_common (int small ATTRIBUTE_UNUSED); +#endif + +static const char *default_arch = DEFAULT_ARCH; + +/* This struct describes rounding control and SAE in the instruction. */ +struct RC_Operation +{ + enum rc_type + { + rne = 0, + rd, + ru, + rz, + saeonly + } type; + int operand; +}; + +static struct RC_Operation rc_op; + +/* The struct describes masking, applied to OPERAND in the instruction. + MASK is a pointer to the corresponding mask register. ZEROING tells + whether merging or zeroing mask is used. */ +struct Mask_Operation +{ + const reg_entry *mask; + unsigned int zeroing; + /* The operand where this operation is associated. */ + int operand; +}; + +static struct Mask_Operation mask_op; + +/* The struct describes broadcasting, applied to OPERAND. FACTOR is + broadcast factor. */ +struct Broadcast_Operation +{ + /* Type of broadcast: no broadcast, {1to8}, or {1to16}. */ + int type; + + /* Index of broadcasted operand. */ + int operand; +}; + +static struct Broadcast_Operation broadcast_op; + +/* VEX prefix. */ +typedef struct +{ + /* VEX prefix is either 2 byte or 3 byte. EVEX is 4 byte. */ + unsigned char bytes[4]; + unsigned int length; + /* Destination or source register specifier. */ + const reg_entry *register_specifier; +} vex_prefix; + +/* 'md_assemble ()' gathers together information and puts it into a + i386_insn. */ + +union i386_op + { + expressionS *disps; + expressionS *imms; + const reg_entry *regs; + }; + +enum i386_error + { + operand_size_mismatch, + operand_type_mismatch, + register_type_mismatch, + number_of_operands_mismatch, + invalid_instruction_suffix, + bad_imm4, + old_gcc_only, + unsupported_with_intel_mnemonic, + unsupported_syntax, + unsupported, + invalid_vsib_address, + invalid_vector_register_set, + unsupported_vector_index_register, + unsupported_broadcast, + broadcast_not_on_src_operand, + broadcast_needed, + unsupported_masking, + mask_not_on_destination, + no_default_mask, + unsupported_rc_sae, + rc_sae_operand_not_last_imm, + invalid_register_operand, + try_vector_disp8 + }; + +struct _i386_insn + { + /* TM holds the template for the insn were currently assembling. */ + insn_template tm; + + /* SUFFIX holds the instruction size suffix for byte, word, dword + or qword, if given. */ + char suffix; + + /* OPERANDS gives the number of given operands. */ + unsigned int operands; + + /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number + of given register, displacement, memory operands and immediate + operands. */ + unsigned int reg_operands, disp_operands, mem_operands, imm_operands; + + /* TYPES [i] is the type (see above #defines) which tells us how to + use OP[i] for the corresponding operand. */ + i386_operand_type types[MAX_OPERANDS]; + + /* Displacement expression, immediate expression, or register for each + operand. */ + union i386_op op[MAX_OPERANDS]; + + /* Flags for operands. */ + unsigned int flags[MAX_OPERANDS]; +#define Operand_PCrel 1 + + /* Relocation type for operand */ + enum bfd_reloc_code_real reloc[MAX_OPERANDS]; + + /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode + the base index byte below. */ + const reg_entry *base_reg; + const reg_entry *index_reg; + unsigned int log2_scale_factor; + + /* SEG gives the seg_entries of this insn. They are zero unless + explicit segment overrides are given. */ + const seg_entry *seg[2]; + + /* PREFIX holds all the given prefix opcodes (usually null). + PREFIXES is the number of prefix opcodes. */ + unsigned int prefixes; + unsigned char prefix[MAX_PREFIXES]; + + /* RM and SIB are the modrm byte and the sib byte where the + addressing modes of this insn are encoded. */ + modrm_byte rm; + rex_byte rex; + rex_byte vrex; + sib_byte sib; + vex_prefix vex; + + /* Masking attributes. */ + struct Mask_Operation *mask; + + /* Rounding control and SAE attributes. */ + struct RC_Operation *rounding; + + /* Broadcasting attributes. */ + struct Broadcast_Operation *broadcast; + + /* Compressed disp8*N attribute. */ + unsigned int memshift; + + /* Swap operand in encoding. */ + unsigned int swap_operand; + + /* Prefer 8bit or 32bit displacement in encoding. */ + enum + { + disp_encoding_default = 0, + disp_encoding_8bit, + disp_encoding_32bit + } disp_encoding; + + /* REP prefix. */ + const char *rep_prefix; + + /* HLE prefix. */ + const char *hle_prefix; + + /* Have BND prefix. */ + const char *bnd_prefix; + + /* Need VREX to support upper 16 registers. */ + int need_vrex; + + /* Error message. */ + enum i386_error error; + }; + +typedef struct _i386_insn i386_insn; + +/* Link RC type with corresponding string, that'll be looked for in + asm. */ +struct RC_name +{ + enum rc_type type; + const char *name; + unsigned int len; +}; + +static const struct RC_name RC_NamesTable[] = +{ + { rne, STRING_COMMA_LEN ("rn-sae") }, + { rd, STRING_COMMA_LEN ("rd-sae") }, + { ru, STRING_COMMA_LEN ("ru-sae") }, + { rz, STRING_COMMA_LEN ("rz-sae") }, + { saeonly, STRING_COMMA_LEN ("sae") }, +}; + +/* List of chars besides those in app.c:symbol_chars that can start an + operand. Used to prevent the scrubber eating vital white-space. */ +const char extra_symbol_chars[] = "*%-([{" +#ifdef LEX_AT + "@" +#endif +#ifdef LEX_QM + "?" +#endif + ; + +#if (defined (TE_I386AIX) \ + || ((defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) \ + && !defined (TE_GNU) \ + && !defined (TE_LINUX) \ + && !defined (TE_NACL) \ + && !defined (TE_NETWARE) \ + && !defined (TE_FreeBSD) \ + && !defined (TE_DragonFly) \ + && !defined (TE_NetBSD))) +/* This array holds the chars that always start a comment. If the + pre-processor is disabled, these aren't very useful. The option + --divide will remove '/' from this list. */ +const char *i386_comment_chars = "#/"; +#define SVR4_COMMENT_CHARS 1 +#define PREFIX_SEPARATOR '\\' + +#else +const char *i386_comment_chars = "#"; +#define PREFIX_SEPARATOR '/' +#endif + +/* This array holds the chars that only start a comment at the beginning of + a line. If the line seems to have the form '# 123 filename' + .line and .file directives will appear in the pre-processed output. + Note that input_file.c hand checks for '#' at the beginning of the + first line of the input file. This is because the compiler outputs + #NO_APP at the beginning of its output. + Also note that comments started like this one will always work if + '/' isn't otherwise defined. */ +const char line_comment_chars[] = "#/"; + +const char line_separator_chars[] = ";"; + +/* Chars that can be used to separate mant from exp in floating point + nums. */ +const char EXP_CHARS[] = "eE"; + +/* Chars that mean this number is a floating point constant + As in 0f12.456 + or 0d1.2345e12. */ +const char FLT_CHARS[] = "fFdDxX"; + +/* Tables for lexical analysis. */ +static char mnemonic_chars[256]; +static char register_chars[256]; +static char operand_chars[256]; +static char identifier_chars[256]; +static char digit_chars[256]; + +/* Lexical macros. */ +#define is_mnemonic_char(x) (mnemonic_chars[(unsigned char) x]) +#define is_operand_char(x) (operand_chars[(unsigned char) x]) +#define is_register_char(x) (register_chars[(unsigned char) x]) +#define is_space_char(x) ((x) == ' ') +#define is_identifier_char(x) (identifier_chars[(unsigned char) x]) +#define is_digit_char(x) (digit_chars[(unsigned char) x]) + +/* All non-digit non-letter characters that may occur in an operand. */ +static char operand_special_chars[] = "%$-+(,)*._~/<>|&^!:[@]"; + +/* md_assemble() always leaves the strings it's passed unaltered. To + effect this we maintain a stack of saved characters that we've smashed + with '\0's (indicating end of strings for various sub-fields of the + assembler instruction). */ +static char save_stack[32]; +static char *save_stack_p; +#define END_STRING_AND_SAVE(s) \ + do { *save_stack_p++ = *(s); *(s) = '\0'; } while (0) +#define RESTORE_END_STRING(s) \ + do { *(s) = *--save_stack_p; } while (0) + +/* The instruction we're assembling. */ +static i386_insn i; + +/* Possible templates for current insn. */ +static const templates *current_templates; + +/* Per instruction expressionS buffers: max displacements & immediates. */ +static expressionS disp_expressions[MAX_MEMORY_OPERANDS]; +static expressionS im_expressions[MAX_IMMEDIATE_OPERANDS]; + +/* Current operand we are working on. */ +static int this_operand = -1; + +/* We support four different modes. FLAG_CODE variable is used to distinguish + these. */ + +enum flag_code { + CODE_32BIT, + CODE_16BIT, + CODE_64BIT }; + +static enum flag_code flag_code; +static unsigned int object_64bit; +static unsigned int disallow_64bit_reloc; +static int use_rela_relocations = 0; + +#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ + || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) + +/* The ELF ABI to use. */ +enum x86_elf_abi +{ + I386_ABI, + X86_64_ABI, + X86_64_X32_ABI +}; + +static enum x86_elf_abi x86_elf_abi = I386_ABI; +#endif + +/* 1 for intel syntax, + 0 if att syntax. */ +static int intel_syntax = 0; + +/* 1 for intel mnemonic, + 0 if att mnemonic. */ +static int intel_mnemonic = !SYSV386_COMPAT; + +/* 1 if support old (<= 2.8.1) versions of gcc. */ +static int old_gcc = OLDGCC_COMPAT; + +/* 1 if pseudo registers are permitted. */ +static int allow_pseudo_reg = 0; + +/* 1 if register prefix % not required. */ +static int allow_naked_reg = 0; + +/* 1 if the assembler should add BND prefix for all control-tranferring + instructions supporting it, even if this prefix wasn't specified + explicitly. */ +static int add_bnd_prefix = 0; + +/* 1 if pseudo index register, eiz/riz, is allowed . */ +static int allow_index_reg = 0; + +static enum check_kind + { + check_none = 0, + check_warning, + check_error + } +sse_check, operand_check = check_warning; + +/* Register prefix used for error message. */ +static const char *register_prefix = "%"; + +/* Used in 16 bit gcc mode to add an l suffix to call, ret, enter, + leave, push, and pop instructions so that gcc has the same stack + frame as in 32 bit mode. */ +static char stackop_size = '\0'; + +/* Non-zero to optimize code alignment. */ +int optimize_align_code = 1; + +/* Non-zero to quieten some warnings. */ +static int quiet_warnings = 0; + +/* CPU name. */ +static const char *cpu_arch_name = NULL; +static char *cpu_sub_arch_name = NULL; + +/* CPU feature flags. */ +static i386_cpu_flags cpu_arch_flags = CPU_UNKNOWN_FLAGS; + +/* If we have selected a cpu we are generating instructions for. */ +static int cpu_arch_tune_set = 0; + +/* Cpu we are generating instructions for. */ +enum processor_type cpu_arch_tune = PROCESSOR_UNKNOWN; + +/* CPU feature flags of cpu we are generating instructions for. */ +static i386_cpu_flags cpu_arch_tune_flags; + +/* CPU instruction set architecture used. */ +enum processor_type cpu_arch_isa = PROCESSOR_UNKNOWN; + +/* CPU feature flags of instruction set architecture used. */ +i386_cpu_flags cpu_arch_isa_flags; + +/* If set, conditional jumps are not automatically promoted to handle + larger than a byte offset. */ +static unsigned int no_cond_jump_promotion = 0; + +/* Encode SSE instructions with VEX prefix. */ +static unsigned int sse2avx; + +/* Encode scalar AVX instructions with specific vector length. */ +static enum + { + vex128 = 0, + vex256 + } avxscalar; + +/* Encode scalar EVEX LIG instructions with specific vector length. */ +static enum + { + evexl128 = 0, + evexl256, + evexl512 + } evexlig; + +/* Encode EVEX WIG instructions with specific evex.w. */ +static enum + { + evexw0 = 0, + evexw1 + } evexwig; + +/* Pre-defined "_GLOBAL_OFFSET_TABLE_". */ +static symbolS *GOT_symbol; + +/* The dwarf2 return column, adjusted for 32 or 64 bit. */ +unsigned int x86_dwarf2_return_column; + +/* The dwarf2 data alignment, adjusted for 32 or 64 bit. */ +int x86_cie_data_alignment; + +/* Interface to relax_segment. + There are 3 major relax states for 386 jump insns because the + different types of jumps add different sizes to frags when we're + figuring out what sort of jump to choose to reach a given label. */ + +/* Types. */ +#define UNCOND_JUMP 0 +#define COND_JUMP 1 +#define COND_JUMP86 2 + +/* Sizes. */ +#define CODE16 1 +#define SMALL 0 +#define SMALL16 (SMALL | CODE16) +#define BIG 2 +#define BIG16 (BIG | CODE16) + +#ifndef INLINE +#ifdef __GNUC__ +#define INLINE __inline__ +#else +#define INLINE +#endif +#endif + +#define ENCODE_RELAX_STATE(type, size) \ + ((relax_substateT) (((type) << 2) | (size))) +#define TYPE_FROM_RELAX_STATE(s) \ + ((s) >> 2) +#define DISP_SIZE_FROM_RELAX_STATE(s) \ + ((((s) & 3) == BIG ? 4 : (((s) & 3) == BIG16 ? 2 : 1))) + +/* This table is used by relax_frag to promote short jumps to long + ones where necessary. SMALL (short) jumps may be promoted to BIG + (32 bit long) ones, and SMALL16 jumps to BIG16 (16 bit long). We + don't allow a short jump in a 32 bit code segment to be promoted to + a 16 bit offset jump because it's slower (requires data size + prefix), and doesn't work, unless the destination is in the bottom + 64k of the code segment (The top 16 bits of eip are zeroed). */ + +const relax_typeS md_relax_table[] = +{ + /* The fields are: + 1) most positive reach of this state, + 2) most negative reach of this state, + 3) how many bytes this mode will have in the variable part of the frag + 4) which index into the table to try if we can't fit into this one. */ + + /* UNCOND_JUMP states. */ + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)}, + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)}, + /* dword jmp adds 4 bytes to frag: + 0 extra opcode bytes, 4 displacement bytes. */ + {0, 0, 4, 0}, + /* word jmp adds 2 byte2 to frag: + 0 extra opcode bytes, 2 displacement bytes. */ + {0, 0, 2, 0}, + + /* COND_JUMP states. */ + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)}, + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)}, + /* dword conditionals adds 5 bytes to frag: + 1 extra opcode byte, 4 displacement bytes. */ + {0, 0, 5, 0}, + /* word conditionals add 3 bytes to frag: + 1 extra opcode byte, 2 displacement bytes. */ + {0, 0, 3, 0}, + + /* COND_JUMP86 states. */ + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)}, + {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)}, + /* dword conditionals adds 5 bytes to frag: + 1 extra opcode byte, 4 displacement bytes. */ + {0, 0, 5, 0}, + /* word conditionals add 4 bytes to frag: + 1 displacement byte and a 3 byte long branch insn. */ + {0, 0, 4, 0} +}; + +static const arch_entry cpu_arch[] = +{ + /* Do not replace the first two entries - i386_target_format() + relies on them being there in this order. */ + { STRING_COMMA_LEN ("generic32"), PROCESSOR_GENERIC32, + CPU_GENERIC32_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("generic64"), PROCESSOR_GENERIC64, + CPU_GENERIC64_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i8086"), PROCESSOR_UNKNOWN, + CPU_NONE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i186"), PROCESSOR_UNKNOWN, + CPU_I186_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i286"), PROCESSOR_UNKNOWN, + CPU_I286_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i386"), PROCESSOR_I386, + CPU_I386_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i486"), PROCESSOR_I486, + CPU_I486_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i586"), PROCESSOR_PENTIUM, + CPU_I586_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("i686"), PROCESSOR_PENTIUMPRO, + CPU_I686_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("pentium"), PROCESSOR_PENTIUM, + CPU_I586_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("pentiumpro"), PROCESSOR_PENTIUMPRO, + CPU_PENTIUMPRO_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("pentiumii"), PROCESSOR_PENTIUMPRO, + CPU_P2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("pentiumiii"),PROCESSOR_PENTIUMPRO, + CPU_P3_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("pentium4"), PROCESSOR_PENTIUM4, + CPU_P4_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("prescott"), PROCESSOR_NOCONA, + CPU_CORE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("nocona"), PROCESSOR_NOCONA, + CPU_NOCONA_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("yonah"), PROCESSOR_CORE, + CPU_CORE_FLAGS, 1, 0 }, + { STRING_COMMA_LEN ("core"), PROCESSOR_CORE, + CPU_CORE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("merom"), PROCESSOR_CORE2, + CPU_CORE2_FLAGS, 1, 0 }, + { STRING_COMMA_LEN ("core2"), PROCESSOR_CORE2, + CPU_CORE2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("corei7"), PROCESSOR_COREI7, + CPU_COREI7_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("l1om"), PROCESSOR_L1OM, + CPU_L1OM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("k1om"), PROCESSOR_K1OM, + CPU_K1OM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("k6"), PROCESSOR_K6, + CPU_K6_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("k6_2"), PROCESSOR_K6, + CPU_K6_2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("athlon"), PROCESSOR_ATHLON, + CPU_ATHLON_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("sledgehammer"), PROCESSOR_K8, + CPU_K8_FLAGS, 1, 0 }, + { STRING_COMMA_LEN ("opteron"), PROCESSOR_K8, + CPU_K8_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("k8"), PROCESSOR_K8, + CPU_K8_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("amdfam10"), PROCESSOR_AMDFAM10, + CPU_AMDFAM10_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("bdver1"), PROCESSOR_BD, + CPU_BDVER1_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("bdver2"), PROCESSOR_BD, + CPU_BDVER2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("bdver3"), PROCESSOR_BD, + CPU_BDVER3_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("btver1"), PROCESSOR_BT, + CPU_BTVER1_FLAGS, 0, 0 }, + { STRING_COMMA_LEN ("btver2"), PROCESSOR_BT, + CPU_BTVER2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".8087"), PROCESSOR_UNKNOWN, + CPU_8087_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".287"), PROCESSOR_UNKNOWN, + CPU_287_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".387"), PROCESSOR_UNKNOWN, + CPU_387_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".no87"), PROCESSOR_UNKNOWN, + CPU_ANY87_FLAGS, 0, 1 }, + { STRING_COMMA_LEN (".mmx"), PROCESSOR_UNKNOWN, + CPU_MMX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".nommx"), PROCESSOR_UNKNOWN, + CPU_3DNOWA_FLAGS, 0, 1 }, + { STRING_COMMA_LEN (".sse"), PROCESSOR_UNKNOWN, + CPU_SSE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse2"), PROCESSOR_UNKNOWN, + CPU_SSE2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse3"), PROCESSOR_UNKNOWN, + CPU_SSE3_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".ssse3"), PROCESSOR_UNKNOWN, + CPU_SSSE3_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse4.1"), PROCESSOR_UNKNOWN, + CPU_SSE4_1_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse4.2"), PROCESSOR_UNKNOWN, + CPU_SSE4_2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse4"), PROCESSOR_UNKNOWN, + CPU_SSE4_2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".nosse"), PROCESSOR_UNKNOWN, + CPU_ANY_SSE_FLAGS, 0, 1 }, + { STRING_COMMA_LEN (".avx"), PROCESSOR_UNKNOWN, + CPU_AVX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".avx2"), PROCESSOR_UNKNOWN, + CPU_AVX2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".avx512f"), PROCESSOR_UNKNOWN, + CPU_AVX512F_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".avx512cd"), PROCESSOR_UNKNOWN, + CPU_AVX512CD_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".avx512er"), PROCESSOR_UNKNOWN, + CPU_AVX512ER_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".avx512pf"), PROCESSOR_UNKNOWN, + CPU_AVX512PF_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".noavx"), PROCESSOR_UNKNOWN, + CPU_ANY_AVX_FLAGS, 0, 1 }, + { STRING_COMMA_LEN (".vmx"), PROCESSOR_UNKNOWN, + CPU_VMX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".vmfunc"), PROCESSOR_UNKNOWN, + CPU_VMFUNC_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".smx"), PROCESSOR_UNKNOWN, + CPU_SMX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".xsave"), PROCESSOR_UNKNOWN, + CPU_XSAVE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".xsaveopt"), PROCESSOR_UNKNOWN, + CPU_XSAVEOPT_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".aes"), PROCESSOR_UNKNOWN, + CPU_AES_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".pclmul"), PROCESSOR_UNKNOWN, + CPU_PCLMUL_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".clmul"), PROCESSOR_UNKNOWN, + CPU_PCLMUL_FLAGS, 1, 0 }, + { STRING_COMMA_LEN (".fsgsbase"), PROCESSOR_UNKNOWN, + CPU_FSGSBASE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".rdrnd"), PROCESSOR_UNKNOWN, + CPU_RDRND_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".f16c"), PROCESSOR_UNKNOWN, + CPU_F16C_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".bmi2"), PROCESSOR_UNKNOWN, + CPU_BMI2_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".fma"), PROCESSOR_UNKNOWN, + CPU_FMA_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".fma4"), PROCESSOR_UNKNOWN, + CPU_FMA4_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".xop"), PROCESSOR_UNKNOWN, + CPU_XOP_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".lwp"), PROCESSOR_UNKNOWN, + CPU_LWP_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".movbe"), PROCESSOR_UNKNOWN, + CPU_MOVBE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".cx16"), PROCESSOR_UNKNOWN, + CPU_CX16_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".ept"), PROCESSOR_UNKNOWN, + CPU_EPT_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".lzcnt"), PROCESSOR_UNKNOWN, + CPU_LZCNT_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".hle"), PROCESSOR_UNKNOWN, + CPU_HLE_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".rtm"), PROCESSOR_UNKNOWN, + CPU_RTM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".invpcid"), PROCESSOR_UNKNOWN, + CPU_INVPCID_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".clflush"), PROCESSOR_UNKNOWN, + CPU_CLFLUSH_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".nop"), PROCESSOR_UNKNOWN, + CPU_NOP_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".syscall"), PROCESSOR_UNKNOWN, + CPU_SYSCALL_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".rdtscp"), PROCESSOR_UNKNOWN, + CPU_RDTSCP_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".3dnow"), PROCESSOR_UNKNOWN, + CPU_3DNOW_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".3dnowa"), PROCESSOR_UNKNOWN, + CPU_3DNOWA_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".padlock"), PROCESSOR_UNKNOWN, + CPU_PADLOCK_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".pacifica"), PROCESSOR_UNKNOWN, + CPU_SVME_FLAGS, 1, 0 }, + { STRING_COMMA_LEN (".svme"), PROCESSOR_UNKNOWN, + CPU_SVME_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sse4a"), PROCESSOR_UNKNOWN, + CPU_SSE4A_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".abm"), PROCESSOR_UNKNOWN, + CPU_ABM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".bmi"), PROCESSOR_UNKNOWN, + CPU_BMI_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".tbm"), PROCESSOR_UNKNOWN, + CPU_TBM_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".adx"), PROCESSOR_UNKNOWN, + CPU_ADX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".rdseed"), PROCESSOR_UNKNOWN, + CPU_RDSEED_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".prfchw"), PROCESSOR_UNKNOWN, + CPU_PRFCHW_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".smap"), PROCESSOR_UNKNOWN, + CPU_SMAP_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".mpx"), PROCESSOR_UNKNOWN, + CPU_MPX_FLAGS, 0, 0 }, + { STRING_COMMA_LEN (".sha"), PROCESSOR_UNKNOWN, + CPU_SHA_FLAGS, 0, 0 }, +}; + +#ifdef I386COFF +/* Like s_lcomm_internal in gas/read.c but the alignment string + is allowed to be optional. */ + +static symbolS * +pe_lcomm_internal (int needs_align, symbolS *symbolP, addressT size) +{ + addressT align = 0; + + SKIP_WHITESPACE (); + + if (needs_align + && *input_line_pointer == ',') + { + align = parse_align (needs_align - 1); + + if (align == (addressT) -1) + return NULL; + } + else + { + if (size >= 8) + align = 3; + else if (size >= 4) + align = 2; + else if (size >= 2) + align = 1; + else + align = 0; + } + + bss_alloc (symbolP, size, align); + return symbolP; +} + +static void +pe_lcomm (int needs_align) +{ + s_comm_internal (needs_align * 2, pe_lcomm_internal); +} +#endif + +const pseudo_typeS md_pseudo_table[] = +{ +#if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO) + {"align", s_align_bytes, 0}, +#else + {"align", s_align_ptwo, 0}, +#endif + {"arch", set_cpu_arch, 0}, +#ifndef I386COFF + {"bss", s_bss, 0}, +#else + {"lcomm", pe_lcomm, 1}, +#endif + {"ffloat", float_cons, 'f'}, + {"dfloat", float_cons, 'd'}, + {"tfloat", float_cons, 'x'}, + {"value", cons, 2}, + {"slong", signed_cons, 4}, + {"noopt", s_ignore, 0}, + {"optim", s_ignore, 0}, + {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT}, + {"code16", set_code_flag, CODE_16BIT}, + {"code32", set_code_flag, CODE_32BIT}, + {"code64", set_code_flag, CODE_64BIT}, + {"intel_syntax", set_intel_syntax, 1}, + {"att_syntax", set_intel_syntax, 0}, + {"intel_mnemonic", set_intel_mnemonic, 1}, + {"att_mnemonic", set_intel_mnemonic, 0}, + {"allow_index_reg", set_allow_index_reg, 1}, + {"disallow_index_reg", set_allow_index_reg, 0}, + {"sse_check", set_check, 0}, + {"operand_check", set_check, 1}, +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + {"largecomm", handle_large_common, 0}, +#else + {"file", (void (*) (int)) dwarf2_directive_file, 0}, + {"loc", dwarf2_directive_loc, 0}, + {"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0}, +#endif +#ifdef TE_PE + {"secrel32", pe_directive_secrel, 0}, +#endif + {0, 0, 0} +}; + +/* For interface with expression (). */ +extern char *input_line_pointer; + +/* Hash table for instruction mnemonic lookup. */ +static struct hash_control *op_hash; + +/* Hash table for register lookup. */ +static struct hash_control *reg_hash; + +void +i386_align_code (fragS *fragP, int count) +{ + /* Various efficient no-op patterns for aligning code labels. + Note: Don't try to assemble the instructions in the comments. + 0L and 0w are not legal. */ + static const char f32_1[] = + {0x90}; /* nop */ + static const char f32_2[] = + {0x66,0x90}; /* xchg %ax,%ax */ + static const char f32_3[] = + {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */ + static const char f32_4[] = + {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ + static const char f32_5[] = + {0x90, /* nop */ + 0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */ + static const char f32_6[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */ + static const char f32_7[] = + {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ + static const char f32_8[] = + {0x90, /* nop */ + 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */ + static const char f32_9[] = + {0x89,0xf6, /* movl %esi,%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const char f32_10[] = + {0x8d,0x76,0x00, /* leal 0(%esi),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const char f32_11[] = + {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const char f32_12[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ + 0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */ + static const char f32_13[] = + {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const char f32_14[] = + {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */ + 0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */ + static const char f16_3[] = + {0x8d,0x74,0x00}; /* lea 0(%esi),%esi */ + static const char f16_4[] = + {0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ + static const char f16_5[] = + {0x90, /* nop */ + 0x8d,0xb4,0x00,0x00}; /* lea 0w(%si),%si */ + static const char f16_6[] = + {0x89,0xf6, /* mov %si,%si */ + 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ + static const char f16_7[] = + {0x8d,0x74,0x00, /* lea 0(%si),%si */ + 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ + static const char f16_8[] = + {0x8d,0xb4,0x00,0x00, /* lea 0w(%si),%si */ + 0x8d,0xbd,0x00,0x00}; /* lea 0w(%di),%di */ + static const char jump_31[] = + {0xeb,0x1d,0x90,0x90,0x90,0x90,0x90, /* jmp .+31; lotsa nops */ + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, + 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; + static const char *const f32_patt[] = { + f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8, + f32_9, f32_10, f32_11, f32_12, f32_13, f32_14 + }; + static const char *const f16_patt[] = { + f32_1, f32_2, f16_3, f16_4, f16_5, f16_6, f16_7, f16_8 + }; + /* nopl (%[re]ax) */ + static const char alt_3[] = + {0x0f,0x1f,0x00}; + /* nopl 0(%[re]ax) */ + static const char alt_4[] = + {0x0f,0x1f,0x40,0x00}; + /* nopl 0(%[re]ax,%[re]ax,1) */ + static const char alt_5[] = + {0x0f,0x1f,0x44,0x00,0x00}; + /* nopw 0(%[re]ax,%[re]ax,1) */ + static const char alt_6[] = + {0x66,0x0f,0x1f,0x44,0x00,0x00}; + /* nopl 0L(%[re]ax) */ + static const char alt_7[] = + {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; + /* nopl 0L(%[re]ax,%[re]ax,1) */ + static const char alt_8[] = + {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* nopw 0L(%[re]ax,%[re]ax,1) */ + static const char alt_9[] = + {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_10[] = + {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* data16 + nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_long_11[] = + {0x66, + 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* data16 + data16 + nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_long_12[] = + {0x66, + 0x66, + 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* data16 + data16 + data16 + nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_long_13[] = + {0x66, + 0x66, + 0x66, + 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* data16 + data16 + data16 + data16 + nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_long_14[] = + {0x66, + 0x66, + 0x66, + 0x66, + 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* data16 + data16 + data16 + data16 + data16 + nopw %cs:0L(%[re]ax,%[re]ax,1) */ + static const char alt_long_15[] = + {0x66, + 0x66, + 0x66, + 0x66, + 0x66, + 0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + /* nopl 0(%[re]ax,%[re]ax,1) + nopw 0(%[re]ax,%[re]ax,1) */ + static const char alt_short_11[] = + {0x0f,0x1f,0x44,0x00,0x00, + 0x66,0x0f,0x1f,0x44,0x00,0x00}; + /* nopw 0(%[re]ax,%[re]ax,1) + nopw 0(%[re]ax,%[re]ax,1) */ + static const char alt_short_12[] = + {0x66,0x0f,0x1f,0x44,0x00,0x00, + 0x66,0x0f,0x1f,0x44,0x00,0x00}; + /* nopw 0(%[re]ax,%[re]ax,1) + nopl 0L(%[re]ax) */ + static const char alt_short_13[] = + {0x66,0x0f,0x1f,0x44,0x00,0x00, + 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; + /* nopl 0L(%[re]ax) + nopl 0L(%[re]ax) */ + static const char alt_short_14[] = + {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00, + 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; + /* nopl 0L(%[re]ax) + nopl 0L(%[re]ax,%[re]ax,1) */ + static const char alt_short_15[] = + {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00, + 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; + static const char *const alt_short_patt[] = { + f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, + alt_9, alt_10, alt_short_11, alt_short_12, alt_short_13, + alt_short_14, alt_short_15 + }; + static const char *const alt_long_patt[] = { + f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, + alt_9, alt_10, alt_long_11, alt_long_12, alt_long_13, + alt_long_14, alt_long_15 + }; + + /* Only align for at least a positive non-zero boundary. */ + if (count <= 0 || count > MAX_MEM_FOR_RS_ALIGN_CODE) + return; + + /* We need to decide which NOP sequence to use for 32bit and + 64bit. When -mtune= is used: + + 1. For PROCESSOR_I386, PROCESSOR_I486, PROCESSOR_PENTIUM and + PROCESSOR_GENERIC32, f32_patt will be used. + 2. For PROCESSOR_PENTIUMPRO, PROCESSOR_PENTIUM4, PROCESSOR_NOCONA, + PROCESSOR_CORE, PROCESSOR_CORE2, PROCESSOR_COREI7, and + PROCESSOR_GENERIC64, alt_long_patt will be used. + 3. For PROCESSOR_ATHLON, PROCESSOR_K6, PROCESSOR_K8 and + PROCESSOR_AMDFAM10, PROCESSOR_BD and PROCESSOR_BT, alt_short_patt + will be used. + + When -mtune= isn't used, alt_long_patt will be used if + cpu_arch_isa_flags has CpuNop. Otherwise, f32_patt will + be used. + + When -march= or .arch is used, we can't use anything beyond + cpu_arch_isa_flags. */ + + if (flag_code == CODE_16BIT) + { + if (count > 8) + { + memcpy (fragP->fr_literal + fragP->fr_fix, + jump_31, count); + /* Adjust jump offset. */ + fragP->fr_literal[fragP->fr_fix + 1] = count - 2; + } + else + memcpy (fragP->fr_literal + fragP->fr_fix, + f16_patt[count - 1], count); + } + else + { + const char *const *patt = NULL; + + if (fragP->tc_frag_data.isa == PROCESSOR_UNKNOWN) + { + /* PROCESSOR_UNKNOWN means that all ISAs may be used. */ + switch (cpu_arch_tune) + { + case PROCESSOR_UNKNOWN: + /* We use cpu_arch_isa_flags to check if we SHOULD + optimize with nops. */ + if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) + patt = alt_long_patt; + else + patt = f32_patt; + break; + case PROCESSOR_PENTIUM4: + case PROCESSOR_NOCONA: + case PROCESSOR_CORE: + case PROCESSOR_CORE2: + case PROCESSOR_COREI7: + case PROCESSOR_L1OM: + case PROCESSOR_K1OM: + case PROCESSOR_GENERIC64: + patt = alt_long_patt; + break; + case PROCESSOR_K6: + case PROCESSOR_ATHLON: + case PROCESSOR_K8: + case PROCESSOR_AMDFAM10: + case PROCESSOR_BD: + case PROCESSOR_BT: + patt = alt_short_patt; + break; + case PROCESSOR_I386: + case PROCESSOR_I486: + case PROCESSOR_PENTIUM: + case PROCESSOR_PENTIUMPRO: + case PROCESSOR_GENERIC32: + patt = f32_patt; + break; + } + } + else + { + switch (fragP->tc_frag_data.tune) + { + case PROCESSOR_UNKNOWN: + /* When cpu_arch_isa is set, cpu_arch_tune shouldn't be + PROCESSOR_UNKNOWN. */ + abort (); + break; + + case PROCESSOR_I386: + case PROCESSOR_I486: + case PROCESSOR_PENTIUM: + case PROCESSOR_K6: + case PROCESSOR_ATHLON: + case PROCESSOR_K8: + case PROCESSOR_AMDFAM10: + case PROCESSOR_BD: + case PROCESSOR_BT: + case PROCESSOR_GENERIC32: + /* We use cpu_arch_isa_flags to check if we CAN optimize + with nops. */ + if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) + patt = alt_short_patt; + else + patt = f32_patt; + break; + case PROCESSOR_PENTIUMPRO: + case PROCESSOR_PENTIUM4: + case PROCESSOR_NOCONA: + case PROCESSOR_CORE: + case PROCESSOR_CORE2: + case PROCESSOR_COREI7: + case PROCESSOR_L1OM: + case PROCESSOR_K1OM: + if (fragP->tc_frag_data.isa_flags.bitfield.cpunop) + patt = alt_long_patt; + else + patt = f32_patt; + break; + case PROCESSOR_GENERIC64: + patt = alt_long_patt; + break; + } + } + + if (patt == f32_patt) + { + /* If the padding is less than 15 bytes, we use the normal + ones. Otherwise, we use a jump instruction and adjust + its offset. */ + int limit; + + /* For 64bit, the limit is 3 bytes. */ + if (flag_code == CODE_64BIT + && fragP->tc_frag_data.isa_flags.bitfield.cpulm) + limit = 3; + else + limit = 15; + if (count < limit) + memcpy (fragP->fr_literal + fragP->fr_fix, + patt[count - 1], count); + else + { + memcpy (fragP->fr_literal + fragP->fr_fix, + jump_31, count); + /* Adjust jump offset. */ + fragP->fr_literal[fragP->fr_fix + 1] = count - 2; + } + } + else + { + /* Maximum length of an instruction is 15 byte. If the + padding is greater than 15 bytes and we don't use jump, + we have to break it into smaller pieces. */ + int padding = count; + while (padding > 15) + { + padding -= 15; + memcpy (fragP->fr_literal + fragP->fr_fix + padding, + patt [14], 15); + } + + if (padding) + memcpy (fragP->fr_literal + fragP->fr_fix, + patt [padding - 1], padding); + } + } + fragP->fr_var = count; +} + +static INLINE int +operand_type_all_zero (const union i386_operand_type *x) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + if (x->array[2]) + return 0; + case 2: + if (x->array[1]) + return 0; + case 1: + return !x->array[0]; + default: + abort (); + } +} + +static INLINE void +operand_type_set (union i386_operand_type *x, unsigned int v) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + x->array[2] = v; + case 2: + x->array[1] = v; + case 1: + x->array[0] = v; + break; + default: + abort (); + } +} + +static INLINE int +operand_type_equal (const union i386_operand_type *x, + const union i386_operand_type *y) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + if (x->array[2] != y->array[2]) + return 0; + case 2: + if (x->array[1] != y->array[1]) + return 0; + case 1: + return x->array[0] == y->array[0]; + break; + default: + abort (); + } +} + +static INLINE int +cpu_flags_all_zero (const union i386_cpu_flags *x) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + if (x->array[2]) + return 0; + case 2: + if (x->array[1]) + return 0; + case 1: + return !x->array[0]; + default: + abort (); + } +} + +static INLINE void +cpu_flags_set (union i386_cpu_flags *x, unsigned int v) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + x->array[2] = v; + case 2: + x->array[1] = v; + case 1: + x->array[0] = v; + break; + default: + abort (); + } +} + +static INLINE int +cpu_flags_equal (const union i386_cpu_flags *x, + const union i386_cpu_flags *y) +{ + switch (ARRAY_SIZE(x->array)) + { + case 3: + if (x->array[2] != y->array[2]) + return 0; + case 2: + if (x->array[1] != y->array[1]) + return 0; + case 1: + return x->array[0] == y->array[0]; + break; + default: + abort (); + } +} + +static INLINE int +cpu_flags_check_cpu64 (i386_cpu_flags f) +{ + return !((flag_code == CODE_64BIT && f.bitfield.cpuno64) + || (flag_code != CODE_64BIT && f.bitfield.cpu64)); +} + +static INLINE i386_cpu_flags +cpu_flags_and (i386_cpu_flags x, i386_cpu_flags y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] &= y.array [2]; + case 2: + x.array [1] &= y.array [1]; + case 1: + x.array [0] &= y.array [0]; + break; + default: + abort (); + } + return x; +} + +static INLINE i386_cpu_flags +cpu_flags_or (i386_cpu_flags x, i386_cpu_flags y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] |= y.array [2]; + case 2: + x.array [1] |= y.array [1]; + case 1: + x.array [0] |= y.array [0]; + break; + default: + abort (); + } + return x; +} + +static INLINE i386_cpu_flags +cpu_flags_and_not (i386_cpu_flags x, i386_cpu_flags y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] &= ~y.array [2]; + case 2: + x.array [1] &= ~y.array [1]; + case 1: + x.array [0] &= ~y.array [0]; + break; + default: + abort (); + } + return x; +} + +#define CPU_FLAGS_ARCH_MATCH 0x1 +#define CPU_FLAGS_64BIT_MATCH 0x2 +#define CPU_FLAGS_AES_MATCH 0x4 +#define CPU_FLAGS_PCLMUL_MATCH 0x8 +#define CPU_FLAGS_AVX_MATCH 0x10 + +#define CPU_FLAGS_32BIT_MATCH \ + (CPU_FLAGS_ARCH_MATCH | CPU_FLAGS_AES_MATCH \ + | CPU_FLAGS_PCLMUL_MATCH | CPU_FLAGS_AVX_MATCH) +#define CPU_FLAGS_PERFECT_MATCH \ + (CPU_FLAGS_32BIT_MATCH | CPU_FLAGS_64BIT_MATCH) + +/* Return CPU flags match bits. */ + +static int +cpu_flags_match (const insn_template *t) +{ + i386_cpu_flags x = t->cpu_flags; + int match = cpu_flags_check_cpu64 (x) ? CPU_FLAGS_64BIT_MATCH : 0; + + x.bitfield.cpu64 = 0; + x.bitfield.cpuno64 = 0; + + if (cpu_flags_all_zero (&x)) + { + /* This instruction is available on all archs. */ + match |= CPU_FLAGS_32BIT_MATCH; + } + else + { + /* This instruction is available only on some archs. */ + i386_cpu_flags cpu = cpu_arch_flags; + + cpu.bitfield.cpu64 = 0; + cpu.bitfield.cpuno64 = 0; + cpu = cpu_flags_and (x, cpu); + if (!cpu_flags_all_zero (&cpu)) + { + if (x.bitfield.cpuavx) + { + /* We only need to check AES/PCLMUL/SSE2AVX with AVX. */ + if (cpu.bitfield.cpuavx) + { + /* Check SSE2AVX. */ + if (!t->opcode_modifier.sse2avx|| sse2avx) + { + match |= (CPU_FLAGS_ARCH_MATCH + | CPU_FLAGS_AVX_MATCH); + /* Check AES. */ + if (!x.bitfield.cpuaes || cpu.bitfield.cpuaes) + match |= CPU_FLAGS_AES_MATCH; + /* Check PCLMUL. */ + if (!x.bitfield.cpupclmul + || cpu.bitfield.cpupclmul) + match |= CPU_FLAGS_PCLMUL_MATCH; + } + } + else + match |= CPU_FLAGS_ARCH_MATCH; + } + else + match |= CPU_FLAGS_32BIT_MATCH; + } + } + return match; +} + +static INLINE i386_operand_type +operand_type_and (i386_operand_type x, i386_operand_type y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] &= y.array [2]; + case 2: + x.array [1] &= y.array [1]; + case 1: + x.array [0] &= y.array [0]; + break; + default: + abort (); + } + return x; +} + +static INLINE i386_operand_type +operand_type_or (i386_operand_type x, i386_operand_type y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] |= y.array [2]; + case 2: + x.array [1] |= y.array [1]; + case 1: + x.array [0] |= y.array [0]; + break; + default: + abort (); + } + return x; +} + +static INLINE i386_operand_type +operand_type_xor (i386_operand_type x, i386_operand_type y) +{ + switch (ARRAY_SIZE (x.array)) + { + case 3: + x.array [2] ^= y.array [2]; + case 2: + x.array [1] ^= y.array [1]; + case 1: + x.array [0] ^= y.array [0]; + break; + default: + abort (); + } + return x; +} + +static const i386_operand_type acc32 = OPERAND_TYPE_ACC32; +static const i386_operand_type acc64 = OPERAND_TYPE_ACC64; +static const i386_operand_type control = OPERAND_TYPE_CONTROL; +static const i386_operand_type inoutportreg + = OPERAND_TYPE_INOUTPORTREG; +static const i386_operand_type reg16_inoutportreg + = OPERAND_TYPE_REG16_INOUTPORTREG; +static const i386_operand_type disp16 = OPERAND_TYPE_DISP16; +static const i386_operand_type disp32 = OPERAND_TYPE_DISP32; +static const i386_operand_type disp32s = OPERAND_TYPE_DISP32S; +static const i386_operand_type disp16_32 = OPERAND_TYPE_DISP16_32; +static const i386_operand_type anydisp + = OPERAND_TYPE_ANYDISP; +static const i386_operand_type regxmm = OPERAND_TYPE_REGXMM; +static const i386_operand_type regymm = OPERAND_TYPE_REGYMM; +static const i386_operand_type regzmm = OPERAND_TYPE_REGZMM; +static const i386_operand_type regmask = OPERAND_TYPE_REGMASK; +static const i386_operand_type imm8 = OPERAND_TYPE_IMM8; +static const i386_operand_type imm8s = OPERAND_TYPE_IMM8S; +static const i386_operand_type imm16 = OPERAND_TYPE_IMM16; +static const i386_operand_type imm32 = OPERAND_TYPE_IMM32; +static const i386_operand_type imm32s = OPERAND_TYPE_IMM32S; +static const i386_operand_type imm64 = OPERAND_TYPE_IMM64; +static const i386_operand_type imm16_32 = OPERAND_TYPE_IMM16_32; +static const i386_operand_type imm16_32s = OPERAND_TYPE_IMM16_32S; +static const i386_operand_type imm16_32_32s = OPERAND_TYPE_IMM16_32_32S; +static const i386_operand_type vec_imm4 = OPERAND_TYPE_VEC_IMM4; +static const i386_operand_type regbnd = OPERAND_TYPE_REGBND; +static const i386_operand_type vec_disp8 = OPERAND_TYPE_VEC_DISP8; + +enum operand_type +{ + reg, + imm, + disp, + anymem +}; + +static INLINE int +operand_type_check (i386_operand_type t, enum operand_type c) +{ + switch (c) + { + case reg: + return (t.bitfield.reg8 + || t.bitfield.reg16 + || t.bitfield.reg32 + || t.bitfield.reg64); + + case imm: + return (t.bitfield.imm8 + || t.bitfield.imm8s + || t.bitfield.imm16 + || t.bitfield.imm32 + || t.bitfield.imm32s + || t.bitfield.imm64); + + case disp: + return (t.bitfield.disp8 + || t.bitfield.disp16 + || t.bitfield.disp32 + || t.bitfield.disp32s + || t.bitfield.disp64); + + case anymem: + return (t.bitfield.disp8 + || t.bitfield.disp16 + || t.bitfield.disp32 + || t.bitfield.disp32s + || t.bitfield.disp64 + || t.bitfield.baseindex); + + default: + abort (); + } + + return 0; +} + +/* Return 1 if there is no conflict in 8bit/16bit/32bit/64bit on + operand J for instruction template T. */ + +static INLINE int +match_reg_size (const insn_template *t, unsigned int j) +{ + return !((i.types[j].bitfield.byte + && !t->operand_types[j].bitfield.byte) + || (i.types[j].bitfield.word + && !t->operand_types[j].bitfield.word) + || (i.types[j].bitfield.dword + && !t->operand_types[j].bitfield.dword) + || (i.types[j].bitfield.qword + && !t->operand_types[j].bitfield.qword)); +} + +/* Return 1 if there is no conflict in any size on operand J for + instruction template T. */ + +static INLINE int +match_mem_size (const insn_template *t, unsigned int j) +{ + return (match_reg_size (t, j) + && !((i.types[j].bitfield.unspecified + && !t->operand_types[j].bitfield.unspecified) + || (i.types[j].bitfield.fword + && !t->operand_types[j].bitfield.fword) + || (i.types[j].bitfield.tbyte + && !t->operand_types[j].bitfield.tbyte) + || (i.types[j].bitfield.xmmword + && !t->operand_types[j].bitfield.xmmword) + || (i.types[j].bitfield.ymmword + && !t->operand_types[j].bitfield.ymmword) + || (i.types[j].bitfield.zmmword + && !t->operand_types[j].bitfield.zmmword))); +} + +/* Return 1 if there is no size conflict on any operands for + instruction template T. */ + +static INLINE int +operand_size_match (const insn_template *t) +{ + unsigned int j; + int match = 1; + + /* Don't check jump instructions. */ + if (t->opcode_modifier.jump + || t->opcode_modifier.jumpbyte + || t->opcode_modifier.jumpdword + || t->opcode_modifier.jumpintersegment) + return match; + + /* Check memory and accumulator operand size. */ + for (j = 0; j < i.operands; j++) + { + if (t->operand_types[j].bitfield.anysize) + continue; + + if (t->operand_types[j].bitfield.acc && !match_reg_size (t, j)) + { + match = 0; + break; + } + + if (i.types[j].bitfield.mem && !match_mem_size (t, j)) + { + match = 0; + break; + } + } + + if (match) + return match; + else if (!t->opcode_modifier.d && !t->opcode_modifier.floatd) + { +mismatch: + i.error = operand_size_mismatch; + return 0; + } + + /* Check reverse. */ + gas_assert (i.operands == 2); + + match = 1; + for (j = 0; j < 2; j++) + { + if (t->operand_types[j].bitfield.acc + && !match_reg_size (t, j ? 0 : 1)) + goto mismatch; + + if (i.types[j].bitfield.mem + && !match_mem_size (t, j ? 0 : 1)) + goto mismatch; + } + + return match; +} + +static INLINE int +operand_type_match (i386_operand_type overlap, + i386_operand_type given) +{ + i386_operand_type temp = overlap; + + temp.bitfield.jumpabsolute = 0; + temp.bitfield.unspecified = 0; + temp.bitfield.byte = 0; + temp.bitfield.word = 0; + temp.bitfield.dword = 0; + temp.bitfield.fword = 0; + temp.bitfield.qword = 0; + temp.bitfield.tbyte = 0; + temp.bitfield.xmmword = 0; + temp.bitfield.ymmword = 0; + temp.bitfield.zmmword = 0; + if (operand_type_all_zero (&temp)) + goto mismatch; + + if (given.bitfield.baseindex == overlap.bitfield.baseindex + && given.bitfield.jumpabsolute == overlap.bitfield.jumpabsolute) + return 1; + +mismatch: + i.error = operand_type_mismatch; + return 0; +} + +/* If given types g0 and g1 are registers they must be of the same type + unless the expected operand type register overlap is null. + Note that Acc in a template matches every size of reg. */ + +static INLINE int +operand_type_register_match (i386_operand_type m0, + i386_operand_type g0, + i386_operand_type t0, + i386_operand_type m1, + i386_operand_type g1, + i386_operand_type t1) +{ + if (!operand_type_check (g0, reg)) + return 1; + + if (!operand_type_check (g1, reg)) + return 1; + + if (g0.bitfield.reg8 == g1.bitfield.reg8 + && g0.bitfield.reg16 == g1.bitfield.reg16 + && g0.bitfield.reg32 == g1.bitfield.reg32 + && g0.bitfield.reg64 == g1.bitfield.reg64) + return 1; + + if (m0.bitfield.acc) + { + t0.bitfield.reg8 = 1; + t0.bitfield.reg16 = 1; + t0.bitfield.reg32 = 1; + t0.bitfield.reg64 = 1; + } + + if (m1.bitfield.acc) + { + t1.bitfield.reg8 = 1; + t1.bitfield.reg16 = 1; + t1.bitfield.reg32 = 1; + t1.bitfield.reg64 = 1; + } + + if (!(t0.bitfield.reg8 & t1.bitfield.reg8) + && !(t0.bitfield.reg16 & t1.bitfield.reg16) + && !(t0.bitfield.reg32 & t1.bitfield.reg32) + && !(t0.bitfield.reg64 & t1.bitfield.reg64)) + return 1; + + i.error = register_type_mismatch; + + return 0; +} + +static INLINE unsigned int +register_number (const reg_entry *r) +{ + unsigned int nr = r->reg_num; + + if (r->reg_flags & RegRex) + nr += 8; + + return nr; +} + +static INLINE unsigned int +mode_from_disp_size (i386_operand_type t) +{ + if (t.bitfield.disp8 || t.bitfield.vec_disp8) + return 1; + else if (t.bitfield.disp16 + || t.bitfield.disp32 + || t.bitfield.disp32s) + return 2; + else + return 0; +} + +static INLINE int +fits_in_signed_byte (offsetT num) +{ + return (num >= -128) && (num <= 127); +} + +static INLINE int +fits_in_unsigned_byte (offsetT num) +{ + return (num & 0xff) == num; +} + +static INLINE int +fits_in_unsigned_word (offsetT num) +{ + return (num & 0xffff) == num; +} + +static INLINE int +fits_in_signed_word (offsetT num) +{ + return (-32768 <= num) && (num <= 32767); +} + +static INLINE int +fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED) +{ +#ifndef BFD64 + return 1; +#else + return (!(((offsetT) -1 << 31) & num) + || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31)); +#endif +} /* fits_in_signed_long() */ + +static INLINE int +fits_in_unsigned_long (offsetT num ATTRIBUTE_UNUSED) +{ +#ifndef BFD64 + return 1; +#else + return (num & (((offsetT) 2 << 31) - 1)) == num; +#endif +} /* fits_in_unsigned_long() */ + +static INLINE int +fits_in_vec_disp8 (offsetT num) +{ + int shift = i.memshift; + unsigned int mask; + + if (shift == -1) + abort (); + + mask = (1 << shift) - 1; + + /* Return 0 if NUM isn't properly aligned. */ + if ((num & mask)) + return 0; + + /* Check if NUM will fit in 8bit after shift. */ + return fits_in_signed_byte (num >> shift); +} + +static INLINE int +fits_in_imm4 (offsetT num) +{ + return (num & 0xf) == num; +} + +static i386_operand_type +smallest_imm_type (offsetT num) +{ + i386_operand_type t; + + operand_type_set (&t, 0); + t.bitfield.imm64 = 1; + + if (cpu_arch_tune != PROCESSOR_I486 && num == 1) + { + /* This code is disabled on the 486 because all the Imm1 forms + in the opcode table are slower on the i486. They're the + versions with the implicitly specified single-position + displacement, which has another syntax if you really want to + use that form. */ + t.bitfield.imm1 = 1; + t.bitfield.imm8 = 1; + t.bitfield.imm8s = 1; + t.bitfield.imm16 = 1; + t.bitfield.imm32 = 1; + t.bitfield.imm32s = 1; + } + else if (fits_in_signed_byte (num)) + { + t.bitfield.imm8 = 1; + t.bitfield.imm8s = 1; + t.bitfield.imm16 = 1; + t.bitfield.imm32 = 1; + t.bitfield.imm32s = 1; + } + else if (fits_in_unsigned_byte (num)) + { + t.bitfield.imm8 = 1; + t.bitfield.imm16 = 1; + t.bitfield.imm32 = 1; + t.bitfield.imm32s = 1; + } + else if (fits_in_signed_word (num) || fits_in_unsigned_word (num)) + { + t.bitfield.imm16 = 1; + t.bitfield.imm32 = 1; + t.bitfield.imm32s = 1; + } + else if (fits_in_signed_long (num)) + { + t.bitfield.imm32 = 1; + t.bitfield.imm32s = 1; + } + else if (fits_in_unsigned_long (num)) + t.bitfield.imm32 = 1; + + return t; +} + +static offsetT +offset_in_range (offsetT val, int size) +{ + addressT mask; + + switch (size) + { + case 1: mask = ((addressT) 1 << 8) - 1; break; + case 2: mask = ((addressT) 1 << 16) - 1; break; + case 4: mask = ((addressT) 2 << 31) - 1; break; +#ifdef BFD64 + case 8: mask = ((addressT) 2 << 63) - 1; break; +#endif + default: abort (); + } + +#ifdef BFD64 + /* If BFD64, sign extend val for 32bit address mode. */ + if (flag_code != CODE_64BIT + || i.prefix[ADDR_PREFIX]) + if ((val & ~(((addressT) 2 << 31) - 1)) == 0) + val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31); +#endif + + if ((val & ~mask) != 0 && (val & ~mask) != ~mask) + { + char buf1[40], buf2[40]; + + sprint_value (buf1, val); + sprint_value (buf2, val & mask); + as_warn (_("%s shortened to %s"), buf1, buf2); + } + return val & mask; +} + +enum PREFIX_GROUP +{ + PREFIX_EXIST = 0, + PREFIX_LOCK, + PREFIX_REP, + PREFIX_OTHER +}; + +/* Returns + a. PREFIX_EXIST if attempting to add a prefix where one from the + same class already exists. + b. PREFIX_LOCK if lock prefix is added. + c. PREFIX_REP if rep/repne prefix is added. + d. PREFIX_OTHER if other prefix is added. + */ + +static enum PREFIX_GROUP +add_prefix (unsigned int prefix) +{ + enum PREFIX_GROUP ret = PREFIX_OTHER; + unsigned int q; + + if (prefix >= REX_OPCODE && prefix < REX_OPCODE + 16 + && flag_code == CODE_64BIT) + { + if ((i.prefix[REX_PREFIX] & prefix & REX_W) + || ((i.prefix[REX_PREFIX] & (REX_R | REX_X | REX_B)) + && (prefix & (REX_R | REX_X | REX_B)))) + ret = PREFIX_EXIST; + q = REX_PREFIX; + } + else + { + switch (prefix) + { + default: + abort (); + + case CS_PREFIX_OPCODE: + case DS_PREFIX_OPCODE: + case ES_PREFIX_OPCODE: + case FS_PREFIX_OPCODE: + case GS_PREFIX_OPCODE: + case SS_PREFIX_OPCODE: + q = SEG_PREFIX; + break; + + case REPNE_PREFIX_OPCODE: + case REPE_PREFIX_OPCODE: + q = REP_PREFIX; + ret = PREFIX_REP; + break; + + case LOCK_PREFIX_OPCODE: + q = LOCK_PREFIX; + ret = PREFIX_LOCK; + break; + + case FWAIT_OPCODE: + q = WAIT_PREFIX; + break; + + case ADDR_PREFIX_OPCODE: + q = ADDR_PREFIX; + break; + + case DATA_PREFIX_OPCODE: + q = DATA_PREFIX; + break; + } + if (i.prefix[q] != 0) + ret = PREFIX_EXIST; + } + + if (ret) + { + if (!i.prefix[q]) + ++i.prefixes; + i.prefix[q] |= prefix; + } + else + as_bad (_("same type of prefix used twice")); + + return ret; +} + +static void +update_code_flag (int value, int check) +{ + PRINTF_LIKE ((*as_error)); + + flag_code = (enum flag_code) value; + if (flag_code == CODE_64BIT) + { + cpu_arch_flags.bitfield.cpu64 = 1; + cpu_arch_flags.bitfield.cpuno64 = 0; + } + else + { + cpu_arch_flags.bitfield.cpu64 = 0; + cpu_arch_flags.bitfield.cpuno64 = 1; + } + if (value == CODE_64BIT && !cpu_arch_flags.bitfield.cpulm ) + { + if (check) + as_error = as_fatal; + else + as_error = as_bad; + (*as_error) (_("64bit mode not supported on `%s'."), + cpu_arch_name ? cpu_arch_name : default_arch); + } + if (value == CODE_32BIT && !cpu_arch_flags.bitfield.cpui386) + { + if (check) + as_error = as_fatal; + else + as_error = as_bad; + (*as_error) (_("32bit mode not supported on `%s'."), + cpu_arch_name ? cpu_arch_name : default_arch); + } + stackop_size = '\0'; +} + +static void +set_code_flag (int value) +{ + update_code_flag (value, 0); +} + +static void +set_16bit_gcc_code_flag (int new_code_flag) +{ + flag_code = (enum flag_code) new_code_flag; + if (flag_code != CODE_16BIT) + abort (); + cpu_arch_flags.bitfield.cpu64 = 0; + cpu_arch_flags.bitfield.cpuno64 = 1; + stackop_size = LONG_MNEM_SUFFIX; +} + +static void +set_intel_syntax (int syntax_flag) +{ + /* Find out if register prefixing is specified. */ + int ask_naked_reg = 0; + + SKIP_WHITESPACE (); + if (!is_end_of_line[(unsigned char) *input_line_pointer]) + { + char *string = input_line_pointer; + int e = get_symbol_end (); + + if (strcmp (string, "prefix") == 0) + ask_naked_reg = 1; + else if (strcmp (string, "noprefix") == 0) + ask_naked_reg = -1; + else + as_bad (_("bad argument to syntax directive.")); + *input_line_pointer = e; + } + demand_empty_rest_of_line (); + + intel_syntax = syntax_flag; + + if (ask_naked_reg == 0) + allow_naked_reg = (intel_syntax + && (bfd_get_symbol_leading_char (stdoutput) != '\0')); + else + allow_naked_reg = (ask_naked_reg < 0); + + expr_set_rank (O_full_ptr, syntax_flag ? 10 : 0); + + identifier_chars['%'] = intel_syntax && allow_naked_reg ? '%' : 0; + identifier_chars['$'] = intel_syntax ? '$' : 0; + register_prefix = allow_naked_reg ? "" : "%"; +} + +static void +set_intel_mnemonic (int mnemonic_flag) +{ + intel_mnemonic = mnemonic_flag; +} + +static void +set_allow_index_reg (int flag) +{ + allow_index_reg = flag; +} + +static void +set_check (int what) +{ + enum check_kind *kind; + const char *str; + + if (what) + { + kind = &operand_check; + str = "operand"; + } + else + { + kind = &sse_check; + str = "sse"; + } + + SKIP_WHITESPACE (); + + if (!is_end_of_line[(unsigned char) *input_line_pointer]) + { + char *string = input_line_pointer; + int e = get_symbol_end (); + + if (strcmp (string, "none") == 0) + *kind = check_none; + else if (strcmp (string, "warning") == 0) + *kind = check_warning; + else if (strcmp (string, "error") == 0) + *kind = check_error; + else + as_bad (_("bad argument to %s_check directive."), str); + *input_line_pointer = e; + } + else + as_bad (_("missing argument for %s_check directive"), str); + + demand_empty_rest_of_line (); +} + +static void +check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED, + i386_cpu_flags new_flag ATTRIBUTE_UNUSED) +{ +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + static const char *arch; + + /* Intel LIOM is only supported on ELF. */ + if (!IS_ELF) + return; + + if (!arch) + { + /* Use cpu_arch_name if it is set in md_parse_option. Otherwise + use default_arch. */ + arch = cpu_arch_name; + if (!arch) + arch = default_arch; + } + + /* If we are targeting Intel L1OM, we must enable it. */ + if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_L1OM + || new_flag.bitfield.cpul1om) + return; + + /* If we are targeting Intel K1OM, we must enable it. */ + if (get_elf_backend_data (stdoutput)->elf_machine_code != EM_K1OM + || new_flag.bitfield.cpuk1om) + return; + + as_bad (_("`%s' is not supported on `%s'"), name, arch); +#endif +} + +static void +set_cpu_arch (int dummy ATTRIBUTE_UNUSED) +{ + SKIP_WHITESPACE (); + + if (!is_end_of_line[(unsigned char) *input_line_pointer]) + { + char *string = input_line_pointer; + int e = get_symbol_end (); + unsigned int j; + i386_cpu_flags flags; + + for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) + { + if (strcmp (string, cpu_arch[j].name) == 0) + { + check_cpu_arch_compatible (string, cpu_arch[j].flags); + + if (*string != '.') + { + cpu_arch_name = cpu_arch[j].name; + cpu_sub_arch_name = NULL; + cpu_arch_flags = cpu_arch[j].flags; + if (flag_code == CODE_64BIT) + { + cpu_arch_flags.bitfield.cpu64 = 1; + cpu_arch_flags.bitfield.cpuno64 = 0; + } + else + { + cpu_arch_flags.bitfield.cpu64 = 0; + cpu_arch_flags.bitfield.cpuno64 = 1; + } + cpu_arch_isa = cpu_arch[j].type; + cpu_arch_isa_flags = cpu_arch[j].flags; + if (!cpu_arch_tune_set) + { + cpu_arch_tune = cpu_arch_isa; + cpu_arch_tune_flags = cpu_arch_isa_flags; + } + break; + } + + if (!cpu_arch[j].negated) + flags = cpu_flags_or (cpu_arch_flags, + cpu_arch[j].flags); + else + flags = cpu_flags_and_not (cpu_arch_flags, + cpu_arch[j].flags); + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + { + if (cpu_sub_arch_name) + { + char *name = cpu_sub_arch_name; + cpu_sub_arch_name = concat (name, + cpu_arch[j].name, + (const char *) NULL); + free (name); + } + else + cpu_sub_arch_name = xstrdup (cpu_arch[j].name); + cpu_arch_flags = flags; + cpu_arch_isa_flags = flags; + } + *input_line_pointer = e; + demand_empty_rest_of_line (); + return; + } + } + if (j >= ARRAY_SIZE (cpu_arch)) + as_bad (_("no such architecture: `%s'"), string); + + *input_line_pointer = e; + } + else + as_bad (_("missing cpu architecture")); + + no_cond_jump_promotion = 0; + if (*input_line_pointer == ',' + && !is_end_of_line[(unsigned char) input_line_pointer[1]]) + { + char *string = ++input_line_pointer; + int e = get_symbol_end (); + + if (strcmp (string, "nojumps") == 0) + no_cond_jump_promotion = 1; + else if (strcmp (string, "jumps") == 0) + ; + else + as_bad (_("no such architecture modifier: `%s'"), string); + + *input_line_pointer = e; + } + + demand_empty_rest_of_line (); +} + +enum bfd_architecture +i386_arch (void) +{ + if (cpu_arch_isa == PROCESSOR_L1OM) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour + || flag_code != CODE_64BIT) + as_fatal (_("Intel L1OM is 64bit ELF only")); + return bfd_arch_l1om; + } + else if (cpu_arch_isa == PROCESSOR_K1OM) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour + || flag_code != CODE_64BIT) + as_fatal (_("Intel K1OM is 64bit ELF only")); + return bfd_arch_k1om; + } + else + return bfd_arch_i386; +} + +unsigned long +i386_mach (void) +{ + if (!strncmp (default_arch, "x86_64", 6)) + { + if (cpu_arch_isa == PROCESSOR_L1OM) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour + || default_arch[6] != '\0') + as_fatal (_("Intel L1OM is 64bit ELF only")); + return bfd_mach_l1om; + } + else if (cpu_arch_isa == PROCESSOR_K1OM) + { + if (OUTPUT_FLAVOR != bfd_target_elf_flavour + || default_arch[6] != '\0') + as_fatal (_("Intel K1OM is 64bit ELF only")); + return bfd_mach_k1om; + } + else if (default_arch[6] == '\0') + return bfd_mach_x86_64; + else + return bfd_mach_x64_32; + } + else if (!strcmp (default_arch, "i386")) + return bfd_mach_i386_i386; + else + as_fatal (_("unknown architecture")); +} + +void +md_begin (void) +{ + const char *hash_err; + + /* Initialize op_hash hash table. */ + op_hash = hash_new (); + + { + const insn_template *optab; + templates *core_optab; + + /* Setup for loop. */ + optab = i386_optab; + core_optab = (templates *) xmalloc (sizeof (templates)); + core_optab->start = optab; + + while (1) + { + ++optab; + if (optab->name == NULL + || strcmp (optab->name, (optab - 1)->name) != 0) + { + /* different name --> ship out current template list; + add to hash table; & begin anew. */ + core_optab->end = optab; + hash_err = hash_insert (op_hash, + (optab - 1)->name, + (void *) core_optab); + if (hash_err) + { + as_fatal (_("can't hash %s: %s"), + (optab - 1)->name, + hash_err); + } + if (optab->name == NULL) + break; + core_optab = (templates *) xmalloc (sizeof (templates)); + core_optab->start = optab; + } + } + } + + /* Initialize reg_hash hash table. */ + reg_hash = hash_new (); + { + const reg_entry *regtab; + unsigned int regtab_size = i386_regtab_size; + + for (regtab = i386_regtab; regtab_size--; regtab++) + { + hash_err = hash_insert (reg_hash, regtab->reg_name, (void *) regtab); + if (hash_err) + as_fatal (_("can't hash %s: %s"), + regtab->reg_name, + hash_err); + } + } + + /* Fill in lexical tables: mnemonic_chars, operand_chars. */ + { + int c; + char *p; + + for (c = 0; c < 256; c++) + { + if (ISDIGIT (c)) + { + digit_chars[c] = c; + mnemonic_chars[c] = c; + register_chars[c] = c; + operand_chars[c] = c; + } + else if (ISLOWER (c)) + { + mnemonic_chars[c] = c; + register_chars[c] = c; + operand_chars[c] = c; + } + else if (ISUPPER (c)) + { + mnemonic_chars[c] = TOLOWER (c); + register_chars[c] = mnemonic_chars[c]; + operand_chars[c] = c; + } + else if (c == '{' || c == '}') + operand_chars[c] = c; + + if (ISALPHA (c) || ISDIGIT (c)) + identifier_chars[c] = c; + else if (c >= 128) + { + identifier_chars[c] = c; + operand_chars[c] = c; + } + } + +#ifdef LEX_AT + identifier_chars['@'] = '@'; +#endif +#ifdef LEX_QM + identifier_chars['?'] = '?'; + operand_chars['?'] = '?'; +#endif + digit_chars['-'] = '-'; + mnemonic_chars['_'] = '_'; + mnemonic_chars['-'] = '-'; + mnemonic_chars['.'] = '.'; + identifier_chars['_'] = '_'; + identifier_chars['.'] = '.'; + + for (p = operand_special_chars; *p != '\0'; p++) + operand_chars[(unsigned char) *p] = *p; + } + + if (flag_code == CODE_64BIT) + { +#if defined (OBJ_COFF) && defined (TE_PE) + x86_dwarf2_return_column = (OUTPUT_FLAVOR == bfd_target_coff_flavour + ? 32 : 16); +#else + x86_dwarf2_return_column = 16; +#endif + x86_cie_data_alignment = -8; + } + else + { + x86_dwarf2_return_column = 8; + x86_cie_data_alignment = -4; + } +} + +void +i386_print_statistics (FILE *file) +{ + hash_print_statistics (file, "i386 opcode", op_hash); + hash_print_statistics (file, "i386 register", reg_hash); +} + +#ifdef DEBUG386 + +/* Debugging routines for md_assemble. */ +static void pte (insn_template *); +static void pt (i386_operand_type); +static void pe (expressionS *); +static void ps (symbolS *); + +static void +pi (char *line, i386_insn *x) +{ + unsigned int j; + + fprintf (stdout, "%s: template ", line); + pte (&x->tm); + fprintf (stdout, " address: base %s index %s scale %x\n", + x->base_reg ? x->base_reg->reg_name : "none", + x->index_reg ? x->index_reg->reg_name : "none", + x->log2_scale_factor); + fprintf (stdout, " modrm: mode %x reg %x reg/mem %x\n", + x->rm.mode, x->rm.reg, x->rm.regmem); + fprintf (stdout, " sib: base %x index %x scale %x\n", + x->sib.base, x->sib.index, x->sib.scale); + fprintf (stdout, " rex: 64bit %x extX %x extY %x extZ %x\n", + (x->rex & REX_W) != 0, + (x->rex & REX_R) != 0, + (x->rex & REX_X) != 0, + (x->rex & REX_B) != 0); + for (j = 0; j < x->operands; j++) + { + fprintf (stdout, " #%d: ", j + 1); + pt (x->types[j]); + fprintf (stdout, "\n"); + if (x->types[j].bitfield.reg8 + || x->types[j].bitfield.reg16 + || x->types[j].bitfield.reg32 + || x->types[j].bitfield.reg64 + || x->types[j].bitfield.regmmx + || x->types[j].bitfield.regxmm + || x->types[j].bitfield.regymm + || x->types[j].bitfield.regzmm + || x->types[j].bitfield.sreg2 + || x->types[j].bitfield.sreg3 + || x->types[j].bitfield.control + || x->types[j].bitfield.debug + || x->types[j].bitfield.test) + fprintf (stdout, "%s\n", x->op[j].regs->reg_name); + if (operand_type_check (x->types[j], imm)) + pe (x->op[j].imms); + if (operand_type_check (x->types[j], disp)) + pe (x->op[j].disps); + } +} + +static void +pte (insn_template *t) +{ + unsigned int j; + fprintf (stdout, " %d operands ", t->operands); + fprintf (stdout, "opcode %x ", t->base_opcode); + if (t->extension_opcode != None) + fprintf (stdout, "ext %x ", t->extension_opcode); + if (t->opcode_modifier.d) + fprintf (stdout, "D"); + if (t->opcode_modifier.w) + fprintf (stdout, "W"); + fprintf (stdout, "\n"); + for (j = 0; j < t->operands; j++) + { + fprintf (stdout, " #%d type ", j + 1); + pt (t->operand_types[j]); + fprintf (stdout, "\n"); + } +} + +static void +pe (expressionS *e) +{ + fprintf (stdout, " operation %d\n", e->X_op); + fprintf (stdout, " add_number %ld (%lx)\n", + (long) e->X_add_number, (long) e->X_add_number); + if (e->X_add_symbol) + { + fprintf (stdout, " add_symbol "); + ps (e->X_add_symbol); + fprintf (stdout, "\n"); + } + if (e->X_op_symbol) + { + fprintf (stdout, " op_symbol "); + ps (e->X_op_symbol); + fprintf (stdout, "\n"); + } +} + +static void +ps (symbolS *s) +{ + fprintf (stdout, "%s type %s%s", + S_GET_NAME (s), + S_IS_EXTERNAL (s) ? "EXTERNAL " : "", + segment_name (S_GET_SEGMENT (s))); +} + +static struct type_name + { + i386_operand_type mask; + const char *name; + } +const type_names[] = +{ + { OPERAND_TYPE_REG8, "r8" }, + { OPERAND_TYPE_REG16, "r16" }, + { OPERAND_TYPE_REG32, "r32" }, + { OPERAND_TYPE_REG64, "r64" }, + { OPERAND_TYPE_IMM8, "i8" }, + { OPERAND_TYPE_IMM8, "i8s" }, + { OPERAND_TYPE_IMM16, "i16" }, + { OPERAND_TYPE_IMM32, "i32" }, + { OPERAND_TYPE_IMM32S, "i32s" }, + { OPERAND_TYPE_IMM64, "i64" }, + { OPERAND_TYPE_IMM1, "i1" }, + { OPERAND_TYPE_BASEINDEX, "BaseIndex" }, + { OPERAND_TYPE_DISP8, "d8" }, + { OPERAND_TYPE_DISP16, "d16" }, + { OPERAND_TYPE_DISP32, "d32" }, + { OPERAND_TYPE_DISP32S, "d32s" }, + { OPERAND_TYPE_DISP64, "d64" }, + { OPERAND_TYPE_VEC_DISP8, "Vector d8" }, + { OPERAND_TYPE_INOUTPORTREG, "InOutPortReg" }, + { OPERAND_TYPE_SHIFTCOUNT, "ShiftCount" }, + { OPERAND_TYPE_CONTROL, "control reg" }, + { OPERAND_TYPE_TEST, "test reg" }, + { OPERAND_TYPE_DEBUG, "debug reg" }, + { OPERAND_TYPE_FLOATREG, "FReg" }, + { OPERAND_TYPE_FLOATACC, "FAcc" }, + { OPERAND_TYPE_SREG2, "SReg2" }, + { OPERAND_TYPE_SREG3, "SReg3" }, + { OPERAND_TYPE_ACC, "Acc" }, + { OPERAND_TYPE_JUMPABSOLUTE, "Jump Absolute" }, + { OPERAND_TYPE_REGMMX, "rMMX" }, + { OPERAND_TYPE_REGXMM, "rXMM" }, + { OPERAND_TYPE_REGYMM, "rYMM" }, + { OPERAND_TYPE_REGZMM, "rZMM" }, + { OPERAND_TYPE_REGMASK, "Mask reg" }, + { OPERAND_TYPE_ESSEG, "es" }, +}; + +static void +pt (i386_operand_type t) +{ + unsigned int j; + i386_operand_type a; + + for (j = 0; j < ARRAY_SIZE (type_names); j++) + { + a = operand_type_and (t, type_names[j].mask); + if (!operand_type_all_zero (&a)) + fprintf (stdout, "%s, ", type_names[j].name); + } + fflush (stdout); +} + +#endif /* DEBUG386 */ + +static bfd_reloc_code_real_type +reloc (unsigned int size, + int pcrel, + int sign, + int bnd_prefix, + bfd_reloc_code_real_type other) +{ + if (other != NO_RELOC) + { + reloc_howto_type *rel; + + if (size == 8) + switch (other) + { + case BFD_RELOC_X86_64_GOT32: + return BFD_RELOC_X86_64_GOT64; + break; + case BFD_RELOC_X86_64_PLTOFF64: + return BFD_RELOC_X86_64_PLTOFF64; + break; + case BFD_RELOC_X86_64_GOTPC32: + other = BFD_RELOC_X86_64_GOTPC64; + break; + case BFD_RELOC_X86_64_GOTPCREL: + other = BFD_RELOC_X86_64_GOTPCREL64; + break; + case BFD_RELOC_X86_64_TPOFF32: + other = BFD_RELOC_X86_64_TPOFF64; + break; + case BFD_RELOC_X86_64_DTPOFF32: + other = BFD_RELOC_X86_64_DTPOFF64; + break; + default: + break; + } + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + if (other == BFD_RELOC_SIZE32) + { + if (size == 8) + return BFD_RELOC_SIZE64; + if (pcrel) + as_bad (_("there are no pc-relative size relocations")); + } +#endif + + /* Sign-checking 4-byte relocations in 16-/32-bit code is pointless. */ + if (size == 4 && (flag_code != CODE_64BIT || disallow_64bit_reloc)) + sign = -1; + + rel = bfd_reloc_type_lookup (stdoutput, other); + if (!rel) + as_bad (_("unknown relocation (%u)"), other); + else if (size != bfd_get_reloc_size (rel)) + as_bad (_("%u-byte relocation cannot be applied to %u-byte field"), + bfd_get_reloc_size (rel), + size); + else if (pcrel && !rel->pc_relative) + as_bad (_("non-pc-relative relocation for pc-relative field")); + else if ((rel->complain_on_overflow == complain_overflow_signed + && !sign) + || (rel->complain_on_overflow == complain_overflow_unsigned + && sign > 0)) + as_bad (_("relocated field and relocation type differ in signedness")); + else + return other; + return NO_RELOC; + } + + if (pcrel) + { + if (!sign) + as_bad (_("there are no unsigned pc-relative relocations")); + switch (size) + { + case 1: return BFD_RELOC_8_PCREL; + case 2: return BFD_RELOC_16_PCREL; + case 4: return (bnd_prefix && object_64bit + ? BFD_RELOC_X86_64_PC32_BND + : BFD_RELOC_32_PCREL); + case 8: return BFD_RELOC_64_PCREL; + } + as_bad (_("cannot do %u byte pc-relative relocation"), size); + } + else + { + if (sign > 0) + switch (size) + { + case 4: return BFD_RELOC_X86_64_32S; + } + else + switch (size) + { + case 1: return BFD_RELOC_8; + case 2: return BFD_RELOC_16; + case 4: return BFD_RELOC_32; + case 8: return BFD_RELOC_64; + } + as_bad (_("cannot do %s %u byte relocation"), + sign > 0 ? "signed" : "unsigned", size); + } + + return NO_RELOC; +} + +/* Here we decide which fixups can be adjusted to make them relative to + the beginning of the section instead of the symbol. Basically we need + to make sure that the dynamic relocations are done correctly, so in + some cases we force the original symbol to be used. */ + +int +tc_i386_fix_adjustable (fixS *fixP ATTRIBUTE_UNUSED) +{ +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + if (!IS_ELF) + return 1; + + /* Don't adjust pc-relative references to merge sections in 64-bit + mode. */ + if (use_rela_relocations + && (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0 + && fixP->fx_pcrel) + return 0; + + /* The x86_64 GOTPCREL are represented as 32bit PCrel relocations + and changed later by validate_fix. */ + if (GOT_symbol && fixP->fx_subsy == GOT_symbol + && fixP->fx_r_type == BFD_RELOC_32_PCREL) + return 0; + + /* Adjust_reloc_syms doesn't know about the GOT. Need to keep symbol + for size relocations. */ + if (fixP->fx_r_type == BFD_RELOC_SIZE32 + || fixP->fx_r_type == BFD_RELOC_SIZE64 + || fixP->fx_r_type == BFD_RELOC_386_GOTOFF + || fixP->fx_r_type == BFD_RELOC_386_PLT32 + || fixP->fx_r_type == BFD_RELOC_386_GOT32 + || fixP->fx_r_type == BFD_RELOC_386_TLS_GD + || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM + || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32 + || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32 + || fixP->fx_r_type == BFD_RELOC_386_TLS_IE + || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE + || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32 + || fixP->fx_r_type == BFD_RELOC_386_TLS_LE + || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTDESC + || fixP->fx_r_type == BFD_RELOC_386_TLS_DESC_CALL + || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOT32 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL + || fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD + || fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD + || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32 + || fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF + || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32 + || fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64 + || fixP->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC + || fixP->fx_r_type == BFD_RELOC_X86_64_TLSDESC_CALL + || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 0; +#endif + return 1; +} + +static int +intel_float_operand (const char *mnemonic) +{ + /* Note that the value returned is meaningful only for opcodes with (memory) + operands, hence the code here is free to improperly handle opcodes that + have no operands (for better performance and smaller code). */ + + if (mnemonic[0] != 'f') + return 0; /* non-math */ + + switch (mnemonic[1]) + { + /* fclex, fdecstp, fdisi, femms, feni, fincstp, finit, fsetpm, and + the fs segment override prefix not currently handled because no + call path can make opcodes without operands get here */ + case 'i': + return 2 /* integer op */; + case 'l': + if (mnemonic[2] == 'd' && (mnemonic[3] == 'c' || mnemonic[3] == 'e')) + return 3; /* fldcw/fldenv */ + break; + case 'n': + if (mnemonic[2] != 'o' /* fnop */) + return 3; /* non-waiting control op */ + break; + case 'r': + if (mnemonic[2] == 's') + return 3; /* frstor/frstpm */ + break; + case 's': + if (mnemonic[2] == 'a') + return 3; /* fsave */ + if (mnemonic[2] == 't') + { + switch (mnemonic[3]) + { + case 'c': /* fstcw */ + case 'd': /* fstdw */ + case 'e': /* fstenv */ + case 's': /* fsts[gw] */ + return 3; + } + } + break; + case 'x': + if (mnemonic[2] == 'r' || mnemonic[2] == 's') + return 0; /* fxsave/fxrstor are not really math ops */ + break; + } + + return 1; +} + +/* Build the VEX prefix. */ + +static void +build_vex_prefix (const insn_template *t) +{ + unsigned int register_specifier; + unsigned int implied_prefix; + unsigned int vector_length; + + /* Check register specifier. */ + if (i.vex.register_specifier) + { + register_specifier = + ~register_number (i.vex.register_specifier) & 0xf; + gas_assert ((i.vex.register_specifier->reg_flags & RegVRex) == 0); + } + else + register_specifier = 0xf; + + /* Use 2-byte VEX prefix by swappping destination and source + operand. */ + if (!i.swap_operand + && i.operands == i.reg_operands + && i.tm.opcode_modifier.vexopcode == VEX0F + && i.tm.opcode_modifier.s + && i.rex == REX_B) + { + unsigned int xchg = i.operands - 1; + union i386_op temp_op; + i386_operand_type temp_type; + + temp_type = i.types[xchg]; + i.types[xchg] = i.types[0]; + i.types[0] = temp_type; + temp_op = i.op[xchg]; + i.op[xchg] = i.op[0]; + i.op[0] = temp_op; + + gas_assert (i.rm.mode == 3); + + i.rex = REX_R; + xchg = i.rm.regmem; + i.rm.regmem = i.rm.reg; + i.rm.reg = xchg; + + /* Use the next insn. */ + i.tm = t[1]; + } + + if (i.tm.opcode_modifier.vex == VEXScalar) + vector_length = avxscalar; + else + vector_length = i.tm.opcode_modifier.vex == VEX256 ? 1 : 0; + + switch ((i.tm.base_opcode >> 8) & 0xff) + { + case 0: + implied_prefix = 0; + break; + case DATA_PREFIX_OPCODE: + implied_prefix = 1; + break; + case REPE_PREFIX_OPCODE: + implied_prefix = 2; + break; + case REPNE_PREFIX_OPCODE: + implied_prefix = 3; + break; + default: + abort (); + } + + /* Use 2-byte VEX prefix if possible. */ + if (i.tm.opcode_modifier.vexopcode == VEX0F + && i.tm.opcode_modifier.vexw != VEXW1 + && (i.rex & (REX_W | REX_X | REX_B)) == 0) + { + /* 2-byte VEX prefix. */ + unsigned int r; + + i.vex.length = 2; + i.vex.bytes[0] = 0xc5; + + /* Check the REX.R bit. */ + r = (i.rex & REX_R) ? 0 : 1; + i.vex.bytes[1] = (r << 7 + | register_specifier << 3 + | vector_length << 2 + | implied_prefix); + } + else + { + /* 3-byte VEX prefix. */ + unsigned int m, w; + + i.vex.length = 3; + + switch (i.tm.opcode_modifier.vexopcode) + { + case VEX0F: + m = 0x1; + i.vex.bytes[0] = 0xc4; + break; + case VEX0F38: + m = 0x2; + i.vex.bytes[0] = 0xc4; + break; + case VEX0F3A: + m = 0x3; + i.vex.bytes[0] = 0xc4; + break; + case XOP08: + m = 0x8; + i.vex.bytes[0] = 0x8f; + break; + case XOP09: + m = 0x9; + i.vex.bytes[0] = 0x8f; + break; + case XOP0A: + m = 0xa; + i.vex.bytes[0] = 0x8f; + break; + default: + abort (); + } + + /* The high 3 bits of the second VEX byte are 1's compliment + of RXB bits from REX. */ + i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m; + + /* Check the REX.W bit. */ + w = (i.rex & REX_W) ? 1 : 0; + if (i.tm.opcode_modifier.vexw) + { + if (w) + abort (); + + if (i.tm.opcode_modifier.vexw == VEXW1) + w = 1; + } + + i.vex.bytes[2] = (w << 7 + | register_specifier << 3 + | vector_length << 2 + | implied_prefix); + } +} + +/* Build the EVEX prefix. */ + +static void +build_evex_prefix (void) +{ + unsigned int register_specifier; + unsigned int implied_prefix; + unsigned int m, w; + rex_byte vrex_used = 0; + + /* Check register specifier. */ + if (i.vex.register_specifier) + { + gas_assert ((i.vrex & REX_X) == 0); + + register_specifier = i.vex.register_specifier->reg_num; + if ((i.vex.register_specifier->reg_flags & RegRex)) + register_specifier += 8; + /* The upper 16 registers are encoded in the fourth byte of the + EVEX prefix. */ + if (!(i.vex.register_specifier->reg_flags & RegVRex)) + i.vex.bytes[3] = 0x8; + register_specifier = ~register_specifier & 0xf; + } + else + { + register_specifier = 0xf; + + /* Encode upper 16 vector index register in the fourth byte of + the EVEX prefix. */ + if (!(i.vrex & REX_X)) + i.vex.bytes[3] = 0x8; + else + vrex_used |= REX_X; + } + + switch ((i.tm.base_opcode >> 8) & 0xff) + { + case 0: + implied_prefix = 0; + break; + case DATA_PREFIX_OPCODE: + implied_prefix = 1; + break; + case REPE_PREFIX_OPCODE: + implied_prefix = 2; + break; + case REPNE_PREFIX_OPCODE: + implied_prefix = 3; + break; + default: + abort (); + } + + /* 4 byte EVEX prefix. */ + i.vex.length = 4; + i.vex.bytes[0] = 0x62; + + /* mmmm bits. */ + switch (i.tm.opcode_modifier.vexopcode) + { + case VEX0F: + m = 1; + break; + case VEX0F38: + m = 2; + break; + case VEX0F3A: + m = 3; + break; + default: + abort (); + break; + } + + /* The high 3 bits of the second EVEX byte are 1's compliment of RXB + bits from REX. */ + i.vex.bytes[1] = (~i.rex & 0x7) << 5 | m; + + /* The fifth bit of the second EVEX byte is 1's compliment of the + REX_R bit in VREX. */ + if (!(i.vrex & REX_R)) + i.vex.bytes[1] |= 0x10; + else + vrex_used |= REX_R; + + if ((i.reg_operands + i.imm_operands) == i.operands) + { + /* When all operands are registers, the REX_X bit in REX is not + used. We reuse it to encode the upper 16 registers, which is + indicated by the REX_B bit in VREX. The REX_X bit is encoded + as 1's compliment. */ + if ((i.vrex & REX_B)) + { + vrex_used |= REX_B; + i.vex.bytes[1] &= ~0x40; + } + } + + /* EVEX instructions shouldn't need the REX prefix. */ + i.vrex &= ~vrex_used; + gas_assert (i.vrex == 0); + + /* Check the REX.W bit. */ + w = (i.rex & REX_W) ? 1 : 0; + if (i.tm.opcode_modifier.vexw) + { + if (i.tm.opcode_modifier.vexw == VEXW1) + w = 1; + } + /* If w is not set it means we are dealing with WIG instruction. */ + else if (!w) + { + if (evexwig == evexw1) + w = 1; + } + + /* Encode the U bit. */ + implied_prefix |= 0x4; + + /* The third byte of the EVEX prefix. */ + i.vex.bytes[2] = (w << 7 | register_specifier << 3 | implied_prefix); + + /* The fourth byte of the EVEX prefix. */ + /* The zeroing-masking bit. */ + if (i.mask && i.mask->zeroing) + i.vex.bytes[3] |= 0x80; + + /* Don't always set the broadcast bit if there is no RC. */ + if (!i.rounding) + { + /* Encode the vector length. */ + unsigned int vec_length; + + switch (i.tm.opcode_modifier.evex) + { + case EVEXLIG: /* LL' is ignored */ + vec_length = evexlig << 5; + break; + case EVEX128: + vec_length = 0 << 5; + break; + case EVEX256: + vec_length = 1 << 5; + break; + case EVEX512: + vec_length = 2 << 5; + break; + default: + abort (); + break; + } + i.vex.bytes[3] |= vec_length; + /* Encode the broadcast bit. */ + if (i.broadcast) + i.vex.bytes[3] |= 0x10; + } + else + { + if (i.rounding->type != saeonly) + i.vex.bytes[3] |= 0x10 | (i.rounding->type << 5); + else + i.vex.bytes[3] |= 0x10; + } + + if (i.mask && i.mask->mask) + i.vex.bytes[3] |= i.mask->mask->reg_num; +} + +static void +process_immext (void) +{ + expressionS *exp; + + if ((i.tm.cpu_flags.bitfield.cpusse3 || i.tm.cpu_flags.bitfield.cpusvme) + && i.operands > 0) + { + /* MONITOR/MWAIT as well as SVME instructions have fixed operands + with an opcode suffix which is coded in the same place as an + 8-bit immediate field would be. + Here we check those operands and remove them afterwards. */ + unsigned int x; + + for (x = 0; x < i.operands; x++) + if (register_number (i.op[x].regs) != x) + as_bad (_("can't use register '%s%s' as operand %d in '%s'."), + register_prefix, i.op[x].regs->reg_name, x + 1, + i.tm.name); + + i.operands = 0; + } + + /* These AMD 3DNow! and SSE2 instructions have an opcode suffix + which is coded in the same place as an 8-bit immediate field + would be. Here we fake an 8-bit immediate operand from the + opcode suffix stored in tm.extension_opcode. + + AVX instructions also use this encoding, for some of + 3 argument instructions. */ + + gas_assert (i.imm_operands <= 1 + && (i.operands <= 2 + || ((i.tm.opcode_modifier.vex + || i.tm.opcode_modifier.evex) + && i.operands <= 4))); + + exp = &im_expressions[i.imm_operands++]; + i.op[i.operands].imms = exp; + i.types[i.operands] = imm8; + i.operands++; + exp->X_op = O_constant; + exp->X_add_number = i.tm.extension_opcode; + i.tm.extension_opcode = None; +} + + +static int +check_hle (void) +{ + switch (i.tm.opcode_modifier.hleprefixok) + { + default: + abort (); + case HLEPrefixNone: + as_bad (_("invalid instruction `%s' after `%s'"), + i.tm.name, i.hle_prefix); + return 0; + case HLEPrefixLock: + if (i.prefix[LOCK_PREFIX]) + return 1; + as_bad (_("missing `lock' with `%s'"), i.hle_prefix); + return 0; + case HLEPrefixAny: + return 1; + case HLEPrefixRelease: + if (i.prefix[HLE_PREFIX] != XRELEASE_PREFIX_OPCODE) + { + as_bad (_("instruction `%s' after `xacquire' not allowed"), + i.tm.name); + return 0; + } + if (i.mem_operands == 0 + || !operand_type_check (i.types[i.operands - 1], anymem)) + { + as_bad (_("memory destination needed for instruction `%s'" + " after `xrelease'"), i.tm.name); + return 0; + } + return 1; + } +} + +/* This is the guts of the machine-dependent assembler. LINE points to a + machine dependent instruction. This function is supposed to emit + the frags/bytes it assembles to. */ + +void +md_assemble (char *line) +{ + unsigned int j; + char mnemonic[MAX_MNEM_SIZE]; + const insn_template *t; + + /* Initialize globals. */ + memset (&i, '\0', sizeof (i)); + for (j = 0; j < MAX_OPERANDS; j++) + i.reloc[j] = NO_RELOC; + memset (disp_expressions, '\0', sizeof (disp_expressions)); + memset (im_expressions, '\0', sizeof (im_expressions)); + save_stack_p = save_stack; + + /* First parse an instruction mnemonic & call i386_operand for the operands. + We assume that the scrubber has arranged it so that line[0] is the valid + start of a (possibly prefixed) mnemonic. */ + + line = parse_insn (line, mnemonic); + if (line == NULL) + return; + + line = parse_operands (line, mnemonic); + this_operand = -1; + if (line == NULL) + return; + + /* Now we've parsed the mnemonic into a set of templates, and have the + operands at hand. */ + + /* All intel opcodes have reversed operands except for "bound" and + "enter". We also don't reverse intersegment "jmp" and "call" + instructions with 2 immediate operands so that the immediate segment + precedes the offset, as it does when in AT&T mode. */ + if (intel_syntax + && i.operands > 1 + && (strcmp (mnemonic, "bound") != 0) + && (strcmp (mnemonic, "invlpga") != 0) + && !(operand_type_check (i.types[0], imm) + && operand_type_check (i.types[1], imm))) + swap_operands (); + + /* The order of the immediates should be reversed + for 2 immediates extrq and insertq instructions */ + if (i.imm_operands == 2 + && (strcmp (mnemonic, "extrq") == 0 + || strcmp (mnemonic, "insertq") == 0)) + swap_2_operands (0, 1); + + if (i.imm_operands) + optimize_imm (); + + /* Don't optimize displacement for movabs since it only takes 64bit + displacement. */ + if (i.disp_operands + && i.disp_encoding != disp_encoding_32bit + && (flag_code != CODE_64BIT + || strcmp (mnemonic, "movabs") != 0)) + optimize_disp (); + + /* Next, we find a template that matches the given insn, + making sure the overlap of the given operands types is consistent + with the template operand types. */ + + if (!(t = match_template ())) + return; + + if (sse_check != check_none + && !i.tm.opcode_modifier.noavx + && (i.tm.cpu_flags.bitfield.cpusse + || i.tm.cpu_flags.bitfield.cpusse2 + || i.tm.cpu_flags.bitfield.cpusse3 + || i.tm.cpu_flags.bitfield.cpussse3 + || i.tm.cpu_flags.bitfield.cpusse4_1 + || i.tm.cpu_flags.bitfield.cpusse4_2)) + { + (sse_check == check_warning + ? as_warn + : as_bad) (_("SSE instruction `%s' is used"), i.tm.name); + } + + /* Zap movzx and movsx suffix. The suffix has been set from + "word ptr" or "byte ptr" on the source operand in Intel syntax + or extracted from mnemonic in AT&T syntax. But we'll use + the destination register to choose the suffix for encoding. */ + if ((i.tm.base_opcode & ~9) == 0x0fb6) + { + /* In Intel syntax, there must be a suffix. In AT&T syntax, if + there is no suffix, the default will be byte extension. */ + if (i.reg_operands != 2 + && !i.suffix + && intel_syntax) + as_bad (_("ambiguous operand size for `%s'"), i.tm.name); + + i.suffix = 0; + } + + if (i.tm.opcode_modifier.fwait) + if (!add_prefix (FWAIT_OPCODE)) + return; + + /* Check if REP prefix is OK. */ + if (i.rep_prefix && !i.tm.opcode_modifier.repprefixok) + { + as_bad (_("invalid instruction `%s' after `%s'"), + i.tm.name, i.rep_prefix); + return; + } + + /* Check for lock without a lockable instruction. Destination operand + must be memory unless it is xchg (0x86). */ + if (i.prefix[LOCK_PREFIX] + && (!i.tm.opcode_modifier.islockable + || i.mem_operands == 0 + || (i.tm.base_opcode != 0x86 + && !operand_type_check (i.types[i.operands - 1], anymem)))) + { + as_bad (_("expecting lockable instruction after `lock'")); + return; + } + + /* Check if HLE prefix is OK. */ + if (i.hle_prefix && !check_hle ()) + return; + + /* Check BND prefix. */ + if (i.bnd_prefix && !i.tm.opcode_modifier.bndprefixok) + as_bad (_("expecting valid branch instruction after `bnd'")); + + if (i.tm.cpu_flags.bitfield.cpumpx + && flag_code == CODE_64BIT + && i.prefix[ADDR_PREFIX]) + as_bad (_("32-bit address isn't allowed in 64-bit MPX instructions.")); + + /* Insert BND prefix. */ + if (add_bnd_prefix + && i.tm.opcode_modifier.bndprefixok + && !i.prefix[BND_PREFIX]) + add_prefix (BND_PREFIX_OPCODE); + + /* Check string instruction segment overrides. */ + if (i.tm.opcode_modifier.isstring && i.mem_operands != 0) + { + if (!check_string ()) + return; + i.disp_operands = 0; + } + + if (!process_suffix ()) + return; + + /* Update operand types. */ + for (j = 0; j < i.operands; j++) + i.types[j] = operand_type_and (i.types[j], i.tm.operand_types[j]); + + /* Make still unresolved immediate matches conform to size of immediate + given in i.suffix. */ + if (!finalize_imm ()) + return; + + if (i.types[0].bitfield.imm1) + i.imm_operands = 0; /* kludge for shift insns. */ + + /* We only need to check those implicit registers for instructions + with 3 operands or less. */ + if (i.operands <= 3) + for (j = 0; j < i.operands; j++) + if (i.types[j].bitfield.inoutportreg + || i.types[j].bitfield.shiftcount + || i.types[j].bitfield.acc + || i.types[j].bitfield.floatacc) + i.reg_operands--; + + /* ImmExt should be processed after SSE2AVX. */ + if (!i.tm.opcode_modifier.sse2avx + && i.tm.opcode_modifier.immext) + process_immext (); + + /* For insns with operands there are more diddles to do to the opcode. */ + if (i.operands) + { + if (!process_operands ()) + return; + } + else if (!quiet_warnings && i.tm.opcode_modifier.ugh) + { + /* UnixWare fsub no args is alias for fsubp, fadd -> faddp, etc. */ + as_warn (_("translating to `%sp'"), i.tm.name); + } + + if (i.tm.opcode_modifier.vex) + build_vex_prefix (t); + + if (i.tm.opcode_modifier.evex) + build_evex_prefix (); + + /* Handle conversion of 'int $3' --> special int3 insn. XOP or FMA4 + instructions may define INT_OPCODE as well, so avoid this corner + case for those instructions that use MODRM. */ + if (i.tm.base_opcode == INT_OPCODE + && !i.tm.opcode_modifier.modrm + && i.op[0].imms->X_add_number == 3) + { + i.tm.base_opcode = INT3_OPCODE; + i.imm_operands = 0; + } + + if ((i.tm.opcode_modifier.jump + || i.tm.opcode_modifier.jumpbyte + || i.tm.opcode_modifier.jumpdword) + && i.op[0].disps->X_op == O_constant) + { + /* Convert "jmp constant" (and "call constant") to a jump (call) to + the absolute address given by the constant. Since ix86 jumps and + calls are pc relative, we need to generate a reloc. */ + i.op[0].disps->X_add_symbol = &abs_symbol; + i.op[0].disps->X_op = O_symbol; + } + + if (i.tm.opcode_modifier.rex64) + i.rex |= REX_W; + + /* For 8 bit registers we need an empty rex prefix. Also if the + instruction already has a prefix, we need to convert old + registers to new ones. */ + + if ((i.types[0].bitfield.reg8 + && (i.op[0].regs->reg_flags & RegRex64) != 0) + || (i.types[1].bitfield.reg8 + && (i.op[1].regs->reg_flags & RegRex64) != 0) + || ((i.types[0].bitfield.reg8 + || i.types[1].bitfield.reg8) + && i.rex != 0)) + { + int x; + + i.rex |= REX_OPCODE; + for (x = 0; x < 2; x++) + { + /* Look for 8 bit operand that uses old registers. */ + if (i.types[x].bitfield.reg8 + && (i.op[x].regs->reg_flags & RegRex64) == 0) + { + /* In case it is "hi" register, give up. */ + if (i.op[x].regs->reg_num > 3) + as_bad (_("can't encode register '%s%s' in an " + "instruction requiring REX prefix."), + register_prefix, i.op[x].regs->reg_name); + + /* Otherwise it is equivalent to the extended register. + Since the encoding doesn't change this is merely + cosmetic cleanup for debug output. */ + + i.op[x].regs = i.op[x].regs + 8; + } + } + } + + if (i.rex != 0) + add_prefix (REX_OPCODE | i.rex); + + /* We are ready to output the insn. */ + output_insn (); +} + +static char * +parse_insn (char *line, char *mnemonic) +{ + char *l = line; + char *token_start = l; + char *mnem_p; + int supported; + const insn_template *t; + char *dot_p = NULL; + + while (1) + { + mnem_p = mnemonic; + while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0) + { + if (*mnem_p == '.') + dot_p = mnem_p; + mnem_p++; + if (mnem_p >= mnemonic + MAX_MNEM_SIZE) + { + as_bad (_("no such instruction: `%s'"), token_start); + return NULL; + } + l++; + } + if (!is_space_char (*l) + && *l != END_OF_INSN + && (intel_syntax + || (*l != PREFIX_SEPARATOR + && *l != ','))) + { + as_bad (_("invalid character %s in mnemonic"), + output_invalid (*l)); + return NULL; + } + if (token_start == l) + { + if (!intel_syntax && *l == PREFIX_SEPARATOR) + as_bad (_("expecting prefix; got nothing")); + else + as_bad (_("expecting mnemonic; got nothing")); + return NULL; + } + + /* Look up instruction (or prefix) via hash table. */ + current_templates = (const templates *) hash_find (op_hash, mnemonic); + + if (*l != END_OF_INSN + && (!is_space_char (*l) || l[1] != END_OF_INSN) + && current_templates + && current_templates->start->opcode_modifier.isprefix) + { + if (!cpu_flags_check_cpu64 (current_templates->start->cpu_flags)) + { + as_bad ((flag_code != CODE_64BIT + ? _("`%s' is only supported in 64-bit mode") + : _("`%s' is not supported in 64-bit mode")), + current_templates->start->name); + return NULL; + } + /* If we are in 16-bit mode, do not allow addr16 or data16. + Similarly, in 32-bit mode, do not allow addr32 or data32. */ + if ((current_templates->start->opcode_modifier.size16 + || current_templates->start->opcode_modifier.size32) + && flag_code != CODE_64BIT + && (current_templates->start->opcode_modifier.size32 + ^ (flag_code == CODE_16BIT))) + { + as_bad (_("redundant %s prefix"), + current_templates->start->name); + return NULL; + } + /* Add prefix, checking for repeated prefixes. */ + switch (add_prefix (current_templates->start->base_opcode)) + { + case PREFIX_EXIST: + return NULL; + case PREFIX_REP: + if (current_templates->start->cpu_flags.bitfield.cpuhle) + i.hle_prefix = current_templates->start->name; + else if (current_templates->start->cpu_flags.bitfield.cpumpx) + i.bnd_prefix = current_templates->start->name; + else + i.rep_prefix = current_templates->start->name; + break; + default: + break; + } + /* Skip past PREFIX_SEPARATOR and reset token_start. */ + token_start = ++l; + } + else + break; + } + + if (!current_templates) + { + /* Check if we should swap operand or force 32bit displacement in + encoding. */ + if (mnem_p - 2 == dot_p && dot_p[1] == 's') + i.swap_operand = 1; + else if (mnem_p - 3 == dot_p + && dot_p[1] == 'd' + && dot_p[2] == '8') + i.disp_encoding = disp_encoding_8bit; + else if (mnem_p - 4 == dot_p + && dot_p[1] == 'd' + && dot_p[2] == '3' + && dot_p[3] == '2') + i.disp_encoding = disp_encoding_32bit; + else + goto check_suffix; + mnem_p = dot_p; + *dot_p = '\0'; + current_templates = (const templates *) hash_find (op_hash, mnemonic); + } + + if (!current_templates) + { +check_suffix: + /* See if we can get a match by trimming off a suffix. */ + switch (mnem_p[-1]) + { + case WORD_MNEM_SUFFIX: + if (intel_syntax && (intel_float_operand (mnemonic) & 2)) + i.suffix = SHORT_MNEM_SUFFIX; + else + case BYTE_MNEM_SUFFIX: + case QWORD_MNEM_SUFFIX: + i.suffix = mnem_p[-1]; + mnem_p[-1] = '\0'; + current_templates = (const templates *) hash_find (op_hash, + mnemonic); + break; + case SHORT_MNEM_SUFFIX: + case LONG_MNEM_SUFFIX: + if (!intel_syntax) + { + i.suffix = mnem_p[-1]; + mnem_p[-1] = '\0'; + current_templates = (const templates *) hash_find (op_hash, + mnemonic); + } + break; + + /* Intel Syntax. */ + case 'd': + if (intel_syntax) + { + if (intel_float_operand (mnemonic) == 1) + i.suffix = SHORT_MNEM_SUFFIX; + else + i.suffix = LONG_MNEM_SUFFIX; + mnem_p[-1] = '\0'; + current_templates = (const templates *) hash_find (op_hash, + mnemonic); + } + break; + } + if (!current_templates) + { + as_bad (_("no such instruction: `%s'"), token_start); + return NULL; + } + } + + if (current_templates->start->opcode_modifier.jump + || current_templates->start->opcode_modifier.jumpbyte) + { + /* Check for a branch hint. We allow ",pt" and ",pn" for + predict taken and predict not taken respectively. + I'm not sure that branch hints actually do anything on loop + and jcxz insns (JumpByte) for current Pentium4 chips. They + may work in the future and it doesn't hurt to accept them + now. */ + if (l[0] == ',' && l[1] == 'p') + { + if (l[2] == 't') + { + if (!add_prefix (DS_PREFIX_OPCODE)) + return NULL; + l += 3; + } + else if (l[2] == 'n') + { + if (!add_prefix (CS_PREFIX_OPCODE)) + return NULL; + l += 3; + } + } + } + /* Any other comma loses. */ + if (*l == ',') + { + as_bad (_("invalid character %s in mnemonic"), + output_invalid (*l)); + return NULL; + } + + /* Check if instruction is supported on specified architecture. */ + supported = 0; + for (t = current_templates->start; t < current_templates->end; ++t) + { + supported |= cpu_flags_match (t); + if (supported == CPU_FLAGS_PERFECT_MATCH) + goto skip; + } + + if (!(supported & CPU_FLAGS_64BIT_MATCH)) + { + as_bad (flag_code == CODE_64BIT + ? _("`%s' is not supported in 64-bit mode") + : _("`%s' is only supported in 64-bit mode"), + current_templates->start->name); + return NULL; + } + if (supported != CPU_FLAGS_PERFECT_MATCH) + { + as_bad (_("`%s' is not supported on `%s%s'"), + current_templates->start->name, + cpu_arch_name ? cpu_arch_name : default_arch, + cpu_sub_arch_name ? cpu_sub_arch_name : ""); + return NULL; + } + +skip: + if (!cpu_arch_flags.bitfield.cpui386 + && (flag_code != CODE_16BIT)) + { + as_warn (_("use .code16 to ensure correct addressing mode")); + } + + return l; +} + +static char * +parse_operands (char *l, const char *mnemonic) +{ + char *token_start; + + /* 1 if operand is pending after ','. */ + unsigned int expecting_operand = 0; + + /* Non-zero if operand parens not balanced. */ + unsigned int paren_not_balanced; + + while (*l != END_OF_INSN) + { + /* Skip optional white space before operand. */ + if (is_space_char (*l)) + ++l; + if (!is_operand_char (*l) && *l != END_OF_INSN) + { + as_bad (_("invalid character %s before operand %d"), + output_invalid (*l), + i.operands + 1); + return NULL; + } + token_start = l; /* after white space */ + paren_not_balanced = 0; + while (paren_not_balanced || *l != ',') + { + if (*l == END_OF_INSN) + { + if (paren_not_balanced) + { + if (!intel_syntax) + as_bad (_("unbalanced parenthesis in operand %d."), + i.operands + 1); + else + as_bad (_("unbalanced brackets in operand %d."), + i.operands + 1); + return NULL; + } + else + break; /* we are done */ + } + else if (!is_operand_char (*l) && !is_space_char (*l)) + { + as_bad (_("invalid character %s in operand %d"), + output_invalid (*l), + i.operands + 1); + return NULL; + } + if (!intel_syntax) + { + if (*l == '(') + ++paren_not_balanced; + if (*l == ')') + --paren_not_balanced; + } + else + { + if (*l == '[') + ++paren_not_balanced; + if (*l == ']') + --paren_not_balanced; + } + l++; + } + if (l != token_start) + { /* Yes, we've read in another operand. */ + unsigned int operand_ok; + this_operand = i.operands++; + i.types[this_operand].bitfield.unspecified = 1; + if (i.operands > MAX_OPERANDS) + { + as_bad (_("spurious operands; (%d operands/instruction max)"), + MAX_OPERANDS); + return NULL; + } + /* Now parse operand adding info to 'i' as we go along. */ + END_STRING_AND_SAVE (l); + + if (intel_syntax) + operand_ok = + i386_intel_operand (token_start, + intel_float_operand (mnemonic)); + else + operand_ok = i386_att_operand (token_start); + + RESTORE_END_STRING (l); + if (!operand_ok) + return NULL; + } + else + { + if (expecting_operand) + { + expecting_operand_after_comma: + as_bad (_("expecting operand after ','; got nothing")); + return NULL; + } + if (*l == ',') + { + as_bad (_("expecting operand before ','; got nothing")); + return NULL; + } + } + + /* Now *l must be either ',' or END_OF_INSN. */ + if (*l == ',') + { + if (*++l == END_OF_INSN) + { + /* Just skip it, if it's \n complain. */ + goto expecting_operand_after_comma; + } + expecting_operand = 1; + } + } + return l; +} + +static void +swap_2_operands (int xchg1, int xchg2) +{ + union i386_op temp_op; + i386_operand_type temp_type; + enum bfd_reloc_code_real temp_reloc; + + temp_type = i.types[xchg2]; + i.types[xchg2] = i.types[xchg1]; + i.types[xchg1] = temp_type; + temp_op = i.op[xchg2]; + i.op[xchg2] = i.op[xchg1]; + i.op[xchg1] = temp_op; + temp_reloc = i.reloc[xchg2]; + i.reloc[xchg2] = i.reloc[xchg1]; + i.reloc[xchg1] = temp_reloc; + + if (i.mask) + { + if (i.mask->operand == xchg1) + i.mask->operand = xchg2; + else if (i.mask->operand == xchg2) + i.mask->operand = xchg1; + } + if (i.broadcast) + { + if (i.broadcast->operand == xchg1) + i.broadcast->operand = xchg2; + else if (i.broadcast->operand == xchg2) + i.broadcast->operand = xchg1; + } + if (i.rounding) + { + if (i.rounding->operand == xchg1) + i.rounding->operand = xchg2; + else if (i.rounding->operand == xchg2) + i.rounding->operand = xchg1; + } +} + +static void +swap_operands (void) +{ + switch (i.operands) + { + case 5: + case 4: + swap_2_operands (1, i.operands - 2); + case 3: + case 2: + swap_2_operands (0, i.operands - 1); + break; + default: + abort (); + } + + if (i.mem_operands == 2) + { + const seg_entry *temp_seg; + temp_seg = i.seg[0]; + i.seg[0] = i.seg[1]; + i.seg[1] = temp_seg; + } +} + +/* Try to ensure constant immediates are represented in the smallest + opcode possible. */ +static void +optimize_imm (void) +{ + char guess_suffix = 0; + int op; + + if (i.suffix) + guess_suffix = i.suffix; + else if (i.reg_operands) + { + /* Figure out a suffix from the last register operand specified. + We can't do this properly yet, ie. excluding InOutPortReg, + but the following works for instructions with immediates. + In any case, we can't set i.suffix yet. */ + for (op = i.operands; --op >= 0;) + if (i.types[op].bitfield.reg8) + { + guess_suffix = BYTE_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg16) + { + guess_suffix = WORD_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg32) + { + guess_suffix = LONG_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg64) + { + guess_suffix = QWORD_MNEM_SUFFIX; + break; + } + } + else if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)) + guess_suffix = WORD_MNEM_SUFFIX; + + for (op = i.operands; --op >= 0;) + if (operand_type_check (i.types[op], imm)) + { + switch (i.op[op].imms->X_op) + { + case O_constant: + /* If a suffix is given, this operand may be shortened. */ + switch (guess_suffix) + { + case LONG_MNEM_SUFFIX: + i.types[op].bitfield.imm32 = 1; + i.types[op].bitfield.imm64 = 1; + break; + case WORD_MNEM_SUFFIX: + i.types[op].bitfield.imm16 = 1; + i.types[op].bitfield.imm32 = 1; + i.types[op].bitfield.imm32s = 1; + i.types[op].bitfield.imm64 = 1; + break; + case BYTE_MNEM_SUFFIX: + i.types[op].bitfield.imm8 = 1; + i.types[op].bitfield.imm8s = 1; + i.types[op].bitfield.imm16 = 1; + i.types[op].bitfield.imm32 = 1; + i.types[op].bitfield.imm32s = 1; + i.types[op].bitfield.imm64 = 1; + break; + } + + /* If this operand is at most 16 bits, convert it + to a signed 16 bit number before trying to see + whether it will fit in an even smaller size. + This allows a 16-bit operand such as $0xffe0 to + be recognised as within Imm8S range. */ + if ((i.types[op].bitfield.imm16) + && (i.op[op].imms->X_add_number & ~(offsetT) 0xffff) == 0) + { + i.op[op].imms->X_add_number = + (((i.op[op].imms->X_add_number & 0xffff) ^ 0x8000) - 0x8000); + } + if ((i.types[op].bitfield.imm32) + && ((i.op[op].imms->X_add_number & ~(((offsetT) 2 << 31) - 1)) + == 0)) + { + i.op[op].imms->X_add_number = ((i.op[op].imms->X_add_number + ^ ((offsetT) 1 << 31)) + - ((offsetT) 1 << 31)); + } + i.types[op] + = operand_type_or (i.types[op], + smallest_imm_type (i.op[op].imms->X_add_number)); + + /* We must avoid matching of Imm32 templates when 64bit + only immediate is available. */ + if (guess_suffix == QWORD_MNEM_SUFFIX) + i.types[op].bitfield.imm32 = 0; + break; + + case O_absent: + case O_register: + abort (); + + /* Symbols and expressions. */ + default: + /* Convert symbolic operand to proper sizes for matching, but don't + prevent matching a set of insns that only supports sizes other + than those matching the insn suffix. */ + { + i386_operand_type mask, allowed; + const insn_template *t; + + operand_type_set (&mask, 0); + operand_type_set (&allowed, 0); + + for (t = current_templates->start; + t < current_templates->end; + ++t) + allowed = operand_type_or (allowed, + t->operand_types[op]); + switch (guess_suffix) + { + case QWORD_MNEM_SUFFIX: + mask.bitfield.imm64 = 1; + mask.bitfield.imm32s = 1; + break; + case LONG_MNEM_SUFFIX: + mask.bitfield.imm32 = 1; + break; + case WORD_MNEM_SUFFIX: + mask.bitfield.imm16 = 1; + break; + case BYTE_MNEM_SUFFIX: + mask.bitfield.imm8 = 1; + break; + default: + break; + } + allowed = operand_type_and (mask, allowed); + if (!operand_type_all_zero (&allowed)) + i.types[op] = operand_type_and (i.types[op], mask); + } + break; + } + } +} + +/* Try to use the smallest displacement type too. */ +static void +optimize_disp (void) +{ + int op; + + for (op = i.operands; --op >= 0;) + if (operand_type_check (i.types[op], disp)) + { + if (i.op[op].disps->X_op == O_constant) + { + offsetT op_disp = i.op[op].disps->X_add_number; + + if (i.types[op].bitfield.disp16 + && (op_disp & ~(offsetT) 0xffff) == 0) + { + /* If this operand is at most 16 bits, convert + to a signed 16 bit number and don't use 64bit + displacement. */ + op_disp = (((op_disp & 0xffff) ^ 0x8000) - 0x8000); + i.types[op].bitfield.disp64 = 0; + } + if (i.types[op].bitfield.disp32 + && (op_disp & ~(((offsetT) 2 << 31) - 1)) == 0) + { + /* If this operand is at most 32 bits, convert + to a signed 32 bit number and don't use 64bit + displacement. */ + op_disp &= (((offsetT) 2 << 31) - 1); + op_disp = (op_disp ^ ((offsetT) 1 << 31)) - ((addressT) 1 << 31); + i.types[op].bitfield.disp64 = 0; + } + if (!op_disp && i.types[op].bitfield.baseindex) + { + i.types[op].bitfield.disp8 = 0; + i.types[op].bitfield.disp16 = 0; + i.types[op].bitfield.disp32 = 0; + i.types[op].bitfield.disp32s = 0; + i.types[op].bitfield.disp64 = 0; + i.op[op].disps = 0; + i.disp_operands--; + } + else if (flag_code == CODE_64BIT) + { + if (fits_in_signed_long (op_disp)) + { + i.types[op].bitfield.disp64 = 0; + i.types[op].bitfield.disp32s = 1; + } + if (i.prefix[ADDR_PREFIX] + && fits_in_unsigned_long (op_disp)) + i.types[op].bitfield.disp32 = 1; + } + if ((i.types[op].bitfield.disp32 + || i.types[op].bitfield.disp32s + || i.types[op].bitfield.disp16) + && fits_in_signed_byte (op_disp)) + i.types[op].bitfield.disp8 = 1; + } + else if (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL + || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL) + { + fix_new_exp (frag_now, frag_more (0) - frag_now->fr_literal, 0, + i.op[op].disps, 0, i.reloc[op]); + i.types[op].bitfield.disp8 = 0; + i.types[op].bitfield.disp16 = 0; + i.types[op].bitfield.disp32 = 0; + i.types[op].bitfield.disp32s = 0; + i.types[op].bitfield.disp64 = 0; + } + else + /* We only support 64bit displacement on constants. */ + i.types[op].bitfield.disp64 = 0; + } +} + +/* Check if operands are valid for the instruction. */ + +static int +check_VecOperands (const insn_template *t) +{ + unsigned int op; + + /* Without VSIB byte, we can't have a vector register for index. */ + if (!t->opcode_modifier.vecsib + && i.index_reg + && (i.index_reg->reg_type.bitfield.regxmm + || i.index_reg->reg_type.bitfield.regymm + || i.index_reg->reg_type.bitfield.regzmm)) + { + i.error = unsupported_vector_index_register; + return 1; + } + + /* Check if default mask is allowed. */ + if (t->opcode_modifier.nodefmask + && (!i.mask || i.mask->mask->reg_num == 0)) + { + i.error = no_default_mask; + return 1; + } + + /* For VSIB byte, we need a vector register for index, and all vector + registers must be distinct. */ + if (t->opcode_modifier.vecsib) + { + if (!i.index_reg + || !((t->opcode_modifier.vecsib == VecSIB128 + && i.index_reg->reg_type.bitfield.regxmm) + || (t->opcode_modifier.vecsib == VecSIB256 + && i.index_reg->reg_type.bitfield.regymm) + || (t->opcode_modifier.vecsib == VecSIB512 + && i.index_reg->reg_type.bitfield.regzmm))) + { + i.error = invalid_vsib_address; + return 1; + } + + gas_assert (i.reg_operands == 2 || i.mask); + if (i.reg_operands == 2 && !i.mask) + { + gas_assert (i.types[0].bitfield.regxmm + || i.types[0].bitfield.regymm + || i.types[0].bitfield.regzmm); + gas_assert (i.types[2].bitfield.regxmm + || i.types[2].bitfield.regymm + || i.types[2].bitfield.regzmm); + if (operand_check == check_none) + return 0; + if (register_number (i.op[0].regs) + != register_number (i.index_reg) + && register_number (i.op[2].regs) + != register_number (i.index_reg) + && register_number (i.op[0].regs) + != register_number (i.op[2].regs)) + return 0; + if (operand_check == check_error) + { + i.error = invalid_vector_register_set; + return 1; + } + as_warn (_("mask, index, and destination registers should be distinct")); + } + } + + /* Check if broadcast is supported by the instruction and is applied + to the memory operand. */ + if (i.broadcast) + { + int broadcasted_opnd_size; + + /* Check if specified broadcast is supported in this instruction, + and it's applied to memory operand of DWORD or QWORD type, + depending on VecESize. */ + if (i.broadcast->type != t->opcode_modifier.broadcast + || !i.types[i.broadcast->operand].bitfield.mem + || (t->opcode_modifier.vecesize == 0 + && !i.types[i.broadcast->operand].bitfield.dword + && !i.types[i.broadcast->operand].bitfield.unspecified) + || (t->opcode_modifier.vecesize == 1 + && !i.types[i.broadcast->operand].bitfield.qword + && !i.types[i.broadcast->operand].bitfield.unspecified)) + goto bad_broadcast; + + broadcasted_opnd_size = t->opcode_modifier.vecesize ? 64 : 32; + if (i.broadcast->type == BROADCAST_1TO16) + broadcasted_opnd_size <<= 4; /* Broadcast 1to16. */ + else if (i.broadcast->type == BROADCAST_1TO8) + broadcasted_opnd_size <<= 3; /* Broadcast 1to8. */ + else + goto bad_broadcast; + + if ((broadcasted_opnd_size == 256 + && !t->operand_types[i.broadcast->operand].bitfield.ymmword) + || (broadcasted_opnd_size == 512 + && !t->operand_types[i.broadcast->operand].bitfield.zmmword)) + { + bad_broadcast: + i.error = unsupported_broadcast; + return 1; + } + } + /* If broadcast is supported in this instruction, we need to check if + operand of one-element size isn't specified without broadcast. */ + else if (t->opcode_modifier.broadcast && i.mem_operands) + { + /* Find memory operand. */ + for (op = 0; op < i.operands; op++) + if (operand_type_check (i.types[op], anymem)) + break; + gas_assert (op < i.operands); + /* Check size of the memory operand. */ + if ((t->opcode_modifier.vecesize == 0 + && i.types[op].bitfield.dword) + || (t->opcode_modifier.vecesize == 1 + && i.types[op].bitfield.qword)) + { + i.error = broadcast_needed; + return 1; + } + } + + /* Check if requested masking is supported. */ + if (i.mask + && (!t->opcode_modifier.masking + || (i.mask->zeroing + && t->opcode_modifier.masking == MERGING_MASKING))) + { + i.error = unsupported_masking; + return 1; + } + + /* Check if masking is applied to dest operand. */ + if (i.mask && (i.mask->operand != (int) (i.operands - 1))) + { + i.error = mask_not_on_destination; + return 1; + } + + /* Check RC/SAE. */ + if (i.rounding) + { + if ((i.rounding->type != saeonly + && !t->opcode_modifier.staticrounding) + || (i.rounding->type == saeonly + && (t->opcode_modifier.staticrounding + || !t->opcode_modifier.sae))) + { + i.error = unsupported_rc_sae; + return 1; + } + /* If the instruction has several immediate operands and one of + them is rounding, the rounding operand should be the last + immediate operand. */ + if (i.imm_operands > 1 + && i.rounding->operand != (int) (i.imm_operands - 1)) + { + i.error = rc_sae_operand_not_last_imm; + return 1; + } + } + + /* Check vector Disp8 operand. */ + if (t->opcode_modifier.disp8memshift) + { + if (i.broadcast) + i.memshift = t->opcode_modifier.vecesize ? 3 : 2; + else + i.memshift = t->opcode_modifier.disp8memshift; + + for (op = 0; op < i.operands; op++) + if (operand_type_check (i.types[op], disp) + && i.op[op].disps->X_op == O_constant) + { + offsetT value = i.op[op].disps->X_add_number; + int vec_disp8_ok = fits_in_vec_disp8 (value); + if (t->operand_types [op].bitfield.vec_disp8) + { + if (vec_disp8_ok) + i.types[op].bitfield.vec_disp8 = 1; + else + { + /* Vector insn can only have Vec_Disp8/Disp32 in + 32/64bit modes, and Vec_Disp8/Disp16 in 16bit + mode. */ + i.types[op].bitfield.disp8 = 0; + if (flag_code != CODE_16BIT) + i.types[op].bitfield.disp16 = 0; + } + } + else if (flag_code != CODE_16BIT) + { + /* One form of this instruction supports vector Disp8. + Try vector Disp8 if we need to use Disp32. */ + if (vec_disp8_ok && !fits_in_signed_byte (value)) + { + i.error = try_vector_disp8; + return 1; + } + } + } + } + else + i.memshift = -1; + + return 0; +} + +/* Check if operands are valid for the instruction. Update VEX + operand types. */ + +static int +VEX_check_operands (const insn_template *t) +{ + /* VREX is only valid with EVEX prefix. */ + if (i.need_vrex && !t->opcode_modifier.evex) + { + i.error = invalid_register_operand; + return 1; + } + + if (!t->opcode_modifier.vex) + return 0; + + /* Only check VEX_Imm4, which must be the first operand. */ + if (t->operand_types[0].bitfield.vec_imm4) + { + if (i.op[0].imms->X_op != O_constant + || !fits_in_imm4 (i.op[0].imms->X_add_number)) + { + i.error = bad_imm4; + return 1; + } + + /* Turn off Imm8 so that update_imm won't complain. */ + i.types[0] = vec_imm4; + } + + return 0; +} + +static const insn_template * +match_template (void) +{ + /* Points to template once we've found it. */ + const insn_template *t; + i386_operand_type overlap0, overlap1, overlap2, overlap3; + i386_operand_type overlap4; + unsigned int found_reverse_match; + i386_opcode_modifier suffix_check; + i386_operand_type operand_types [MAX_OPERANDS]; + int addr_prefix_disp; + unsigned int j; + unsigned int found_cpu_match; + unsigned int check_register; + enum i386_error specific_error = 0; + +#if MAX_OPERANDS != 5 +# error "MAX_OPERANDS must be 5." +#endif + + found_reverse_match = 0; + addr_prefix_disp = -1; + + memset (&suffix_check, 0, sizeof (suffix_check)); + if (i.suffix == BYTE_MNEM_SUFFIX) + suffix_check.no_bsuf = 1; + else if (i.suffix == WORD_MNEM_SUFFIX) + suffix_check.no_wsuf = 1; + else if (i.suffix == SHORT_MNEM_SUFFIX) + suffix_check.no_ssuf = 1; + else if (i.suffix == LONG_MNEM_SUFFIX) + suffix_check.no_lsuf = 1; + else if (i.suffix == QWORD_MNEM_SUFFIX) + suffix_check.no_qsuf = 1; + else if (i.suffix == LONG_DOUBLE_MNEM_SUFFIX) + suffix_check.no_ldsuf = 1; + + /* Must have right number of operands. */ + i.error = number_of_operands_mismatch; + + for (t = current_templates->start; t < current_templates->end; t++) + { + addr_prefix_disp = -1; + + if (i.operands != t->operands) + continue; + + /* Check processor support. */ + i.error = unsupported; + found_cpu_match = (cpu_flags_match (t) + == CPU_FLAGS_PERFECT_MATCH); + if (!found_cpu_match) + continue; + + /* Check old gcc support. */ + i.error = old_gcc_only; + if (!old_gcc && t->opcode_modifier.oldgcc) + continue; + + /* Check AT&T mnemonic. */ + i.error = unsupported_with_intel_mnemonic; + if (intel_mnemonic && t->opcode_modifier.attmnemonic) + continue; + + /* Check AT&T/Intel syntax. */ + i.error = unsupported_syntax; + if ((intel_syntax && t->opcode_modifier.attsyntax) + || (!intel_syntax && t->opcode_modifier.intelsyntax)) + continue; + + /* Check the suffix, except for some instructions in intel mode. */ + i.error = invalid_instruction_suffix; + if ((!intel_syntax || !t->opcode_modifier.ignoresize) + && ((t->opcode_modifier.no_bsuf && suffix_check.no_bsuf) + || (t->opcode_modifier.no_wsuf && suffix_check.no_wsuf) + || (t->opcode_modifier.no_lsuf && suffix_check.no_lsuf) + || (t->opcode_modifier.no_ssuf && suffix_check.no_ssuf) + || (t->opcode_modifier.no_qsuf && suffix_check.no_qsuf) + || (t->opcode_modifier.no_ldsuf && suffix_check.no_ldsuf))) + continue; + + if (!operand_size_match (t)) + continue; + + for (j = 0; j < MAX_OPERANDS; j++) + operand_types[j] = t->operand_types[j]; + + /* In general, don't allow 64-bit operands in 32-bit mode. */ + if (i.suffix == QWORD_MNEM_SUFFIX + && flag_code != CODE_64BIT + && (intel_syntax + ? (!t->opcode_modifier.ignoresize + && !intel_float_operand (t->name)) + : intel_float_operand (t->name) != 2) + && ((!operand_types[0].bitfield.regmmx + && !operand_types[0].bitfield.regxmm + && !operand_types[0].bitfield.regymm + && !operand_types[0].bitfield.regzmm) + || (!operand_types[t->operands > 1].bitfield.regmmx + && !!operand_types[t->operands > 1].bitfield.regxmm + && !!operand_types[t->operands > 1].bitfield.regymm + && !!operand_types[t->operands > 1].bitfield.regzmm)) + && (t->base_opcode != 0x0fc7 + || t->extension_opcode != 1 /* cmpxchg8b */)) + continue; + + /* In general, don't allow 32-bit operands on pre-386. */ + else if (i.suffix == LONG_MNEM_SUFFIX + && !cpu_arch_flags.bitfield.cpui386 + && (intel_syntax + ? (!t->opcode_modifier.ignoresize + && !intel_float_operand (t->name)) + : intel_float_operand (t->name) != 2) + && ((!operand_types[0].bitfield.regmmx + && !operand_types[0].bitfield.regxmm) + || (!operand_types[t->operands > 1].bitfield.regmmx + && !!operand_types[t->operands > 1].bitfield.regxmm))) + continue; + + /* Do not verify operands when there are none. */ + else + { + if (!t->operands) + /* We've found a match; break out of loop. */ + break; + } + + /* Address size prefix will turn Disp64/Disp32/Disp16 operand + into Disp32/Disp16/Disp32 operand. */ + if (i.prefix[ADDR_PREFIX] != 0) + { + /* There should be only one Disp operand. */ + switch (flag_code) + { + case CODE_16BIT: + for (j = 0; j < MAX_OPERANDS; j++) + { + if (operand_types[j].bitfield.disp16) + { + addr_prefix_disp = j; + operand_types[j].bitfield.disp32 = 1; + operand_types[j].bitfield.disp16 = 0; + break; + } + } + break; + case CODE_32BIT: + for (j = 0; j < MAX_OPERANDS; j++) + { + if (operand_types[j].bitfield.disp32) + { + addr_prefix_disp = j; + operand_types[j].bitfield.disp32 = 0; + operand_types[j].bitfield.disp16 = 1; + break; + } + } + break; + case CODE_64BIT: + for (j = 0; j < MAX_OPERANDS; j++) + { + if (operand_types[j].bitfield.disp64) + { + addr_prefix_disp = j; + operand_types[j].bitfield.disp64 = 0; + operand_types[j].bitfield.disp32 = 1; + break; + } + } + break; + } + } + + /* We check register size if needed. */ + check_register = t->opcode_modifier.checkregsize; + overlap0 = operand_type_and (i.types[0], operand_types[0]); + switch (t->operands) + { + case 1: + if (!operand_type_match (overlap0, i.types[0])) + continue; + break; + case 2: + /* xchg %eax, %eax is a special case. It is an aliase for nop + only in 32bit mode and we can use opcode 0x90. In 64bit + mode, we can't use 0x90 for xchg %eax, %eax since it should + zero-extend %eax to %rax. */ + if (flag_code == CODE_64BIT + && t->base_opcode == 0x90 + && operand_type_equal (&i.types [0], &acc32) + && operand_type_equal (&i.types [1], &acc32)) + continue; + if (i.swap_operand) + { + /* If we swap operand in encoding, we either match + the next one or reverse direction of operands. */ + if (t->opcode_modifier.s) + continue; + else if (t->opcode_modifier.d) + goto check_reverse; + } + + case 3: + /* If we swap operand in encoding, we match the next one. */ + if (i.swap_operand && t->opcode_modifier.s) + continue; + case 4: + case 5: + overlap1 = operand_type_and (i.types[1], operand_types[1]); + if (!operand_type_match (overlap0, i.types[0]) + || !operand_type_match (overlap1, i.types[1]) + || (check_register + && !operand_type_register_match (overlap0, i.types[0], + operand_types[0], + overlap1, i.types[1], + operand_types[1]))) + { + /* Check if other direction is valid ... */ + if (!t->opcode_modifier.d && !t->opcode_modifier.floatd) + continue; + +check_reverse: + /* Try reversing direction of operands. */ + overlap0 = operand_type_and (i.types[0], operand_types[1]); + overlap1 = operand_type_and (i.types[1], operand_types[0]); + if (!operand_type_match (overlap0, i.types[0]) + || !operand_type_match (overlap1, i.types[1]) + || (check_register + && !operand_type_register_match (overlap0, + i.types[0], + operand_types[1], + overlap1, + i.types[1], + operand_types[0]))) + { + /* Does not match either direction. */ + continue; + } + /* found_reverse_match holds which of D or FloatDR + we've found. */ + if (t->opcode_modifier.d) + found_reverse_match = Opcode_D; + else if (t->opcode_modifier.floatd) + found_reverse_match = Opcode_FloatD; + else + found_reverse_match = 0; + if (t->opcode_modifier.floatr) + found_reverse_match |= Opcode_FloatR; + } + else + { + /* Found a forward 2 operand match here. */ + switch (t->operands) + { + case 5: + overlap4 = operand_type_and (i.types[4], + operand_types[4]); + case 4: + overlap3 = operand_type_and (i.types[3], + operand_types[3]); + case 3: + overlap2 = operand_type_and (i.types[2], + operand_types[2]); + break; + } + + switch (t->operands) + { + case 5: + if (!operand_type_match (overlap4, i.types[4]) + || !operand_type_register_match (overlap3, + i.types[3], + operand_types[3], + overlap4, + i.types[4], + operand_types[4])) + continue; + case 4: + if (!operand_type_match (overlap3, i.types[3]) + || (check_register + && !operand_type_register_match (overlap2, + i.types[2], + operand_types[2], + overlap3, + i.types[3], + operand_types[3]))) + continue; + case 3: + /* Here we make use of the fact that there are no + reverse match 3 operand instructions, and all 3 + operand instructions only need to be checked for + register consistency between operands 2 and 3. */ + if (!operand_type_match (overlap2, i.types[2]) + || (check_register + && !operand_type_register_match (overlap1, + i.types[1], + operand_types[1], + overlap2, + i.types[2], + operand_types[2]))) + continue; + break; + } + } + /* Found either forward/reverse 2, 3 or 4 operand match here: + slip through to break. */ + } + if (!found_cpu_match) + { + found_reverse_match = 0; + continue; + } + + /* Check if vector and VEX operands are valid. */ + if (check_VecOperands (t) || VEX_check_operands (t)) + { + specific_error = i.error; + continue; + } + + /* We've found a match; break out of loop. */ + break; + } + + if (t == current_templates->end) + { + /* We found no match. */ + const char *err_msg; + switch (specific_error ? specific_error : i.error) + { + default: + abort (); + case operand_size_mismatch: + err_msg = _("operand size mismatch"); + break; + case operand_type_mismatch: + err_msg = _("operand type mismatch"); + break; + case register_type_mismatch: + err_msg = _("register type mismatch"); + break; + case number_of_operands_mismatch: + err_msg = _("number of operands mismatch"); + break; + case invalid_instruction_suffix: + err_msg = _("invalid instruction suffix"); + break; + case bad_imm4: + err_msg = _("constant doesn't fit in 4 bits"); + break; + case old_gcc_only: + err_msg = _("only supported with old gcc"); + break; + case unsupported_with_intel_mnemonic: + err_msg = _("unsupported with Intel mnemonic"); + break; + case unsupported_syntax: + err_msg = _("unsupported syntax"); + break; + case unsupported: + as_bad (_("unsupported instruction `%s'"), + current_templates->start->name); + return NULL; + case invalid_vsib_address: + err_msg = _("invalid VSIB address"); + break; + case invalid_vector_register_set: + err_msg = _("mask, index, and destination registers must be distinct"); + break; + case unsupported_vector_index_register: + err_msg = _("unsupported vector index register"); + break; + case unsupported_broadcast: + err_msg = _("unsupported broadcast"); + break; + case broadcast_not_on_src_operand: + err_msg = _("broadcast not on source memory operand"); + break; + case broadcast_needed: + err_msg = _("broadcast is needed for operand of such type"); + break; + case unsupported_masking: + err_msg = _("unsupported masking"); + break; + case mask_not_on_destination: + err_msg = _("mask not on destination operand"); + break; + case no_default_mask: + err_msg = _("default mask isn't allowed"); + break; + case unsupported_rc_sae: + err_msg = _("unsupported static rounding/sae"); + break; + case rc_sae_operand_not_last_imm: + if (intel_syntax) + err_msg = _("RC/SAE operand must precede immediate operands"); + else + err_msg = _("RC/SAE operand must follow immediate operands"); + break; + case invalid_register_operand: + err_msg = _("invalid register operand"); + break; + } + as_bad (_("%s for `%s'"), err_msg, + current_templates->start->name); + return NULL; + } + + if (!quiet_warnings) + { + if (!intel_syntax + && (i.types[0].bitfield.jumpabsolute + != operand_types[0].bitfield.jumpabsolute)) + { + as_warn (_("indirect %s without `*'"), t->name); + } + + if (t->opcode_modifier.isprefix + && t->opcode_modifier.ignoresize) + { + /* Warn them that a data or address size prefix doesn't + affect assembly of the next line of code. */ + as_warn (_("stand-alone `%s' prefix"), t->name); + } + } + + /* Copy the template we found. */ + i.tm = *t; + + if (addr_prefix_disp != -1) + i.tm.operand_types[addr_prefix_disp] + = operand_types[addr_prefix_disp]; + + if (found_reverse_match) + { + /* If we found a reverse match we must alter the opcode + direction bit. found_reverse_match holds bits to change + (different for int & float insns). */ + + i.tm.base_opcode ^= found_reverse_match; + + i.tm.operand_types[0] = operand_types[1]; + i.tm.operand_types[1] = operand_types[0]; + } + + return t; +} + +static int +check_string (void) +{ + int mem_op = operand_type_check (i.types[0], anymem) ? 0 : 1; + if (i.tm.operand_types[mem_op].bitfield.esseg) + { + if (i.seg[0] != NULL && i.seg[0] != &es) + { + as_bad (_("`%s' operand %d must use `%ses' segment"), + i.tm.name, + mem_op + 1, + register_prefix); + return 0; + } + /* There's only ever one segment override allowed per instruction. + This instruction possibly has a legal segment override on the + second operand, so copy the segment to where non-string + instructions store it, allowing common code. */ + i.seg[0] = i.seg[1]; + } + else if (i.tm.operand_types[mem_op + 1].bitfield.esseg) + { + if (i.seg[1] != NULL && i.seg[1] != &es) + { + as_bad (_("`%s' operand %d must use `%ses' segment"), + i.tm.name, + mem_op + 2, + register_prefix); + return 0; + } + } + return 1; +} + +static int +process_suffix (void) +{ + /* If matched instruction specifies an explicit instruction mnemonic + suffix, use it. */ + if (i.tm.opcode_modifier.size16) + i.suffix = WORD_MNEM_SUFFIX; + else if (i.tm.opcode_modifier.size32) + i.suffix = LONG_MNEM_SUFFIX; + else if (i.tm.opcode_modifier.size64) + i.suffix = QWORD_MNEM_SUFFIX; + else if (i.reg_operands) + { + /* If there's no instruction mnemonic suffix we try to invent one + based on register operands. */ + if (!i.suffix) + { + /* We take i.suffix from the last register operand specified, + Destination register type is more significant than source + register type. crc32 in SSE4.2 prefers source register + type. */ + if (i.tm.base_opcode == 0xf20f38f1) + { + if (i.types[0].bitfield.reg16) + i.suffix = WORD_MNEM_SUFFIX; + else if (i.types[0].bitfield.reg32) + i.suffix = LONG_MNEM_SUFFIX; + else if (i.types[0].bitfield.reg64) + i.suffix = QWORD_MNEM_SUFFIX; + } + else if (i.tm.base_opcode == 0xf20f38f0) + { + if (i.types[0].bitfield.reg8) + i.suffix = BYTE_MNEM_SUFFIX; + } + + if (!i.suffix) + { + int op; + + if (i.tm.base_opcode == 0xf20f38f1 + || i.tm.base_opcode == 0xf20f38f0) + { + /* We have to know the operand size for crc32. */ + as_bad (_("ambiguous memory operand size for `%s`"), + i.tm.name); + return 0; + } + + for (op = i.operands; --op >= 0;) + if (!i.tm.operand_types[op].bitfield.inoutportreg) + { + if (i.types[op].bitfield.reg8) + { + i.suffix = BYTE_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg16) + { + i.suffix = WORD_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg32) + { + i.suffix = LONG_MNEM_SUFFIX; + break; + } + else if (i.types[op].bitfield.reg64) + { + i.suffix = QWORD_MNEM_SUFFIX; + break; + } + } + } + } + else if (i.suffix == BYTE_MNEM_SUFFIX) + { + if (intel_syntax + && i.tm.opcode_modifier.ignoresize + && i.tm.opcode_modifier.no_bsuf) + i.suffix = 0; + else if (!check_byte_reg ()) + return 0; + } + else if (i.suffix == LONG_MNEM_SUFFIX) + { + if (intel_syntax + && i.tm.opcode_modifier.ignoresize + && i.tm.opcode_modifier.no_lsuf) + i.suffix = 0; + else if (!check_long_reg ()) + return 0; + } + else if (i.suffix == QWORD_MNEM_SUFFIX) + { + if (intel_syntax + && i.tm.opcode_modifier.ignoresize + && i.tm.opcode_modifier.no_qsuf) + i.suffix = 0; + else if (!check_qword_reg ()) + return 0; + } + else if (i.suffix == WORD_MNEM_SUFFIX) + { + if (intel_syntax + && i.tm.opcode_modifier.ignoresize + && i.tm.opcode_modifier.no_wsuf) + i.suffix = 0; + else if (!check_word_reg ()) + return 0; + } + else if (i.suffix == XMMWORD_MNEM_SUFFIX + || i.suffix == YMMWORD_MNEM_SUFFIX + || i.suffix == ZMMWORD_MNEM_SUFFIX) + { + /* Skip if the instruction has x/y/z suffix. match_template + should check if it is a valid suffix. */ + } + else if (intel_syntax && i.tm.opcode_modifier.ignoresize) + /* Do nothing if the instruction is going to ignore the prefix. */ + ; + else + abort (); + } + else if (i.tm.opcode_modifier.defaultsize + && !i.suffix + /* exclude fldenv/frstor/fsave/fstenv */ + && i.tm.opcode_modifier.no_ssuf) + { + i.suffix = stackop_size; + } + else if (intel_syntax + && !i.suffix + && (i.tm.operand_types[0].bitfield.jumpabsolute + || i.tm.opcode_modifier.jumpbyte + || i.tm.opcode_modifier.jumpintersegment + || (i.tm.base_opcode == 0x0f01 /* [ls][gi]dt */ + && i.tm.extension_opcode <= 3))) + { + switch (flag_code) + { + case CODE_64BIT: + if (!i.tm.opcode_modifier.no_qsuf) + { + i.suffix = QWORD_MNEM_SUFFIX; + break; + } + case CODE_32BIT: + if (!i.tm.opcode_modifier.no_lsuf) + i.suffix = LONG_MNEM_SUFFIX; + break; + case CODE_16BIT: + if (!i.tm.opcode_modifier.no_wsuf) + i.suffix = WORD_MNEM_SUFFIX; + break; + } + } + + if (!i.suffix) + { + if (!intel_syntax) + { + if (i.tm.opcode_modifier.w) + { + as_bad (_("no instruction mnemonic suffix given and " + "no register operands; can't size instruction")); + return 0; + } + } + else + { + unsigned int suffixes; + + suffixes = !i.tm.opcode_modifier.no_bsuf; + if (!i.tm.opcode_modifier.no_wsuf) + suffixes |= 1 << 1; + if (!i.tm.opcode_modifier.no_lsuf) + suffixes |= 1 << 2; + if (!i.tm.opcode_modifier.no_ldsuf) + suffixes |= 1 << 3; + if (!i.tm.opcode_modifier.no_ssuf) + suffixes |= 1 << 4; + if (!i.tm.opcode_modifier.no_qsuf) + suffixes |= 1 << 5; + + /* There are more than suffix matches. */ + if (i.tm.opcode_modifier.w + || ((suffixes & (suffixes - 1)) + && !i.tm.opcode_modifier.defaultsize + && !i.tm.opcode_modifier.ignoresize)) + { + as_bad (_("ambiguous operand size for `%s'"), i.tm.name); + return 0; + } + } + } + + /* Change the opcode based on the operand size given by i.suffix; + We don't need to change things for byte insns. */ + + if (i.suffix + && i.suffix != BYTE_MNEM_SUFFIX + && i.suffix != XMMWORD_MNEM_SUFFIX + && i.suffix != YMMWORD_MNEM_SUFFIX + && i.suffix != ZMMWORD_MNEM_SUFFIX) + { + /* It's not a byte, select word/dword operation. */ + if (i.tm.opcode_modifier.w) + { + if (i.tm.opcode_modifier.shortform) + i.tm.base_opcode |= 8; + else + i.tm.base_opcode |= 1; + } + + /* Now select between word & dword operations via the operand + size prefix, except for instructions that will ignore this + prefix anyway. */ + if (i.tm.opcode_modifier.addrprefixop0) + { + /* The address size override prefix changes the size of the + first operand. */ + if ((flag_code == CODE_32BIT + && i.op->regs[0].reg_type.bitfield.reg16) + || (flag_code != CODE_32BIT + && i.op->regs[0].reg_type.bitfield.reg32)) + if (!add_prefix (ADDR_PREFIX_OPCODE)) + return 0; + } + else if (i.suffix != QWORD_MNEM_SUFFIX + && i.suffix != LONG_DOUBLE_MNEM_SUFFIX + && !i.tm.opcode_modifier.ignoresize + && !i.tm.opcode_modifier.floatmf + && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) + || (flag_code == CODE_64BIT + && i.tm.opcode_modifier.jumpbyte))) + { + unsigned int prefix = DATA_PREFIX_OPCODE; + + if (i.tm.opcode_modifier.jumpbyte) /* jcxz, loop */ + prefix = ADDR_PREFIX_OPCODE; + + if (!add_prefix (prefix)) + return 0; + } + + /* Set mode64 for an operand. */ + if (i.suffix == QWORD_MNEM_SUFFIX + && flag_code == CODE_64BIT + && !i.tm.opcode_modifier.norex64) + { + /* Special case for xchg %rax,%rax. It is NOP and doesn't + need rex64. cmpxchg8b is also a special case. */ + if (! (i.operands == 2 + && i.tm.base_opcode == 0x90 + && i.tm.extension_opcode == None + && operand_type_equal (&i.types [0], &acc64) + && operand_type_equal (&i.types [1], &acc64)) + && ! (i.operands == 1 + && i.tm.base_opcode == 0xfc7 + && i.tm.extension_opcode == 1 + && !operand_type_check (i.types [0], reg) + && operand_type_check (i.types [0], anymem))) + i.rex |= REX_W; + } + + /* Size floating point instruction. */ + if (i.suffix == LONG_MNEM_SUFFIX) + if (i.tm.opcode_modifier.floatmf) + i.tm.base_opcode ^= 4; + } + + return 1; +} + +static int +check_byte_reg (void) +{ + int op; + + for (op = i.operands; --op >= 0;) + { + /* If this is an eight bit register, it's OK. If it's the 16 or + 32 bit version of an eight bit register, we will just use the + low portion, and that's OK too. */ + if (i.types[op].bitfield.reg8) + continue; + + /* I/O port address operands are OK too. */ + if (i.tm.operand_types[op].bitfield.inoutportreg) + continue; + + /* crc32 doesn't generate this warning. */ + if (i.tm.base_opcode == 0xf20f38f0) + continue; + + if ((i.types[op].bitfield.reg16 + || i.types[op].bitfield.reg32 + || i.types[op].bitfield.reg64) + && i.op[op].regs->reg_num < 4 + /* Prohibit these changes in 64bit mode, since the lowering + would be more complicated. */ + && flag_code != CODE_64BIT) + { +#if REGISTER_WARNINGS + if (!quiet_warnings) + as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), + register_prefix, + (i.op[op].regs + (i.types[op].bitfield.reg16 + ? REGNAM_AL - REGNAM_AX + : REGNAM_AL - REGNAM_EAX))->reg_name, + register_prefix, + i.op[op].regs->reg_name, + i.suffix); +#endif + continue; + } + /* Any other register is bad. */ + if (i.types[op].bitfield.reg16 + || i.types[op].bitfield.reg32 + || i.types[op].bitfield.reg64 + || i.types[op].bitfield.regmmx + || i.types[op].bitfield.regxmm + || i.types[op].bitfield.regymm + || i.types[op].bitfield.regzmm + || i.types[op].bitfield.sreg2 + || i.types[op].bitfield.sreg3 + || i.types[op].bitfield.control + || i.types[op].bitfield.debug + || i.types[op].bitfield.test + || i.types[op].bitfield.floatreg + || i.types[op].bitfield.floatacc) + { + as_bad (_("`%s%s' not allowed with `%s%c'"), + register_prefix, + i.op[op].regs->reg_name, + i.tm.name, + i.suffix); + return 0; + } + } + return 1; +} + +static int +check_long_reg (void) +{ + int op; + + for (op = i.operands; --op >= 0;) + /* Reject eight bit registers, except where the template requires + them. (eg. movzb) */ + if (i.types[op].bitfield.reg8 + && (i.tm.operand_types[op].bitfield.reg16 + || i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + as_bad (_("`%s%s' not allowed with `%s%c'"), + register_prefix, + i.op[op].regs->reg_name, + i.tm.name, + i.suffix); + return 0; + } + /* Warn if the e prefix on a general reg is missing. */ + else if ((!quiet_warnings || flag_code == CODE_64BIT) + && i.types[op].bitfield.reg16 + && (i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + /* Prohibit these changes in the 64bit mode, since the + lowering is more complicated. */ + if (flag_code == CODE_64BIT) + { + as_bad (_("incorrect register `%s%s' used with `%c' suffix"), + register_prefix, i.op[op].regs->reg_name, + i.suffix); + return 0; + } +#if REGISTER_WARNINGS + else + as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), + register_prefix, + (i.op[op].regs + REGNAM_EAX - REGNAM_AX)->reg_name, + register_prefix, + i.op[op].regs->reg_name, + i.suffix); +#endif + } + /* Warn if the r prefix on a general reg is missing. */ + else if (i.types[op].bitfield.reg64 + && (i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + if (intel_syntax + && i.tm.opcode_modifier.toqword + && !i.types[0].bitfield.regxmm) + { + /* Convert to QWORD. We want REX byte. */ + i.suffix = QWORD_MNEM_SUFFIX; + } + else + { + as_bad (_("incorrect register `%s%s' used with `%c' suffix"), + register_prefix, i.op[op].regs->reg_name, + i.suffix); + return 0; + } + } + return 1; +} + +static int +check_qword_reg (void) +{ + int op; + + for (op = i.operands; --op >= 0; ) + /* Reject eight bit registers, except where the template requires + them. (eg. movzb) */ + if (i.types[op].bitfield.reg8 + && (i.tm.operand_types[op].bitfield.reg16 + || i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + as_bad (_("`%s%s' not allowed with `%s%c'"), + register_prefix, + i.op[op].regs->reg_name, + i.tm.name, + i.suffix); + return 0; + } + /* Warn if the e prefix on a general reg is missing. */ + else if ((i.types[op].bitfield.reg16 + || i.types[op].bitfield.reg32) + && (i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + /* Prohibit these changes in the 64bit mode, since the + lowering is more complicated. */ + if (intel_syntax + && i.tm.opcode_modifier.todword + && !i.types[0].bitfield.regxmm) + { + /* Convert to DWORD. We don't want REX byte. */ + i.suffix = LONG_MNEM_SUFFIX; + } + else + { + as_bad (_("incorrect register `%s%s' used with `%c' suffix"), + register_prefix, i.op[op].regs->reg_name, + i.suffix); + return 0; + } + } + return 1; +} + +static int +check_word_reg (void) +{ + int op; + for (op = i.operands; --op >= 0;) + /* Reject eight bit registers, except where the template requires + them. (eg. movzb) */ + if (i.types[op].bitfield.reg8 + && (i.tm.operand_types[op].bitfield.reg16 + || i.tm.operand_types[op].bitfield.reg32 + || i.tm.operand_types[op].bitfield.acc)) + { + as_bad (_("`%s%s' not allowed with `%s%c'"), + register_prefix, + i.op[op].regs->reg_name, + i.tm.name, + i.suffix); + return 0; + } + /* Warn if the e prefix on a general reg is present. */ + else if ((!quiet_warnings || flag_code == CODE_64BIT) + && i.types[op].bitfield.reg32 + && (i.tm.operand_types[op].bitfield.reg16 + || i.tm.operand_types[op].bitfield.acc)) + { + /* Prohibit these changes in the 64bit mode, since the + lowering is more complicated. */ + if (flag_code == CODE_64BIT) + { + as_bad (_("incorrect register `%s%s' used with `%c' suffix"), + register_prefix, i.op[op].regs->reg_name, + i.suffix); + return 0; + } + else +#if REGISTER_WARNINGS + as_warn (_("using `%s%s' instead of `%s%s' due to `%c' suffix"), + register_prefix, + (i.op[op].regs + REGNAM_AX - REGNAM_EAX)->reg_name, + register_prefix, + i.op[op].regs->reg_name, + i.suffix); +#endif + } + return 1; +} + +static int +update_imm (unsigned int j) +{ + i386_operand_type overlap = i.types[j]; + if ((overlap.bitfield.imm8 + || overlap.bitfield.imm8s + || overlap.bitfield.imm16 + || overlap.bitfield.imm32 + || overlap.bitfield.imm32s + || overlap.bitfield.imm64) + && !operand_type_equal (&overlap, &imm8) + && !operand_type_equal (&overlap, &imm8s) + && !operand_type_equal (&overlap, &imm16) + && !operand_type_equal (&overlap, &imm32) + && !operand_type_equal (&overlap, &imm32s) + && !operand_type_equal (&overlap, &imm64)) + { + if (i.suffix) + { + i386_operand_type temp; + + operand_type_set (&temp, 0); + if (i.suffix == BYTE_MNEM_SUFFIX) + { + temp.bitfield.imm8 = overlap.bitfield.imm8; + temp.bitfield.imm8s = overlap.bitfield.imm8s; + } + else if (i.suffix == WORD_MNEM_SUFFIX) + temp.bitfield.imm16 = overlap.bitfield.imm16; + else if (i.suffix == QWORD_MNEM_SUFFIX) + { + temp.bitfield.imm64 = overlap.bitfield.imm64; + temp.bitfield.imm32s = overlap.bitfield.imm32s; + } + else + temp.bitfield.imm32 = overlap.bitfield.imm32; + overlap = temp; + } + else if (operand_type_equal (&overlap, &imm16_32_32s) + || operand_type_equal (&overlap, &imm16_32) + || operand_type_equal (&overlap, &imm16_32s)) + { + if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0)) + overlap = imm16; + else + overlap = imm32s; + } + if (!operand_type_equal (&overlap, &imm8) + && !operand_type_equal (&overlap, &imm8s) + && !operand_type_equal (&overlap, &imm16) + && !operand_type_equal (&overlap, &imm32) + && !operand_type_equal (&overlap, &imm32s) + && !operand_type_equal (&overlap, &imm64)) + { + as_bad (_("no instruction mnemonic suffix given; " + "can't determine immediate size")); + return 0; + } + } + i.types[j] = overlap; + + return 1; +} + +static int +finalize_imm (void) +{ + unsigned int j, n; + + /* Update the first 2 immediate operands. */ + n = i.operands > 2 ? 2 : i.operands; + if (n) + { + for (j = 0; j < n; j++) + if (update_imm (j) == 0) + return 0; + + /* The 3rd operand can't be immediate operand. */ + gas_assert (operand_type_check (i.types[2], imm) == 0); + } + + return 1; +} + +static int +bad_implicit_operand (int xmm) +{ + const char *ireg = xmm ? "xmm0" : "ymm0"; + + if (intel_syntax) + as_bad (_("the last operand of `%s' must be `%s%s'"), + i.tm.name, register_prefix, ireg); + else + as_bad (_("the first operand of `%s' must be `%s%s'"), + i.tm.name, register_prefix, ireg); + return 0; +} + +static int +process_operands (void) +{ + /* Default segment register this instruction will use for memory + accesses. 0 means unknown. This is only for optimizing out + unnecessary segment overrides. */ + const seg_entry *default_seg = 0; + + if (i.tm.opcode_modifier.sse2avx && i.tm.opcode_modifier.vexvvvv) + { + unsigned int dupl = i.operands; + unsigned int dest = dupl - 1; + unsigned int j; + + /* The destination must be an xmm register. */ + gas_assert (i.reg_operands + && MAX_OPERANDS > dupl + && operand_type_equal (&i.types[dest], ®xmm)); + + if (i.tm.opcode_modifier.firstxmm0) + { + /* The first operand is implicit and must be xmm0. */ + gas_assert (operand_type_equal (&i.types[0], ®xmm)); + if (register_number (i.op[0].regs) != 0) + return bad_implicit_operand (1); + + if (i.tm.opcode_modifier.vexsources == VEX3SOURCES) + { + /* Keep xmm0 for instructions with VEX prefix and 3 + sources. */ + goto duplicate; + } + else + { + /* We remove the first xmm0 and keep the number of + operands unchanged, which in fact duplicates the + destination. */ + for (j = 1; j < i.operands; j++) + { + i.op[j - 1] = i.op[j]; + i.types[j - 1] = i.types[j]; + i.tm.operand_types[j - 1] = i.tm.operand_types[j]; + } + } + } + else if (i.tm.opcode_modifier.implicit1stxmm0) + { + gas_assert ((MAX_OPERANDS - 1) > dupl + && (i.tm.opcode_modifier.vexsources + == VEX3SOURCES)); + + /* Add the implicit xmm0 for instructions with VEX prefix + and 3 sources. */ + for (j = i.operands; j > 0; j--) + { + i.op[j] = i.op[j - 1]; + i.types[j] = i.types[j - 1]; + i.tm.operand_types[j] = i.tm.operand_types[j - 1]; + } + i.op[0].regs + = (const reg_entry *) hash_find (reg_hash, "xmm0"); + i.types[0] = regxmm; + i.tm.operand_types[0] = regxmm; + + i.operands += 2; + i.reg_operands += 2; + i.tm.operands += 2; + + dupl++; + dest++; + i.op[dupl] = i.op[dest]; + i.types[dupl] = i.types[dest]; + i.tm.operand_types[dupl] = i.tm.operand_types[dest]; + } + else + { +duplicate: + i.operands++; + i.reg_operands++; + i.tm.operands++; + + i.op[dupl] = i.op[dest]; + i.types[dupl] = i.types[dest]; + i.tm.operand_types[dupl] = i.tm.operand_types[dest]; + } + + if (i.tm.opcode_modifier.immext) + process_immext (); + } + else if (i.tm.opcode_modifier.firstxmm0) + { + unsigned int j; + + /* The first operand is implicit and must be xmm0/ymm0/zmm0. */ + gas_assert (i.reg_operands + && (operand_type_equal (&i.types[0], ®xmm) + || operand_type_equal (&i.types[0], ®ymm) + || operand_type_equal (&i.types[0], ®zmm))); + if (register_number (i.op[0].regs) != 0) + return bad_implicit_operand (i.types[0].bitfield.regxmm); + + for (j = 1; j < i.operands; j++) + { + i.op[j - 1] = i.op[j]; + i.types[j - 1] = i.types[j]; + + /* We need to adjust fields in i.tm since they are used by + build_modrm_byte. */ + i.tm.operand_types [j - 1] = i.tm.operand_types [j]; + } + + i.operands--; + i.reg_operands--; + i.tm.operands--; + } + else if (i.tm.opcode_modifier.regkludge) + { + /* The imul $imm, %reg instruction is converted into + imul $imm, %reg, %reg, and the clr %reg instruction + is converted into xor %reg, %reg. */ + + unsigned int first_reg_op; + + if (operand_type_check (i.types[0], reg)) + first_reg_op = 0; + else + first_reg_op = 1; + /* Pretend we saw the extra register operand. */ + gas_assert (i.reg_operands == 1 + && i.op[first_reg_op + 1].regs == 0); + i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs; + i.types[first_reg_op + 1] = i.types[first_reg_op]; + i.operands++; + i.reg_operands++; + } + + if (i.tm.opcode_modifier.shortform) + { + if (i.types[0].bitfield.sreg2 + || i.types[0].bitfield.sreg3) + { + if (i.tm.base_opcode == POP_SEG_SHORT + && i.op[0].regs->reg_num == 1) + { + as_bad (_("you can't `pop %scs'"), register_prefix); + return 0; + } + i.tm.base_opcode |= (i.op[0].regs->reg_num << 3); + if ((i.op[0].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + } + else + { + /* The register or float register operand is in operand + 0 or 1. */ + unsigned int op; + + if (i.types[0].bitfield.floatreg + || operand_type_check (i.types[0], reg)) + op = 0; + else + op = 1; + /* Register goes in low 3 bits of opcode. */ + i.tm.base_opcode |= i.op[op].regs->reg_num; + if ((i.op[op].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + if (!quiet_warnings && i.tm.opcode_modifier.ugh) + { + /* Warn about some common errors, but press on regardless. + The first case can be generated by gcc (<= 2.8.1). */ + if (i.operands == 2) + { + /* Reversed arguments on faddp, fsubp, etc. */ + as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name, + register_prefix, i.op[!intel_syntax].regs->reg_name, + register_prefix, i.op[intel_syntax].regs->reg_name); + } + else + { + /* Extraneous `l' suffix on fp insn. */ + as_warn (_("translating to `%s %s%s'"), i.tm.name, + register_prefix, i.op[0].regs->reg_name); + } + } + } + } + else if (i.tm.opcode_modifier.modrm) + { + /* The opcode is completed (modulo i.tm.extension_opcode which + must be put into the modrm byte). Now, we make the modrm and + index base bytes based on all the info we've collected. */ + + default_seg = build_modrm_byte (); + } + else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32) + { + default_seg = &ds; + } + else if (i.tm.opcode_modifier.isstring) + { + /* For the string instructions that allow a segment override + on one of their operands, the default segment is ds. */ + default_seg = &ds; + } + + if (i.tm.base_opcode == 0x8d /* lea */ + && i.seg[0] + && !quiet_warnings) + as_warn (_("segment override on `%s' is ineffectual"), i.tm.name); + + /* If a segment was explicitly specified, and the specified segment + is not the default, use an opcode prefix to select it. If we + never figured out what the default segment is, then default_seg + will be zero at this point, and the specified segment prefix will + always be used. */ + if ((i.seg[0]) && (i.seg[0] != default_seg)) + { + if (!add_prefix (i.seg[0]->seg_prefix)) + return 0; + } + return 1; +} + +static const seg_entry * +build_modrm_byte (void) +{ + const seg_entry *default_seg = 0; + unsigned int source, dest; + int vex_3_sources; + + /* The first operand of instructions with VEX prefix and 3 sources + must be VEX_Imm4. */ + vex_3_sources = i.tm.opcode_modifier.vexsources == VEX3SOURCES; + if (vex_3_sources) + { + unsigned int nds, reg_slot; + expressionS *exp; + + if (i.tm.opcode_modifier.veximmext + && i.tm.opcode_modifier.immext) + { + dest = i.operands - 2; + gas_assert (dest == 3); + } + else + dest = i.operands - 1; + nds = dest - 1; + + /* There are 2 kinds of instructions: + 1. 5 operands: 4 register operands or 3 register operands + plus 1 memory operand plus one Vec_Imm4 operand, VexXDS, and + VexW0 or VexW1. The destination must be either XMM, YMM or + ZMM register. + 2. 4 operands: 4 register operands or 3 register operands + plus 1 memory operand, VexXDS, and VexImmExt */ + gas_assert ((i.reg_operands == 4 + || (i.reg_operands == 3 && i.mem_operands == 1)) + && i.tm.opcode_modifier.vexvvvv == VEXXDS + && (i.tm.opcode_modifier.veximmext + || (i.imm_operands == 1 + && i.types[0].bitfield.vec_imm4 + && (i.tm.opcode_modifier.vexw == VEXW0 + || i.tm.opcode_modifier.vexw == VEXW1) + && (operand_type_equal (&i.tm.operand_types[dest], ®xmm) + || operand_type_equal (&i.tm.operand_types[dest], ®ymm) + || operand_type_equal (&i.tm.operand_types[dest], ®zmm))))); + + if (i.imm_operands == 0) + { + /* When there is no immediate operand, generate an 8bit + immediate operand to encode the first operand. */ + exp = &im_expressions[i.imm_operands++]; + i.op[i.operands].imms = exp; + i.types[i.operands] = imm8; + i.operands++; + /* If VexW1 is set, the first operand is the source and + the second operand is encoded in the immediate operand. */ + if (i.tm.opcode_modifier.vexw == VEXW1) + { + source = 0; + reg_slot = 1; + } + else + { + source = 1; + reg_slot = 0; + } + + /* FMA swaps REG and NDS. */ + if (i.tm.cpu_flags.bitfield.cpufma) + { + unsigned int tmp; + tmp = reg_slot; + reg_slot = nds; + nds = tmp; + } + + gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot], + ®xmm) + || operand_type_equal (&i.tm.operand_types[reg_slot], + ®ymm) + || operand_type_equal (&i.tm.operand_types[reg_slot], + ®zmm)); + exp->X_op = O_constant; + exp->X_add_number = register_number (i.op[reg_slot].regs) << 4; + gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0); + } + else + { + unsigned int imm_slot; + + if (i.tm.opcode_modifier.vexw == VEXW0) + { + /* If VexW0 is set, the third operand is the source and + the second operand is encoded in the immediate + operand. */ + source = 2; + reg_slot = 1; + } + else + { + /* VexW1 is set, the second operand is the source and + the third operand is encoded in the immediate + operand. */ + source = 1; + reg_slot = 2; + } + + if (i.tm.opcode_modifier.immext) + { + /* When ImmExt is set, the immdiate byte is the last + operand. */ + imm_slot = i.operands - 1; + source--; + reg_slot--; + } + else + { + imm_slot = 0; + + /* Turn on Imm8 so that output_imm will generate it. */ + i.types[imm_slot].bitfield.imm8 = 1; + } + + gas_assert (operand_type_equal (&i.tm.operand_types[reg_slot], + ®xmm) + || operand_type_equal (&i.tm.operand_types[reg_slot], + ®ymm) + || operand_type_equal (&i.tm.operand_types[reg_slot], + ®zmm)); + i.op[imm_slot].imms->X_add_number + |= register_number (i.op[reg_slot].regs) << 4; + gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0); + } + + gas_assert (operand_type_equal (&i.tm.operand_types[nds], ®xmm) + || operand_type_equal (&i.tm.operand_types[nds], + ®ymm) + || operand_type_equal (&i.tm.operand_types[nds], + ®zmm)); + i.vex.register_specifier = i.op[nds].regs; + } + else + source = dest = 0; + + /* i.reg_operands MUST be the number of real register operands; + implicit registers do not count. If there are 3 register + operands, it must be a instruction with VexNDS. For a + instruction with VexNDD, the destination register is encoded + in VEX prefix. If there are 4 register operands, it must be + a instruction with VEX prefix and 3 sources. */ + if (i.mem_operands == 0 + && ((i.reg_operands == 2 + && i.tm.opcode_modifier.vexvvvv <= VEXXDS) + || (i.reg_operands == 3 + && i.tm.opcode_modifier.vexvvvv == VEXXDS) + || (i.reg_operands == 4 && vex_3_sources))) + { + switch (i.operands) + { + case 2: + source = 0; + break; + case 3: + /* When there are 3 operands, one of them may be immediate, + which may be the first or the last operand. Otherwise, + the first operand must be shift count register (cl) or it + is an instruction with VexNDS. */ + gas_assert (i.imm_operands == 1 + || (i.imm_operands == 0 + && (i.tm.opcode_modifier.vexvvvv == VEXXDS + || i.types[0].bitfield.shiftcount))); + if (operand_type_check (i.types[0], imm) + || i.types[0].bitfield.shiftcount) + source = 1; + else + source = 0; + break; + case 4: + /* When there are 4 operands, the first two must be 8bit + immediate operands. The source operand will be the 3rd + one. + + For instructions with VexNDS, if the first operand + an imm8, the source operand is the 2nd one. If the last + operand is imm8, the source operand is the first one. */ + gas_assert ((i.imm_operands == 2 + && i.types[0].bitfield.imm8 + && i.types[1].bitfield.imm8) + || (i.tm.opcode_modifier.vexvvvv == VEXXDS + && i.imm_operands == 1 + && (i.types[0].bitfield.imm8 + || i.types[i.operands - 1].bitfield.imm8 + || i.rounding))); + if (i.imm_operands == 2) + source = 2; + else + { + if (i.types[0].bitfield.imm8) + source = 1; + else + source = 0; + } + break; + case 5: + if (i.tm.opcode_modifier.evex) + { + /* For EVEX instructions, when there are 5 operands, the + first one must be immediate operand. If the second one + is immediate operand, the source operand is the 3th + one. If the last one is immediate operand, the source + operand is the 2nd one. */ + gas_assert (i.imm_operands == 2 + && i.tm.opcode_modifier.sae + && operand_type_check (i.types[0], imm)); + if (operand_type_check (i.types[1], imm)) + source = 2; + else if (operand_type_check (i.types[4], imm)) + source = 1; + else + abort (); + } + break; + default: + abort (); + } + + if (!vex_3_sources) + { + dest = source + 1; + + /* RC/SAE operand could be between DEST and SRC. That happens + when one operand is GPR and the other one is XMM/YMM/ZMM + register. */ + if (i.rounding && i.rounding->operand == (int) dest) + dest++; + + if (i.tm.opcode_modifier.vexvvvv == VEXXDS) + { + /* For instructions with VexNDS, the register-only source + operand must be 32/64bit integer, XMM, YMM or ZMM + register. It is encoded in VEX prefix. We need to + clear RegMem bit before calling operand_type_equal. */ + + i386_operand_type op; + unsigned int vvvv; + + /* Check register-only source operand when two source + operands are swapped. */ + if (!i.tm.operand_types[source].bitfield.baseindex + && i.tm.operand_types[dest].bitfield.baseindex) + { + vvvv = source; + source = dest; + } + else + vvvv = dest; + + op = i.tm.operand_types[vvvv]; + op.bitfield.regmem = 0; + if ((dest + 1) >= i.operands + || (op.bitfield.reg32 != 1 + && !op.bitfield.reg64 != 1 + && !operand_type_equal (&op, ®xmm) + && !operand_type_equal (&op, ®ymm) + && !operand_type_equal (&op, ®zmm) + && !operand_type_equal (&op, ®mask))) + abort (); + i.vex.register_specifier = i.op[vvvv].regs; + dest++; + } + } + + i.rm.mode = 3; + /* One of the register operands will be encoded in the i.tm.reg + field, the other in the combined i.tm.mode and i.tm.regmem + fields. If no form of this instruction supports a memory + destination operand, then we assume the source operand may + sometimes be a memory operand and so we need to store the + destination in the i.rm.reg field. */ + if (!i.tm.operand_types[dest].bitfield.regmem + && operand_type_check (i.tm.operand_types[dest], anymem) == 0) + { + i.rm.reg = i.op[dest].regs->reg_num; + i.rm.regmem = i.op[source].regs->reg_num; + if ((i.op[dest].regs->reg_flags & RegRex) != 0) + i.rex |= REX_R; + if ((i.op[dest].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_R; + if ((i.op[source].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + if ((i.op[source].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_B; + } + else + { + i.rm.reg = i.op[source].regs->reg_num; + i.rm.regmem = i.op[dest].regs->reg_num; + if ((i.op[dest].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + if ((i.op[dest].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_B; + if ((i.op[source].regs->reg_flags & RegRex) != 0) + i.rex |= REX_R; + if ((i.op[source].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_R; + } + if (flag_code != CODE_64BIT && (i.rex & (REX_R | REX_B))) + { + if (!i.types[0].bitfield.control + && !i.types[1].bitfield.control) + abort (); + i.rex &= ~(REX_R | REX_B); + add_prefix (LOCK_PREFIX_OPCODE); + } + } + else + { /* If it's not 2 reg operands... */ + unsigned int mem; + + if (i.mem_operands) + { + unsigned int fake_zero_displacement = 0; + unsigned int op; + + for (op = 0; op < i.operands; op++) + if (operand_type_check (i.types[op], anymem)) + break; + gas_assert (op < i.operands); + + if (i.tm.opcode_modifier.vecsib) + { + if (i.index_reg->reg_num == RegEiz + || i.index_reg->reg_num == RegRiz) + abort (); + + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + if (!i.base_reg) + { + i.sib.base = NO_BASE_REGISTER; + i.sib.scale = i.log2_scale_factor; + /* No Vec_Disp8 if there is no base. */ + i.types[op].bitfield.vec_disp8 = 0; + i.types[op].bitfield.disp8 = 0; + i.types[op].bitfield.disp16 = 0; + i.types[op].bitfield.disp64 = 0; + if (flag_code != CODE_64BIT) + { + /* Must be 32 bit */ + i.types[op].bitfield.disp32 = 1; + i.types[op].bitfield.disp32s = 0; + } + else + { + i.types[op].bitfield.disp32 = 0; + i.types[op].bitfield.disp32s = 1; + } + } + i.sib.index = i.index_reg->reg_num; + if ((i.index_reg->reg_flags & RegRex) != 0) + i.rex |= REX_X; + if ((i.index_reg->reg_flags & RegVRex) != 0) + i.vrex |= REX_X; + } + + default_seg = &ds; + + if (i.base_reg == 0) + { + i.rm.mode = 0; + if (!i.disp_operands) + { + fake_zero_displacement = 1; + /* Instructions with VSIB byte need 32bit displacement + if there is no base register. */ + if (i.tm.opcode_modifier.vecsib) + i.types[op].bitfield.disp32 = 1; + } + if (i.index_reg == 0) + { + gas_assert (!i.tm.opcode_modifier.vecsib); + /* Operand is just */ + if (flag_code == CODE_64BIT) + { + /* 64bit mode overwrites the 32bit absolute + addressing by RIP relative addressing and + absolute addressing is encoded by one of the + redundant SIB forms. */ + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + i.sib.base = NO_BASE_REGISTER; + i.sib.index = NO_INDEX_REGISTER; + i.types[op] = ((i.prefix[ADDR_PREFIX] == 0) + ? disp32s : disp32); + } + else if ((flag_code == CODE_16BIT) + ^ (i.prefix[ADDR_PREFIX] != 0)) + { + i.rm.regmem = NO_BASE_REGISTER_16; + i.types[op] = disp16; + } + else + { + i.rm.regmem = NO_BASE_REGISTER; + i.types[op] = disp32; + } + } + else if (!i.tm.opcode_modifier.vecsib) + { + /* !i.base_reg && i.index_reg */ + if (i.index_reg->reg_num == RegEiz + || i.index_reg->reg_num == RegRiz) + i.sib.index = NO_INDEX_REGISTER; + else + i.sib.index = i.index_reg->reg_num; + i.sib.base = NO_BASE_REGISTER; + i.sib.scale = i.log2_scale_factor; + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + /* No Vec_Disp8 if there is no base. */ + i.types[op].bitfield.vec_disp8 = 0; + i.types[op].bitfield.disp8 = 0; + i.types[op].bitfield.disp16 = 0; + i.types[op].bitfield.disp64 = 0; + if (flag_code != CODE_64BIT) + { + /* Must be 32 bit */ + i.types[op].bitfield.disp32 = 1; + i.types[op].bitfield.disp32s = 0; + } + else + { + i.types[op].bitfield.disp32 = 0; + i.types[op].bitfield.disp32s = 1; + } + if ((i.index_reg->reg_flags & RegRex) != 0) + i.rex |= REX_X; + } + } + /* RIP addressing for 64bit mode. */ + else if (i.base_reg->reg_num == RegRip || + i.base_reg->reg_num == RegEip) + { + gas_assert (!i.tm.opcode_modifier.vecsib); + i.rm.regmem = NO_BASE_REGISTER; + i.types[op].bitfield.disp8 = 0; + i.types[op].bitfield.disp16 = 0; + i.types[op].bitfield.disp32 = 0; + i.types[op].bitfield.disp32s = 1; + i.types[op].bitfield.disp64 = 0; + i.types[op].bitfield.vec_disp8 = 0; + i.flags[op] |= Operand_PCrel; + if (! i.disp_operands) + fake_zero_displacement = 1; + } + else if (i.base_reg->reg_type.bitfield.reg16) + { + gas_assert (!i.tm.opcode_modifier.vecsib); + switch (i.base_reg->reg_num) + { + case 3: /* (%bx) */ + if (i.index_reg == 0) + i.rm.regmem = 7; + else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */ + i.rm.regmem = i.index_reg->reg_num - 6; + break; + case 5: /* (%bp) */ + default_seg = &ss; + if (i.index_reg == 0) + { + i.rm.regmem = 6; + if (operand_type_check (i.types[op], disp) == 0) + { + /* fake (%bp) into 0(%bp) */ + if (i.tm.operand_types[op].bitfield.vec_disp8) + i.types[op].bitfield.vec_disp8 = 1; + else + i.types[op].bitfield.disp8 = 1; + fake_zero_displacement = 1; + } + } + else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */ + i.rm.regmem = i.index_reg->reg_num - 6 + 2; + break; + default: /* (%si) -> 4 or (%di) -> 5 */ + i.rm.regmem = i.base_reg->reg_num - 6 + 4; + } + i.rm.mode = mode_from_disp_size (i.types[op]); + } + else /* i.base_reg and 32/64 bit mode */ + { + if (flag_code == CODE_64BIT + && operand_type_check (i.types[op], disp)) + { + i386_operand_type temp; + operand_type_set (&temp, 0); + temp.bitfield.disp8 = i.types[op].bitfield.disp8; + temp.bitfield.vec_disp8 + = i.types[op].bitfield.vec_disp8; + i.types[op] = temp; + if (i.prefix[ADDR_PREFIX] == 0) + i.types[op].bitfield.disp32s = 1; + else + i.types[op].bitfield.disp32 = 1; + } + + if (!i.tm.opcode_modifier.vecsib) + i.rm.regmem = i.base_reg->reg_num; + if ((i.base_reg->reg_flags & RegRex) != 0) + i.rex |= REX_B; + i.sib.base = i.base_reg->reg_num; + /* x86-64 ignores REX prefix bit here to avoid decoder + complications. */ + if (!(i.base_reg->reg_flags & RegRex) + && (i.base_reg->reg_num == EBP_REG_NUM + || i.base_reg->reg_num == ESP_REG_NUM)) + default_seg = &ss; + if (i.base_reg->reg_num == 5 && i.disp_operands == 0) + { + fake_zero_displacement = 1; + if (i.tm.operand_types [op].bitfield.vec_disp8) + i.types[op].bitfield.vec_disp8 = 1; + else + i.types[op].bitfield.disp8 = 1; + } + i.sib.scale = i.log2_scale_factor; + if (i.index_reg == 0) + { + gas_assert (!i.tm.opcode_modifier.vecsib); + /* (%esp) becomes two byte modrm with no index + register. We've already stored the code for esp + in i.rm.regmem ie. ESCAPE_TO_TWO_BYTE_ADDRESSING. + Any base register besides %esp will not use the + extra modrm byte. */ + i.sib.index = NO_INDEX_REGISTER; + } + else if (!i.tm.opcode_modifier.vecsib) + { + if (i.index_reg->reg_num == RegEiz + || i.index_reg->reg_num == RegRiz) + i.sib.index = NO_INDEX_REGISTER; + else + i.sib.index = i.index_reg->reg_num; + i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING; + if ((i.index_reg->reg_flags & RegRex) != 0) + i.rex |= REX_X; + } + + if (i.disp_operands + && (i.reloc[op] == BFD_RELOC_386_TLS_DESC_CALL + || i.reloc[op] == BFD_RELOC_X86_64_TLSDESC_CALL)) + i.rm.mode = 0; + else + { + if (!fake_zero_displacement + && !i.disp_operands + && i.disp_encoding) + { + fake_zero_displacement = 1; + if (i.disp_encoding == disp_encoding_8bit) + i.types[op].bitfield.disp8 = 1; + else + i.types[op].bitfield.disp32 = 1; + } + i.rm.mode = mode_from_disp_size (i.types[op]); + } + } + + if (fake_zero_displacement) + { + /* Fakes a zero displacement assuming that i.types[op] + holds the correct displacement size. */ + expressionS *exp; + + gas_assert (i.op[op].disps == 0); + exp = &disp_expressions[i.disp_operands++]; + i.op[op].disps = exp; + exp->X_op = O_constant; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_op_symbol = (symbolS *) 0; + } + + mem = op; + } + else + mem = ~0; + + if (i.tm.opcode_modifier.vexsources == XOP2SOURCES) + { + if (operand_type_check (i.types[0], imm)) + i.vex.register_specifier = NULL; + else + { + /* VEX.vvvv encodes one of the sources when the first + operand is not an immediate. */ + if (i.tm.opcode_modifier.vexw == VEXW0) + i.vex.register_specifier = i.op[0].regs; + else + i.vex.register_specifier = i.op[1].regs; + } + + /* Destination is a XMM register encoded in the ModRM.reg + and VEX.R bit. */ + i.rm.reg = i.op[2].regs->reg_num; + if ((i.op[2].regs->reg_flags & RegRex) != 0) + i.rex |= REX_R; + + /* ModRM.rm and VEX.B encodes the other source. */ + if (!i.mem_operands) + { + i.rm.mode = 3; + + if (i.tm.opcode_modifier.vexw == VEXW0) + i.rm.regmem = i.op[1].regs->reg_num; + else + i.rm.regmem = i.op[0].regs->reg_num; + + if ((i.op[1].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + } + } + else if (i.tm.opcode_modifier.vexvvvv == VEXLWP) + { + i.vex.register_specifier = i.op[2].regs; + if (!i.mem_operands) + { + i.rm.mode = 3; + i.rm.regmem = i.op[1].regs->reg_num; + if ((i.op[1].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + } + } + /* Fill in i.rm.reg or i.rm.regmem field with register operand + (if any) based on i.tm.extension_opcode. Again, we must be + careful to make sure that segment/control/debug/test/MMX + registers are coded into the i.rm.reg field. */ + else if (i.reg_operands) + { + unsigned int op; + unsigned int vex_reg = ~0; + + for (op = 0; op < i.operands; op++) + if (i.types[op].bitfield.reg8 + || i.types[op].bitfield.reg16 + || i.types[op].bitfield.reg32 + || i.types[op].bitfield.reg64 + || i.types[op].bitfield.regmmx + || i.types[op].bitfield.regxmm + || i.types[op].bitfield.regymm + || i.types[op].bitfield.regbnd + || i.types[op].bitfield.regzmm + || i.types[op].bitfield.regmask + || i.types[op].bitfield.sreg2 + || i.types[op].bitfield.sreg3 + || i.types[op].bitfield.control + || i.types[op].bitfield.debug + || i.types[op].bitfield.test) + break; + + if (vex_3_sources) + op = dest; + else if (i.tm.opcode_modifier.vexvvvv == VEXXDS) + { + /* For instructions with VexNDS, the register-only + source operand is encoded in VEX prefix. */ + gas_assert (mem != (unsigned int) ~0); + + if (op > mem) + { + vex_reg = op++; + gas_assert (op < i.operands); + } + else + { + /* Check register-only source operand when two source + operands are swapped. */ + if (!i.tm.operand_types[op].bitfield.baseindex + && i.tm.operand_types[op + 1].bitfield.baseindex) + { + vex_reg = op; + op += 2; + gas_assert (mem == (vex_reg + 1) + && op < i.operands); + } + else + { + vex_reg = op + 1; + gas_assert (vex_reg < i.operands); + } + } + } + else if (i.tm.opcode_modifier.vexvvvv == VEXNDD) + { + /* For instructions with VexNDD, the register destination + is encoded in VEX prefix. */ + if (i.mem_operands == 0) + { + /* There is no memory operand. */ + gas_assert ((op + 2) == i.operands); + vex_reg = op + 1; + } + else + { + /* There are only 2 operands. */ + gas_assert (op < 2 && i.operands == 2); + vex_reg = 1; + } + } + else + gas_assert (op < i.operands); + + if (vex_reg != (unsigned int) ~0) + { + i386_operand_type *type = &i.tm.operand_types[vex_reg]; + + if (type->bitfield.reg32 != 1 + && type->bitfield.reg64 != 1 + && !operand_type_equal (type, ®xmm) + && !operand_type_equal (type, ®ymm) + && !operand_type_equal (type, ®zmm) + && !operand_type_equal (type, ®mask)) + abort (); + + i.vex.register_specifier = i.op[vex_reg].regs; + } + + /* Don't set OP operand twice. */ + if (vex_reg != op) + { + /* If there is an extension opcode to put here, the + register number must be put into the regmem field. */ + if (i.tm.extension_opcode != None) + { + i.rm.regmem = i.op[op].regs->reg_num; + if ((i.op[op].regs->reg_flags & RegRex) != 0) + i.rex |= REX_B; + if ((i.op[op].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_B; + } + else + { + i.rm.reg = i.op[op].regs->reg_num; + if ((i.op[op].regs->reg_flags & RegRex) != 0) + i.rex |= REX_R; + if ((i.op[op].regs->reg_flags & RegVRex) != 0) + i.vrex |= REX_R; + } + } + + /* Now, if no memory operand has set i.rm.mode = 0, 1, 2 we + must set it to 3 to indicate this is a register operand + in the regmem field. */ + if (!i.mem_operands) + i.rm.mode = 3; + } + + /* Fill in i.rm.reg field with extension opcode (if any). */ + if (i.tm.extension_opcode != None) + i.rm.reg = i.tm.extension_opcode; + } + return default_seg; +} + +static void +output_branch (void) +{ + char *p; + int size; + int code16; + int prefix; + relax_substateT subtype; + symbolS *sym; + offsetT off; + + code16 = flag_code == CODE_16BIT ? CODE16 : 0; + size = i.disp_encoding == disp_encoding_32bit ? BIG : SMALL; + + prefix = 0; + if (i.prefix[DATA_PREFIX] != 0) + { + prefix = 1; + i.prefixes -= 1; + code16 ^= CODE16; + } + /* Pentium4 branch hints. */ + if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */ + || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */) + { + prefix++; + i.prefixes--; + } + if (i.prefix[REX_PREFIX] != 0) + { + prefix++; + i.prefixes--; + } + + /* BND prefixed jump. */ + if (i.prefix[BND_PREFIX] != 0) + { + FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]); + i.prefixes -= 1; + } + + if (i.prefixes != 0 && !intel_syntax) + as_warn (_("skipping prefixes on this instruction")); + + /* It's always a symbol; End frag & setup for relax. + Make sure there is enough room in this frag for the largest + instruction we may generate in md_convert_frag. This is 2 + bytes for the opcode and room for the prefix and largest + displacement. */ + frag_grow (prefix + 2 + 4); + /* Prefix and 1 opcode byte go in fr_fix. */ + p = frag_more (prefix + 1); + if (i.prefix[DATA_PREFIX] != 0) + *p++ = DATA_PREFIX_OPCODE; + if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE + || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE) + *p++ = i.prefix[SEG_PREFIX]; + if (i.prefix[REX_PREFIX] != 0) + *p++ = i.prefix[REX_PREFIX]; + *p = i.tm.base_opcode; + + if ((unsigned char) *p == JUMP_PC_RELATIVE) + subtype = ENCODE_RELAX_STATE (UNCOND_JUMP, size); + else if (cpu_arch_flags.bitfield.cpui386) + subtype = ENCODE_RELAX_STATE (COND_JUMP, size); + else + subtype = ENCODE_RELAX_STATE (COND_JUMP86, size); + subtype |= code16; + + sym = i.op[0].disps->X_add_symbol; + off = i.op[0].disps->X_add_number; + + if (i.op[0].disps->X_op != O_constant + && i.op[0].disps->X_op != O_symbol) + { + /* Handle complex expressions. */ + sym = make_expr_symbol (i.op[0].disps); + off = 0; + } + + /* 1 possible extra opcode + 4 byte displacement go in var part. + Pass reloc in fr_var. */ + frag_var (rs_machine_dependent, 5, + ((!object_64bit + || i.reloc[0] != NO_RELOC + || (i.bnd_prefix == NULL && !add_bnd_prefix)) + ? i.reloc[0] + : BFD_RELOC_X86_64_PC32_BND), + subtype, sym, off, p); +} + +static void +output_jump (void) +{ + char *p; + int size; + fixS *fixP; + + if (i.tm.opcode_modifier.jumpbyte) + { + /* This is a loop or jecxz type instruction. */ + size = 1; + if (i.prefix[ADDR_PREFIX] != 0) + { + FRAG_APPEND_1_CHAR (ADDR_PREFIX_OPCODE); + i.prefixes -= 1; + } + /* Pentium4 branch hints. */ + if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE /* not taken */ + || i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE /* taken */) + { + FRAG_APPEND_1_CHAR (i.prefix[SEG_PREFIX]); + i.prefixes--; + } + } + else + { + int code16; + + code16 = 0; + if (flag_code == CODE_16BIT) + code16 = CODE16; + + if (i.prefix[DATA_PREFIX] != 0) + { + FRAG_APPEND_1_CHAR (DATA_PREFIX_OPCODE); + i.prefixes -= 1; + code16 ^= CODE16; + } + + size = 4; + if (code16) + size = 2; + } + + if (i.prefix[REX_PREFIX] != 0) + { + FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]); + i.prefixes -= 1; + } + + /* BND prefixed jump. */ + if (i.prefix[BND_PREFIX] != 0) + { + FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]); + i.prefixes -= 1; + } + + if (i.prefixes != 0 && !intel_syntax) + as_warn (_("skipping prefixes on this instruction")); + + p = frag_more (i.tm.opcode_length + size); + switch (i.tm.opcode_length) + { + case 2: + *p++ = i.tm.base_opcode >> 8; + case 1: + *p++ = i.tm.base_opcode; + break; + default: + abort (); + } + + fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[0].disps, 1, reloc (size, 1, 1, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[0])); + + /* All jumps handled here are signed, but don't use a signed limit + check for 32 and 16 bit jumps as we want to allow wrap around at + 4G and 64k respectively. */ + if (size == 1) + fixP->fx_signed = 1; +} + +static void +output_interseg_jump (void) +{ + char *p; + int size; + int prefix; + int code16; + + code16 = 0; + if (flag_code == CODE_16BIT) + code16 = CODE16; + + prefix = 0; + if (i.prefix[DATA_PREFIX] != 0) + { + prefix = 1; + i.prefixes -= 1; + code16 ^= CODE16; + } + if (i.prefix[REX_PREFIX] != 0) + { + prefix++; + i.prefixes -= 1; + } + + size = 4; + if (code16) + size = 2; + + if (i.prefixes != 0 && !intel_syntax) + as_warn (_("skipping prefixes on this instruction")); + + /* 1 opcode; 2 segment; offset */ + p = frag_more (prefix + 1 + 2 + size); + + if (i.prefix[DATA_PREFIX] != 0) + *p++ = DATA_PREFIX_OPCODE; + + if (i.prefix[REX_PREFIX] != 0) + *p++ = i.prefix[REX_PREFIX]; + + *p++ = i.tm.base_opcode; + if (i.op[1].imms->X_op == O_constant) + { + offsetT n = i.op[1].imms->X_add_number; + + if (size == 2 + && !fits_in_unsigned_word (n) + && !fits_in_signed_word (n)) + { + as_bad (_("16-bit jump out of range")); + return; + } + md_number_to_chars (p, n, size); + } + else + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[1].imms, 0, reloc (size, 0, 0, 0, i.reloc[1])); + if (i.op[0].imms->X_op != O_constant) + as_bad (_("can't handle non absolute segment in `%s'"), + i.tm.name); + md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2); +} + +static void +output_insn (void) +{ + fragS *insn_start_frag; + offsetT insn_start_off; + + /* Tie dwarf2 debug info to the address at the start of the insn. + We can't do this after the insn has been output as the current + frag may have been closed off. eg. by frag_var. */ + dwarf2_emit_insn (0); + + insn_start_frag = frag_now; + insn_start_off = frag_now_fix (); + + /* Output jumps. */ + if (i.tm.opcode_modifier.jump) + output_branch (); + else if (i.tm.opcode_modifier.jumpbyte + || i.tm.opcode_modifier.jumpdword) + output_jump (); + else if (i.tm.opcode_modifier.jumpintersegment) + output_interseg_jump (); + else + { + /* Output normal instructions here. */ + char *p; + unsigned char *q; + unsigned int j; + unsigned int prefix; + + /* Since the VEX/EVEX prefix contains the implicit prefix, we + don't need the explicit prefix. */ + if (!i.tm.opcode_modifier.vex && !i.tm.opcode_modifier.evex) + { + switch (i.tm.opcode_length) + { + case 3: + if (i.tm.base_opcode & 0xff000000) + { + prefix = (i.tm.base_opcode >> 24) & 0xff; + goto check_prefix; + } + break; + case 2: + if ((i.tm.base_opcode & 0xff0000) != 0) + { + prefix = (i.tm.base_opcode >> 16) & 0xff; + if (i.tm.cpu_flags.bitfield.cpupadlock) + { +check_prefix: + if (prefix != REPE_PREFIX_OPCODE + || (i.prefix[REP_PREFIX] + != REPE_PREFIX_OPCODE)) + add_prefix (prefix); + } + else + add_prefix (prefix); + } + break; + case 1: + break; + default: + abort (); + } + + /* The prefix bytes. */ + for (j = ARRAY_SIZE (i.prefix), q = i.prefix; j > 0; j--, q++) + if (*q) + FRAG_APPEND_1_CHAR (*q); + } + else + { + for (j = 0, q = i.prefix; j < ARRAY_SIZE (i.prefix); j++, q++) + if (*q) + switch (j) + { + case REX_PREFIX: + /* REX byte is encoded in VEX prefix. */ + break; + case SEG_PREFIX: + case ADDR_PREFIX: + FRAG_APPEND_1_CHAR (*q); + break; + default: + /* There should be no other prefixes for instructions + with VEX prefix. */ + abort (); + } + + /* For EVEX instructions i.vrex should become 0 after + build_evex_prefix. For VEX instructions upper 16 registers + aren't available, so VREX should be 0. */ + if (i.vrex) + abort (); + /* Now the VEX prefix. */ + p = frag_more (i.vex.length); + for (j = 0; j < i.vex.length; j++) + p[j] = i.vex.bytes[j]; + } + + /* Now the opcode; be careful about word order here! */ + if (i.tm.opcode_length == 1) + { + FRAG_APPEND_1_CHAR (i.tm.base_opcode); + } + else + { + switch (i.tm.opcode_length) + { + case 4: + p = frag_more (4); + *p++ = (i.tm.base_opcode >> 24) & 0xff; + *p++ = (i.tm.base_opcode >> 16) & 0xff; + break; + case 3: + p = frag_more (3); + *p++ = (i.tm.base_opcode >> 16) & 0xff; + break; + case 2: + p = frag_more (2); + break; + default: + abort (); + break; + } + + /* Put out high byte first: can't use md_number_to_chars! */ + *p++ = (i.tm.base_opcode >> 8) & 0xff; + *p = i.tm.base_opcode & 0xff; + } + + /* Now the modrm byte and sib byte (if present). */ + if (i.tm.opcode_modifier.modrm) + { + FRAG_APPEND_1_CHAR ((i.rm.regmem << 0 + | i.rm.reg << 3 + | i.rm.mode << 6)); + /* If i.rm.regmem == ESP (4) + && i.rm.mode != (Register mode) + && not 16 bit + ==> need second modrm byte. */ + if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING + && i.rm.mode != 3 + && !(i.base_reg && i.base_reg->reg_type.bitfield.reg16)) + FRAG_APPEND_1_CHAR ((i.sib.base << 0 + | i.sib.index << 3 + | i.sib.scale << 6)); + } + + if (i.disp_operands) + output_disp (insn_start_frag, insn_start_off); + + if (i.imm_operands) + output_imm (insn_start_frag, insn_start_off); + } + +#ifdef DEBUG386 + if (flag_debug) + { + pi ("" /*line*/, &i); + } +#endif /* DEBUG386 */ +} + +/* Return the size of the displacement operand N. */ + +static int +disp_size (unsigned int n) +{ + int size = 4; + + /* Vec_Disp8 has to be 8bit. */ + if (i.types[n].bitfield.vec_disp8) + size = 1; + else if (i.types[n].bitfield.disp64) + size = 8; + else if (i.types[n].bitfield.disp8) + size = 1; + else if (i.types[n].bitfield.disp16) + size = 2; + return size; +} + +/* Return the size of the immediate operand N. */ + +static int +imm_size (unsigned int n) +{ + int size = 4; + if (i.types[n].bitfield.imm64) + size = 8; + else if (i.types[n].bitfield.imm8 || i.types[n].bitfield.imm8s) + size = 1; + else if (i.types[n].bitfield.imm16) + size = 2; + return size; +} + +static void +output_disp (fragS *insn_start_frag, offsetT insn_start_off) +{ + char *p; + unsigned int n; + + for (n = 0; n < i.operands; n++) + { + if (i.types[n].bitfield.vec_disp8 + || operand_type_check (i.types[n], disp)) + { + if (i.op[n].disps->X_op == O_constant) + { + int size = disp_size (n); + offsetT val = i.op[n].disps->X_add_number; + + if (i.types[n].bitfield.vec_disp8) + val >>= i.memshift; + val = offset_in_range (val, size); + p = frag_more (size); + md_number_to_chars (p, val, size); + } + else + { + enum bfd_reloc_code_real reloc_type; + int size = disp_size (n); + int sign = i.types[n].bitfield.disp32s; + int pcrel = (i.flags[n] & Operand_PCrel) != 0; + + /* We can't have 8 bit displacement here. */ + gas_assert (!i.types[n].bitfield.disp8); + + /* The PC relative address is computed relative + to the instruction boundary, so in case immediate + fields follows, we need to adjust the value. */ + if (pcrel && i.imm_operands) + { + unsigned int n1; + int sz = 0; + + for (n1 = 0; n1 < i.operands; n1++) + if (operand_type_check (i.types[n1], imm)) + { + /* Only one immediate is allowed for PC + relative address. */ + gas_assert (sz == 0); + sz = imm_size (n1); + i.op[n].disps->X_add_number -= sz; + } + /* We should find the immediate. */ + gas_assert (sz != 0); + } + + p = frag_more (size); + reloc_type = reloc (size, pcrel, sign, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[n]); + if (GOT_symbol + && GOT_symbol == i.op[n].disps->X_add_symbol + && (((reloc_type == BFD_RELOC_32 + || reloc_type == BFD_RELOC_X86_64_32S + || (reloc_type == BFD_RELOC_64 + && object_64bit)) + && (i.op[n].disps->X_op == O_symbol + || (i.op[n].disps->X_op == O_add + && ((symbol_get_value_expression + (i.op[n].disps->X_op_symbol)->X_op) + == O_subtract)))) + || reloc_type == BFD_RELOC_32_PCREL)) + { + offsetT add; + + if (insn_start_frag == frag_now) + add = (p - frag_now->fr_literal) - insn_start_off; + else + { + fragS *fr; + + add = insn_start_frag->fr_fix - insn_start_off; + for (fr = insn_start_frag->fr_next; + fr && fr != frag_now; fr = fr->fr_next) + add += fr->fr_fix; + add += p - frag_now->fr_literal; + } + + if (!object_64bit) + { + reloc_type = BFD_RELOC_386_GOTPC; + i.op[n].imms->X_add_number += add; + } + else if (reloc_type == BFD_RELOC_64) + reloc_type = BFD_RELOC_X86_64_GOTPC64; + else + /* Don't do the adjustment for x86-64, as there + the pcrel addressing is relative to the _next_ + insn, and that is taken care of in other code. */ + reloc_type = BFD_RELOC_X86_64_GOTPC32; + } + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[n].disps, pcrel, reloc_type); + } + } + } +} + +static void +output_imm (fragS *insn_start_frag, offsetT insn_start_off) +{ + char *p; + unsigned int n; + + for (n = 0; n < i.operands; n++) + { + /* Skip SAE/RC Imm operand in EVEX. They are already handled. */ + if (i.rounding && (int) n == i.rounding->operand) + continue; + + if (operand_type_check (i.types[n], imm)) + { + if (i.op[n].imms->X_op == O_constant) + { + int size = imm_size (n); + offsetT val; + + val = offset_in_range (i.op[n].imms->X_add_number, + size); + p = frag_more (size); + md_number_to_chars (p, val, size); + } + else + { + /* Not absolute_section. + Need a 32-bit fixup (don't support 8bit + non-absolute imms). Try to support other + sizes ... */ + enum bfd_reloc_code_real reloc_type; + int size = imm_size (n); + int sign; + + if (i.types[n].bitfield.imm32s + && (i.suffix == QWORD_MNEM_SUFFIX + || (!i.suffix && i.tm.opcode_modifier.no_lsuf))) + sign = 1; + else + sign = 0; + + p = frag_more (size); + reloc_type = reloc (size, 0, sign, 0, i.reloc[n]); + + /* This is tough to explain. We end up with this one if we + * have operands that look like + * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to + * obtain the absolute address of the GOT, and it is strongly + * preferable from a performance point of view to avoid using + * a runtime relocation for this. The actual sequence of + * instructions often look something like: + * + * call .L66 + * .L66: + * popl %ebx + * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx + * + * The call and pop essentially return the absolute address + * of the label .L66 and store it in %ebx. The linker itself + * will ultimately change the first operand of the addl so + * that %ebx points to the GOT, but to keep things simple, the + * .o file must have this operand set so that it generates not + * the absolute address of .L66, but the absolute address of + * itself. This allows the linker itself simply treat a GOTPC + * relocation as asking for a pcrel offset to the GOT to be + * added in, and the addend of the relocation is stored in the + * operand field for the instruction itself. + * + * Our job here is to fix the operand so that it would add + * the correct offset so that %ebx would point to itself. The + * thing that is tricky is that .-.L66 will point to the + * beginning of the instruction, so we need to further modify + * the operand so that it will point to itself. There are + * other cases where you have something like: + * + * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66] + * + * and here no correction would be required. Internally in + * the assembler we treat operands of this form as not being + * pcrel since the '.' is explicitly mentioned, and I wonder + * whether it would simplify matters to do it this way. Who + * knows. In earlier versions of the PIC patches, the + * pcrel_adjust field was used to store the correction, but + * since the expression is not pcrel, I felt it would be + * confusing to do it this way. */ + + if ((reloc_type == BFD_RELOC_32 + || reloc_type == BFD_RELOC_X86_64_32S + || reloc_type == BFD_RELOC_64) + && GOT_symbol + && GOT_symbol == i.op[n].imms->X_add_symbol + && (i.op[n].imms->X_op == O_symbol + || (i.op[n].imms->X_op == O_add + && ((symbol_get_value_expression + (i.op[n].imms->X_op_symbol)->X_op) + == O_subtract)))) + { + offsetT add; + + if (insn_start_frag == frag_now) + add = (p - frag_now->fr_literal) - insn_start_off; + else + { + fragS *fr; + + add = insn_start_frag->fr_fix - insn_start_off; + for (fr = insn_start_frag->fr_next; + fr && fr != frag_now; fr = fr->fr_next) + add += fr->fr_fix; + add += p - frag_now->fr_literal; + } + + if (!object_64bit) + reloc_type = BFD_RELOC_386_GOTPC; + else if (size == 4) + reloc_type = BFD_RELOC_X86_64_GOTPC32; + else if (size == 8) + reloc_type = BFD_RELOC_X86_64_GOTPC64; + i.op[n].imms->X_add_number += add; + } + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[n].imms, 0, reloc_type); + } + } + } +} + +/* x86_cons_fix_new is called via the expression parsing code when a + reloc is needed. We use this hook to get the correct .got reloc. */ +static enum bfd_reloc_code_real got_reloc = NO_RELOC; +static int cons_sign = -1; + +void +x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, + expressionS *exp) +{ + enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, 0, got_reloc); + + got_reloc = NO_RELOC; + +#ifdef TE_PE + if (exp->X_op == O_secrel) + { + exp->X_op = O_symbol; + r = BFD_RELOC_32_SECREL; + } +#endif + + fix_new_exp (frag, off, len, exp, 0, r); +} + +/* Export the ABI address size for use by TC_ADDRESS_BYTES for the + purpose of the `.dc.a' internal pseudo-op. */ + +int +x86_address_bytes (void) +{ + if ((stdoutput->arch_info->mach & bfd_mach_x64_32)) + return 4; + return stdoutput->arch_info->bits_per_address / 8; +} + +#if !(defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (OBJ_MACH_O)) \ + || defined (LEX_AT) +# define lex_got(reloc, adjust, types, bnd_prefix) NULL +#else +/* Parse operands of the form + @GOTOFF+ + and similar .plt or .got references. + + If we find one, set up the correct relocation in RELOC and copy the + input string, minus the `@GOTOFF' into a malloc'd buffer for + parsing by the calling routine. Return this buffer, and if ADJUST + is non-null set it to the length of the string we removed from the + input line. Otherwise return NULL. */ +static char * +lex_got (enum bfd_reloc_code_real *rel, + int *adjust, + i386_operand_type *types, + int bnd_prefix) +{ + /* Some of the relocations depend on the size of what field is to + be relocated. But in our callers i386_immediate and i386_displacement + we don't yet know the operand size (this will be set by insn + matching). Hence we record the word32 relocation here, + and adjust the reloc according to the real size in reloc(). */ + static const struct { + const char *str; + int len; + const enum bfd_reloc_code_real rel[2]; + const i386_operand_type types64; + } gotrel[] = { +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + { STRING_COMMA_LEN ("SIZE"), { BFD_RELOC_SIZE32, + BFD_RELOC_SIZE32 }, + OPERAND_TYPE_IMM32_64 }, +#endif + { STRING_COMMA_LEN ("PLTOFF"), { _dummy_first_bfd_reloc_code_real, + BFD_RELOC_X86_64_PLTOFF64 }, + OPERAND_TYPE_IMM64 }, + { STRING_COMMA_LEN ("PLT"), { BFD_RELOC_386_PLT32, + BFD_RELOC_X86_64_PLT32 }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("GOTPLT"), { _dummy_first_bfd_reloc_code_real, + BFD_RELOC_X86_64_GOTPLT64 }, + OPERAND_TYPE_IMM64_DISP64 }, + { STRING_COMMA_LEN ("GOTOFF"), { BFD_RELOC_386_GOTOFF, + BFD_RELOC_X86_64_GOTOFF64 }, + OPERAND_TYPE_IMM64_DISP64 }, + { STRING_COMMA_LEN ("GOTPCREL"), { _dummy_first_bfd_reloc_code_real, + BFD_RELOC_X86_64_GOTPCREL }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("TLSGD"), { BFD_RELOC_386_TLS_GD, + BFD_RELOC_X86_64_TLSGD }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("TLSLDM"), { BFD_RELOC_386_TLS_LDM, + _dummy_first_bfd_reloc_code_real }, + OPERAND_TYPE_NONE }, + { STRING_COMMA_LEN ("TLSLD"), { _dummy_first_bfd_reloc_code_real, + BFD_RELOC_X86_64_TLSLD }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("GOTTPOFF"), { BFD_RELOC_386_TLS_IE_32, + BFD_RELOC_X86_64_GOTTPOFF }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("TPOFF"), { BFD_RELOC_386_TLS_LE_32, + BFD_RELOC_X86_64_TPOFF32 }, + OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, + { STRING_COMMA_LEN ("NTPOFF"), { BFD_RELOC_386_TLS_LE, + _dummy_first_bfd_reloc_code_real }, + OPERAND_TYPE_NONE }, + { STRING_COMMA_LEN ("DTPOFF"), { BFD_RELOC_386_TLS_LDO_32, + BFD_RELOC_X86_64_DTPOFF32 }, + OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, + { STRING_COMMA_LEN ("GOTNTPOFF"),{ BFD_RELOC_386_TLS_GOTIE, + _dummy_first_bfd_reloc_code_real }, + OPERAND_TYPE_NONE }, + { STRING_COMMA_LEN ("INDNTPOFF"),{ BFD_RELOC_386_TLS_IE, + _dummy_first_bfd_reloc_code_real }, + OPERAND_TYPE_NONE }, + { STRING_COMMA_LEN ("GOT"), { BFD_RELOC_386_GOT32, + BFD_RELOC_X86_64_GOT32 }, + OPERAND_TYPE_IMM32_32S_64_DISP32 }, + { STRING_COMMA_LEN ("TLSDESC"), { BFD_RELOC_386_TLS_GOTDESC, + BFD_RELOC_X86_64_GOTPC32_TLSDESC }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + { STRING_COMMA_LEN ("TLSCALL"), { BFD_RELOC_386_TLS_DESC_CALL, + BFD_RELOC_X86_64_TLSDESC_CALL }, + OPERAND_TYPE_IMM32_32S_DISP32 }, + }; + char *cp; + unsigned int j; + +#if defined (OBJ_MAYBE_ELF) + if (!IS_ELF) + return NULL; +#endif + + for (cp = input_line_pointer; *cp != '@'; cp++) + if (is_end_of_line[(unsigned char) *cp] || *cp == ',') + return NULL; + + for (j = 0; j < ARRAY_SIZE (gotrel); j++) + { + int len = gotrel[j].len; + if (strncasecmp (cp + 1, gotrel[j].str, len) == 0) + { + if (gotrel[j].rel[object_64bit] != 0) + { + int first, second; + char *tmpbuf, *past_reloc; + + *rel = gotrel[j].rel[object_64bit]; + + if (types) + { + if (flag_code != CODE_64BIT) + { + types->bitfield.imm32 = 1; + types->bitfield.disp32 = 1; + } + else + *types = gotrel[j].types64; + } + + if (j != 0 && GOT_symbol == NULL) + GOT_symbol = symbol_find_or_make (GLOBAL_OFFSET_TABLE_NAME); + + /* The length of the first part of our input line. */ + first = cp - input_line_pointer; + + /* The second part goes from after the reloc token until + (and including) an end_of_line char or comma. */ + past_reloc = cp + 1 + len; + cp = past_reloc; + while (!is_end_of_line[(unsigned char) *cp] && *cp != ',') + ++cp; + second = cp + 1 - past_reloc; + + /* Allocate and copy string. The trailing NUL shouldn't + be necessary, but be safe. */ + tmpbuf = (char *) xmalloc (first + second + 2); + memcpy (tmpbuf, input_line_pointer, first); + if (second != 0 && *past_reloc != ' ') + /* Replace the relocation token with ' ', so that + errors like foo@GOTOFF1 will be detected. */ + tmpbuf[first++] = ' '; + else + /* Increment length by 1 if the relocation token is + removed. */ + len++; + if (adjust) + *adjust = len; + memcpy (tmpbuf + first, past_reloc, second); + tmpbuf[first + second] = '\0'; + if (bnd_prefix && *rel == BFD_RELOC_X86_64_PLT32) + *rel = BFD_RELOC_X86_64_PLT32_BND; + return tmpbuf; + } + + as_bad (_("@%s reloc is not supported with %d-bit output format"), + gotrel[j].str, 1 << (5 + object_64bit)); + return NULL; + } + } + + /* Might be a symbol version string. Don't as_bad here. */ + return NULL; +} +#endif + +#ifdef TE_PE +#ifdef lex_got +#undef lex_got +#endif +/* Parse operands of the form + @SECREL32+ + + If we find one, set up the correct relocation in RELOC and copy the + input string, minus the `@SECREL32' into a malloc'd buffer for + parsing by the calling routine. Return this buffer, and if ADJUST + is non-null set it to the length of the string we removed from the + input line. Otherwise return NULL. + + This function is copied from the ELF version above adjusted for PE targets. */ + +static char * +lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED, + int *adjust ATTRIBUTE_UNUSED, + i386_operand_type *types, + int bnd_prefix ATTRIBUTE_UNUSED) +{ + static const struct + { + const char *str; + int len; + const enum bfd_reloc_code_real rel[2]; + const i386_operand_type types64; + } + gotrel[] = + { + { STRING_COMMA_LEN ("SECREL32"), { BFD_RELOC_32_SECREL, + BFD_RELOC_32_SECREL }, + OPERAND_TYPE_IMM32_32S_64_DISP32_64 }, + }; + + char *cp; + unsigned j; + + for (cp = input_line_pointer; *cp != '@'; cp++) + if (is_end_of_line[(unsigned char) *cp] || *cp == ',') + return NULL; + + for (j = 0; j < ARRAY_SIZE (gotrel); j++) + { + int len = gotrel[j].len; + + if (strncasecmp (cp + 1, gotrel[j].str, len) == 0) + { + if (gotrel[j].rel[object_64bit] != 0) + { + int first, second; + char *tmpbuf, *past_reloc; + + *rel = gotrel[j].rel[object_64bit]; + if (adjust) + *adjust = len; + + if (types) + { + if (flag_code != CODE_64BIT) + { + types->bitfield.imm32 = 1; + types->bitfield.disp32 = 1; + } + else + *types = gotrel[j].types64; + } + + /* The length of the first part of our input line. */ + first = cp - input_line_pointer; + + /* The second part goes from after the reloc token until + (and including) an end_of_line char or comma. */ + past_reloc = cp + 1 + len; + cp = past_reloc; + while (!is_end_of_line[(unsigned char) *cp] && *cp != ',') + ++cp; + second = cp + 1 - past_reloc; + + /* Allocate and copy string. The trailing NUL shouldn't + be necessary, but be safe. */ + tmpbuf = (char *) xmalloc (first + second + 2); + memcpy (tmpbuf, input_line_pointer, first); + if (second != 0 && *past_reloc != ' ') + /* Replace the relocation token with ' ', so that + errors like foo@SECLREL321 will be detected. */ + tmpbuf[first++] = ' '; + memcpy (tmpbuf + first, past_reloc, second); + tmpbuf[first + second] = '\0'; + return tmpbuf; + } + + as_bad (_("@%s reloc is not supported with %d-bit output format"), + gotrel[j].str, 1 << (5 + object_64bit)); + return NULL; + } + } + + /* Might be a symbol version string. Don't as_bad here. */ + return NULL; +} + +#endif /* TE_PE */ + +void +x86_cons (expressionS *exp, int size) +{ + intel_syntax = -intel_syntax; + + exp->X_md = 0; + if (size == 4 || (object_64bit && size == 8)) + { + /* Handle @GOTOFF and the like in an expression. */ + char *save; + char *gotfree_input_line; + int adjust = 0; + + save = input_line_pointer; + gotfree_input_line = lex_got (&got_reloc, &adjust, NULL, 0); + if (gotfree_input_line) + input_line_pointer = gotfree_input_line; + + expression (exp); + + if (gotfree_input_line) + { + /* expression () has merrily parsed up to the end of line, + or a comma - in the wrong buffer. Transfer how far + input_line_pointer has moved to the right buffer. */ + input_line_pointer = (save + + (input_line_pointer - gotfree_input_line) + + adjust); + free (gotfree_input_line); + if (exp->X_op == O_constant + || exp->X_op == O_absent + || exp->X_op == O_illegal + || exp->X_op == O_register + || exp->X_op == O_big) + { + char c = *input_line_pointer; + *input_line_pointer = 0; + as_bad (_("missing or invalid expression `%s'"), save); + *input_line_pointer = c; + } + } + } + else + expression (exp); + + intel_syntax = -intel_syntax; + + if (intel_syntax) + i386_intel_simplify (exp); +} + +static void +signed_cons (int size) +{ + if (flag_code == CODE_64BIT) + cons_sign = 1; + cons (size); + cons_sign = -1; +} + +#ifdef TE_PE +static void +pe_directive_secrel (int dummy ATTRIBUTE_UNUSED) +{ + expressionS exp; + + do + { + expression (&exp); + if (exp.X_op == O_symbol) + exp.X_op = O_secrel; + + emit_expr (&exp, 4); + } + while (*input_line_pointer++ == ','); + + input_line_pointer--; + demand_empty_rest_of_line (); +} +#endif + +/* Handle Vector operations. */ + +static char * +check_VecOperations (char *op_string, char *op_end) +{ + const reg_entry *mask; + const char *saved; + char *end_op; + + while (*op_string + && (op_end == NULL || op_string < op_end)) + { + saved = op_string; + if (*op_string == '{') + { + op_string++; + + /* Check broadcasts. */ + if (strncmp (op_string, "1to", 3) == 0) + { + int bcst_type; + + if (i.broadcast) + goto duplicated_vec_op; + + op_string += 3; + if (*op_string == '8') + bcst_type = BROADCAST_1TO8; + else if (*op_string == '1' + && *(op_string+1) == '6') + { + bcst_type = BROADCAST_1TO16; + op_string++; + } + else + { + as_bad (_("Unsupported broadcast: `%s'"), saved); + return NULL; + } + op_string++; + + broadcast_op.type = bcst_type; + broadcast_op.operand = this_operand; + i.broadcast = &broadcast_op; + } + /* Check masking operation. */ + else if ((mask = parse_register (op_string, &end_op)) != NULL) + { + /* k0 can't be used for write mask. */ + if (mask->reg_num == 0) + { + as_bad (_("`%s' can't be used for write mask"), + op_string); + return NULL; + } + + if (!i.mask) + { + mask_op.mask = mask; + mask_op.zeroing = 0; + mask_op.operand = this_operand; + i.mask = &mask_op; + } + else + { + if (i.mask->mask) + goto duplicated_vec_op; + + i.mask->mask = mask; + + /* Only "{z}" is allowed here. No need to check + zeroing mask explicitly. */ + if (i.mask->operand != this_operand) + { + as_bad (_("invalid write mask `%s'"), saved); + return NULL; + } + } + + op_string = end_op; + } + /* Check zeroing-flag for masking operation. */ + else if (*op_string == 'z') + { + if (!i.mask) + { + mask_op.mask = NULL; + mask_op.zeroing = 1; + mask_op.operand = this_operand; + i.mask = &mask_op; + } + else + { + if (i.mask->zeroing) + { + duplicated_vec_op: + as_bad (_("duplicated `%s'"), saved); + return NULL; + } + + i.mask->zeroing = 1; + + /* Only "{%k}" is allowed here. No need to check mask + register explicitly. */ + if (i.mask->operand != this_operand) + { + as_bad (_("invalid zeroing-masking `%s'"), + saved); + return NULL; + } + } + + op_string++; + } + else + goto unknown_vec_op; + + if (*op_string != '}') + { + as_bad (_("missing `}' in `%s'"), saved); + return NULL; + } + op_string++; + continue; + } + unknown_vec_op: + /* We don't know this one. */ + as_bad (_("unknown vector operation: `%s'"), saved); + return NULL; + } + + return op_string; +} + +static int +i386_immediate (char *imm_start) +{ + char *save_input_line_pointer; + char *gotfree_input_line; + segT exp_seg = 0; + expressionS *exp; + i386_operand_type types; + + operand_type_set (&types, ~0); + + if (i.imm_operands == MAX_IMMEDIATE_OPERANDS) + { + as_bad (_("at most %d immediate operands are allowed"), + MAX_IMMEDIATE_OPERANDS); + return 0; + } + + exp = &im_expressions[i.imm_operands++]; + i.op[this_operand].imms = exp; + + if (is_space_char (*imm_start)) + ++imm_start; + + save_input_line_pointer = input_line_pointer; + input_line_pointer = imm_start; + + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); + if (gotfree_input_line) + input_line_pointer = gotfree_input_line; + + exp_seg = expression (exp); + + SKIP_WHITESPACE (); + + /* Handle vector operations. */ + if (*input_line_pointer == '{') + { + input_line_pointer = check_VecOperations (input_line_pointer, + NULL); + if (input_line_pointer == NULL) + return 0; + } + + if (*input_line_pointer) + as_bad (_("junk `%s' after expression"), input_line_pointer); + + input_line_pointer = save_input_line_pointer; + if (gotfree_input_line) + { + free (gotfree_input_line); + + if (exp->X_op == O_constant || exp->X_op == O_register) + exp->X_op = O_illegal; + } + + return i386_finalize_immediate (exp_seg, exp, types, imm_start); +} + +static int +i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, + i386_operand_type types, const char *imm_start) +{ + if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big) + { + if (imm_start) + as_bad (_("missing or invalid immediate expression `%s'"), + imm_start); + return 0; + } + else if (exp->X_op == O_constant) + { + /* Size it properly later. */ + i.types[this_operand].bitfield.imm64 = 1; + /* If not 64bit, sign extend val. */ + if (flag_code != CODE_64BIT + && (exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0) + exp->X_add_number + = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31); + } +#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) + else if (OUTPUT_FLAVOR == bfd_target_aout_flavour + && exp_seg != absolute_section + && exp_seg != text_section + && exp_seg != data_section + && exp_seg != bss_section + && exp_seg != undefined_section + && !bfd_is_com_section (exp_seg)) + { + as_bad (_("unimplemented segment %s in operand"), exp_seg->name); + return 0; + } +#endif + else if (!intel_syntax && exp->X_op == O_register) + { + if (imm_start) + as_bad (_("illegal immediate register operand %s"), imm_start); + return 0; + } + else + { + /* This is an address. The size of the address will be + determined later, depending on destination register, + suffix, or the default for the section. */ + i.types[this_operand].bitfield.imm8 = 1; + i.types[this_operand].bitfield.imm16 = 1; + i.types[this_operand].bitfield.imm32 = 1; + i.types[this_operand].bitfield.imm32s = 1; + i.types[this_operand].bitfield.imm64 = 1; + i.types[this_operand] = operand_type_and (i.types[this_operand], + types); + } + + return 1; +} + +static char * +i386_scale (char *scale) +{ + offsetT val; + char *save = input_line_pointer; + + input_line_pointer = scale; + val = get_absolute_expression (); + + switch (val) + { + case 1: + i.log2_scale_factor = 0; + break; + case 2: + i.log2_scale_factor = 1; + break; + case 4: + i.log2_scale_factor = 2; + break; + case 8: + i.log2_scale_factor = 3; + break; + default: + { + char sep = *input_line_pointer; + + *input_line_pointer = '\0'; + as_bad (_("expecting scale factor of 1, 2, 4, or 8: got `%s'"), + scale); + *input_line_pointer = sep; + input_line_pointer = save; + return NULL; + } + } + if (i.log2_scale_factor != 0 && i.index_reg == 0) + { + as_warn (_("scale factor of %d without an index register"), + 1 << i.log2_scale_factor); + i.log2_scale_factor = 0; + } + scale = input_line_pointer; + input_line_pointer = save; + return scale; +} + +static int +i386_displacement (char *disp_start, char *disp_end) +{ + expressionS *exp; + segT exp_seg = 0; + char *save_input_line_pointer; + char *gotfree_input_line; + int override; + i386_operand_type bigdisp, types = anydisp; + int ret; + + if (i.disp_operands == MAX_MEMORY_OPERANDS) + { + as_bad (_("at most %d displacement operands are allowed"), + MAX_MEMORY_OPERANDS); + return 0; + } + + operand_type_set (&bigdisp, 0); + if ((i.types[this_operand].bitfield.jumpabsolute) + || (!current_templates->start->opcode_modifier.jump + && !current_templates->start->opcode_modifier.jumpdword)) + { + bigdisp.bitfield.disp32 = 1; + override = (i.prefix[ADDR_PREFIX] != 0); + if (flag_code == CODE_64BIT) + { + if (!override) + { + bigdisp.bitfield.disp32s = 1; + bigdisp.bitfield.disp64 = 1; + } + } + else if ((flag_code == CODE_16BIT) ^ override) + { + bigdisp.bitfield.disp32 = 0; + bigdisp.bitfield.disp16 = 1; + } + } + else + { + /* For PC-relative branches, the width of the displacement + is dependent upon data size, not address size. */ + override = (i.prefix[DATA_PREFIX] != 0); + if (flag_code == CODE_64BIT) + { + if (override || i.suffix == WORD_MNEM_SUFFIX) + bigdisp.bitfield.disp16 = 1; + else + { + bigdisp.bitfield.disp32 = 1; + bigdisp.bitfield.disp32s = 1; + } + } + else + { + if (!override) + override = (i.suffix == (flag_code != CODE_16BIT + ? WORD_MNEM_SUFFIX + : LONG_MNEM_SUFFIX)); + bigdisp.bitfield.disp32 = 1; + if ((flag_code == CODE_16BIT) ^ override) + { + bigdisp.bitfield.disp32 = 0; + bigdisp.bitfield.disp16 = 1; + } + } + } + i.types[this_operand] = operand_type_or (i.types[this_operand], + bigdisp); + + exp = &disp_expressions[i.disp_operands]; + i.op[this_operand].disps = exp; + i.disp_operands++; + save_input_line_pointer = input_line_pointer; + input_line_pointer = disp_start; + END_STRING_AND_SAVE (disp_end); + +#ifndef GCC_ASM_O_HACK +#define GCC_ASM_O_HACK 0 +#endif +#if GCC_ASM_O_HACK + END_STRING_AND_SAVE (disp_end + 1); + if (i.types[this_operand].bitfield.baseIndex + && displacement_string_end[-1] == '+') + { + /* This hack is to avoid a warning when using the "o" + constraint within gcc asm statements. + For instance: + + #define _set_tssldt_desc(n,addr,limit,type) \ + __asm__ __volatile__ ( \ + "movw %w2,%0\n\t" \ + "movw %w1,2+%0\n\t" \ + "rorl $16,%1\n\t" \ + "movb %b1,4+%0\n\t" \ + "movb %4,5+%0\n\t" \ + "movb $0,6+%0\n\t" \ + "movb %h1,7+%0\n\t" \ + "rorl $16,%1" \ + : "=o"(*(n)) : "q" (addr), "ri"(limit), "i"(type)) + + This works great except that the output assembler ends + up looking a bit weird if it turns out that there is + no offset. You end up producing code that looks like: + + #APP + movw $235,(%eax) + movw %dx,2+(%eax) + rorl $16,%edx + movb %dl,4+(%eax) + movb $137,5+(%eax) + movb $0,6+(%eax) + movb %dh,7+(%eax) + rorl $16,%edx + #NO_APP + + So here we provide the missing zero. */ + + *displacement_string_end = '0'; + } +#endif + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); + if (gotfree_input_line) + input_line_pointer = gotfree_input_line; + + exp_seg = expression (exp); + + SKIP_WHITESPACE (); + if (*input_line_pointer) + as_bad (_("junk `%s' after expression"), input_line_pointer); +#if GCC_ASM_O_HACK + RESTORE_END_STRING (disp_end + 1); +#endif + input_line_pointer = save_input_line_pointer; + if (gotfree_input_line) + { + free (gotfree_input_line); + + if (exp->X_op == O_constant || exp->X_op == O_register) + exp->X_op = O_illegal; + } + + ret = i386_finalize_displacement (exp_seg, exp, types, disp_start); + + RESTORE_END_STRING (disp_end); + + return ret; +} + +static int +i386_finalize_displacement (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, + i386_operand_type types, const char *disp_start) +{ + i386_operand_type bigdisp; + int ret = 1; + + /* We do this to make sure that the section symbol is in + the symbol table. We will ultimately change the relocation + to be relative to the beginning of the section. */ + if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF + || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL + || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) + { + if (exp->X_op != O_symbol) + goto inv_disp; + + if (S_IS_LOCAL (exp->X_add_symbol) + && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section + && S_GET_SEGMENT (exp->X_add_symbol) != expr_section) + section_symbol (S_GET_SEGMENT (exp->X_add_symbol)); + exp->X_op = O_subtract; + exp->X_op_symbol = GOT_symbol; + if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL) + i.reloc[this_operand] = BFD_RELOC_32_PCREL; + else if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64) + i.reloc[this_operand] = BFD_RELOC_64; + else + i.reloc[this_operand] = BFD_RELOC_32; + } + + else if (exp->X_op == O_absent + || exp->X_op == O_illegal + || exp->X_op == O_big) + { + inv_disp: + as_bad (_("missing or invalid displacement expression `%s'"), + disp_start); + ret = 0; + } + + else if (flag_code == CODE_64BIT + && !i.prefix[ADDR_PREFIX] + && exp->X_op == O_constant) + { + /* Since displacement is signed extended to 64bit, don't allow + disp32 and turn off disp32s if they are out of range. */ + i.types[this_operand].bitfield.disp32 = 0; + if (!fits_in_signed_long (exp->X_add_number)) + { + i.types[this_operand].bitfield.disp32s = 0; + if (i.types[this_operand].bitfield.baseindex) + { + as_bad (_("0x%lx out range of signed 32bit displacement"), + (long) exp->X_add_number); + ret = 0; + } + } + } + +#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) + else if (exp->X_op != O_constant + && OUTPUT_FLAVOR == bfd_target_aout_flavour + && exp_seg != absolute_section + && exp_seg != text_section + && exp_seg != data_section + && exp_seg != bss_section + && exp_seg != undefined_section + && !bfd_is_com_section (exp_seg)) + { + as_bad (_("unimplemented segment %s in operand"), exp_seg->name); + ret = 0; + } +#endif + + /* Check if this is a displacement only operand. */ + bigdisp = i.types[this_operand]; + bigdisp.bitfield.disp8 = 0; + bigdisp.bitfield.disp16 = 0; + bigdisp.bitfield.disp32 = 0; + bigdisp.bitfield.disp32s = 0; + bigdisp.bitfield.disp64 = 0; + if (operand_type_all_zero (&bigdisp)) + i.types[this_operand] = operand_type_and (i.types[this_operand], + types); + + return ret; +} + +/* Make sure the memory operand we've been dealt is valid. + Return 1 on success, 0 on a failure. */ + +static int +i386_index_check (const char *operand_string) +{ + const char *kind = "base/index"; + enum flag_code addr_mode; + + if (i.prefix[ADDR_PREFIX]) + addr_mode = flag_code == CODE_32BIT ? CODE_16BIT : CODE_32BIT; + else + { + addr_mode = flag_code; + +#if INFER_ADDR_PREFIX + if (i.mem_operands == 0) + { + /* Infer address prefix from the first memory operand. */ + const reg_entry *addr_reg = i.base_reg; + + if (addr_reg == NULL) + addr_reg = i.index_reg; + + if (addr_reg) + { + if (addr_reg->reg_num == RegEip + || addr_reg->reg_num == RegEiz + || addr_reg->reg_type.bitfield.reg32) + addr_mode = CODE_32BIT; + else if (flag_code != CODE_64BIT + && addr_reg->reg_type.bitfield.reg16) + addr_mode = CODE_16BIT; + + if (addr_mode != flag_code) + { + i.prefix[ADDR_PREFIX] = ADDR_PREFIX_OPCODE; + i.prefixes += 1; + /* Change the size of any displacement too. At most one + of Disp16 or Disp32 is set. + FIXME. There doesn't seem to be any real need for + separate Disp16 and Disp32 flags. The same goes for + Imm16 and Imm32. Removing them would probably clean + up the code quite a lot. */ + if (flag_code != CODE_64BIT + && (i.types[this_operand].bitfield.disp16 + || i.types[this_operand].bitfield.disp32)) + i.types[this_operand] + = operand_type_xor (i.types[this_operand], disp16_32); + } + } + } +#endif + } + + if (current_templates->start->opcode_modifier.isstring + && !current_templates->start->opcode_modifier.immext + && (current_templates->end[-1].opcode_modifier.isstring + || i.mem_operands)) + { + /* Memory operands of string insns are special in that they only allow + a single register (rDI, rSI, or rBX) as their memory address. */ + const reg_entry *expected_reg; + static const char *di_si[][2] = + { + { "esi", "edi" }, + { "si", "di" }, + { "rsi", "rdi" } + }; + static const char *bx[] = { "ebx", "bx", "rbx" }; + + kind = "string address"; + + if (current_templates->start->opcode_modifier.w) + { + i386_operand_type type = current_templates->end[-1].operand_types[0]; + + if (!type.bitfield.baseindex + || ((!i.mem_operands != !intel_syntax) + && current_templates->end[-1].operand_types[1] + .bitfield.baseindex)) + type = current_templates->end[-1].operand_types[1]; + expected_reg = hash_find (reg_hash, + di_si[addr_mode][type.bitfield.esseg]); + + } + else + expected_reg = hash_find (reg_hash, bx[addr_mode]); + + if (i.base_reg != expected_reg + || i.index_reg + || operand_type_check (i.types[this_operand], disp)) + { + /* The second memory operand must have the same size as + the first one. */ + if (i.mem_operands + && i.base_reg + && !((addr_mode == CODE_64BIT + && i.base_reg->reg_type.bitfield.reg64) + || (addr_mode == CODE_32BIT + ? i.base_reg->reg_type.bitfield.reg32 + : i.base_reg->reg_type.bitfield.reg16))) + goto bad_address; + + as_warn (_("`%s' is not valid here (expected `%c%s%s%c')"), + operand_string, + intel_syntax ? '[' : '(', + register_prefix, + expected_reg->reg_name, + intel_syntax ? ']' : ')'); + return 1; + } + else + return 1; + +bad_address: + as_bad (_("`%s' is not a valid %s expression"), + operand_string, kind); + return 0; + } + else + { + if (addr_mode != CODE_16BIT) + { + /* 32-bit/64-bit checks. */ + if ((i.base_reg + && (addr_mode == CODE_64BIT + ? !i.base_reg->reg_type.bitfield.reg64 + : !i.base_reg->reg_type.bitfield.reg32) + && (i.index_reg + || (i.base_reg->reg_num + != (addr_mode == CODE_64BIT ? RegRip : RegEip)))) + || (i.index_reg + && !i.index_reg->reg_type.bitfield.regxmm + && !i.index_reg->reg_type.bitfield.regymm + && !i.index_reg->reg_type.bitfield.regzmm + && ((addr_mode == CODE_64BIT + ? !(i.index_reg->reg_type.bitfield.reg64 + || i.index_reg->reg_num == RegRiz) + : !(i.index_reg->reg_type.bitfield.reg32 + || i.index_reg->reg_num == RegEiz)) + || !i.index_reg->reg_type.bitfield.baseindex))) + goto bad_address; + } + else + { + /* 16-bit checks. */ + if ((i.base_reg + && (!i.base_reg->reg_type.bitfield.reg16 + || !i.base_reg->reg_type.bitfield.baseindex)) + || (i.index_reg + && (!i.index_reg->reg_type.bitfield.reg16 + || !i.index_reg->reg_type.bitfield.baseindex + || !(i.base_reg + && i.base_reg->reg_num < 6 + && i.index_reg->reg_num >= 6 + && i.log2_scale_factor == 0)))) + goto bad_address; + } + } + return 1; +} + +/* Handle vector immediates. */ + +static int +RC_SAE_immediate (const char *imm_start) +{ + unsigned int match_found, j; + const char *pstr = imm_start; + expressionS *exp; + + if (*pstr != '{') + return 0; + + pstr++; + match_found = 0; + for (j = 0; j < ARRAY_SIZE (RC_NamesTable); j++) + { + if (!strncmp (pstr, RC_NamesTable[j].name, RC_NamesTable[j].len)) + { + if (!i.rounding) + { + rc_op.type = RC_NamesTable[j].type; + rc_op.operand = this_operand; + i.rounding = &rc_op; + } + else + { + as_bad (_("duplicated `%s'"), imm_start); + return 0; + } + pstr += RC_NamesTable[j].len; + match_found = 1; + break; + } + } + if (!match_found) + return 0; + + if (*pstr++ != '}') + { + as_bad (_("Missing '}': '%s'"), imm_start); + return 0; + } + /* RC/SAE immediate string should contain nothing more. */; + if (*pstr != 0) + { + as_bad (_("Junk after '}': '%s'"), imm_start); + return 0; + } + + exp = &im_expressions[i.imm_operands++]; + i.op[this_operand].imms = exp; + + exp->X_op = O_constant; + exp->X_add_number = 0; + exp->X_add_symbol = (symbolS *) 0; + exp->X_op_symbol = (symbolS *) 0; + + i.types[this_operand].bitfield.imm8 = 1; + return 1; +} + +/* Parse OPERAND_STRING into the i386_insn structure I. Returns zero + on error. */ + +static int +i386_att_operand (char *operand_string) +{ + const reg_entry *r; + char *end_op; + char *op_string = operand_string; + + if (is_space_char (*op_string)) + ++op_string; + + /* We check for an absolute prefix (differentiating, + for example, 'jmp pc_relative_label' from 'jmp *absolute_label'. */ + if (*op_string == ABSOLUTE_PREFIX) + { + ++op_string; + if (is_space_char (*op_string)) + ++op_string; + i.types[this_operand].bitfield.jumpabsolute = 1; + } + + /* Check if operand is a register. */ + if ((r = parse_register (op_string, &end_op)) != NULL) + { + i386_operand_type temp; + + /* Check for a segment override by searching for ':' after a + segment register. */ + op_string = end_op; + if (is_space_char (*op_string)) + ++op_string; + if (*op_string == ':' + && (r->reg_type.bitfield.sreg2 + || r->reg_type.bitfield.sreg3)) + { + switch (r->reg_num) + { + case 0: + i.seg[i.mem_operands] = &es; + break; + case 1: + i.seg[i.mem_operands] = &cs; + break; + case 2: + i.seg[i.mem_operands] = &ss; + break; + case 3: + i.seg[i.mem_operands] = &ds; + break; + case 4: + i.seg[i.mem_operands] = &fs; + break; + case 5: + i.seg[i.mem_operands] = &gs; + break; + } + + /* Skip the ':' and whitespace. */ + ++op_string; + if (is_space_char (*op_string)) + ++op_string; + + if (!is_digit_char (*op_string) + && !is_identifier_char (*op_string) + && *op_string != '(' + && *op_string != ABSOLUTE_PREFIX) + { + as_bad (_("bad memory operand `%s'"), op_string); + return 0; + } + /* Handle case of %es:*foo. */ + if (*op_string == ABSOLUTE_PREFIX) + { + ++op_string; + if (is_space_char (*op_string)) + ++op_string; + i.types[this_operand].bitfield.jumpabsolute = 1; + } + goto do_memory_reference; + } + + /* Handle vector operations. */ + if (*op_string == '{') + { + op_string = check_VecOperations (op_string, NULL); + if (op_string == NULL) + return 0; + } + + if (*op_string) + { + as_bad (_("junk `%s' after register"), op_string); + return 0; + } + temp = r->reg_type; + temp.bitfield.baseindex = 0; + i.types[this_operand] = operand_type_or (i.types[this_operand], + temp); + i.types[this_operand].bitfield.unspecified = 0; + i.op[this_operand].regs = r; + i.reg_operands++; + } + else if (*op_string == REGISTER_PREFIX) + { + as_bad (_("bad register name `%s'"), op_string); + return 0; + } + else if (*op_string == IMMEDIATE_PREFIX) + { + ++op_string; + if (i.types[this_operand].bitfield.jumpabsolute) + { + as_bad (_("immediate operand illegal with absolute jump")); + return 0; + } + if (!i386_immediate (op_string)) + return 0; + } + else if (RC_SAE_immediate (operand_string)) + { + /* If it is a RC or SAE immediate, do nothing. */ + ; + } + else if (is_digit_char (*op_string) + || is_identifier_char (*op_string) + || *op_string == '(') + { + /* This is a memory reference of some sort. */ + char *base_string; + + /* Start and end of displacement string expression (if found). */ + char *displacement_string_start; + char *displacement_string_end; + char *vop_start; + + do_memory_reference: + if ((i.mem_operands == 1 + && !current_templates->start->opcode_modifier.isstring) + || i.mem_operands == 2) + { + as_bad (_("too many memory references for `%s'"), + current_templates->start->name); + return 0; + } + + /* Check for base index form. We detect the base index form by + looking for an ')' at the end of the operand, searching + for the '(' matching it, and finding a REGISTER_PREFIX or ',' + after the '('. */ + base_string = op_string + strlen (op_string); + + /* Handle vector operations. */ + vop_start = strchr (op_string, '{'); + if (vop_start && vop_start < base_string) + { + if (check_VecOperations (vop_start, base_string) == NULL) + return 0; + base_string = vop_start; + } + + --base_string; + if (is_space_char (*base_string)) + --base_string; + + /* If we only have a displacement, set-up for it to be parsed later. */ + displacement_string_start = op_string; + displacement_string_end = base_string + 1; + + if (*base_string == ')') + { + char *temp_string; + unsigned int parens_balanced = 1; + /* We've already checked that the number of left & right ()'s are + equal, so this loop will not be infinite. */ + do + { + base_string--; + if (*base_string == ')') + parens_balanced++; + if (*base_string == '(') + parens_balanced--; + } + while (parens_balanced); + + temp_string = base_string; + + /* Skip past '(' and whitespace. */ + ++base_string; + if (is_space_char (*base_string)) + ++base_string; + + if (*base_string == ',' + || ((i.base_reg = parse_register (base_string, &end_op)) + != NULL)) + { + displacement_string_end = temp_string; + + i.types[this_operand].bitfield.baseindex = 1; + + if (i.base_reg) + { + base_string = end_op; + if (is_space_char (*base_string)) + ++base_string; + } + + /* There may be an index reg or scale factor here. */ + if (*base_string == ',') + { + ++base_string; + if (is_space_char (*base_string)) + ++base_string; + + if ((i.index_reg = parse_register (base_string, &end_op)) + != NULL) + { + base_string = end_op; + if (is_space_char (*base_string)) + ++base_string; + if (*base_string == ',') + { + ++base_string; + if (is_space_char (*base_string)) + ++base_string; + } + else if (*base_string != ')') + { + as_bad (_("expecting `,' or `)' " + "after index register in `%s'"), + operand_string); + return 0; + } + } + else if (*base_string == REGISTER_PREFIX) + { + end_op = strchr (base_string, ','); + if (end_op) + *end_op = '\0'; + as_bad (_("bad register name `%s'"), base_string); + return 0; + } + + /* Check for scale factor. */ + if (*base_string != ')') + { + char *end_scale = i386_scale (base_string); + + if (!end_scale) + return 0; + + base_string = end_scale; + if (is_space_char (*base_string)) + ++base_string; + if (*base_string != ')') + { + as_bad (_("expecting `)' " + "after scale factor in `%s'"), + operand_string); + return 0; + } + } + else if (!i.index_reg) + { + as_bad (_("expecting index register or scale factor " + "after `,'; got '%c'"), + *base_string); + return 0; + } + } + else if (*base_string != ')') + { + as_bad (_("expecting `,' or `)' " + "after base register in `%s'"), + operand_string); + return 0; + } + } + else if (*base_string == REGISTER_PREFIX) + { + end_op = strchr (base_string, ','); + if (end_op) + *end_op = '\0'; + as_bad (_("bad register name `%s'"), base_string); + return 0; + } + } + + /* If there's an expression beginning the operand, parse it, + assuming displacement_string_start and + displacement_string_end are meaningful. */ + if (displacement_string_start != displacement_string_end) + { + if (!i386_displacement (displacement_string_start, + displacement_string_end)) + return 0; + } + + /* Special case for (%dx) while doing input/output op. */ + if (i.base_reg + && operand_type_equal (&i.base_reg->reg_type, + ®16_inoutportreg) + && i.index_reg == 0 + && i.log2_scale_factor == 0 + && i.seg[i.mem_operands] == 0 + && !operand_type_check (i.types[this_operand], disp)) + { + i.types[this_operand] = inoutportreg; + return 1; + } + + if (i386_index_check (operand_string) == 0) + return 0; + i.types[this_operand].bitfield.mem = 1; + i.mem_operands++; + } + else + { + /* It's not a memory operand; argh! */ + as_bad (_("invalid char %s beginning operand %d `%s'"), + output_invalid (*op_string), + this_operand + 1, + op_string); + return 0; + } + return 1; /* Normal return. */ +} + +/* Calculate the maximum variable size (i.e., excluding fr_fix) + that an rs_machine_dependent frag may reach. */ + +unsigned int +i386_frag_max_var (fragS *frag) +{ + /* The only relaxable frags are for jumps. + Unconditional jumps can grow by 4 bytes and others by 5 bytes. */ + gas_assert (frag->fr_type == rs_machine_dependent); + return TYPE_FROM_RELAX_STATE (frag->fr_subtype) == UNCOND_JUMP ? 4 : 5; +} + +/* md_estimate_size_before_relax() + + Called just before relax() for rs_machine_dependent frags. The x86 + assembler uses these frags to handle variable size jump + instructions. + + Any symbol that is now undefined will not become defined. + Return the correct fr_subtype in the frag. + Return the initial "guess for variable size of frag" to caller. + The guess is actually the growth beyond the fixed part. Whatever + we do to grow the fixed or variable part contributes to our + returned value. */ + +int +md_estimate_size_before_relax (fragS *fragP, segT segment) +{ + /* We've already got fragP->fr_subtype right; all we have to do is + check for un-relaxable symbols. On an ELF system, we can't relax + an externally visible symbol, because it may be overridden by a + shared library. */ + if (S_GET_SEGMENT (fragP->fr_symbol) != segment +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + || (IS_ELF + && (S_IS_EXTERNAL (fragP->fr_symbol) + || S_IS_WEAK (fragP->fr_symbol) + || ((symbol_get_bfdsym (fragP->fr_symbol)->flags + & BSF_GNU_INDIRECT_FUNCTION)))) +#endif +#if defined (OBJ_COFF) && defined (TE_PE) + || (OUTPUT_FLAVOR == bfd_target_coff_flavour + && S_IS_WEAK (fragP->fr_symbol)) +#endif + ) + { + /* Symbol is undefined in this segment, or we need to keep a + reloc so that weak symbols can be overridden. */ + int size = (fragP->fr_subtype & CODE16) ? 2 : 4; + enum bfd_reloc_code_real reloc_type; + unsigned char *opcode; + int old_fr_fix; + + if (fragP->fr_var != NO_RELOC) + reloc_type = (enum bfd_reloc_code_real) fragP->fr_var; + else if (size == 2) + reloc_type = BFD_RELOC_16_PCREL; + else + reloc_type = BFD_RELOC_32_PCREL; + + old_fr_fix = fragP->fr_fix; + opcode = (unsigned char *) fragP->fr_opcode; + + switch (TYPE_FROM_RELAX_STATE (fragP->fr_subtype)) + { + case UNCOND_JUMP: + /* Make jmp (0xeb) a (d)word displacement jump. */ + opcode[0] = 0xe9; + fragP->fr_fix += size; + fix_new (fragP, old_fr_fix, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); + break; + + case COND_JUMP86: + if (size == 2 + && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC)) + { + /* Negate the condition, and branch past an + unconditional jump. */ + opcode[0] ^= 1; + opcode[1] = 3; + /* Insert an unconditional jump. */ + opcode[2] = 0xe9; + /* We added two extra opcode bytes, and have a two byte + offset. */ + fragP->fr_fix += 2 + 2; + fix_new (fragP, old_fr_fix + 2, 2, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); + break; + } + /* Fall through. */ + + case COND_JUMP: + if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC) + { + fixS *fixP; + + fragP->fr_fix += 1; + fixP = fix_new (fragP, old_fr_fix, 1, + fragP->fr_symbol, + fragP->fr_offset, 1, + BFD_RELOC_8_PCREL); + fixP->fx_signed = 1; + break; + } + + /* This changes the byte-displacement jump 0x7N + to the (d)word-displacement jump 0x0f,0x8N. */ + opcode[1] = opcode[0] + 0x10; + opcode[0] = TWO_BYTE_OPCODE_ESCAPE; + /* We've added an opcode byte. */ + fragP->fr_fix += 1 + size; + fix_new (fragP, old_fr_fix + 1, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); + break; + + default: + BAD_CASE (fragP->fr_subtype); + break; + } + frag_wane (fragP); + return fragP->fr_fix - old_fr_fix; + } + + /* Guess size depending on current relax state. Initially the relax + state will correspond to a short jump and we return 1, because + the variable part of the frag (the branch offset) is one byte + long. However, we can relax a section more than once and in that + case we must either set fr_subtype back to the unrelaxed state, + or return the value for the appropriate branch. */ + return md_relax_table[fragP->fr_subtype].rlx_length; +} + +/* Called after relax() is finished. + + In: Address of frag. + fr_type == rs_machine_dependent. + fr_subtype is what the address relaxed to. + + Out: Any fixSs and constants are set up. + Caller will turn frag into a ".space 0". */ + +void +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, + fragS *fragP) +{ + unsigned char *opcode; + unsigned char *where_to_put_displacement = NULL; + offsetT target_address; + offsetT opcode_address; + unsigned int extension = 0; + offsetT displacement_from_opcode_start; + + opcode = (unsigned char *) fragP->fr_opcode; + + /* Address we want to reach in file space. */ + target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; + + /* Address opcode resides at in file space. */ + opcode_address = fragP->fr_address + fragP->fr_fix; + + /* Displacement from opcode start to fill into instruction. */ + displacement_from_opcode_start = target_address - opcode_address; + + if ((fragP->fr_subtype & BIG) == 0) + { + /* Don't have to change opcode. */ + extension = 1; /* 1 opcode + 1 displacement */ + where_to_put_displacement = &opcode[1]; + } + else + { + if (no_cond_jump_promotion + && TYPE_FROM_RELAX_STATE (fragP->fr_subtype) != UNCOND_JUMP) + as_warn_where (fragP->fr_file, fragP->fr_line, + _("long jump required")); + + switch (fragP->fr_subtype) + { + case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG): + extension = 4; /* 1 opcode + 4 displacement */ + opcode[0] = 0xe9; + where_to_put_displacement = &opcode[1]; + break; + + case ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16): + extension = 2; /* 1 opcode + 2 displacement */ + opcode[0] = 0xe9; + where_to_put_displacement = &opcode[1]; + break; + + case ENCODE_RELAX_STATE (COND_JUMP, BIG): + case ENCODE_RELAX_STATE (COND_JUMP86, BIG): + extension = 5; /* 2 opcode + 4 displacement */ + opcode[1] = opcode[0] + 0x10; + opcode[0] = TWO_BYTE_OPCODE_ESCAPE; + where_to_put_displacement = &opcode[2]; + break; + + case ENCODE_RELAX_STATE (COND_JUMP, BIG16): + extension = 3; /* 2 opcode + 2 displacement */ + opcode[1] = opcode[0] + 0x10; + opcode[0] = TWO_BYTE_OPCODE_ESCAPE; + where_to_put_displacement = &opcode[2]; + break; + + case ENCODE_RELAX_STATE (COND_JUMP86, BIG16): + extension = 4; + opcode[0] ^= 1; + opcode[1] = 3; + opcode[2] = 0xe9; + where_to_put_displacement = &opcode[3]; + break; + + default: + BAD_CASE (fragP->fr_subtype); + break; + } + } + + /* If size if less then four we are sure that the operand fits, + but if it's 4, then it could be that the displacement is larger + then -/+ 2GB. */ + if (DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype) == 4 + && object_64bit + && ((addressT) (displacement_from_opcode_start - extension + + ((addressT) 1 << 31)) + > (((addressT) 2 << 31) - 1))) + { + as_bad_where (fragP->fr_file, fragP->fr_line, + _("jump target out of range")); + /* Make us emit 0. */ + displacement_from_opcode_start = extension; + } + /* Now put displacement after opcode. */ + md_number_to_chars ((char *) where_to_put_displacement, + (valueT) (displacement_from_opcode_start - extension), + DISP_SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); + fragP->fr_fix += extension; +} + +/* Apply a fixup (fixP) to segment data, once it has been determined + by our caller that we have all the info we need to fix it up. + + Parameter valP is the pointer to the value of the bits. + + On the 386, immediates, displacements, and data pointers are all in + the same (little-endian) format, so we don't need to care about which + we are handling. */ + +void +md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) +{ + char *p = fixP->fx_where + fixP->fx_frag->fr_literal; + valueT value = *valP; + +#if !defined (TE_Mach) + if (fixP->fx_pcrel) + { + switch (fixP->fx_r_type) + { + default: + break; + + case BFD_RELOC_64: + fixP->fx_r_type = BFD_RELOC_64_PCREL; + break; + case BFD_RELOC_32: + case BFD_RELOC_X86_64_32S: + fixP->fx_r_type = BFD_RELOC_32_PCREL; + break; + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_16_PCREL; + break; + case BFD_RELOC_8: + fixP->fx_r_type = BFD_RELOC_8_PCREL; + break; + } + } + + if (fixP->fx_addsy != NULL + && (fixP->fx_r_type == BFD_RELOC_32_PCREL + || fixP->fx_r_type == BFD_RELOC_64_PCREL + || fixP->fx_r_type == BFD_RELOC_16_PCREL + || fixP->fx_r_type == BFD_RELOC_8_PCREL + || fixP->fx_r_type == BFD_RELOC_X86_64_PC32_BND) + && !use_rela_relocations) + { + /* This is a hack. There should be a better way to handle this. + This covers for the fact that bfd_install_relocation will + subtract the current location (for partial_inplace, PC relative + relocations); see more below. */ +#ifndef OBJ_AOUT + if (IS_ELF +#ifdef TE_PE + || OUTPUT_FLAVOR == bfd_target_coff_flavour +#endif + ) + value += fixP->fx_where + fixP->fx_frag->fr_address; +#endif +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + if (IS_ELF) + { + segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy); + + if ((sym_seg == seg + || (symbol_section_p (fixP->fx_addsy) + && sym_seg != absolute_section)) + && !generic_force_reloc (fixP)) + { + /* Yes, we add the values in twice. This is because + bfd_install_relocation subtracts them out again. I think + bfd_install_relocation is broken, but I don't dare change + it. FIXME. */ + value += fixP->fx_where + fixP->fx_frag->fr_address; + } + } +#endif +#if defined (OBJ_COFF) && defined (TE_PE) + /* For some reason, the PE format does not store a + section address offset for a PC relative symbol. */ + if (S_GET_SEGMENT (fixP->fx_addsy) != seg + || S_IS_WEAK (fixP->fx_addsy)) + value += md_pcrel_from (fixP); +#endif + } +#if defined (OBJ_COFF) && defined (TE_PE) + if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy)) + { + value -= S_GET_VALUE (fixP->fx_addsy); + } +#endif + + /* Fix a few things - the dynamic linker expects certain values here, + and we must not disappoint it. */ +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + if (IS_ELF && fixP->fx_addsy) + switch (fixP->fx_r_type) + { + case BFD_RELOC_386_PLT32: + case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: + /* Make the jump instruction point to the address of the operand. At + runtime we merely add the offset to the actual PLT entry. */ + value = -4; + break; + + case BFD_RELOC_386_TLS_GD: + case BFD_RELOC_386_TLS_LDM: + case BFD_RELOC_386_TLS_IE_32: + case BFD_RELOC_386_TLS_IE: + case BFD_RELOC_386_TLS_GOTIE: + case BFD_RELOC_386_TLS_GOTDESC: + case BFD_RELOC_X86_64_TLSGD: + case BFD_RELOC_X86_64_TLSLD: + case BFD_RELOC_X86_64_GOTTPOFF: + case BFD_RELOC_X86_64_GOTPC32_TLSDESC: + value = 0; /* Fully resolved at runtime. No addend. */ + /* Fallthrough */ + case BFD_RELOC_386_TLS_LE: + case BFD_RELOC_386_TLS_LDO_32: + case BFD_RELOC_386_TLS_LE_32: + case BFD_RELOC_X86_64_DTPOFF32: + case BFD_RELOC_X86_64_DTPOFF64: + case BFD_RELOC_X86_64_TPOFF32: + case BFD_RELOC_X86_64_TPOFF64: + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; + + case BFD_RELOC_386_TLS_DESC_CALL: + case BFD_RELOC_X86_64_TLSDESC_CALL: + value = 0; /* Fully resolved at runtime. No addend. */ + S_SET_THREAD_LOCAL (fixP->fx_addsy); + fixP->fx_done = 0; + return; + + case BFD_RELOC_386_GOT32: + case BFD_RELOC_X86_64_GOT32: + value = 0; /* Fully resolved at runtime. No addend. */ + break; + + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + fixP->fx_done = 0; + return; + + default: + break; + } +#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */ + *valP = value; +#endif /* !defined (TE_Mach) */ + + /* Are we finished with this relocation now? */ + if (fixP->fx_addsy == NULL) + fixP->fx_done = 1; +#if defined (OBJ_COFF) && defined (TE_PE) + else if (fixP->fx_addsy != NULL && S_IS_WEAK (fixP->fx_addsy)) + { + fixP->fx_done = 0; + /* Remember value for tc_gen_reloc. */ + fixP->fx_addnumber = value; + /* Clear out the frag for now. */ + value = 0; + } +#endif + else if (use_rela_relocations) + { + fixP->fx_no_overflow = 1; + /* Remember value for tc_gen_reloc. */ + fixP->fx_addnumber = value; + value = 0; + } + + md_number_to_chars (p, value, fixP->fx_size); +} + +char * +md_atof (int type, char *litP, int *sizeP) +{ + /* This outputs the LITTLENUMs in REVERSE order; + in accord with the bigendian 386. */ + return ieee_md_atof (type, litP, sizeP, FALSE); +} + +static char output_invalid_buf[sizeof (unsigned char) * 2 + 6]; + +static char * +output_invalid (int c) +{ + if (ISPRINT (c)) + snprintf (output_invalid_buf, sizeof (output_invalid_buf), + "'%c'", c); + else + snprintf (output_invalid_buf, sizeof (output_invalid_buf), + "(0x%x)", (unsigned char) c); + return output_invalid_buf; +} + +/* REG_STRING starts *before* REGISTER_PREFIX. */ + +static const reg_entry * +parse_real_register (char *reg_string, char **end_op) +{ + char *s = reg_string; + char *p; + char reg_name_given[MAX_REG_NAME_SIZE + 1]; + const reg_entry *r; + + /* Skip possible REGISTER_PREFIX and possible whitespace. */ + if (*s == REGISTER_PREFIX) + ++s; + + if (is_space_char (*s)) + ++s; + + p = reg_name_given; + while ((*p++ = register_chars[(unsigned char) *s]) != '\0') + { + if (p >= reg_name_given + MAX_REG_NAME_SIZE) + return (const reg_entry *) NULL; + s++; + } + + /* For naked regs, make sure that we are not dealing with an identifier. + This prevents confusing an identifier like `eax_var' with register + `eax'. */ + if (allow_naked_reg && identifier_chars[(unsigned char) *s]) + return (const reg_entry *) NULL; + + *end_op = s; + + r = (const reg_entry *) hash_find (reg_hash, reg_name_given); + + /* Handle floating point regs, allowing spaces in the (i) part. */ + if (r == i386_regtab /* %st is first entry of table */) + { + if (is_space_char (*s)) + ++s; + if (*s == '(') + { + ++s; + if (is_space_char (*s)) + ++s; + if (*s >= '0' && *s <= '7') + { + int fpr = *s - '0'; + ++s; + if (is_space_char (*s)) + ++s; + if (*s == ')') + { + *end_op = s + 1; + r = (const reg_entry *) hash_find (reg_hash, "st(0)"); + know (r); + return r + fpr; + } + } + /* We have "%st(" then garbage. */ + return (const reg_entry *) NULL; + } + } + + if (r == NULL || allow_pseudo_reg) + return r; + + if (operand_type_all_zero (&r->reg_type)) + return (const reg_entry *) NULL; + + if ((r->reg_type.bitfield.reg32 + || r->reg_type.bitfield.sreg3 + || r->reg_type.bitfield.control + || r->reg_type.bitfield.debug + || r->reg_type.bitfield.test) + && !cpu_arch_flags.bitfield.cpui386) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.floatreg + && !cpu_arch_flags.bitfield.cpu8087 + && !cpu_arch_flags.bitfield.cpu287 + && !cpu_arch_flags.bitfield.cpu387) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.regmmx && !cpu_arch_flags.bitfield.cpummx) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.regxmm && !cpu_arch_flags.bitfield.cpusse) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.regymm && !cpu_arch_flags.bitfield.cpuavx) + return (const reg_entry *) NULL; + + if ((r->reg_type.bitfield.regzmm || r->reg_type.bitfield.regmask) + && !cpu_arch_flags.bitfield.cpuavx512f) + return (const reg_entry *) NULL; + + /* Don't allow fake index register unless allow_index_reg isn't 0. */ + if (!allow_index_reg + && (r->reg_num == RegEiz || r->reg_num == RegRiz)) + return (const reg_entry *) NULL; + + /* Upper 16 vector register is only available with VREX in 64bit + mode. */ + if ((r->reg_flags & RegVRex)) + { + if (!cpu_arch_flags.bitfield.cpuvrex + || flag_code != CODE_64BIT) + return (const reg_entry *) NULL; + + i.need_vrex = 1; + } + + if (((r->reg_flags & (RegRex64 | RegRex)) + || r->reg_type.bitfield.reg64) + && (!cpu_arch_flags.bitfield.cpulm + || !operand_type_equal (&r->reg_type, &control)) + && flag_code != CODE_64BIT) + return (const reg_entry *) NULL; + + if (r->reg_type.bitfield.sreg3 && r->reg_num == RegFlat && !intel_syntax) + return (const reg_entry *) NULL; + + return r; +} + +/* REG_STRING starts *before* REGISTER_PREFIX. */ + +static const reg_entry * +parse_register (char *reg_string, char **end_op) +{ + const reg_entry *r; + + if (*reg_string == REGISTER_PREFIX || allow_naked_reg) + r = parse_real_register (reg_string, end_op); + else + r = NULL; + if (!r) + { + char *save = input_line_pointer; + char c; + symbolS *symbolP; + + input_line_pointer = reg_string; + c = get_symbol_end (); + symbolP = symbol_find (reg_string); + if (symbolP && S_GET_SEGMENT (symbolP) == reg_section) + { + const expressionS *e = symbol_get_value_expression (symbolP); + + know (e->X_op == O_register); + know (e->X_add_number >= 0 + && (valueT) e->X_add_number < i386_regtab_size); + r = i386_regtab + e->X_add_number; + *end_op = input_line_pointer; + } + *input_line_pointer = c; + input_line_pointer = save; + } + return r; +} + +int +i386_parse_name (char *name, expressionS *e, char *nextcharP) +{ + const reg_entry *r; + char *end = input_line_pointer; + + *end = *nextcharP; + r = parse_register (name, &input_line_pointer); + if (r && end <= input_line_pointer) + { + *nextcharP = *input_line_pointer; + *input_line_pointer = 0; + e->X_op = O_register; + e->X_add_number = r - i386_regtab; + return 1; + } + input_line_pointer = end; + *end = 0; + return intel_syntax ? i386_intel_parse_name (name, e) : 0; +} + +void +md_operand (expressionS *e) +{ + char *end; + const reg_entry *r; + + switch (*input_line_pointer) + { + case REGISTER_PREFIX: + r = parse_real_register (input_line_pointer, &end); + if (r) + { + e->X_op = O_register; + e->X_add_number = r - i386_regtab; + input_line_pointer = end; + } + break; + + case '[': + gas_assert (intel_syntax); + end = input_line_pointer++; + expression (e); + if (*input_line_pointer == ']') + { + ++input_line_pointer; + e->X_op_symbol = make_expr_symbol (e); + e->X_add_symbol = NULL; + e->X_add_number = 0; + e->X_op = O_index; + } + else + { + e->X_op = O_absent; + input_line_pointer = end; + } + break; + } +} + + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) +const char *md_shortopts = "kVQ:sqn"; +#else +const char *md_shortopts = "qn"; +#endif + +#define OPTION_32 (OPTION_MD_BASE + 0) +#define OPTION_64 (OPTION_MD_BASE + 1) +#define OPTION_DIVIDE (OPTION_MD_BASE + 2) +#define OPTION_MARCH (OPTION_MD_BASE + 3) +#define OPTION_MTUNE (OPTION_MD_BASE + 4) +#define OPTION_MMNEMONIC (OPTION_MD_BASE + 5) +#define OPTION_MSYNTAX (OPTION_MD_BASE + 6) +#define OPTION_MINDEX_REG (OPTION_MD_BASE + 7) +#define OPTION_MNAKED_REG (OPTION_MD_BASE + 8) +#define OPTION_MOLD_GCC (OPTION_MD_BASE + 9) +#define OPTION_MSSE2AVX (OPTION_MD_BASE + 10) +#define OPTION_MSSE_CHECK (OPTION_MD_BASE + 11) +#define OPTION_MOPERAND_CHECK (OPTION_MD_BASE + 12) +#define OPTION_MAVXSCALAR (OPTION_MD_BASE + 13) +#define OPTION_X32 (OPTION_MD_BASE + 14) +#define OPTION_MADD_BND_PREFIX (OPTION_MD_BASE + 15) +#define OPTION_MEVEXLIG (OPTION_MD_BASE + 16) +#define OPTION_MEVEXWIG (OPTION_MD_BASE + 17) + +struct option md_longopts[] = +{ + {"32", no_argument, NULL, OPTION_32}, +#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) + {"64", no_argument, NULL, OPTION_64}, +#endif +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + {"x32", no_argument, NULL, OPTION_X32}, +#endif + {"divide", no_argument, NULL, OPTION_DIVIDE}, + {"march", required_argument, NULL, OPTION_MARCH}, + {"mtune", required_argument, NULL, OPTION_MTUNE}, + {"mmnemonic", required_argument, NULL, OPTION_MMNEMONIC}, + {"msyntax", required_argument, NULL, OPTION_MSYNTAX}, + {"mindex-reg", no_argument, NULL, OPTION_MINDEX_REG}, + {"mnaked-reg", no_argument, NULL, OPTION_MNAKED_REG}, + {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC}, + {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX}, + {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK}, + {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK}, + {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR}, + {"madd-bnd-prefix", no_argument, NULL, OPTION_MADD_BND_PREFIX}, + {"mevexlig", required_argument, NULL, OPTION_MEVEXLIG}, + {"mevexwig", required_argument, NULL, OPTION_MEVEXWIG}, + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof (md_longopts); + +int +md_parse_option (int c, char *arg) +{ + unsigned int j; + char *arch, *next; + + switch (c) + { + case 'n': + optimize_align_code = 0; + break; + + case 'q': + quiet_warnings = 1; + break; + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section + should be emitted or not. FIXME: Not implemented. */ + case 'Q': + break; + + /* -V: SVR4 argument to print version ID. */ + case 'V': + print_version_id (); + break; + + /* -k: Ignore for FreeBSD compatibility. */ + case 'k': + break; + + case 's': + /* -s: On i386 Solaris, this tells the native assembler to use + .stab instead of .stab.excl. We always use .stab anyhow. */ + break; +#endif +#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) + case OPTION_64: + { + const char **list, **l; + + list = bfd_target_list (); + for (l = list; *l != NULL; l++) + if (CONST_STRNEQ (*l, "elf64-x86-64") + || strcmp (*l, "coff-x86-64") == 0 + || strcmp (*l, "pe-x86-64") == 0 + || strcmp (*l, "pei-x86-64") == 0 + || strcmp (*l, "mach-o-x86-64") == 0) + { + default_arch = "x86_64"; + break; + } + if (*l == NULL) + as_fatal (_("no compiled in support for x86_64")); + free (list); + } + break; +#endif + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + case OPTION_X32: + if (IS_ELF) + { + const char **list, **l; + + list = bfd_target_list (); + for (l = list; *l != NULL; l++) + if (CONST_STRNEQ (*l, "elf32-x86-64")) + { + default_arch = "x86_64:32"; + break; + } + if (*l == NULL) + as_fatal (_("no compiled in support for 32bit x86_64")); + free (list); + } + else + as_fatal (_("32bit x86_64 is only supported for ELF")); + break; +#endif + + case OPTION_32: + default_arch = "i386"; + break; + + case OPTION_DIVIDE: +#ifdef SVR4_COMMENT_CHARS + { + char *n, *t; + const char *s; + + n = (char *) xmalloc (strlen (i386_comment_chars) + 1); + t = n; + for (s = i386_comment_chars; *s != '\0'; s++) + if (*s != '/') + *t++ = *s; + *t = '\0'; + i386_comment_chars = n; + } +#endif + break; + + case OPTION_MARCH: + arch = xstrdup (arg); + do + { + if (*arch == '.') + as_fatal (_("invalid -march= option: `%s'"), arg); + next = strchr (arch, '+'); + if (next) + *next++ = '\0'; + for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) + { + if (strcmp (arch, cpu_arch [j].name) == 0) + { + /* Processor. */ + if (! cpu_arch[j].flags.bitfield.cpui386) + continue; + + cpu_arch_name = cpu_arch[j].name; + cpu_sub_arch_name = NULL; + cpu_arch_flags = cpu_arch[j].flags; + cpu_arch_isa = cpu_arch[j].type; + cpu_arch_isa_flags = cpu_arch[j].flags; + if (!cpu_arch_tune_set) + { + cpu_arch_tune = cpu_arch_isa; + cpu_arch_tune_flags = cpu_arch_isa_flags; + } + break; + } + else if (*cpu_arch [j].name == '.' + && strcmp (arch, cpu_arch [j].name + 1) == 0) + { + /* ISA entension. */ + i386_cpu_flags flags; + + if (!cpu_arch[j].negated) + flags = cpu_flags_or (cpu_arch_flags, + cpu_arch[j].flags); + else + flags = cpu_flags_and_not (cpu_arch_flags, + cpu_arch[j].flags); + if (!cpu_flags_equal (&flags, &cpu_arch_flags)) + { + if (cpu_sub_arch_name) + { + char *name = cpu_sub_arch_name; + cpu_sub_arch_name = concat (name, + cpu_arch[j].name, + (const char *) NULL); + free (name); + } + else + cpu_sub_arch_name = xstrdup (cpu_arch[j].name); + cpu_arch_flags = flags; + cpu_arch_isa_flags = flags; + } + break; + } + } + + if (j >= ARRAY_SIZE (cpu_arch)) + as_fatal (_("invalid -march= option: `%s'"), arg); + + arch = next; + } + while (next != NULL ); + break; + + case OPTION_MTUNE: + if (*arg == '.') + as_fatal (_("invalid -mtune= option: `%s'"), arg); + for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) + { + if (strcmp (arg, cpu_arch [j].name) == 0) + { + cpu_arch_tune_set = 1; + cpu_arch_tune = cpu_arch [j].type; + cpu_arch_tune_flags = cpu_arch[j].flags; + break; + } + } + if (j >= ARRAY_SIZE (cpu_arch)) + as_fatal (_("invalid -mtune= option: `%s'"), arg); + break; + + case OPTION_MMNEMONIC: + if (strcasecmp (arg, "att") == 0) + intel_mnemonic = 0; + else if (strcasecmp (arg, "intel") == 0) + intel_mnemonic = 1; + else + as_fatal (_("invalid -mmnemonic= option: `%s'"), arg); + break; + + case OPTION_MSYNTAX: + if (strcasecmp (arg, "att") == 0) + intel_syntax = 0; + else if (strcasecmp (arg, "intel") == 0) + intel_syntax = 1; + else + as_fatal (_("invalid -msyntax= option: `%s'"), arg); + break; + + case OPTION_MINDEX_REG: + allow_index_reg = 1; + break; + + case OPTION_MNAKED_REG: + allow_naked_reg = 1; + break; + + case OPTION_MOLD_GCC: + old_gcc = 1; + break; + + case OPTION_MSSE2AVX: + sse2avx = 1; + break; + + case OPTION_MSSE_CHECK: + if (strcasecmp (arg, "error") == 0) + sse_check = check_error; + else if (strcasecmp (arg, "warning") == 0) + sse_check = check_warning; + else if (strcasecmp (arg, "none") == 0) + sse_check = check_none; + else + as_fatal (_("invalid -msse-check= option: `%s'"), arg); + break; + + case OPTION_MOPERAND_CHECK: + if (strcasecmp (arg, "error") == 0) + operand_check = check_error; + else if (strcasecmp (arg, "warning") == 0) + operand_check = check_warning; + else if (strcasecmp (arg, "none") == 0) + operand_check = check_none; + else + as_fatal (_("invalid -moperand-check= option: `%s'"), arg); + break; + + case OPTION_MAVXSCALAR: + if (strcasecmp (arg, "128") == 0) + avxscalar = vex128; + else if (strcasecmp (arg, "256") == 0) + avxscalar = vex256; + else + as_fatal (_("invalid -mavxscalar= option: `%s'"), arg); + break; + + case OPTION_MADD_BND_PREFIX: + add_bnd_prefix = 1; + break; + + case OPTION_MEVEXLIG: + if (strcmp (arg, "128") == 0) + evexlig = evexl128; + else if (strcmp (arg, "256") == 0) + evexlig = evexl256; + else if (strcmp (arg, "512") == 0) + evexlig = evexl512; + else + as_fatal (_("invalid -mevexlig= option: `%s'"), arg); + break; + + case OPTION_MEVEXWIG: + if (strcmp (arg, "0") == 0) + evexwig = evexw0; + else if (strcmp (arg, "1") == 0) + evexwig = evexw1; + else + as_fatal (_("invalid -mevexwig= option: `%s'"), arg); + break; + + default: + return 0; + } + return 1; +} + +#define MESSAGE_TEMPLATE \ +" " + +static void +show_arch (FILE *stream, int ext, int check) +{ + static char message[] = MESSAGE_TEMPLATE; + char *start = message + 27; + char *p; + int size = sizeof (MESSAGE_TEMPLATE); + int left; + const char *name; + int len; + unsigned int j; + + p = start; + left = size - (start - message); + for (j = 0; j < ARRAY_SIZE (cpu_arch); j++) + { + /* Should it be skipped? */ + if (cpu_arch [j].skip) + continue; + + name = cpu_arch [j].name; + len = cpu_arch [j].len; + if (*name == '.') + { + /* It is an extension. Skip if we aren't asked to show it. */ + if (ext) + { + name++; + len--; + } + else + continue; + } + else if (ext) + { + /* It is an processor. Skip if we show only extension. */ + continue; + } + else if (check && ! cpu_arch[j].flags.bitfield.cpui386) + { + /* It is an impossible processor - skip. */ + continue; + } + + /* Reserve 2 spaces for ", " or ",\0" */ + left -= len + 2; + + /* Check if there is any room. */ + if (left >= 0) + { + if (p != start) + { + *p++ = ','; + *p++ = ' '; + } + p = mempcpy (p, name, len); + } + else + { + /* Output the current message now and start a new one. */ + *p++ = ','; + *p = '\0'; + fprintf (stream, "%s\n", message); + p = start; + left = size - (start - message) - len - 2; + + gas_assert (left >= 0); + + p = mempcpy (p, name, len); + } + } + + *p = '\0'; + fprintf (stream, "%s\n", message); +} + +void +md_show_usage (FILE *stream) +{ +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + fprintf (stream, _("\ + -Q ignored\n\ + -V print assembler version number\n\ + -k ignored\n")); +#endif + fprintf (stream, _("\ + -n Do not optimize code alignment\n\ + -q quieten some warnings\n")); +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + fprintf (stream, _("\ + -s ignored\n")); +#endif +#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP)) + fprintf (stream, _("\ + --32/--64/--x32 generate 32bit/64bit/x32 code\n")); +#endif +#ifdef SVR4_COMMENT_CHARS + fprintf (stream, _("\ + --divide do not treat `/' as a comment character\n")); +#else + fprintf (stream, _("\ + --divide ignored\n")); +#endif + fprintf (stream, _("\ + -march=CPU[,+EXTENSION...]\n\ + generate code for CPU and EXTENSION, CPU is one of:\n")); + show_arch (stream, 0, 1); + fprintf (stream, _("\ + EXTENSION is combination of:\n")); + show_arch (stream, 1, 0); + fprintf (stream, _("\ + -mtune=CPU optimize for CPU, CPU is one of:\n")); + show_arch (stream, 0, 0); + fprintf (stream, _("\ + -msse2avx encode SSE instructions with VEX prefix\n")); + fprintf (stream, _("\ + -msse-check=[none|error|warning]\n\ + check SSE instructions\n")); + fprintf (stream, _("\ + -moperand-check=[none|error|warning]\n\ + check operand combinations for validity\n")); + fprintf (stream, _("\ + -mavxscalar=[128|256] encode scalar AVX instructions with specific vector\n\ + length\n")); + fprintf (stream, _("\ + -mevexlig=[128|256|512] encode scalar EVEX instructions with specific vector\n\ + length\n")); + fprintf (stream, _("\ + -mevexwig=[0|1] encode EVEX instructions with specific EVEX.W value\n\ + for EVEX.W bit ignored instructions\n")); + fprintf (stream, _("\ + -mmnemonic=[att|intel] use AT&T/Intel mnemonic\n")); + fprintf (stream, _("\ + -msyntax=[att|intel] use AT&T/Intel syntax\n")); + fprintf (stream, _("\ + -mindex-reg support pseudo index registers\n")); + fprintf (stream, _("\ + -mnaked-reg don't require `%%' prefix for registers\n")); + fprintf (stream, _("\ + -mold-gcc support old (<= 2.8.1) versions of gcc\n")); + fprintf (stream, _("\ + -madd-bnd-prefix add BND prefix for all valid branches\n")); +} + +#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ + || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) + +/* Pick the target format to use. */ + +const char * +i386_target_format (void) +{ + if (!strncmp (default_arch, "x86_64", 6)) + { + update_code_flag (CODE_64BIT, 1); + if (default_arch[6] == '\0') + x86_elf_abi = X86_64_ABI; + else + x86_elf_abi = X86_64_X32_ABI; + } + else if (!strcmp (default_arch, "i386")) + update_code_flag (CODE_32BIT, 1); + else + as_fatal (_("unknown architecture")); + + if (cpu_flags_all_zero (&cpu_arch_isa_flags)) + cpu_arch_isa_flags = cpu_arch[flag_code == CODE_64BIT].flags; + if (cpu_flags_all_zero (&cpu_arch_tune_flags)) + cpu_arch_tune_flags = cpu_arch[flag_code == CODE_64BIT].flags; + + switch (OUTPUT_FLAVOR) + { +#if defined (OBJ_MAYBE_AOUT) || defined (OBJ_AOUT) + case bfd_target_aout_flavour: + return AOUT_TARGET_FORMAT; +#endif +#if defined (OBJ_MAYBE_COFF) || defined (OBJ_COFF) +# if defined (TE_PE) || defined (TE_PEP) + case bfd_target_coff_flavour: + return flag_code == CODE_64BIT ? "pe-x86-64" : "pe-i386"; +# elif defined (TE_GO32) + case bfd_target_coff_flavour: + return "coff-go32"; +# else + case bfd_target_coff_flavour: + return "coff-i386"; +# endif +#endif +#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) + case bfd_target_elf_flavour: + { + const char *format; + + switch (x86_elf_abi) + { + default: + format = ELF_TARGET_FORMAT; + break; + case X86_64_ABI: + use_rela_relocations = 1; + object_64bit = 1; + format = ELF_TARGET_FORMAT64; + break; + case X86_64_X32_ABI: + use_rela_relocations = 1; + object_64bit = 1; + disallow_64bit_reloc = 1; + format = ELF_TARGET_FORMAT32; + break; + } + if (cpu_arch_isa == PROCESSOR_L1OM) + { + if (x86_elf_abi != X86_64_ABI) + as_fatal (_("Intel L1OM is 64bit only")); + return ELF_TARGET_L1OM_FORMAT; + } + if (cpu_arch_isa == PROCESSOR_K1OM) + { + if (x86_elf_abi != X86_64_ABI) + as_fatal (_("Intel K1OM is 64bit only")); + return ELF_TARGET_K1OM_FORMAT; + } + else + return format; + } +#endif +#if defined (OBJ_MACH_O) + case bfd_target_mach_o_flavour: + if (flag_code == CODE_64BIT) + { + use_rela_relocations = 1; + object_64bit = 1; + return "mach-o-x86-64"; + } + else + return "mach-o-i386"; +#endif + default: + abort (); + return NULL; + } +} + +#endif /* OBJ_MAYBE_ more than one */ + +#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) +void +i386_elf_emit_arch_note (void) +{ + if (IS_ELF && cpu_arch_name != NULL) + { + char *p; + asection *seg = now_seg; + subsegT subseg = now_subseg; + Elf_Internal_Note i_note; + Elf_External_Note e_note; + asection *note_secp; + int len; + + /* Create the .note section. */ + note_secp = subseg_new (".note", 0); + bfd_set_section_flags (stdoutput, + note_secp, + SEC_HAS_CONTENTS | SEC_READONLY); + + /* Process the arch string. */ + len = strlen (cpu_arch_name); + + i_note.namesz = len + 1; + i_note.descsz = 0; + i_note.type = NT_ARCH; + p = frag_more (sizeof (e_note.namesz)); + md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz)); + p = frag_more (sizeof (e_note.descsz)); + md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz)); + p = frag_more (sizeof (e_note.type)); + md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type)); + p = frag_more (len + 1); + strcpy (p, cpu_arch_name); + + frag_align (2, 0, 0); + + subseg_set (seg, subseg); + } +} +#endif + +symbolS * +md_undefined_symbol (char *name) +{ + if (name[0] == GLOBAL_OFFSET_TABLE_NAME[0] + && name[1] == GLOBAL_OFFSET_TABLE_NAME[1] + && name[2] == GLOBAL_OFFSET_TABLE_NAME[2] + && strcmp (name, GLOBAL_OFFSET_TABLE_NAME) == 0) + { + if (!GOT_symbol) + { + if (symbol_find (name)) + as_bad (_("GOT already in symbol table")); + GOT_symbol = symbol_new (name, undefined_section, + (valueT) 0, &zero_address_frag); + }; + return GOT_symbol; + } + return 0; +} + +/* Round up a section size to the appropriate boundary. */ + +valueT +md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) +{ +#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)) + if (OUTPUT_FLAVOR == bfd_target_aout_flavour) + { + /* For a.out, force the section size to be aligned. If we don't do + this, BFD will align it for us, but it will not write out the + final bytes of the section. This may be a bug in BFD, but it is + easier to fix it here since that is how the other a.out targets + work. */ + int align; + + align = bfd_get_section_alignment (stdoutput, segment); + size = ((size + (1 << align) - 1) & ((valueT) -1 << align)); + } +#endif + + return size; +} + +/* On the i386, PC-relative offsets are relative to the start of the + next instruction. That is, the address of the offset, plus its + size, since the offset is always the last part of the insn. */ + +long +md_pcrel_from (fixS *fixP) +{ + return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; +} + +#ifndef I386COFF + +static void +s_bss (int ignore ATTRIBUTE_UNUSED) +{ + int temp; + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + if (IS_ELF) + obj_elf_section_change_hook (); +#endif + temp = get_absolute_expression (); + subseg_set (bss_section, (subsegT) temp); + demand_empty_rest_of_line (); +} + +#endif + +void +i386_validate_fix (fixS *fixp) +{ + if (fixp->fx_subsy && fixp->fx_subsy == GOT_symbol) + { + if (fixp->fx_r_type == BFD_RELOC_32_PCREL) + { + if (!object_64bit) + abort (); + fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL; + } + else + { + if (!object_64bit) + fixp->fx_r_type = BFD_RELOC_386_GOTOFF; + else + fixp->fx_r_type = BFD_RELOC_X86_64_GOTOFF64; + } + fixp->fx_subsy = 0; + } +} + +arelent * +tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) +{ + arelent *rel; + bfd_reloc_code_real_type code; + + switch (fixp->fx_r_type) + { +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + case BFD_RELOC_SIZE32: + case BFD_RELOC_SIZE64: + if (S_IS_DEFINED (fixp->fx_addsy) + && !S_IS_EXTERNAL (fixp->fx_addsy)) + { + /* Resolve size relocation against local symbol to size of + the symbol plus addend. */ + valueT value = S_GET_SIZE (fixp->fx_addsy) + fixp->fx_offset; + if (fixp->fx_r_type == BFD_RELOC_SIZE32 + && !fits_in_unsigned_long (value)) + as_bad_where (fixp->fx_file, fixp->fx_line, + _("symbol size computation overflow")); + fixp->fx_addsy = NULL; + fixp->fx_subsy = NULL; + md_apply_fix (fixp, (valueT *) &value, NULL); + return NULL; + } +#endif + + case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: + case BFD_RELOC_X86_64_GOT32: + case BFD_RELOC_X86_64_GOTPCREL: + case BFD_RELOC_386_PLT32: + case BFD_RELOC_386_GOT32: + case BFD_RELOC_386_GOTOFF: + case BFD_RELOC_386_GOTPC: + case BFD_RELOC_386_TLS_GD: + case BFD_RELOC_386_TLS_LDM: + case BFD_RELOC_386_TLS_LDO_32: + case BFD_RELOC_386_TLS_IE_32: + case BFD_RELOC_386_TLS_IE: + case BFD_RELOC_386_TLS_GOTIE: + case BFD_RELOC_386_TLS_LE_32: + case BFD_RELOC_386_TLS_LE: + case BFD_RELOC_386_TLS_GOTDESC: + case BFD_RELOC_386_TLS_DESC_CALL: + case BFD_RELOC_X86_64_TLSGD: + case BFD_RELOC_X86_64_TLSLD: + case BFD_RELOC_X86_64_DTPOFF32: + case BFD_RELOC_X86_64_DTPOFF64: + case BFD_RELOC_X86_64_GOTTPOFF: + case BFD_RELOC_X86_64_TPOFF32: + case BFD_RELOC_X86_64_TPOFF64: + case BFD_RELOC_X86_64_GOTOFF64: + case BFD_RELOC_X86_64_GOTPC32: + case BFD_RELOC_X86_64_GOT64: + case BFD_RELOC_X86_64_GOTPCREL64: + case BFD_RELOC_X86_64_GOTPC64: + case BFD_RELOC_X86_64_GOTPLT64: + case BFD_RELOC_X86_64_PLTOFF64: + case BFD_RELOC_X86_64_GOTPC32_TLSDESC: + case BFD_RELOC_X86_64_TLSDESC_CALL: + case BFD_RELOC_RVA: + case BFD_RELOC_VTABLE_ENTRY: + case BFD_RELOC_VTABLE_INHERIT: +#ifdef TE_PE + case BFD_RELOC_32_SECREL: +#endif + code = fixp->fx_r_type; + break; + case BFD_RELOC_X86_64_32S: + if (!fixp->fx_pcrel) + { + /* Don't turn BFD_RELOC_X86_64_32S into BFD_RELOC_32. */ + code = fixp->fx_r_type; + break; + } + default: + if (fixp->fx_pcrel) + { + switch (fixp->fx_size) + { + default: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("can not do %d byte pc-relative relocation"), + fixp->fx_size); + code = BFD_RELOC_32_PCREL; + break; + case 1: code = BFD_RELOC_8_PCREL; break; + case 2: code = BFD_RELOC_16_PCREL; break; + case 4: + code = (fixp->fx_r_type == BFD_RELOC_X86_64_PC32_BND + ? fixp-> fx_r_type : BFD_RELOC_32_PCREL); + break; +#ifdef BFD64 + case 8: code = BFD_RELOC_64_PCREL; break; +#endif + } + } + else + { + switch (fixp->fx_size) + { + default: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("can not do %d byte relocation"), + fixp->fx_size); + code = BFD_RELOC_32; + break; + case 1: code = BFD_RELOC_8; break; + case 2: code = BFD_RELOC_16; break; + case 4: code = BFD_RELOC_32; break; +#ifdef BFD64 + case 8: code = BFD_RELOC_64; break; +#endif + } + } + break; + } + + if ((code == BFD_RELOC_32 + || code == BFD_RELOC_32_PCREL + || code == BFD_RELOC_X86_64_32S) + && GOT_symbol + && fixp->fx_addsy == GOT_symbol) + { + if (!object_64bit) + code = BFD_RELOC_386_GOTPC; + else + code = BFD_RELOC_X86_64_GOTPC32; + } + if ((code == BFD_RELOC_64 || code == BFD_RELOC_64_PCREL) + && GOT_symbol + && fixp->fx_addsy == GOT_symbol) + { + code = BFD_RELOC_X86_64_GOTPC64; + } + + rel = (arelent *) xmalloc (sizeof (arelent)); + rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + + rel->address = fixp->fx_frag->fr_address + fixp->fx_where; + + if (!use_rela_relocations) + { + /* HACK: Since i386 ELF uses Rel instead of Rela, encode the + vtable entry to be used in the relocation's section offset. */ + if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + rel->address = fixp->fx_offset; +#if defined (OBJ_COFF) && defined (TE_PE) + else if (fixp->fx_addsy && S_IS_WEAK (fixp->fx_addsy)) + rel->addend = fixp->fx_addnumber - (S_GET_VALUE (fixp->fx_addsy) * 2); + else +#endif + rel->addend = 0; + } + /* Use the rela in 64bit mode. */ + else + { + if (disallow_64bit_reloc) + switch (code) + { + case BFD_RELOC_X86_64_DTPOFF64: + case BFD_RELOC_X86_64_TPOFF64: + case BFD_RELOC_64_PCREL: + case BFD_RELOC_X86_64_GOTOFF64: + case BFD_RELOC_X86_64_GOT64: + case BFD_RELOC_X86_64_GOTPCREL64: + case BFD_RELOC_X86_64_GOTPC64: + case BFD_RELOC_X86_64_GOTPLT64: + case BFD_RELOC_X86_64_PLTOFF64: + as_bad_where (fixp->fx_file, fixp->fx_line, + _("cannot represent relocation type %s in x32 mode"), + bfd_get_reloc_code_name (code)); + break; + default: + break; + } + + if (!fixp->fx_pcrel) + rel->addend = fixp->fx_offset; + else + switch (code) + { + case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: + case BFD_RELOC_X86_64_GOT32: + case BFD_RELOC_X86_64_GOTPCREL: + case BFD_RELOC_X86_64_TLSGD: + case BFD_RELOC_X86_64_TLSLD: + case BFD_RELOC_X86_64_GOTTPOFF: + case BFD_RELOC_X86_64_GOTPC32_TLSDESC: + case BFD_RELOC_X86_64_TLSDESC_CALL: + rel->addend = fixp->fx_offset - fixp->fx_size; + break; + default: + rel->addend = (section->vma + - fixp->fx_size + + fixp->fx_addnumber + + md_pcrel_from (fixp)); + break; + } + } + + rel->howto = bfd_reloc_type_lookup (stdoutput, code); + if (rel->howto == NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("cannot represent relocation type %s"), + bfd_get_reloc_code_name (code)); + /* Set howto to a garbage value so that we can keep going. */ + rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32); + gas_assert (rel->howto != NULL); + } + + return rel; +} + +#include "tc-i386-intel.c" + +void +tc_x86_parse_to_dw2regnum (expressionS *exp) +{ + int saved_naked_reg; + char saved_register_dot; + + saved_naked_reg = allow_naked_reg; + allow_naked_reg = 1; + saved_register_dot = register_chars['.']; + register_chars['.'] = '.'; + allow_pseudo_reg = 1; + expression_and_evaluate (exp); + allow_pseudo_reg = 0; + register_chars['.'] = saved_register_dot; + allow_naked_reg = saved_naked_reg; + + if (exp->X_op == O_register && exp->X_add_number >= 0) + { + if ((addressT) exp->X_add_number < i386_regtab_size) + { + exp->X_op = O_constant; + exp->X_add_number = i386_regtab[exp->X_add_number] + .dw2_regnum[flag_code >> 1]; + } + else + exp->X_op = O_illegal; + } +} + +void +tc_x86_frame_initial_instructions (void) +{ + static unsigned int sp_regno[2]; + + if (!sp_regno[flag_code >> 1]) + { + char *saved_input = input_line_pointer; + char sp[][4] = {"esp", "rsp"}; + expressionS exp; + + input_line_pointer = sp[flag_code >> 1]; + tc_x86_parse_to_dw2regnum (&exp); + gas_assert (exp.X_op == O_constant); + sp_regno[flag_code >> 1] = exp.X_add_number; + input_line_pointer = saved_input; + } + + cfi_add_CFA_def_cfa (sp_regno[flag_code >> 1], -x86_cie_data_alignment); + cfi_add_CFA_offset (x86_dwarf2_return_column, x86_cie_data_alignment); +} + +int +x86_dwarf2_addr_size (void) +{ +#if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF) + if (x86_elf_abi == X86_64_X32_ABI) + return 4; +#endif + return bfd_arch_bits_per_address (stdoutput) / 8; +} + +int +i386_elf_section_type (const char *str, size_t len) +{ + if (flag_code == CODE_64BIT + && len == sizeof ("unwind") - 1 + && strncmp (str, "unwind", 6) == 0) + return SHT_X86_64_UNWIND; + + return -1; +} + +#ifdef TE_SOLARIS +void +i386_solaris_fix_up_eh_frame (segT sec) +{ + if (flag_code == CODE_64BIT) + elf_section_type (sec) = SHT_X86_64_UNWIND; +} +#endif + +#ifdef TE_PE +void +tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size) +{ + expressionS exp; + + exp.X_op = O_secrel; + exp.X_add_symbol = symbol; + exp.X_add_number = 0; + emit_expr (&exp, size); +} +#endif + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) +/* For ELF on x86-64, add support for SHF_X86_64_LARGE. */ + +bfd_vma +x86_64_section_letter (int letter, char **ptr_msg) +{ + if (flag_code == CODE_64BIT) + { + if (letter == 'l') + return SHF_X86_64_LARGE; + + *ptr_msg = _("bad .section directive: want a,l,w,x,M,S,G,T in string"); + } + else + *ptr_msg = _("bad .section directive: want a,w,x,M,S,G,T in string"); + return -1; +} + +bfd_vma +x86_64_section_word (char *str, size_t len) +{ + if (len == 5 && flag_code == CODE_64BIT && CONST_STRNEQ (str, "large")) + return SHF_X86_64_LARGE; + + return -1; +} + +static void +handle_large_common (int small ATTRIBUTE_UNUSED) +{ + if (flag_code != CODE_64BIT) + { + s_comm_internal (0, elf_common_parse); + as_warn (_(".largecomm supported only in 64bit mode, producing .comm")); + } + else + { + static segT lbss_section; + asection *saved_com_section_ptr = elf_com_section_ptr; + asection *saved_bss_section = bss_section; + + if (lbss_section == NULL) + { + flagword applicable; + segT seg = now_seg; + subsegT subseg = now_subseg; + + /* The .lbss section is for local .largecomm symbols. */ + lbss_section = subseg_new (".lbss", 0); + applicable = bfd_applicable_section_flags (stdoutput); + bfd_set_section_flags (stdoutput, lbss_section, + applicable & SEC_ALLOC); + seg_info (lbss_section)->bss = 1; + + subseg_set (seg, subseg); + } + + elf_com_section_ptr = &_bfd_elf_large_com_section; + bss_section = lbss_section; + + s_comm_internal (0, elf_common_parse); + + elf_com_section_ptr = saved_com_section_ptr; + bss_section = saved_bss_section; + } +} +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */ diff --git a/contrib/toolchain/binutils/gas/config/tc-i386.h b/contrib/toolchain/binutils/gas/config/tc-i386.h new file mode 100644 index 0000000000..de132d69d7 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/tc-i386.h @@ -0,0 +1,342 @@ +/* tc-i386.h -- Header file for tc-i386.c + Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef TC_I386 +#define TC_I386 1 + +#include "opcodes/i386-opc.h" + +struct fix; + +#define TARGET_BYTES_BIG_ENDIAN 0 + +#define TARGET_ARCH (i386_arch ()) +#define TARGET_MACH (i386_mach ()) +extern enum bfd_architecture i386_arch (void); +extern unsigned long i386_mach (void); + +#ifdef TE_FreeBSD +#define AOUT_TARGET_FORMAT "a.out-i386-freebsd" +#endif +#ifdef TE_NetBSD +#define AOUT_TARGET_FORMAT "a.out-i386-netbsd" +#endif +#ifdef TE_386BSD +#define AOUT_TARGET_FORMAT "a.out-i386-bsd" +#endif +#ifdef TE_LINUX +#define AOUT_TARGET_FORMAT "a.out-i386-linux" +#endif +#ifdef TE_Mach +#define AOUT_TARGET_FORMAT "a.out-mach3" +#endif +#ifdef TE_DYNIX +#define AOUT_TARGET_FORMAT "a.out-i386-dynix" +#endif +#ifndef AOUT_TARGET_FORMAT +#define AOUT_TARGET_FORMAT "a.out-i386" +#endif + +#ifdef TE_FreeBSD +#define ELF_TARGET_FORMAT "elf32-i386-freebsd" +#define ELF_TARGET_FORMAT64 "elf64-x86-64-freebsd" +#elif defined (TE_VXWORKS) +#define ELF_TARGET_FORMAT "elf32-i386-vxworks" +#elif defined (TE_NACL) +#define ELF_TARGET_FORMAT "elf32-i386-nacl" +#define ELF_TARGET_FORMAT32 "elf32-x86-64-nacl" +#define ELF_TARGET_FORMAT64 "elf64-x86-64-nacl" +#endif + +#ifdef TE_SOLARIS +#define ELF_TARGET_FORMAT "elf32-i386-sol2" +#define ELF_TARGET_FORMAT64 "elf64-x86-64-sol2" +#endif + +#ifndef ELF_TARGET_FORMAT +#define ELF_TARGET_FORMAT "elf32-i386" +#endif + +#ifndef ELF_TARGET_FORMAT64 +#define ELF_TARGET_FORMAT64 "elf64-x86-64" +#endif + +#ifndef ELF_TARGET_FORMAT32 +#define ELF_TARGET_FORMAT32 "elf32-x86-64" +#endif + +#ifndef ELF_TARGET_L1OM_FORMAT +#define ELF_TARGET_L1OM_FORMAT "elf64-l1om" +#endif + +#ifndef ELF_TARGET_K1OM_FORMAT +#define ELF_TARGET_K1OM_FORMAT "elf64-k1om" +#endif + +#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \ + || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \ + || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O)) +extern const char *i386_target_format (void); +#define TARGET_FORMAT i386_target_format () +#else +#ifdef TE_GO32 +#define TARGET_FORMAT "coff-go32" +#endif +#ifdef OBJ_AOUT +#define TARGET_FORMAT AOUT_TARGET_FORMAT +#endif +#endif + +#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)) +#define md_end i386_elf_emit_arch_note +extern void i386_elf_emit_arch_note (void); +#endif + +#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0 + +/* '$' may be used as immediate prefix. */ +#undef LOCAL_LABELS_DOLLAR +#define LOCAL_LABELS_DOLLAR 0 +#undef LOCAL_LABELS_FB +#define LOCAL_LABELS_FB 1 + +extern const char extra_symbol_chars[]; +#define tc_symbol_chars extra_symbol_chars + +extern const char *i386_comment_chars; +#define tc_comment_chars i386_comment_chars + +/* The name of the global offset table generated by the compiler. Allow + this to be overridden if need be. */ +#ifndef GLOBAL_OFFSET_TABLE_NAME +#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" +#endif + +#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT) +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES) +#endif +extern void x86_cons (expressionS *, int); + +#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP) +extern void x86_cons_fix_new + (fragS *, unsigned int, unsigned int, expressionS *); + +#define TC_ADDRESS_BYTES x86_address_bytes +extern int x86_address_bytes (void); + +#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */ + +#define NO_RELOC BFD_RELOC_NONE + +void i386_validate_fix (struct fix *); +#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX) + +#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X) +extern int tc_i386_fix_adjustable (struct fix *); + +/* Values passed to md_apply_fix don't include the symbol value. */ +#define MD_APPLY_SYM_VALUE(FIX) 0 + +/* ELF wants external syms kept, as does PE COFF. */ +#if defined (TE_PE) && defined (STRICT_PE_FORMAT) +#define EXTERN_FORCE_RELOC \ + (OUTPUT_FLAVOR == bfd_target_elf_flavour \ + || OUTPUT_FLAVOR == bfd_target_coff_flavour) +#else +#define EXTERN_FORCE_RELOC \ + (OUTPUT_FLAVOR == bfd_target_elf_flavour) +#endif + +/* This expression evaluates to true if the relocation is for a local + object for which we still want to do the relocation at runtime. + False if we are willing to perform this relocation while building + the .o file. GOTOFF and GOT32 do not need to be checked here because + they are not pcrel. .*/ + +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || (FIX)->fx_r_type == BFD_RELOC_386_PLT32 \ + || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC \ + || (FIX)->fx_r_type == BFD_RELOC_X86_64_GOTPCREL \ + || TC_FORCE_RELOCATION (FIX)) + +extern int i386_parse_name (char *, expressionS *, char *); +#define md_parse_name(s, e, m, c) i386_parse_name (s, e, c) + +extern operatorT i386_operator (const char *name, unsigned int operands, char *); +#define md_operator i386_operator + +extern int i386_need_index_operator (void); +#define md_need_index_operator i386_need_index_operator + +#define md_register_arithmetic 0 + +extern const struct relax_type md_relax_table[]; +#define TC_GENERIC_RELAX_TABLE md_relax_table + +extern int optimize_align_code; + +#define md_do_align(n, fill, len, max, around) \ +if ((n) \ + && !need_pass_2 \ + && optimize_align_code \ + && (!(fill) \ + || ((char)*(fill) == (char)0x90 && (len) == 1)) \ + && subseg_text_p (now_seg)) \ + { \ + frag_align_code ((n), (max)); \ + goto around; \ + } + +#define MAX_MEM_FOR_RS_ALIGN_CODE 31 + +extern void i386_align_code (fragS *, int); + +#define HANDLE_ALIGN(fragP) \ +if (fragP->fr_type == rs_align_code) \ + i386_align_code (fragP, (fragP->fr_next->fr_address \ + - fragP->fr_address \ + - fragP->fr_fix)); + +void i386_print_statistics (FILE *); +#define tc_print_statistics i386_print_statistics + +extern unsigned int i386_frag_max_var (fragS *); +#define md_frag_max_var i386_frag_max_var + +#define md_number_to_chars number_to_chars_littleendian + +enum processor_type +{ + PROCESSOR_UNKNOWN, + PROCESSOR_I386, + PROCESSOR_I486, + PROCESSOR_PENTIUM, + PROCESSOR_PENTIUMPRO, + PROCESSOR_PENTIUM4, + PROCESSOR_NOCONA, + PROCESSOR_CORE, + PROCESSOR_CORE2, + PROCESSOR_COREI7, + PROCESSOR_L1OM, + PROCESSOR_K1OM, + PROCESSOR_K6, + PROCESSOR_ATHLON, + PROCESSOR_K8, + PROCESSOR_GENERIC32, + PROCESSOR_GENERIC64, + PROCESSOR_AMDFAM10, + PROCESSOR_BD, + PROCESSOR_BT +}; + +extern enum processor_type cpu_arch_tune; +extern enum processor_type cpu_arch_isa; +extern i386_cpu_flags cpu_arch_isa_flags; + +struct i386_tc_frag_data +{ + enum processor_type isa; + i386_cpu_flags isa_flags; + enum processor_type tune; +}; + +/* We need to emit the right NOP pattern in .align frags. This is + done after the text-to-bits assembly pass, so we need to mark it with + the isa/tune settings at the time the .align was assembled. */ +#define TC_FRAG_TYPE struct i386_tc_frag_data + +#define TC_FRAG_INIT(FRAGP) \ + do \ + { \ + (FRAGP)->tc_frag_data.isa = cpu_arch_isa; \ + (FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags; \ + (FRAGP)->tc_frag_data.tune = cpu_arch_tune; \ + } \ + while (0) + +#ifdef SCO_ELF +#define tc_init_after_args() sco_id () +extern void sco_id (void); +#endif + +#define WORKING_DOT_WORD 1 + +/* We want .cfi_* pseudo-ops for generating unwind info. */ +#define TARGET_USE_CFIPOP 1 + +extern unsigned int x86_dwarf2_return_column; +#define DWARF2_DEFAULT_RETURN_COLUMN x86_dwarf2_return_column + +extern int x86_cie_data_alignment; +#define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment + +extern int x86_dwarf2_addr_size (void); +#define DWARF2_ADDR_SIZE(bfd) x86_dwarf2_addr_size () + +#define tc_parse_to_dw2regnum tc_x86_parse_to_dw2regnum +extern void tc_x86_parse_to_dw2regnum (expressionS *); + +#define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions +extern void tc_x86_frame_initial_instructions (void); + +#define md_elf_section_type(str,len) i386_elf_section_type (str, len) +extern int i386_elf_section_type (const char *, size_t); + +#ifdef TE_SOLARIS +#define md_fix_up_eh_frame(sec) i386_solaris_fix_up_eh_frame (sec) +extern void i386_solaris_fix_up_eh_frame (segT); +#endif + +/* Support for SHF_X86_64_LARGE */ +extern bfd_vma x86_64_section_word (char *, size_t); +extern bfd_vma x86_64_section_letter (int, char **); +#define md_elf_section_letter(LETTER, PTR_MSG) x86_64_section_letter (LETTER, PTR_MSG) +#define md_elf_section_word(STR, LEN) x86_64_section_word (STR, LEN) + +#ifdef TE_PE + +#define O_secrel O_md1 + +#define TC_DWARF2_EMIT_OFFSET tc_pe_dwarf2_emit_offset +void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int); + +#endif /* TE_PE */ + +/* X_add_symbol:X_op_symbol (Intel mode only) */ +#define O_full_ptr O_md2 + +#ifdef OBJ_MACH_O + +#define TC_FORCE_RELOCATION(FIX) (obj_mach_o_force_reloc (FIX)) + +#define TC_FORCE_RELOCATION_SUB_SAME(FIX,SEG) \ + (obj_mach_o_force_reloc_sub_same (FIX, SEG)) + +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX,SEG) \ + (obj_mach_o_force_reloc_sub_local (FIX, SEG)) + +#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1 + +#endif /* OBJ_MACH_O */ + +#endif /* TC_I386 */ diff --git a/contrib/toolchain/binutils/gas/config/te-pe.h b/contrib/toolchain/binutils/gas/config/te-pe.h new file mode 100644 index 0000000000..1ac632cb78 --- /dev/null +++ b/contrib/toolchain/binutils/gas/config/te-pe.h @@ -0,0 +1,26 @@ +/* Copyright 2007 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 3, + 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#define TE_PE +#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME) /* Can have @'s inside labels. */ + +/* The PE format supports long section names. */ +#define COFF_LONG_SECTION_NAMES + +#include "obj-format.h" diff --git a/contrib/toolchain/binutils/gas/depend.c b/contrib/toolchain/binutils/gas/depend.c new file mode 100644 index 0000000000..7a3c54c4e1 --- /dev/null +++ b/contrib/toolchain/binutils/gas/depend.c @@ -0,0 +1,208 @@ +/* depend.c - Handle dependency tracking. + Copyright 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "filenames.h" + +/* The file to write to, or NULL if no dependencies being kept. */ +static char * dep_file = NULL; + +struct dependency + { + char * file; + struct dependency * next; + }; + +/* All the files we depend on. */ +static struct dependency * dep_chain = NULL; + +/* Current column in output file. */ +static int column = 0; + +static int quote_string_for_make (FILE *, char *); +static void wrap_output (FILE *, char *, int); + +/* Number of columns allowable. */ +#define MAX_COLUMNS 72 + +/* Start saving dependencies, to be written to FILENAME. If this is + never called, then dependency tracking is simply skipped. */ + +void +start_dependencies (char *filename) +{ + dep_file = filename; +} + +/* Noticed a new filename, so try to register it. */ + +void +register_dependency (char *filename) +{ + struct dependency *dep; + + if (dep_file == NULL) + return; + + for (dep = dep_chain; dep != NULL; dep = dep->next) + { + if (!filename_cmp (filename, dep->file)) + return; + } + + dep = (struct dependency *) xmalloc (sizeof (struct dependency)); + dep->file = xstrdup (filename); + dep->next = dep_chain; + dep_chain = dep; +} + +/* Quote a file name the way `make' wants it, and print it to FILE. + If FILE is NULL, do no printing, but return the length of the + quoted string. + + This code is taken from gcc with only minor changes. */ + +static int +quote_string_for_make (FILE *file, char *src) +{ + char *p = src; + int i = 0; + + for (;;) + { + char c = *p++; + + switch (c) + { + case '\0': + case ' ': + case '\t': + { + /* GNU make uses a weird quoting scheme for white space. + A space or tab preceded by 2N+1 backslashes represents + N backslashes followed by space; a space or tab + preceded by 2N backslashes represents N backslashes at + the end of a file name; and backslashes in other + contexts should not be doubled. */ + char *q; + + for (q = p - 1; src < q && q[-1] == '\\'; q--) + { + if (file) + putc ('\\', file); + i++; + } + } + if (!c) + return i; + if (file) + putc ('\\', file); + i++; + goto ordinary_char; + + case '$': + if (file) + putc (c, file); + i++; + /* Fall through. This can mishandle things like "$(" but + there's no easy fix. */ + default: + ordinary_char: + /* This can mishandle characters in the string "\0\n%*?[\\~"; + exactly which chars are mishandled depends on the `make' version. + We know of no portable solution for this; + even GNU make 3.76.1 doesn't solve the problem entirely. + (Also, '\0' is mishandled due to our calling conventions.) */ + if (file) + putc (c, file); + i++; + break; + } + } +} + +/* Append some output to the file, keeping track of columns and doing + wrapping as necessary. */ + +static void +wrap_output (FILE *f, char *string, int spacer) +{ + int len = quote_string_for_make (NULL, string); + + if (len == 0) + return; + + if (column + && (MAX_COLUMNS + - 1 /* spacer */ + - 2 /* ` \' */ + < column + len)) + { + fprintf (f, " \\\n "); + column = 0; + if (spacer == ' ') + spacer = '\0'; + } + + if (spacer == ' ') + { + putc (spacer, f); + ++column; + } + + quote_string_for_make (f, string); + column += len; + + if (spacer == ':') + { + putc (spacer, f); + ++column; + } +} + +/* Print dependency file. */ + +void +print_dependencies (void) +{ + FILE *f; + struct dependency *dep; + + if (dep_file == NULL) + return; + + f = fopen (dep_file, FOPEN_WT); + if (f == NULL) + { + as_warn (_("can't open `%s' for writing"), dep_file); + return; + } + + column = 0; + wrap_output (f, out_file_name, ':'); + for (dep = dep_chain; dep != NULL; dep = dep->next) + wrap_output (f, dep->file, ' '); + + putc ('\n', f); + + if (fclose (f)) + as_warn (_("can't close `%s'"), dep_file); +} diff --git a/contrib/toolchain/binutils/gas/dw2gencfi.c b/contrib/toolchain/binutils/gas/dw2gencfi.c new file mode 100644 index 0000000000..faa8384d88 --- /dev/null +++ b/contrib/toolchain/binutils/gas/dw2gencfi.c @@ -0,0 +1,2044 @@ +/* dw2gencfi.c - Support for generating Dwarf2 CFI information. + Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + Contributed by Michal Ludvig + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "dw2gencfi.h" +#include "subsegs.h" +#include "dwarf2dbg.h" + +#ifdef TARGET_USE_CFIPOP + +/* By default, use difference expressions if DIFF_EXPR_OK is defined. */ +#ifndef CFI_DIFF_EXPR_OK +# ifdef DIFF_EXPR_OK +# define CFI_DIFF_EXPR_OK 1 +# else +# define CFI_DIFF_EXPR_OK 0 +# endif +#endif + +#ifndef CFI_DIFF_LSDA_OK +#define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK +#endif + +#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0 +# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK" +#endif + +/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field + of the CIE. Default to 1 if not otherwise specified. */ +#ifndef DWARF2_LINE_MIN_INSN_LENGTH +#define DWARF2_LINE_MIN_INSN_LENGTH 1 +#endif + +/* By default, use 32-bit relocations from .eh_frame into .text. */ +#ifndef DWARF2_FDE_RELOC_SIZE +#define DWARF2_FDE_RELOC_SIZE 4 +#endif + +/* By default, use a read-only .eh_frame section. */ +#ifndef DWARF2_EH_FRAME_READ_ONLY +#define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY +#endif + +#ifndef EH_FRAME_ALIGNMENT +#define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2) +#endif + +#ifndef tc_cfi_frame_initial_instructions +#define tc_cfi_frame_initial_instructions() ((void)0) +#endif + +#ifndef tc_cfi_startproc +# define tc_cfi_startproc() ((void)0) +#endif + +#ifndef tc_cfi_endproc +# define tc_cfi_endproc(fde) ((void) (fde)) +#endif + +#ifndef DWARF2_FORMAT +#define DWARF2_FORMAT(SEC) dwarf2_format_32bit +#endif + +#ifndef DWARF2_ADDR_SIZE +#define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8) +#endif + +#if SUPPORT_FRAME_LINKONCE +#define CUR_SEG(structp) structp->cur_seg +#define SET_CUR_SEG(structp, seg) structp->cur_seg = seg +#define HANDLED(structp) structp->handled +#define SET_HANDLED(structp, val) structp->handled = val +#else +#define CUR_SEG(structp) NULL +#define SET_CUR_SEG(structp, seg) (void) (0 && seg) +#define HANDLED(structp) 0 +#define SET_HANDLED(structp, val) (void) (0 && val) +#endif + +/* Private segment collection list. */ +struct dwcfi_seg_list +{ + segT seg; + int subseg; + char * seg_name; +}; + +#define FRAME_NAME ".eh_frame" + +static struct hash_control *dwcfi_hash; + +/* Build based on segment the derived .debug_... + segment name containing origin segment's postfix name part. */ + +static char * +get_debugseg_name (segT seg, const char *base_name) +{ + const char *name; + + if (!seg) + name = ""; + else + { + const char * dollar; + const char * dot; + + name = bfd_get_section_name (stdoutput, seg); + + dollar = strchr (name, '$'); + dot = strchr (name + 1, '.'); + + if (!dollar && !dot) + name = ""; + else if (!dollar) + name = dot; + else if (!dot) + name = dollar; + else if (dot < dollar) + name = dot; + else + name = dollar; + } + + return concat (base_name, name, NULL); +} + +/* Allocate a dwcfi_seg_list structure. */ + +static struct dwcfi_seg_list * +alloc_debugseg_item (segT seg, int subseg, char *name) +{ + struct dwcfi_seg_list *r; + + r = (struct dwcfi_seg_list *) + xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name)); + r->seg = seg; + r->subseg = subseg; + r->seg_name = name; + return r; +} + +static segT +is_now_linkonce_segment (void) +{ + if ((bfd_get_section_flags (stdoutput, now_seg) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE + | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0) + return now_seg; + return NULL; +} + +/* Generate debug... segment with same linkonce properties + of based segment. */ + +static segT +make_debug_seg (segT cseg, char *name, int sflags) +{ + segT save_seg = now_seg; + int save_subseg = now_subseg; + segT r; + flagword flags; + + r = subseg_new (name, 0); + + /* Check if code segment is marked as linked once. */ + if (!cseg) + flags = 0; + else + flags = bfd_get_section_flags (stdoutput, cseg) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE + | SEC_LINK_DUPLICATES_SAME_CONTENTS); + + /* Add standard section flags. */ + flags |= sflags; + + /* Apply possibly linked once flags to new generated segment, too. */ + if (!bfd_set_section_flags (stdoutput, r, flags)) + as_bad (_("bfd_set_section_flags: %s"), + bfd_errmsg (bfd_get_error ())); + + /* Restore to previous segment. */ + if (save_seg != NULL) + subseg_set (save_seg, save_subseg); + return r; +} + +static void +dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item) +{ + const char *error_string; + + if ((error_string = hash_jam (dwcfi_hash, name, (char *) item))) + as_fatal (_("Inserting \"%s\" into structure table failed: %s"), + name, error_string); +} + +static struct dwcfi_seg_list * +dwcfi_hash_find (char *name) +{ + return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name); +} + +static struct dwcfi_seg_list * +dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags) +{ + struct dwcfi_seg_list *item; + char *name; + + /* Initialize dwcfi_hash once. */ + if (!dwcfi_hash) + dwcfi_hash = hash_new (); + + name = get_debugseg_name (cseg, base_name); + + item = dwcfi_hash_find (name); + if (!item) + { + item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name); + + dwcfi_hash_insert (item->seg_name, item); + } + else + free (name); + + return item; +} + +/* ??? Share this with dwarf2cfg.c. */ +#ifndef TC_DWARF2_EMIT_OFFSET +#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset + +/* Create an offset to .dwarf2_*. */ + +static void +generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size) +{ + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = symbol; + exp.X_add_number = 0; + emit_expr (&exp, size); +} +#endif + +struct cfi_escape_data +{ + struct cfi_escape_data *next; + expressionS exp; +}; + +struct cie_entry +{ + struct cie_entry *next; +#if SUPPORT_FRAME_LINKONCE + segT cur_seg; +#endif + symbolS *start_address; + unsigned int return_column; + unsigned int signal_frame; + unsigned char per_encoding; + unsigned char lsda_encoding; + expressionS personality; + struct cfi_insn_data *first, *last; +}; + +/* List of FDE entries. */ + +struct fde_entry *all_fde_data; +static struct fde_entry **last_fde_data = &all_fde_data; + +/* List of CIEs so that they could be reused. */ +static struct cie_entry *cie_root; + +/* Stack of old CFI data, for save/restore. */ +struct cfa_save_data +{ + struct cfa_save_data *next; + offsetT cfa_offset; +}; + +/* Current open FDE entry. */ +struct frch_cfi_data +{ + struct fde_entry *cur_fde_data; + symbolS *last_address; + offsetT cur_cfa_offset; + struct cfa_save_data *cfa_save_stack; +}; + +/* Construct a new FDE structure and add it to the end of the fde list. */ + +static struct fde_entry * +alloc_fde_entry (void) +{ + struct fde_entry *fde = (struct fde_entry *) + xcalloc (1, sizeof (struct fde_entry)); + + frchain_now->frch_cfi_data = (struct frch_cfi_data *) + xcalloc (1, sizeof (struct frch_cfi_data)); + frchain_now->frch_cfi_data->cur_fde_data = fde; + *last_fde_data = fde; + last_fde_data = &fde->next; + SET_CUR_SEG (fde, is_now_linkonce_segment ()); + SET_HANDLED (fde, 0); + fde->last = &fde->data; + fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN; + fde->per_encoding = DW_EH_PE_omit; + fde->lsda_encoding = DW_EH_PE_omit; + + return fde; +} + +/* The following functions are available for a backend to construct its + own unwind information, usually from legacy unwind directives. */ + +/* Construct a new INSN structure and add it to the end of the insn list + for the currently active FDE. */ + +static struct cfi_insn_data * +alloc_cfi_insn_data (void) +{ + struct cfi_insn_data *insn = (struct cfi_insn_data *) + xcalloc (1, sizeof (struct cfi_insn_data)); + struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data; + + *cur_fde_data->last = insn; + cur_fde_data->last = &insn->next; + SET_CUR_SEG (insn, is_now_linkonce_segment ()); + return insn; +} + +/* Construct a new FDE structure that begins at LABEL. */ + +void +cfi_new_fde (symbolS *label) +{ + struct fde_entry *fde = alloc_fde_entry (); + fde->start_address = label; + frchain_now->frch_cfi_data->last_address = label; +} + +/* End the currently open FDE. */ + +void +cfi_end_fde (symbolS *label) +{ + frchain_now->frch_cfi_data->cur_fde_data->end_address = label; + free (frchain_now->frch_cfi_data); + frchain_now->frch_cfi_data = NULL; +} + +/* Set the return column for the current FDE. */ + +void +cfi_set_return_column (unsigned regno) +{ + frchain_now->frch_cfi_data->cur_fde_data->return_column = regno; +} + +/* Universal functions to store new instructions. */ + +static void +cfi_add_CFA_insn (int insn) +{ + struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); + + insn_ptr->insn = insn; +} + +static void +cfi_add_CFA_insn_reg (int insn, unsigned regno) +{ + struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); + + insn_ptr->insn = insn; + insn_ptr->u.r = regno; +} + +static void +cfi_add_CFA_insn_offset (int insn, offsetT offset) +{ + struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); + + insn_ptr->insn = insn; + insn_ptr->u.i = offset; +} + +static void +cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2) +{ + struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); + + insn_ptr->insn = insn; + insn_ptr->u.rr.reg1 = reg1; + insn_ptr->u.rr.reg2 = reg2; +} + +static void +cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset) +{ + struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); + + insn_ptr->insn = insn; + insn_ptr->u.ri.reg = regno; + insn_ptr->u.ri.offset = offset; +} + +/* Add a CFI insn to advance the PC from the last address to LABEL. */ + +void +cfi_add_advance_loc (symbolS *label) +{ + struct cfi_insn_data *insn = alloc_cfi_insn_data (); + + insn->insn = DW_CFA_advance_loc; + insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address; + insn->u.ll.lab2 = label; + + frchain_now->frch_cfi_data->last_address = label; +} + +/* Add a DW_CFA_offset record to the CFI data. */ + +void +cfi_add_CFA_offset (unsigned regno, offsetT offset) +{ + unsigned int abs_data_align; + + gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0); + cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset); + + abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0 + ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT); + if (offset % abs_data_align) + as_bad (_("register save offset not a multiple of %u"), abs_data_align); +} + +/* Add a DW_CFA_def_cfa record to the CFI data. */ + +void +cfi_add_CFA_def_cfa (unsigned regno, offsetT offset) +{ + cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset); + frchain_now->frch_cfi_data->cur_cfa_offset = offset; +} + +/* Add a DW_CFA_register record to the CFI data. */ + +void +cfi_add_CFA_register (unsigned reg1, unsigned reg2) +{ + cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2); +} + +/* Add a DW_CFA_def_cfa_register record to the CFI data. */ + +void +cfi_add_CFA_def_cfa_register (unsigned regno) +{ + cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno); +} + +/* Add a DW_CFA_def_cfa_offset record to the CFI data. */ + +void +cfi_add_CFA_def_cfa_offset (offsetT offset) +{ + cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset); + frchain_now->frch_cfi_data->cur_cfa_offset = offset; +} + +void +cfi_add_CFA_restore (unsigned regno) +{ + cfi_add_CFA_insn_reg (DW_CFA_restore, regno); +} + +void +cfi_add_CFA_undefined (unsigned regno) +{ + cfi_add_CFA_insn_reg (DW_CFA_undefined, regno); +} + +void +cfi_add_CFA_same_value (unsigned regno) +{ + cfi_add_CFA_insn_reg (DW_CFA_same_value, regno); +} + +void +cfi_add_CFA_remember_state (void) +{ + struct cfa_save_data *p; + + cfi_add_CFA_insn (DW_CFA_remember_state); + + p = (struct cfa_save_data *) xmalloc (sizeof (*p)); + p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset; + p->next = frchain_now->frch_cfi_data->cfa_save_stack; + frchain_now->frch_cfi_data->cfa_save_stack = p; +} + +void +cfi_add_CFA_restore_state (void) +{ + struct cfa_save_data *p; + + cfi_add_CFA_insn (DW_CFA_restore_state); + + p = frchain_now->frch_cfi_data->cfa_save_stack; + if (p) + { + frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset; + frchain_now->frch_cfi_data->cfa_save_stack = p->next; + free (p); + } + else + as_bad (_("CFI state restore without previous remember")); +} + + +/* Parse CFI assembler directives. */ + +static void dot_cfi (int); +static void dot_cfi_escape (int); +static void dot_cfi_sections (int); +static void dot_cfi_startproc (int); +static void dot_cfi_endproc (int); +static void dot_cfi_personality (int); +static void dot_cfi_lsda (int); +static void dot_cfi_val_encoded_addr (int); + +const pseudo_typeS cfi_pseudo_table[] = + { + { "cfi_sections", dot_cfi_sections, 0 }, + { "cfi_startproc", dot_cfi_startproc, 0 }, + { "cfi_endproc", dot_cfi_endproc, 0 }, + { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa }, + { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register }, + { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset }, + { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset }, + { "cfi_offset", dot_cfi, DW_CFA_offset }, + { "cfi_rel_offset", dot_cfi, CFI_rel_offset }, + { "cfi_register", dot_cfi, DW_CFA_register }, + { "cfi_return_column", dot_cfi, CFI_return_column }, + { "cfi_restore", dot_cfi, DW_CFA_restore }, + { "cfi_undefined", dot_cfi, DW_CFA_undefined }, + { "cfi_same_value", dot_cfi, DW_CFA_same_value }, + { "cfi_remember_state", dot_cfi, DW_CFA_remember_state }, + { "cfi_restore_state", dot_cfi, DW_CFA_restore_state }, + { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save }, + { "cfi_escape", dot_cfi_escape, 0 }, + { "cfi_signal_frame", dot_cfi, CFI_signal_frame }, + { "cfi_personality", dot_cfi_personality, 0 }, + { "cfi_lsda", dot_cfi_lsda, 0 }, + { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 }, + { NULL, NULL, 0 } + }; + +static void +cfi_parse_separator (void) +{ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + input_line_pointer++; + else + as_bad (_("missing separator")); +} + +#ifndef tc_parse_to_dw2regnum +static void +tc_parse_to_dw2regnum (expressionS *exp) +{ +# ifdef tc_regname_to_dw2regnum + SKIP_WHITESPACE (); + if (is_name_beginner (*input_line_pointer) + || (*input_line_pointer == '%' + && is_name_beginner (*++input_line_pointer))) + { + char *name, c; + + name = input_line_pointer; + c = get_symbol_end (); + + exp->X_op = O_constant; + exp->X_add_number = tc_regname_to_dw2regnum (name); + + *input_line_pointer = c; + } + else +# endif + expression_and_evaluate (exp); +} +#endif + +static unsigned +cfi_parse_reg (void) +{ + int regno; + expressionS exp; + + tc_parse_to_dw2regnum (&exp); + switch (exp.X_op) + { + case O_register: + case O_constant: + regno = exp.X_add_number; + break; + + default: + regno = -1; + break; + } + + if (regno < 0) + { + as_bad (_("bad register expression")); + regno = 0; + } + + return regno; +} + +static offsetT +cfi_parse_const (void) +{ + return get_absolute_expression (); +} + +static void +dot_cfi (int arg) +{ + offsetT offset; + unsigned reg1, reg2; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + /* If the last address was not at the current PC, advance to current. */ + if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now + || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) + != frag_now_fix ()) + cfi_add_advance_loc (symbol_temp_new_now ()); + + switch (arg) + { + case DW_CFA_offset: + reg1 = cfi_parse_reg (); + cfi_parse_separator (); + offset = cfi_parse_const (); + cfi_add_CFA_offset (reg1, offset); + break; + + case CFI_rel_offset: + reg1 = cfi_parse_reg (); + cfi_parse_separator (); + offset = cfi_parse_const (); + cfi_add_CFA_offset (reg1, + offset - frchain_now->frch_cfi_data->cur_cfa_offset); + break; + + case DW_CFA_def_cfa: + reg1 = cfi_parse_reg (); + cfi_parse_separator (); + offset = cfi_parse_const (); + cfi_add_CFA_def_cfa (reg1, offset); + break; + + case DW_CFA_register: + reg1 = cfi_parse_reg (); + cfi_parse_separator (); + reg2 = cfi_parse_reg (); + cfi_add_CFA_register (reg1, reg2); + break; + + case DW_CFA_def_cfa_register: + reg1 = cfi_parse_reg (); + cfi_add_CFA_def_cfa_register (reg1); + break; + + case DW_CFA_def_cfa_offset: + offset = cfi_parse_const (); + cfi_add_CFA_def_cfa_offset (offset); + break; + + case CFI_adjust_cfa_offset: + offset = cfi_parse_const (); + cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset + + offset); + break; + + case DW_CFA_restore: + for (;;) + { + reg1 = cfi_parse_reg (); + cfi_add_CFA_restore (reg1); + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + break; + ++input_line_pointer; + } + break; + + case DW_CFA_undefined: + for (;;) + { + reg1 = cfi_parse_reg (); + cfi_add_CFA_undefined (reg1); + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + break; + ++input_line_pointer; + } + break; + + case DW_CFA_same_value: + reg1 = cfi_parse_reg (); + cfi_add_CFA_same_value (reg1); + break; + + case CFI_return_column: + reg1 = cfi_parse_reg (); + cfi_set_return_column (reg1); + break; + + case DW_CFA_remember_state: + cfi_add_CFA_remember_state (); + break; + + case DW_CFA_restore_state: + cfi_add_CFA_restore_state (); + break; + + case DW_CFA_GNU_window_save: + cfi_add_CFA_insn (DW_CFA_GNU_window_save); + break; + + case CFI_signal_frame: + frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1; + break; + + default: + abort (); + } + + demand_empty_rest_of_line (); +} + +static void +dot_cfi_escape (int ignored ATTRIBUTE_UNUSED) +{ + struct cfi_escape_data *head, **tail, *e; + struct cfi_insn_data *insn; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + /* If the last address was not at the current PC, advance to current. */ + if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now + || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) + != frag_now_fix ()) + cfi_add_advance_loc (symbol_temp_new_now ()); + + tail = &head; + do + { + e = (struct cfi_escape_data *) xmalloc (sizeof (*e)); + do_parse_cons_expression (&e->exp, 1); + *tail = e; + tail = &e->next; + } + while (*input_line_pointer++ == ','); + *tail = NULL; + + insn = alloc_cfi_insn_data (); + insn->insn = CFI_escape; + insn->u.esc = head; + + --input_line_pointer; + demand_empty_rest_of_line (); +} + +static void +dot_cfi_personality (int ignored ATTRIBUTE_UNUSED) +{ + struct fde_entry *fde; + offsetT encoding; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + fde = frchain_now->frch_cfi_data->cur_fde_data; + encoding = cfi_parse_const (); + if (encoding == DW_EH_PE_omit) + { + demand_empty_rest_of_line (); + fde->per_encoding = encoding; + return; + } + + if ((encoding & 0xff) != encoding + || ((encoding & 0x70) != 0 +#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr + && (encoding & 0x70) != DW_EH_PE_pcrel +#endif + ) + /* leb128 can be handled, but does something actually need it? */ + || (encoding & 7) == DW_EH_PE_uleb128 + || (encoding & 7) > DW_EH_PE_udata8) + { + as_bad (_("invalid or unsupported encoding in .cfi_personality")); + ignore_rest_of_line (); + return; + } + + if (*input_line_pointer++ != ',') + { + as_bad (_(".cfi_personality requires encoding and symbol arguments")); + ignore_rest_of_line (); + return; + } + + expression_and_evaluate (&fde->personality); + switch (fde->personality.X_op) + { + case O_symbol: + break; + case O_constant: + if ((encoding & 0x70) == DW_EH_PE_pcrel) + encoding = DW_EH_PE_omit; + break; + default: + encoding = DW_EH_PE_omit; + break; + } + + fde->per_encoding = encoding; + + if (encoding == DW_EH_PE_omit) + { + as_bad (_("wrong second argument to .cfi_personality")); + ignore_rest_of_line (); + return; + } + + demand_empty_rest_of_line (); +} + +static void +dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED) +{ + struct fde_entry *fde; + offsetT encoding; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + fde = frchain_now->frch_cfi_data->cur_fde_data; + encoding = cfi_parse_const (); + if (encoding == DW_EH_PE_omit) + { + demand_empty_rest_of_line (); + fde->lsda_encoding = encoding; + return; + } + + if ((encoding & 0xff) != encoding + || ((encoding & 0x70) != 0 +#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr + && (encoding & 0x70) != DW_EH_PE_pcrel +#endif + ) + /* leb128 can be handled, but does something actually need it? */ + || (encoding & 7) == DW_EH_PE_uleb128 + || (encoding & 7) > DW_EH_PE_udata8) + { + as_bad (_("invalid or unsupported encoding in .cfi_lsda")); + ignore_rest_of_line (); + return; + } + + if (*input_line_pointer++ != ',') + { + as_bad (_(".cfi_lsda requires encoding and symbol arguments")); + ignore_rest_of_line (); + return; + } + + fde->lsda_encoding = encoding; + + expression_and_evaluate (&fde->lsda); + switch (fde->lsda.X_op) + { + case O_symbol: + break; + case O_constant: + if ((encoding & 0x70) == DW_EH_PE_pcrel) + encoding = DW_EH_PE_omit; + break; + default: + encoding = DW_EH_PE_omit; + break; + } + + fde->lsda_encoding = encoding; + + if (encoding == DW_EH_PE_omit) + { + as_bad (_("wrong second argument to .cfi_lsda")); + ignore_rest_of_line (); + return; + } + + demand_empty_rest_of_line (); +} + +static void +dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED) +{ + struct cfi_insn_data *insn_ptr; + offsetT encoding; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + /* If the last address was not at the current PC, advance to current. */ + if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now + || S_GET_VALUE (frchain_now->frch_cfi_data->last_address) + != frag_now_fix ()) + cfi_add_advance_loc (symbol_temp_new_now ()); + + insn_ptr = alloc_cfi_insn_data (); + insn_ptr->insn = CFI_val_encoded_addr; + + insn_ptr->u.ea.reg = cfi_parse_reg (); + + cfi_parse_separator (); + encoding = cfi_parse_const (); + if ((encoding & 0xff) != encoding + || ((encoding & 0x70) != 0 +#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr + && (encoding & 0x70) != DW_EH_PE_pcrel +#endif + ) + /* leb128 can be handled, but does something actually need it? */ + || (encoding & 7) == DW_EH_PE_uleb128 + || (encoding & 7) > DW_EH_PE_udata8) + { + as_bad (_("invalid or unsupported encoding in .cfi_lsda")); + encoding = DW_EH_PE_omit; + } + + cfi_parse_separator (); + expression_and_evaluate (&insn_ptr->u.ea.exp); + switch (insn_ptr->u.ea.exp.X_op) + { + case O_symbol: + break; + case O_constant: + if ((encoding & 0x70) != DW_EH_PE_pcrel) + break; + default: + encoding = DW_EH_PE_omit; + break; + } + + insn_ptr->u.ea.encoding = encoding; + if (encoding == DW_EH_PE_omit) + { + as_bad (_("wrong third argument to .cfi_val_encoded_addr")); + ignore_rest_of_line (); + return; + } + + demand_empty_rest_of_line (); +} + +/* By default emit .eh_frame only, not .debug_frame. */ +#define CFI_EMIT_eh_frame (1 << 0) +#define CFI_EMIT_debug_frame (1 << 1) +#define CFI_EMIT_target (1 << 2) +static int cfi_sections = CFI_EMIT_eh_frame; + +static void +dot_cfi_sections (int ignored ATTRIBUTE_UNUSED) +{ + int sections = 0; + + SKIP_WHITESPACE (); + if (is_name_beginner (*input_line_pointer)) + while (1) + { + char *name, c; + + name = input_line_pointer; + c = get_symbol_end (); + + if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0 + && name[9] != '_') + sections |= CFI_EMIT_eh_frame; + else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0) + sections |= CFI_EMIT_debug_frame; +#ifdef tc_cfi_section_name + else if (strcmp (name, tc_cfi_section_name) == 0) + sections |= CFI_EMIT_target; +#endif + else + { + *input_line_pointer = c; + input_line_pointer = name; + break; + } + + *input_line_pointer = c; + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + name = input_line_pointer++; + SKIP_WHITESPACE (); + if (!is_name_beginner (*input_line_pointer)) + { + input_line_pointer = name; + break; + } + } + else if (is_name_beginner (*input_line_pointer)) + break; + } + + demand_empty_rest_of_line (); + cfi_sections = sections; +} + +static void +dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED) +{ + int simple = 0; + + if (frchain_now->frch_cfi_data != NULL) + { + as_bad (_("previous CFI entry not closed (missing .cfi_endproc)")); + ignore_rest_of_line (); + return; + } + + cfi_new_fde (symbol_temp_new_now ()); + + SKIP_WHITESPACE (); + if (is_name_beginner (*input_line_pointer)) + { + char *name, c; + + name = input_line_pointer; + c = get_symbol_end (); + + if (strcmp (name, "simple") == 0) + { + simple = 1; + *input_line_pointer = c; + } + else + input_line_pointer = name; + } + demand_empty_rest_of_line (); + + frchain_now->frch_cfi_data->cur_cfa_offset = 0; + if (!simple) + tc_cfi_frame_initial_instructions (); + + if ((cfi_sections & CFI_EMIT_target) != 0) + tc_cfi_startproc (); +} + +static void +dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED) +{ + struct fde_entry *fde; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_(".cfi_endproc without corresponding .cfi_startproc")); + ignore_rest_of_line (); + return; + } + + fde = frchain_now->frch_cfi_data->cur_fde_data; + + cfi_end_fde (symbol_temp_new_now ()); + + demand_empty_rest_of_line (); + + if ((cfi_sections & CFI_EMIT_target) != 0) + tc_cfi_endproc (fde); +} + + +/* Emit a single byte into the current segment. */ + +static inline void +out_one (int byte) +{ + FRAG_APPEND_1_CHAR (byte); +} + +/* Emit a two-byte word into the current segment. */ + +static inline void +out_two (int data) +{ + md_number_to_chars (frag_more (2), data, 2); +} + +/* Emit a four byte word into the current segment. */ + +static inline void +out_four (int data) +{ + md_number_to_chars (frag_more (4), data, 4); +} + +/* Emit an unsigned "little-endian base 128" number. */ + +static void +out_uleb128 (addressT value) +{ + output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0); +} + +/* Emit an unsigned "little-endian base 128" number. */ + +static void +out_sleb128 (offsetT value) +{ + output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1); +} + +static void +output_cfi_insn (struct cfi_insn_data *insn) +{ + offsetT offset; + unsigned int regno; + + switch (insn->insn) + { + case DW_CFA_advance_loc: + { + symbolS *from = insn->u.ll.lab1; + symbolS *to = insn->u.ll.lab2; + + if (symbol_get_frag (to) == symbol_get_frag (from)) + { + addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from); + addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH; + + if (scaled <= 0x3F) + out_one (DW_CFA_advance_loc + scaled); + else if (scaled <= 0xFF) + { + out_one (DW_CFA_advance_loc1); + out_one (scaled); + } + else if (scaled <= 0xFFFF) + { + out_one (DW_CFA_advance_loc2); + out_two (scaled); + } + else + { + out_one (DW_CFA_advance_loc4); + out_four (scaled); + } + } + else + { + expressionS exp; + + exp.X_op = O_subtract; + exp.X_add_symbol = to; + exp.X_op_symbol = from; + exp.X_add_number = 0; + + /* The code in ehopt.c expects that one byte of the encoding + is already allocated to the frag. This comes from the way + that it scans the .eh_frame section looking first for the + .byte DW_CFA_advance_loc4. */ + *frag_more (1) = DW_CFA_advance_loc4; + + frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3, + make_expr_symbol (&exp), frag_now_fix () - 1, + (char *) frag_now); + } + } + break; + + case DW_CFA_def_cfa: + offset = insn->u.ri.offset; + if (offset < 0) + { + out_one (DW_CFA_def_cfa_sf); + out_uleb128 (insn->u.ri.reg); + out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT); + } + else + { + out_one (DW_CFA_def_cfa); + out_uleb128 (insn->u.ri.reg); + out_uleb128 (offset); + } + break; + + case DW_CFA_def_cfa_register: + case DW_CFA_undefined: + case DW_CFA_same_value: + out_one (insn->insn); + out_uleb128 (insn->u.r); + break; + + case DW_CFA_def_cfa_offset: + offset = insn->u.i; + if (offset < 0) + { + out_one (DW_CFA_def_cfa_offset_sf); + out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT); + } + else + { + out_one (DW_CFA_def_cfa_offset); + out_uleb128 (offset); + } + break; + + case DW_CFA_restore: + regno = insn->u.r; + if (regno <= 0x3F) + { + out_one (DW_CFA_restore + regno); + } + else + { + out_one (DW_CFA_restore_extended); + out_uleb128 (regno); + } + break; + + case DW_CFA_offset: + regno = insn->u.ri.reg; + offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT; + if (offset < 0) + { + out_one (DW_CFA_offset_extended_sf); + out_uleb128 (regno); + out_sleb128 (offset); + } + else if (regno <= 0x3F) + { + out_one (DW_CFA_offset + regno); + out_uleb128 (offset); + } + else + { + out_one (DW_CFA_offset_extended); + out_uleb128 (regno); + out_uleb128 (offset); + } + break; + + case DW_CFA_register: + out_one (DW_CFA_register); + out_uleb128 (insn->u.rr.reg1); + out_uleb128 (insn->u.rr.reg2); + break; + + case DW_CFA_remember_state: + case DW_CFA_restore_state: + out_one (insn->insn); + break; + + case DW_CFA_GNU_window_save: + out_one (DW_CFA_GNU_window_save); + break; + + case CFI_escape: + { + struct cfi_escape_data *e; + for (e = insn->u.esc; e ; e = e->next) + emit_expr (&e->exp, 1); + break; + } + + case CFI_val_encoded_addr: + { + unsigned encoding = insn->u.ea.encoding; + offsetT encoding_size; + + if (encoding == DW_EH_PE_omit) + break; + out_one (DW_CFA_val_expression); + out_uleb128 (insn->u.ea.reg); + + switch (encoding & 0x7) + { + case DW_EH_PE_absptr: + encoding_size = DWARF2_ADDR_SIZE (stdoutput); + break; + case DW_EH_PE_udata2: + encoding_size = 2; + break; + case DW_EH_PE_udata4: + encoding_size = 4; + break; + case DW_EH_PE_udata8: + encoding_size = 8; + break; + default: + abort (); + } + + /* If the user has requested absolute encoding, + then use the smaller DW_OP_addr encoding. */ + if (insn->u.ea.encoding == DW_EH_PE_absptr) + { + out_uleb128 (1 + encoding_size); + out_one (DW_OP_addr); + } + else + { + out_uleb128 (1 + 1 + encoding_size); + out_one (DW_OP_GNU_encoded_addr); + out_one (encoding); + + if ((encoding & 0x70) == DW_EH_PE_pcrel) + { +#if CFI_DIFF_EXPR_OK + insn->u.ea.exp.X_op = O_subtract; + insn->u.ea.exp.X_op_symbol = symbol_temp_new_now (); +#elif defined (tc_cfi_emit_pcrel_expr) + tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, encoding_size); + break; +#else + abort (); +#endif + } + } + emit_expr (&insn->u.ea.exp, encoding_size); + } + break; + + default: + abort (); + } +} + +static offsetT +encoding_size (unsigned char encoding) +{ + if (encoding == DW_EH_PE_omit) + return 0; + switch (encoding & 0x7) + { + case 0: + return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4; + case DW_EH_PE_udata2: + return 2; + case DW_EH_PE_udata4: + return 4; + case DW_EH_PE_udata8: + return 8; + default: + abort (); + } +} + +static void +output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align) +{ + symbolS *after_size_address, *end_address; + expressionS exp; + struct cfi_insn_data *i; + offsetT augmentation_size; + int enc; + enum dwarf2_format fmt = DWARF2_FORMAT (now_seg); + + cie->start_address = symbol_temp_new_now (); + after_size_address = symbol_temp_make (); + end_address = symbol_temp_make (); + + exp.X_op = O_subtract; + exp.X_add_symbol = end_address; + exp.X_op_symbol = after_size_address; + exp.X_add_number = 0; + + if (eh_frame || fmt == dwarf2_format_32bit) + emit_expr (&exp, 4); /* Length. */ + else + { + if (fmt == dwarf2_format_64bit) + out_four (-1); + emit_expr (&exp, 8); /* Length. */ + } + symbol_set_value_now (after_size_address); + if (eh_frame) + out_four (0); /* CIE id. */ + else + { + out_four (-1); /* CIE id. */ + if (fmt != dwarf2_format_32bit) + out_four (-1); + } + out_one (DW_CIE_VERSION); /* Version. */ + if (eh_frame) + { + out_one ('z'); /* Augmentation. */ + if (cie->per_encoding != DW_EH_PE_omit) + out_one ('P'); + if (cie->lsda_encoding != DW_EH_PE_omit) + out_one ('L'); + out_one ('R'); + } + if (cie->signal_frame) + out_one ('S'); + out_one (0); + out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */ + out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */ + if (DW_CIE_VERSION == 1) /* Return column. */ + out_one (cie->return_column); + else + out_uleb128 (cie->return_column); + if (eh_frame) + { + augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit); + if (cie->per_encoding != DW_EH_PE_omit) + augmentation_size += 1 + encoding_size (cie->per_encoding); + out_uleb128 (augmentation_size); /* Augmentation size. */ + + if (cie->per_encoding != DW_EH_PE_omit) + { + offsetT size = encoding_size (cie->per_encoding); + out_one (cie->per_encoding); + exp = cie->personality; + if ((cie->per_encoding & 0x70) == DW_EH_PE_pcrel) + { +#if CFI_DIFF_EXPR_OK + exp.X_op = O_subtract; + exp.X_op_symbol = symbol_temp_new_now (); + emit_expr (&exp, size); +#elif defined (tc_cfi_emit_pcrel_expr) + tc_cfi_emit_pcrel_expr (&exp, size); +#else + abort (); +#endif + } + else + emit_expr (&exp, size); + } + + if (cie->lsda_encoding != DW_EH_PE_omit) + out_one (cie->lsda_encoding); + } + + switch (DWARF2_FDE_RELOC_SIZE) + { + case 2: + enc = DW_EH_PE_sdata2; + break; + case 4: + enc = DW_EH_PE_sdata4; + break; + case 8: + enc = DW_EH_PE_sdata8; + break; + default: + abort (); + } +#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr + enc |= DW_EH_PE_pcrel; +#endif + if (eh_frame) + out_one (enc); + + if (cie->first) + { + for (i = cie->first; i != cie->last; i = i->next) + { + if (CUR_SEG (i) != CUR_SEG (cie)) + continue; + output_cfi_insn (i); + } + } + + frag_align (align, DW_CFA_nop, 0); + symbol_set_value_now (end_address); +} + +static void +output_fde (struct fde_entry *fde, struct cie_entry *cie, + bfd_boolean eh_frame, struct cfi_insn_data *first, + int align) +{ + symbolS *after_size_address, *end_address; + expressionS exp; + offsetT augmentation_size; + enum dwarf2_format fmt = DWARF2_FORMAT (now_seg); + int offset_size; + int addr_size; + + after_size_address = symbol_temp_make (); + end_address = symbol_temp_make (); + + exp.X_op = O_subtract; + exp.X_add_symbol = end_address; + exp.X_op_symbol = after_size_address; + exp.X_add_number = 0; + if (eh_frame || fmt == dwarf2_format_32bit) + offset_size = 4; + else + { + if (fmt == dwarf2_format_64bit) + out_four (-1); + offset_size = 8; + } + emit_expr (&exp, offset_size); /* Length. */ + symbol_set_value_now (after_size_address); + + if (eh_frame) + { + exp.X_op = O_subtract; + exp.X_add_symbol = after_size_address; + exp.X_op_symbol = cie->start_address; + exp.X_add_number = 0; + emit_expr (&exp, offset_size); /* CIE offset. */ + } + else + { + TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size); + } + + if (eh_frame) + { + exp.X_op = O_subtract; + exp.X_add_number = 0; +#if CFI_DIFF_EXPR_OK + exp.X_add_symbol = fde->start_address; + exp.X_op_symbol = symbol_temp_new_now (); + emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ +#else + exp.X_op = O_symbol; + exp.X_add_symbol = fde->start_address; +#ifdef tc_cfi_emit_pcrel_expr + tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ +#else + emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */ +#endif +#endif + addr_size = DWARF2_FDE_RELOC_SIZE; + } + else + { + exp.X_op = O_symbol; + exp.X_add_symbol = fde->start_address; + exp.X_add_number = 0; + addr_size = DWARF2_ADDR_SIZE (stdoutput); + emit_expr (&exp, addr_size); + } + + exp.X_op = O_subtract; + exp.X_add_symbol = fde->end_address; + exp.X_op_symbol = fde->start_address; /* Code length. */ + exp.X_add_number = 0; + emit_expr (&exp, addr_size); + + augmentation_size = encoding_size (fde->lsda_encoding); + if (eh_frame) + out_uleb128 (augmentation_size); /* Augmentation size. */ + + if (fde->lsda_encoding != DW_EH_PE_omit) + { + exp = fde->lsda; + if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel) + { +#if CFI_DIFF_LSDA_OK + exp.X_op = O_subtract; + exp.X_op_symbol = symbol_temp_new_now (); + emit_expr (&exp, augmentation_size); +#elif defined (tc_cfi_emit_pcrel_expr) + tc_cfi_emit_pcrel_expr (&exp, augmentation_size); +#else + abort (); +#endif + } + else + emit_expr (&exp, augmentation_size); + } + + for (; first; first = first->next) + if (CUR_SEG (first) == CUR_SEG (fde)) + output_cfi_insn (first); + + frag_align (align, DW_CFA_nop, 0); + symbol_set_value_now (end_address); +} + +static struct cie_entry * +select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame, + struct cfi_insn_data **pfirst, int align) +{ + struct cfi_insn_data *i, *j; + struct cie_entry *cie; + + for (cie = cie_root; cie; cie = cie->next) + { + if (CUR_SEG (cie) != CUR_SEG (fde)) + continue; + if (cie->return_column != fde->return_column + || cie->signal_frame != fde->signal_frame + || cie->per_encoding != fde->per_encoding + || cie->lsda_encoding != fde->lsda_encoding) + continue; + if (cie->per_encoding != DW_EH_PE_omit) + { + if (cie->personality.X_op != fde->personality.X_op + || cie->personality.X_add_number + != fde->personality.X_add_number) + continue; + switch (cie->personality.X_op) + { + case O_constant: + if (cie->personality.X_unsigned != fde->personality.X_unsigned) + continue; + break; + case O_symbol: + if (cie->personality.X_add_symbol + != fde->personality.X_add_symbol) + continue; + break; + default: + abort (); + } + } + for (i = cie->first, j = fde->data; + i != cie->last && j != NULL; + i = i->next, j = j->next) + { + if (i->insn != j->insn) + goto fail; + switch (i->insn) + { + case DW_CFA_advance_loc: + case DW_CFA_remember_state: + /* We reached the first advance/remember in the FDE, + but did not reach the end of the CIE list. */ + goto fail; + + case DW_CFA_offset: + case DW_CFA_def_cfa: + if (i->u.ri.reg != j->u.ri.reg) + goto fail; + if (i->u.ri.offset != j->u.ri.offset) + goto fail; + break; + + case DW_CFA_register: + if (i->u.rr.reg1 != j->u.rr.reg1) + goto fail; + if (i->u.rr.reg2 != j->u.rr.reg2) + goto fail; + break; + + case DW_CFA_def_cfa_register: + case DW_CFA_restore: + case DW_CFA_undefined: + case DW_CFA_same_value: + if (i->u.r != j->u.r) + goto fail; + break; + + case DW_CFA_def_cfa_offset: + if (i->u.i != j->u.i) + goto fail; + break; + + case CFI_escape: + case CFI_val_encoded_addr: + /* Don't bother matching these for now. */ + goto fail; + + default: + abort (); + } + } + + /* Success if we reached the end of the CIE list, and we've either + run out of FDE entries or we've encountered an advance, + remember, or escape. */ + if (i == cie->last + && (!j + || j->insn == DW_CFA_advance_loc + || j->insn == DW_CFA_remember_state + || j->insn == CFI_escape + || j->insn == CFI_val_encoded_addr)) + { + *pfirst = j; + return cie; + } + + fail:; + } + + cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry)); + cie->next = cie_root; + cie_root = cie; + SET_CUR_SEG (cie, CUR_SEG (fde)); + cie->return_column = fde->return_column; + cie->signal_frame = fde->signal_frame; + cie->per_encoding = fde->per_encoding; + cie->lsda_encoding = fde->lsda_encoding; + cie->personality = fde->personality; + cie->first = fde->data; + + for (i = cie->first; i ; i = i->next) + if (i->insn == DW_CFA_advance_loc + || i->insn == DW_CFA_remember_state + || i->insn == CFI_escape + || i->insn == CFI_val_encoded_addr) + break; + + cie->last = i; + *pfirst = i; + + output_cie (cie, eh_frame, align); + + return cie; +} + +#ifdef md_reg_eh_frame_to_debug_frame +static void +cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg) +{ + for (; insn; insn = insn->next) + { + if (CUR_SEG (insn) != ccseg) + continue; + switch (insn->insn) + { + case DW_CFA_advance_loc: + case DW_CFA_def_cfa_offset: + case DW_CFA_remember_state: + case DW_CFA_restore_state: + case DW_CFA_GNU_window_save: + case CFI_escape: + break; + + case DW_CFA_def_cfa: + case DW_CFA_offset: + insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg); + break; + + case DW_CFA_def_cfa_register: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_restore: + insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r); + break; + + case DW_CFA_register: + insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1); + insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2); + break; + + case CFI_val_encoded_addr: + insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg); + break; + + default: + abort (); + } + } +} +#else +#define cfi_change_reg_numbers(insn, cseg) do { } while (0) +#endif + +static segT +get_cfi_seg (segT cseg, const char *base, flagword flags, int align) +{ + if (SUPPORT_FRAME_LINKONCE) + { + struct dwcfi_seg_list *l; + + l = dwcfi_hash_find_or_make (cseg, base, flags); + + cseg = l->seg; + subseg_set (cseg, l->subseg); + } + else + { + cseg = subseg_new (base, 0); + bfd_set_section_flags (stdoutput, cseg, flags); + } + record_alignment (cseg, align); + return cseg; +} + +void +cfi_finish (void) +{ + struct cie_entry *cie, *cie_next; + segT cfi_seg, ccseg; + struct fde_entry *fde; + struct cfi_insn_data *first; + int save_flag_traditional_format, seek_next_seg; + + if (all_fde_data == 0) + return; + + if ((cfi_sections & CFI_EMIT_eh_frame) != 0) + { + /* Make sure check_eh_frame doesn't do anything with our output. */ + save_flag_traditional_format = flag_traditional_format; + flag_traditional_format = 1; + + if (!SUPPORT_FRAME_LINKONCE) + { + /* Open .eh_frame section. */ + cfi_seg = get_cfi_seg (NULL, ".eh_frame", + (SEC_ALLOC | SEC_LOAD | SEC_DATA + | DWARF2_EH_FRAME_READ_ONLY), + EH_FRAME_ALIGNMENT); +#ifdef md_fix_up_eh_frame + md_fix_up_eh_frame (cfi_seg); +#else + (void) cfi_seg; +#endif + } + + do + { + ccseg = NULL; + seek_next_seg = 0; + + for (cie = cie_root; cie; cie = cie_next) + { + cie_next = cie->next; + free ((void *) cie); + } + cie_root = NULL; + + for (fde = all_fde_data; fde ; fde = fde->next) + { + if (SUPPORT_FRAME_LINKONCE) + { + if (HANDLED (fde)) + continue; + if (seek_next_seg && CUR_SEG (fde) != ccseg) + { + seek_next_seg = 2; + continue; + } + if (!seek_next_seg) + { + ccseg = CUR_SEG (fde); + /* Open .eh_frame section. */ + cfi_seg = get_cfi_seg (ccseg, ".eh_frame", + (SEC_ALLOC | SEC_LOAD | SEC_DATA + | DWARF2_EH_FRAME_READ_ONLY), + EH_FRAME_ALIGNMENT); +#ifdef md_fix_up_eh_frame + md_fix_up_eh_frame (cfi_seg); +#else + (void) cfi_seg; +#endif + seek_next_seg = 1; + } + SET_HANDLED (fde, 1); + } + + if (fde->end_address == NULL) + { + as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); + fde->end_address = fde->start_address; + } + + cie = select_cie_for_fde (fde, TRUE, &first, 2); + output_fde (fde, cie, TRUE, first, + fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); + } + } + while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2); + + if (SUPPORT_FRAME_LINKONCE) + for (fde = all_fde_data; fde ; fde = fde->next) + SET_HANDLED (fde, 0); + + flag_traditional_format = save_flag_traditional_format; + } + + if ((cfi_sections & CFI_EMIT_debug_frame) != 0) + { + int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1; + + if (!SUPPORT_FRAME_LINKONCE) + get_cfi_seg (NULL, ".debug_frame", + SEC_READONLY | SEC_DEBUGGING, + alignment); + + do + { + ccseg = NULL; + seek_next_seg = 0; + + for (cie = cie_root; cie; cie = cie_next) + { + cie_next = cie->next; + free ((void *) cie); + } + cie_root = NULL; + + for (fde = all_fde_data; fde ; fde = fde->next) + { + if (SUPPORT_FRAME_LINKONCE) + { + if (HANDLED (fde)) + continue; + if (seek_next_seg && CUR_SEG (fde) != ccseg) + { + seek_next_seg = 2; + continue; + } + if (!seek_next_seg) + { + ccseg = CUR_SEG (fde); + /* Open .debug_frame section. */ + get_cfi_seg (ccseg, ".debug_frame", + SEC_READONLY | SEC_DEBUGGING, + alignment); + seek_next_seg = 1; + } + SET_HANDLED (fde, 1); + } + if (fde->end_address == NULL) + { + as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); + fde->end_address = fde->start_address; + } + + fde->per_encoding = DW_EH_PE_omit; + fde->lsda_encoding = DW_EH_PE_omit; + cfi_change_reg_numbers (fde->data, ccseg); + cie = select_cie_for_fde (fde, FALSE, &first, alignment); + output_fde (fde, cie, FALSE, first, alignment); + } + } + while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2); + + if (SUPPORT_FRAME_LINKONCE) + for (fde = all_fde_data; fde ; fde = fde->next) + SET_HANDLED (fde, 0); + } +} + +#else /* TARGET_USE_CFIPOP */ + +/* Emit an intelligible error message for missing support. */ + +static void +dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED) +{ + as_bad (_("CFI is not supported for this target")); + ignore_rest_of_line (); +} + +const pseudo_typeS cfi_pseudo_table[] = + { + { "cfi_sections", dot_cfi_dummy, 0 }, + { "cfi_startproc", dot_cfi_dummy, 0 }, + { "cfi_endproc", dot_cfi_dummy, 0 }, + { "cfi_def_cfa", dot_cfi_dummy, 0 }, + { "cfi_def_cfa_register", dot_cfi_dummy, 0 }, + { "cfi_def_cfa_offset", dot_cfi_dummy, 0 }, + { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 }, + { "cfi_offset", dot_cfi_dummy, 0 }, + { "cfi_rel_offset", dot_cfi_dummy, 0 }, + { "cfi_register", dot_cfi_dummy, 0 }, + { "cfi_return_column", dot_cfi_dummy, 0 }, + { "cfi_restore", dot_cfi_dummy, 0 }, + { "cfi_undefined", dot_cfi_dummy, 0 }, + { "cfi_same_value", dot_cfi_dummy, 0 }, + { "cfi_remember_state", dot_cfi_dummy, 0 }, + { "cfi_restore_state", dot_cfi_dummy, 0 }, + { "cfi_window_save", dot_cfi_dummy, 0 }, + { "cfi_escape", dot_cfi_dummy, 0 }, + { "cfi_signal_frame", dot_cfi_dummy, 0 }, + { "cfi_personality", dot_cfi_dummy, 0 }, + { "cfi_lsda", dot_cfi_dummy, 0 }, + { "cfi_val_encoded_addr", dot_cfi_dummy, 0 }, + { NULL, NULL, 0 } + }; + +void +cfi_finish (void) +{ +} +#endif /* TARGET_USE_CFIPOP */ diff --git a/contrib/toolchain/binutils/gas/dw2gencfi.h b/contrib/toolchain/binutils/gas/dw2gencfi.h new file mode 100644 index 0000000000..7f834966b9 --- /dev/null +++ b/contrib/toolchain/binutils/gas/dw2gencfi.h @@ -0,0 +1,132 @@ +/* dw2gencfi.h - Support for generating Dwarf2 CFI information. + Copyright 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. + Contributed by Michal Ludvig + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef DW2GENCFI_H +#define DW2GENCFI_H + +#include "dwarf2.h" + +struct symbol; + +extern const pseudo_typeS cfi_pseudo_table[]; + +/* cfi_finish() is called at the end of file. It will complain if + the last CFI wasn't properly closed by .cfi_endproc. */ +extern void cfi_finish (void); + +/* Entry points for backends to add unwind information. */ +extern void cfi_new_fde (struct symbol *); +extern void cfi_end_fde (struct symbol *); +extern void cfi_set_return_column (unsigned); +extern void cfi_add_advance_loc (struct symbol *); + +extern void cfi_add_CFA_offset (unsigned, offsetT); +extern void cfi_add_CFA_def_cfa (unsigned, offsetT); +extern void cfi_add_CFA_register (unsigned, unsigned); +extern void cfi_add_CFA_def_cfa_register (unsigned); +extern void cfi_add_CFA_def_cfa_offset (offsetT); +extern void cfi_add_CFA_restore (unsigned); +extern void cfi_add_CFA_undefined (unsigned); +extern void cfi_add_CFA_same_value (unsigned); +extern void cfi_add_CFA_remember_state (void); +extern void cfi_add_CFA_restore_state (void); + +/* Structures for md_cfi_end. */ + +#if defined (TE_PE) || defined (TE_PEP) +#define SUPPORT_FRAME_LINKONCE 1 +#else +#define SUPPORT_FRAME_LINKONCE 0 +#endif + +struct cfi_insn_data +{ + struct cfi_insn_data *next; +#if SUPPORT_FRAME_LINKONCE + segT cur_seg; +#endif + int insn; + union + { + struct + { + unsigned reg; + offsetT offset; + } ri; + + struct + { + unsigned reg1; + unsigned reg2; + } rr; + + unsigned r; + offsetT i; + + struct + { + symbolS *lab1; + symbolS *lab2; + } ll; + + struct cfi_escape_data *esc; + + struct + { + unsigned reg, encoding; + expressionS exp; + } ea; + } u; +}; + +struct fde_entry +{ + struct fde_entry *next; +#if SUPPORT_FRAME_LINKONCE + segT cur_seg; +#endif + symbolS *start_address; + symbolS *end_address; + struct cfi_insn_data *data; + struct cfi_insn_data **last; + unsigned char per_encoding; + unsigned char lsda_encoding; + expressionS personality; + expressionS lsda; + unsigned int return_column; + unsigned int signal_frame; +#if SUPPORT_FRAME_LINKONCE + int handled; +#endif +}; + +/* The list of all FDEs that have been collected. */ +extern struct fde_entry *all_fde_data; + +/* Fake CFI type; outside the byte range of any real CFI insn. */ +#define CFI_adjust_cfa_offset 0x100 +#define CFI_return_column 0x101 +#define CFI_rel_offset 0x102 +#define CFI_escape 0x103 +#define CFI_signal_frame 0x104 +#define CFI_val_encoded_addr 0x105 + +#endif /* DW2GENCFI_H */ diff --git a/contrib/toolchain/binutils/gas/dwarf2dbg.c b/contrib/toolchain/binutils/gas/dwarf2dbg.c new file mode 100644 index 0000000000..6d6ee2dd19 --- /dev/null +++ b/contrib/toolchain/binutils/gas/dwarf2dbg.c @@ -0,0 +1,1944 @@ +/* dwarf2dbg.c - DWARF2 debug support + Copyright 1999-2013 Free Software Foundation, Inc. + Contributed by David Mosberger-Tang + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Logical line numbers can be controlled by the compiler via the + following directives: + + .file FILENO "file.c" + .loc FILENO LINENO [COLUMN] [basic_block] [prologue_end] \ + [epilogue_begin] [is_stmt VALUE] [isa VALUE] \ + [discriminator VALUE] +*/ + +#include "as.h" +#include "safe-ctype.h" + +#ifdef HAVE_LIMITS_H +#include +#else +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifndef INT_MAX +#define INT_MAX (int) (((unsigned) (-1)) >> 1) +#endif +#endif + +#include "dwarf2dbg.h" +#include + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM +/* We need to decide which character to use as a directory separator. + Just because HAVE_DOS_BASED_FILE_SYSTEM is defined, it does not + necessarily mean that the backslash character is the one to use. + Some environments, eg Cygwin, can support both naming conventions. + So we use the heuristic that we only need to use the backslash if + the path is an absolute path starting with a DOS style drive + selector. eg C: or D: */ +# define INSERT_DIR_SEPARATOR(string, offset) \ + do \ + { \ + if (offset > 1 \ + && string[0] != 0 \ + && string[1] == ':') \ + string [offset] = '\\'; \ + else \ + string [offset] = '/'; \ + } \ + while (0) +#else +# define INSERT_DIR_SEPARATOR(string, offset) string[offset] = '/' +#endif + +#ifndef DWARF2_FORMAT +# define DWARF2_FORMAT(SEC) dwarf2_format_32bit +#endif + +#ifndef DWARF2_ADDR_SIZE +# define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8) +#endif + +#ifndef DWARF2_FILE_NAME +#define DWARF2_FILE_NAME(FILENAME, DIRNAME) FILENAME +#endif + +#ifndef DWARF2_FILE_TIME_NAME +#define DWARF2_FILE_TIME_NAME(FILENAME,DIRNAME) 0 +#endif + +#ifndef DWARF2_FILE_SIZE_NAME +#define DWARF2_FILE_SIZE_NAME(FILENAME,DIRNAME) 0 +#endif + +#ifndef DWARF2_VERSION +#define DWARF2_VERSION 2 +#endif + +/* The .debug_aranges version has been 2 in DWARF version 2, 3 and 4. */ +#ifndef DWARF2_ARANGES_VERSION +#define DWARF2_ARANGES_VERSION 2 +#endif + +/* This implementation output version 2 .debug_line information. */ +#ifndef DWARF2_LINE_VERSION +#define DWARF2_LINE_VERSION 2 +#endif + +#include "subsegs.h" + +#include "dwarf2.h" + +/* Since we can't generate the prolog until the body is complete, we + use three different subsegments for .debug_line: one holding the + prolog, one for the directory and filename info, and one for the + body ("statement program"). */ +#define DL_PROLOG 0 +#define DL_FILES 1 +#define DL_BODY 2 + +/* If linker relaxation might change offsets in the code, the DWARF special + opcodes and variable-length operands cannot be used. If this macro is + nonzero, use the DW_LNS_fixed_advance_pc opcode instead. */ +#ifndef DWARF2_USE_FIXED_ADVANCE_PC +# define DWARF2_USE_FIXED_ADVANCE_PC linkrelax +#endif + +/* First special line opcde - leave room for the standard opcodes. + Note: If you want to change this, you'll have to update the + "standard_opcode_lengths" table that is emitted below in + out_debug_line(). */ +#define DWARF2_LINE_OPCODE_BASE 13 + +#ifndef DWARF2_LINE_BASE + /* Minimum line offset in a special line info. opcode. This value + was chosen to give a reasonable range of values. */ +# define DWARF2_LINE_BASE -5 +#endif + +/* Range of line offsets in a special line info. opcode. */ +#ifndef DWARF2_LINE_RANGE +# define DWARF2_LINE_RANGE 14 +#endif + +#ifndef DWARF2_LINE_MIN_INSN_LENGTH + /* Define the architecture-dependent minimum instruction length (in + bytes). This value should be rather too small than too big. */ +# define DWARF2_LINE_MIN_INSN_LENGTH 1 +#endif + +/* Flag that indicates the initial value of the is_stmt_start flag. */ +#define DWARF2_LINE_DEFAULT_IS_STMT 1 + +/* Given a special op, return the line skip amount. */ +#define SPECIAL_LINE(op) \ + (((op) - DWARF2_LINE_OPCODE_BASE)%DWARF2_LINE_RANGE + DWARF2_LINE_BASE) + +/* Given a special op, return the address skip amount (in units of + DWARF2_LINE_MIN_INSN_LENGTH. */ +#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE) + +/* The maximum address skip amount that can be encoded with a special op. */ +#define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255) + +struct line_entry { + struct line_entry *next; + symbolS *label; + struct dwarf2_line_info loc; +}; + +struct line_subseg { + struct line_subseg *next; + subsegT subseg; + struct line_entry *head; + struct line_entry **ptail; + struct line_entry **pmove_tail; +}; + +struct line_seg { + struct line_seg *next; + segT seg; + struct line_subseg *head; + symbolS *text_start; + symbolS *text_end; +}; + +/* Collects data for all line table entries during assembly. */ +static struct line_seg *all_segs; +/* Hash used to quickly lookup a segment by name, avoiding the need to search + through the all_segs list. */ +static struct hash_control *all_segs_hash; +static struct line_seg **last_seg_ptr; + +struct file_entry { + const char *filename; + unsigned int dir; +}; + +/* Table of files used by .debug_line. */ +static struct file_entry *files; +static unsigned int files_in_use; +static unsigned int files_allocated; + +/* Table of directories used by .debug_line. */ +static char **dirs; +static unsigned int dirs_in_use; +static unsigned int dirs_allocated; + +/* TRUE when we've seen a .loc directive recently. Used to avoid + doing work when there's nothing to do. */ +bfd_boolean dwarf2_loc_directive_seen; + +/* TRUE when we're supposed to set the basic block mark whenever a + label is seen. */ +bfd_boolean dwarf2_loc_mark_labels; + +/* Current location as indicated by the most recent .loc directive. */ +static struct dwarf2_line_info current = { + 1, 1, 0, 0, + DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, + 0 +}; + +/* The size of an address on the target. */ +static unsigned int sizeof_address; + +static unsigned int get_filenum (const char *, unsigned int); + +#ifndef TC_DWARF2_EMIT_OFFSET +#define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset + +/* Create an offset to .dwarf2_*. */ + +static void +generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size) +{ + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = symbol; + exp.X_add_number = 0; + emit_expr (&exp, size); +} +#endif + +/* Find or create (if CREATE_P) an entry for SEG+SUBSEG in ALL_SEGS. */ + +static struct line_subseg * +get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p) +{ + static segT last_seg; + static subsegT last_subseg; + static struct line_subseg *last_line_subseg; + + struct line_seg *s; + struct line_subseg **pss, *lss; + + if (seg == last_seg && subseg == last_subseg) + return last_line_subseg; + + s = (struct line_seg *) hash_find (all_segs_hash, seg->name); + if (s == NULL) + { + if (!create_p) + return NULL; + + s = (struct line_seg *) xmalloc (sizeof (*s)); + s->next = NULL; + s->seg = seg; + s->head = NULL; + *last_seg_ptr = s; + last_seg_ptr = &s->next; + hash_insert (all_segs_hash, seg->name, s); + } + gas_assert (seg == s->seg); + + for (pss = &s->head; (lss = *pss) != NULL ; pss = &lss->next) + { + if (lss->subseg == subseg) + goto found_subseg; + if (lss->subseg > subseg) + break; + } + + lss = (struct line_subseg *) xmalloc (sizeof (*lss)); + lss->next = *pss; + lss->subseg = subseg; + lss->head = NULL; + lss->ptail = &lss->head; + lss->pmove_tail = &lss->head; + *pss = lss; + + found_subseg: + last_seg = seg; + last_subseg = subseg; + last_line_subseg = lss; + + return lss; +} + +/* Record an entry for LOC occurring at LABEL. */ + +static void +dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc) +{ + struct line_subseg *lss; + struct line_entry *e; + + e = (struct line_entry *) xmalloc (sizeof (*e)); + e->next = NULL; + e->label = label; + e->loc = *loc; + + lss = get_line_subseg (now_seg, now_subseg, TRUE); + *lss->ptail = e; + lss->ptail = &e->next; +} + +/* Record an entry for LOC occurring at OFS within the current fragment. */ + +void +dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc) +{ + static unsigned int line = -1; + static unsigned int filenum = -1; + + symbolS *sym; + + /* Early out for as-yet incomplete location information. */ + if (loc->filenum == 0 || loc->line == 0) + return; + + /* Don't emit sequences of line symbols for the same line when the + symbols apply to assembler code. It is necessary to emit + duplicate line symbols when a compiler asks for them, because GDB + uses them to determine the end of the prologue. */ + if (debug_type == DEBUG_DWARF2 + && line == loc->line && filenum == loc->filenum) + return; + + line = loc->line; + filenum = loc->filenum; + + if (linkrelax) + { + char name[120]; + + /* Use a non-fake name for the line number location, + so that it can be referred to by relocations. */ + sprintf (name, ".Loc.%u.%u", line, filenum); + sym = symbol_new (name, now_seg, ofs, frag_now); + } + else + sym = symbol_temp_new (now_seg, ofs, frag_now); + dwarf2_gen_line_info_1 (sym, loc); +} + +/* Returns the current source information. If .file directives have + been encountered, the info for the corresponding source file is + returned. Otherwise, the info for the assembly source file is + returned. */ + +void +dwarf2_where (struct dwarf2_line_info *line) +{ + if (debug_type == DEBUG_DWARF2) + { + char *filename; + as_where (&filename, &line->line); + line->filenum = get_filenum (filename, 0); + line->column = 0; + line->flags = DWARF2_FLAG_IS_STMT; + line->isa = current.isa; + line->discriminator = current.discriminator; + } + else + *line = current; +} + +/* A hook to allow the target backend to inform the line number state + machine of isa changes when assembler debug info is enabled. */ + +void +dwarf2_set_isa (unsigned int isa) +{ + current.isa = isa; +} + +/* Called for each machine instruction, or relatively atomic group of + machine instructions (ie built-in macro). The instruction or group + is SIZE bytes in length. If dwarf2 line number generation is called + for, emit a line statement appropriately. */ + +void +dwarf2_emit_insn (int size) +{ + struct dwarf2_line_info loc; + + if (!dwarf2_loc_directive_seen && debug_type != DEBUG_DWARF2) + return; + + dwarf2_where (&loc); + + dwarf2_gen_line_info (frag_now_fix () - size, &loc); + dwarf2_consume_line_info (); +} + +/* Move all previously-emitted line entries for the current position by + DELTA bytes. This function cannot be used to move the same entries + twice. */ + +void +dwarf2_move_insn (int delta) +{ + struct line_subseg *lss; + struct line_entry *e; + valueT now; + + if (delta == 0) + return; + + lss = get_line_subseg (now_seg, now_subseg, FALSE); + if (!lss) + return; + + now = frag_now_fix (); + while ((e = *lss->pmove_tail)) + { + if (S_GET_VALUE (e->label) == now) + S_SET_VALUE (e->label, now + delta); + lss->pmove_tail = &e->next; + } +} + +/* Called after the current line information has been either used with + dwarf2_gen_line_info or saved with a machine instruction for later use. + This resets the state of the line number information to reflect that + it has been used. */ + +void +dwarf2_consume_line_info (void) +{ + /* Unless we generate DWARF2 debugging information for each + assembler line, we only emit one line symbol for one LOC. */ + dwarf2_loc_directive_seen = FALSE; + + current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK + | DWARF2_FLAG_PROLOGUE_END + | DWARF2_FLAG_EPILOGUE_BEGIN); + current.discriminator = 0; +} + +/* Called for each (preferably code) label. If dwarf2_loc_mark_labels + is enabled, emit a basic block marker. */ + +void +dwarf2_emit_label (symbolS *label) +{ + struct dwarf2_line_info loc; + + if (!dwarf2_loc_mark_labels) + return; + if (S_GET_SEGMENT (label) != now_seg) + return; + if (!(bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)) + return; + if (files_in_use == 0 && debug_type != DEBUG_DWARF2) + return; + + dwarf2_where (&loc); + + loc.flags |= DWARF2_FLAG_BASIC_BLOCK; + + dwarf2_gen_line_info_1 (label, &loc); + dwarf2_consume_line_info (); +} + +/* Get a .debug_line file number for FILENAME. If NUM is nonzero, + allocate it on that file table slot, otherwise return the first + empty one. */ + +static unsigned int +get_filenum (const char *filename, unsigned int num) +{ + static unsigned int last_used, last_used_dir_len; + const char *file; + size_t dir_len; + unsigned int i, dir; + + if (num == 0 && last_used) + { + if (! files[last_used].dir + && filename_cmp (filename, files[last_used].filename) == 0) + return last_used; + if (files[last_used].dir + && filename_ncmp (filename, dirs[files[last_used].dir], + last_used_dir_len) == 0 + && IS_DIR_SEPARATOR (filename [last_used_dir_len]) + && filename_cmp (filename + last_used_dir_len + 1, + files[last_used].filename) == 0) + return last_used; + } + + file = lbasename (filename); + /* Don't make empty string from / or A: from A:/ . */ +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + if (file <= filename + 3) + file = filename; +#else + if (file == filename + 1) + file = filename; +#endif + dir_len = file - filename; + + dir = 0; + if (dir_len) + { +#ifndef DWARF2_DIR_SHOULD_END_WITH_SEPARATOR + --dir_len; +#endif + for (dir = 1; dir < dirs_in_use; ++dir) + if (filename_ncmp (filename, dirs[dir], dir_len) == 0 + && dirs[dir][dir_len] == '\0') + break; + + if (dir >= dirs_in_use) + { + if (dir >= dirs_allocated) + { + dirs_allocated = dir + 32; + dirs = (char **) + xrealloc (dirs, (dir + 32) * sizeof (const char *)); + } + + dirs[dir] = (char *) xmalloc (dir_len + 1); + memcpy (dirs[dir], filename, dir_len); + dirs[dir][dir_len] = '\0'; + dirs_in_use = dir + 1; + } + } + + if (num == 0) + { + for (i = 1; i < files_in_use; ++i) + if (files[i].dir == dir + && files[i].filename + && filename_cmp (file, files[i].filename) == 0) + { + last_used = i; + last_used_dir_len = dir_len; + return i; + } + } + else + i = num; + + if (i >= files_allocated) + { + unsigned int old = files_allocated; + + files_allocated = i + 32; + files = (struct file_entry *) + xrealloc (files, (i + 32) * sizeof (struct file_entry)); + + memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry)); + } + + files[i].filename = num ? file : xstrdup (file); + files[i].dir = dir; + if (files_in_use < i + 1) + files_in_use = i + 1; + last_used = i; + last_used_dir_len = dir_len; + + return i; +} + +/* Handle two forms of .file directive: + - Pass .file "source.c" to s_app_file + - Handle .file 1 "source.c" by adding an entry to the DWARF-2 file table + + If an entry is added to the file table, return a pointer to the filename. */ + +char * +dwarf2_directive_file (int dummy ATTRIBUTE_UNUSED) +{ + offsetT num; + char *filename; + int filename_len; + + /* Continue to accept a bare string and pass it off. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == '"') + { + s_app_file (0); + return NULL; + } + + num = get_absolute_expression (); + filename = demand_copy_C_string (&filename_len); + if (filename == NULL) + return NULL; + demand_empty_rest_of_line (); + + if (num < 1) + { + as_bad (_("file number less than one")); + return NULL; + } + + /* A .file directive implies compiler generated debug information is + being supplied. Turn off gas generated debug info. */ + debug_type = DEBUG_NONE; + + if (num < (int) files_in_use && files[num].filename != 0) + { + as_bad (_("file number %ld already allocated"), (long) num); + return NULL; + } + + get_filenum (filename, num); + + return filename; +} + +void +dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED) +{ + offsetT filenum, line; + + /* If we see two .loc directives in a row, force the first one to be + output now. */ + if (dwarf2_loc_directive_seen) + dwarf2_emit_insn (0); + + filenum = get_absolute_expression (); + SKIP_WHITESPACE (); + line = get_absolute_expression (); + + if (filenum < 1) + { + as_bad (_("file number less than one")); + return; + } + if (filenum >= (int) files_in_use || files[filenum].filename == 0) + { + as_bad (_("unassigned file number %ld"), (long) filenum); + return; + } + + current.filenum = filenum; + current.line = line; + current.discriminator = 0; + +#ifndef NO_LISTING + if (listing) + { + if (files[filenum].dir) + { + size_t dir_len = strlen (dirs[files[filenum].dir]); + size_t file_len = strlen (files[filenum].filename); + char *cp = (char *) alloca (dir_len + 1 + file_len + 1); + + memcpy (cp, dirs[files[filenum].dir], dir_len); + INSERT_DIR_SEPARATOR (cp, dir_len); + memcpy (cp + dir_len + 1, files[filenum].filename, file_len); + cp[dir_len + file_len + 1] = '\0'; + listing_source_file (cp); + } + else + listing_source_file (files[filenum].filename); + listing_source_line (line); + } +#endif + + SKIP_WHITESPACE (); + if (ISDIGIT (*input_line_pointer)) + { + current.column = get_absolute_expression (); + SKIP_WHITESPACE (); + } + + while (ISALPHA (*input_line_pointer)) + { + char *p, c; + offsetT value; + + p = input_line_pointer; + c = get_symbol_end (); + + if (strcmp (p, "basic_block") == 0) + { + current.flags |= DWARF2_FLAG_BASIC_BLOCK; + *input_line_pointer = c; + } + else if (strcmp (p, "prologue_end") == 0) + { + current.flags |= DWARF2_FLAG_PROLOGUE_END; + *input_line_pointer = c; + } + else if (strcmp (p, "epilogue_begin") == 0) + { + current.flags |= DWARF2_FLAG_EPILOGUE_BEGIN; + *input_line_pointer = c; + } + else if (strcmp (p, "is_stmt") == 0) + { + *input_line_pointer = c; + value = get_absolute_expression (); + if (value == 0) + current.flags &= ~DWARF2_FLAG_IS_STMT; + else if (value == 1) + current.flags |= DWARF2_FLAG_IS_STMT; + else + { + as_bad (_("is_stmt value not 0 or 1")); + return; + } + } + else if (strcmp (p, "isa") == 0) + { + *input_line_pointer = c; + value = get_absolute_expression (); + if (value >= 0) + current.isa = value; + else + { + as_bad (_("isa number less than zero")); + return; + } + } + else if (strcmp (p, "discriminator") == 0) + { + *input_line_pointer = c; + value = get_absolute_expression (); + if (value >= 0) + current.discriminator = value; + else + { + as_bad (_("discriminator less than zero")); + return; + } + } + else + { + as_bad (_("unknown .loc sub-directive `%s'"), p); + *input_line_pointer = c; + return; + } + + SKIP_WHITESPACE (); + } + + demand_empty_rest_of_line (); + dwarf2_loc_directive_seen = TRUE; + debug_type = DEBUG_NONE; +} + +void +dwarf2_directive_loc_mark_labels (int dummy ATTRIBUTE_UNUSED) +{ + offsetT value = get_absolute_expression (); + + if (value != 0 && value != 1) + { + as_bad (_("expected 0 or 1")); + ignore_rest_of_line (); + } + else + { + dwarf2_loc_mark_labels = value != 0; + demand_empty_rest_of_line (); + } +} + +static struct frag * +first_frag_for_seg (segT seg) +{ + return seg_info (seg)->frchainP->frch_root; +} + +static struct frag * +last_frag_for_seg (segT seg) +{ + frchainS *f = seg_info (seg)->frchainP; + + while (f->frch_next != NULL) + f = f->frch_next; + + return f->frch_last; +} + +/* Emit a single byte into the current segment. */ + +static inline void +out_byte (int byte) +{ + FRAG_APPEND_1_CHAR (byte); +} + +/* Emit a statement program opcode into the current segment. */ + +static inline void +out_opcode (int opc) +{ + out_byte (opc); +} + +/* Emit a two-byte word into the current segment. */ + +static inline void +out_two (int data) +{ + md_number_to_chars (frag_more (2), data, 2); +} + +/* Emit a four byte word into the current segment. */ + +static inline void +out_four (int data) +{ + md_number_to_chars (frag_more (4), data, 4); +} + +/* Emit an unsigned "little-endian base 128" number. */ + +static void +out_uleb128 (addressT value) +{ + output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0); +} + +/* Emit a signed "little-endian base 128" number. */ + +static void +out_leb128 (addressT value) +{ + output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1); +} + +/* Emit a tuple for .debug_abbrev. */ + +static inline void +out_abbrev (int name, int form) +{ + out_uleb128 (name); + out_uleb128 (form); +} + +/* Get the size of a fragment. */ + +static offsetT +get_frag_fix (fragS *frag, segT seg) +{ + frchainS *fr; + + if (frag->fr_next) + return frag->fr_fix; + + /* If a fragment is the last in the chain, special measures must be + taken to find its size before relaxation, since it may be pending + on some subsegment chain. */ + for (fr = seg_info (seg)->frchainP; fr; fr = fr->frch_next) + if (fr->frch_last == frag) + return (char *) obstack_next_free (&fr->frch_obstack) - frag->fr_literal; + + abort (); +} + +/* Set an absolute address (may result in a relocation entry). */ + +static void +out_set_addr (symbolS *sym) +{ + expressionS exp; + + out_opcode (DW_LNS_extended_op); + out_uleb128 (sizeof_address + 1); + + out_opcode (DW_LNE_set_address); + exp.X_op = O_symbol; + exp.X_add_symbol = sym; + exp.X_add_number = 0; + emit_expr (&exp, sizeof_address); +} + +static void scale_addr_delta (addressT *); + +static void +scale_addr_delta (addressT *addr_delta) +{ + static int printed_this = 0; + if (DWARF2_LINE_MIN_INSN_LENGTH > 1) + { + if (*addr_delta % DWARF2_LINE_MIN_INSN_LENGTH != 0 && !printed_this) + { + as_bad("unaligned opcodes detected in executable segment"); + printed_this = 1; + } + *addr_delta /= DWARF2_LINE_MIN_INSN_LENGTH; + } +} + +/* Encode a pair of line and address skips as efficiently as possible. + Note that the line skip is signed, whereas the address skip is unsigned. + + The following two routines *must* be kept in sync. This is + enforced by making emit_inc_line_addr abort if we do not emit + exactly the expected number of bytes. */ + +static int +size_inc_line_addr (int line_delta, addressT addr_delta) +{ + unsigned int tmp, opcode; + int len = 0; + + /* Scale the address delta by the minimum instruction length. */ + scale_addr_delta (&addr_delta); + + /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. + We cannot use special opcodes here, since we want the end_sequence + to emit the matrix entry. */ + if (line_delta == INT_MAX) + { + if (addr_delta == MAX_SPECIAL_ADDR_DELTA) + len = 1; + else + len = 1 + sizeof_leb128 (addr_delta, 0); + return len + 3; + } + + /* Bias the line delta by the base. */ + tmp = line_delta - DWARF2_LINE_BASE; + + /* If the line increment is out of range of a special opcode, we + must encode it with DW_LNS_advance_line. */ + if (tmp >= DWARF2_LINE_RANGE) + { + len = 1 + sizeof_leb128 (line_delta, 1); + line_delta = 0; + tmp = 0 - DWARF2_LINE_BASE; + } + + /* Bias the opcode by the special opcode base. */ + tmp += DWARF2_LINE_OPCODE_BASE; + + /* Avoid overflow when addr_delta is large. */ + if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA) + { + /* Try using a special opcode. */ + opcode = tmp + addr_delta * DWARF2_LINE_RANGE; + if (opcode <= 255) + return len + 1; + + /* Try using DW_LNS_const_add_pc followed by special op. */ + opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE; + if (opcode <= 255) + return len + 2; + } + + /* Otherwise use DW_LNS_advance_pc. */ + len += 1 + sizeof_leb128 (addr_delta, 0); + + /* DW_LNS_copy or special opcode. */ + len += 1; + + return len; +} + +static void +emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len) +{ + unsigned int tmp, opcode; + int need_copy = 0; + char *end = p + len; + + /* Line number sequences cannot go backward in addresses. This means + we've incorrectly ordered the statements in the sequence. */ + gas_assert ((offsetT) addr_delta >= 0); + + /* Scale the address delta by the minimum instruction length. */ + scale_addr_delta (&addr_delta); + + /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. + We cannot use special opcodes here, since we want the end_sequence + to emit the matrix entry. */ + if (line_delta == INT_MAX) + { + if (addr_delta == MAX_SPECIAL_ADDR_DELTA) + *p++ = DW_LNS_const_add_pc; + else + { + *p++ = DW_LNS_advance_pc; + p += output_leb128 (p, addr_delta, 0); + } + + *p++ = DW_LNS_extended_op; + *p++ = 1; + *p++ = DW_LNE_end_sequence; + goto done; + } + + /* Bias the line delta by the base. */ + tmp = line_delta - DWARF2_LINE_BASE; + + /* If the line increment is out of range of a special opcode, we + must encode it with DW_LNS_advance_line. */ + if (tmp >= DWARF2_LINE_RANGE) + { + *p++ = DW_LNS_advance_line; + p += output_leb128 (p, line_delta, 1); + + line_delta = 0; + tmp = 0 - DWARF2_LINE_BASE; + need_copy = 1; + } + + /* Prettier, I think, to use DW_LNS_copy instead of a "line +0, addr +0" + special opcode. */ + if (line_delta == 0 && addr_delta == 0) + { + *p++ = DW_LNS_copy; + goto done; + } + + /* Bias the opcode by the special opcode base. */ + tmp += DWARF2_LINE_OPCODE_BASE; + + /* Avoid overflow when addr_delta is large. */ + if (addr_delta < 256 + MAX_SPECIAL_ADDR_DELTA) + { + /* Try using a special opcode. */ + opcode = tmp + addr_delta * DWARF2_LINE_RANGE; + if (opcode <= 255) + { + *p++ = opcode; + goto done; + } + + /* Try using DW_LNS_const_add_pc followed by special op. */ + opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE; + if (opcode <= 255) + { + *p++ = DW_LNS_const_add_pc; + *p++ = opcode; + goto done; + } + } + + /* Otherwise use DW_LNS_advance_pc. */ + *p++ = DW_LNS_advance_pc; + p += output_leb128 (p, addr_delta, 0); + + if (need_copy) + *p++ = DW_LNS_copy; + else + *p++ = tmp; + + done: + gas_assert (p == end); +} + +/* Handy routine to combine calls to the above two routines. */ + +static void +out_inc_line_addr (int line_delta, addressT addr_delta) +{ + int len = size_inc_line_addr (line_delta, addr_delta); + emit_inc_line_addr (line_delta, addr_delta, frag_more (len), len); +} + +/* Write out an alternative form of line and address skips using + DW_LNS_fixed_advance_pc opcodes. This uses more space than the default + line and address information, but it is required if linker relaxation + could change the code offsets. The following two routines *must* be + kept in sync. */ +#define ADDR_DELTA_LIMIT 50000 + +static int +size_fixed_inc_line_addr (int line_delta, addressT addr_delta) +{ + int len = 0; + + /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */ + if (line_delta != INT_MAX) + len = 1 + sizeof_leb128 (line_delta, 1); + + if (addr_delta > ADDR_DELTA_LIMIT) + { + /* DW_LNS_extended_op */ + len += 1 + sizeof_leb128 (sizeof_address + 1, 0); + /* DW_LNE_set_address */ + len += 1 + sizeof_address; + } + else + /* DW_LNS_fixed_advance_pc */ + len += 3; + + if (line_delta == INT_MAX) + /* DW_LNS_extended_op + DW_LNE_end_sequence */ + len += 3; + else + /* DW_LNS_copy */ + len += 1; + + return len; +} + +static void +emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag, + char *p, int len) +{ + expressionS *pexp; + char *end = p + len; + + /* Line number sequences cannot go backward in addresses. This means + we've incorrectly ordered the statements in the sequence. */ + gas_assert ((offsetT) addr_delta >= 0); + + /* Verify that we have kept in sync with size_fixed_inc_line_addr. */ + gas_assert (len == size_fixed_inc_line_addr (line_delta, addr_delta)); + + /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence. */ + if (line_delta != INT_MAX) + { + *p++ = DW_LNS_advance_line; + p += output_leb128 (p, line_delta, 1); + } + + pexp = symbol_get_value_expression (frag->fr_symbol); + + /* The DW_LNS_fixed_advance_pc opcode has a 2-byte operand so it can + advance the address by at most 64K. Linker relaxation (without + which this function would not be used) could change the operand by + an unknown amount. If the address increment is getting close to + the limit, just reset the address. */ + if (addr_delta > ADDR_DELTA_LIMIT) + { + symbolS *to_sym; + expressionS exp; + + gas_assert (pexp->X_op == O_subtract); + to_sym = pexp->X_add_symbol; + + *p++ = DW_LNS_extended_op; + p += output_leb128 (p, sizeof_address + 1, 0); + *p++ = DW_LNE_set_address; + exp.X_op = O_symbol; + exp.X_add_symbol = to_sym; + exp.X_add_number = 0; + emit_expr_fix (&exp, sizeof_address, frag, p); + p += sizeof_address; + } + else + { + *p++ = DW_LNS_fixed_advance_pc; + emit_expr_fix (pexp, 2, frag, p); + p += 2; + } + + if (line_delta == INT_MAX) + { + *p++ = DW_LNS_extended_op; + *p++ = 1; + *p++ = DW_LNE_end_sequence; + } + else + *p++ = DW_LNS_copy; + + gas_assert (p == end); +} + +/* Generate a variant frag that we can use to relax address/line + increments between fragments of the target segment. */ + +static void +relax_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym) +{ + expressionS exp; + int max_chars; + + exp.X_op = O_subtract; + exp.X_add_symbol = to_sym; + exp.X_op_symbol = from_sym; + exp.X_add_number = 0; + + /* The maximum size of the frag is the line delta with a maximum + sized address delta. */ + if (DWARF2_USE_FIXED_ADVANCE_PC) + max_chars = size_fixed_inc_line_addr (line_delta, + -DWARF2_LINE_MIN_INSN_LENGTH); + else + max_chars = size_inc_line_addr (line_delta, -DWARF2_LINE_MIN_INSN_LENGTH); + + frag_var (rs_dwarf2dbg, max_chars, max_chars, 1, + make_expr_symbol (&exp), line_delta, NULL); +} + +/* The function estimates the size of a rs_dwarf2dbg variant frag + based on the current values of the symbols. It is called before + the relaxation loop. We set fr_subtype to the expected length. */ + +int +dwarf2dbg_estimate_size_before_relax (fragS *frag) +{ + offsetT addr_delta; + int size; + + addr_delta = resolve_symbol_value (frag->fr_symbol); + if (DWARF2_USE_FIXED_ADVANCE_PC) + size = size_fixed_inc_line_addr (frag->fr_offset, addr_delta); + else + size = size_inc_line_addr (frag->fr_offset, addr_delta); + + frag->fr_subtype = size; + + return size; +} + +/* This function relaxes a rs_dwarf2dbg variant frag based on the + current values of the symbols. fr_subtype is the current length + of the frag. This returns the change in frag length. */ + +int +dwarf2dbg_relax_frag (fragS *frag) +{ + int old_size, new_size; + + old_size = frag->fr_subtype; + new_size = dwarf2dbg_estimate_size_before_relax (frag); + + return new_size - old_size; +} + +/* This function converts a rs_dwarf2dbg variant frag into a normal + fill frag. This is called after all relaxation has been done. + fr_subtype will be the desired length of the frag. */ + +void +dwarf2dbg_convert_frag (fragS *frag) +{ + offsetT addr_diff; + + if (DWARF2_USE_FIXED_ADVANCE_PC) + { + /* If linker relaxation is enabled then the distance bewteen the two + symbols in the frag->fr_symbol expression might change. Hence we + cannot rely upon the value computed by resolve_symbol_value. + Instead we leave the expression unfinalized and allow + emit_fixed_inc_line_addr to create a fixup (which later becomes a + relocation) that will allow the linker to correctly compute the + actual address difference. We have to use a fixed line advance for + this as we cannot (easily) relocate leb128 encoded values. */ + int saved_finalize_syms = finalize_syms; + + finalize_syms = 0; + addr_diff = resolve_symbol_value (frag->fr_symbol); + finalize_syms = saved_finalize_syms; + } + else + addr_diff = resolve_symbol_value (frag->fr_symbol); + + /* fr_var carries the max_chars that we created the fragment with. + fr_subtype carries the current expected length. We must, of + course, have allocated enough memory earlier. */ + gas_assert (frag->fr_var >= (int) frag->fr_subtype); + + if (DWARF2_USE_FIXED_ADVANCE_PC) + emit_fixed_inc_line_addr (frag->fr_offset, addr_diff, frag, + frag->fr_literal + frag->fr_fix, + frag->fr_subtype); + else + emit_inc_line_addr (frag->fr_offset, addr_diff, + frag->fr_literal + frag->fr_fix, frag->fr_subtype); + + frag->fr_fix += frag->fr_subtype; + frag->fr_type = rs_fill; + frag->fr_var = 0; + frag->fr_offset = 0; +} + +/* Generate .debug_line content for the chain of line number entries + beginning at E, for segment SEG. */ + +static void +process_entries (segT seg, struct line_entry *e) +{ + unsigned filenum = 1; + unsigned line = 1; + unsigned column = 0; + unsigned isa = 0; + unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; + fragS *last_frag = NULL, *frag; + addressT last_frag_ofs = 0, frag_ofs; + symbolS *last_lab = NULL, *lab; + struct line_entry *next; + + if (flag_dwarf_sections) + { + char * name; + const char * sec_name; + + /* Switch to the relevent sub-section before we start to emit + the line number table. + + FIXME: These sub-sections do not have a normal Line Number + Program Header, thus strictly speaking they are not valid + DWARF sections. Unfortunately the DWARF standard assumes + a one-to-one relationship between compilation units and + line number tables. Thus we have to have a .debug_line + section, as well as our sub-sections, and we have to ensure + that all of the sub-sections are merged into a proper + .debug_line section before a debugger sees them. */ + + sec_name = bfd_get_section_name (stdoutput, seg); + if (strcmp (sec_name, ".text") != 0) + { + unsigned int len; + + len = strlen (sec_name); + name = xmalloc (len + 11 + 2); + sprintf (name, ".debug_line%s", sec_name); + subseg_set (subseg_get (name, FALSE), 0); + } + else + /* Don't create a .debug_line.text section - + that is redundant. Instead just switch back to the + normal .debug_line section. */ + subseg_set (subseg_get (".debug_line", FALSE), 0); + } + + do + { + int line_delta; + + if (filenum != e->loc.filenum) + { + filenum = e->loc.filenum; + out_opcode (DW_LNS_set_file); + out_uleb128 (filenum); + } + + if (column != e->loc.column) + { + column = e->loc.column; + out_opcode (DW_LNS_set_column); + out_uleb128 (column); + } + + if (e->loc.discriminator != 0) + { + out_opcode (DW_LNS_extended_op); + out_leb128 (1 + sizeof_leb128 (e->loc.discriminator, 0)); + out_opcode (DW_LNE_set_discriminator); + out_uleb128 (e->loc.discriminator); + } + + if (isa != e->loc.isa) + { + isa = e->loc.isa; + out_opcode (DW_LNS_set_isa); + out_uleb128 (isa); + } + + if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT) + { + flags = e->loc.flags; + out_opcode (DW_LNS_negate_stmt); + } + + if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK) + out_opcode (DW_LNS_set_basic_block); + + if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END) + out_opcode (DW_LNS_set_prologue_end); + + if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN) + out_opcode (DW_LNS_set_epilogue_begin); + + /* Don't try to optimize away redundant entries; gdb wants two + entries for a function where the code starts on the same line as + the {, and there's no way to identify that case here. Trust gcc + to optimize appropriately. */ + line_delta = e->loc.line - line; + lab = e->label; + frag = symbol_get_frag (lab); + frag_ofs = S_GET_VALUE (lab); + + if (last_frag == NULL) + { + out_set_addr (lab); + out_inc_line_addr (line_delta, 0); + } + else if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC) + out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs); + else + relax_inc_line_addr (line_delta, lab, last_lab); + + line = e->loc.line; + last_lab = lab; + last_frag = frag; + last_frag_ofs = frag_ofs; + + next = e->next; + free (e); + e = next; + } + while (e); + + /* Emit a DW_LNE_end_sequence for the end of the section. */ + frag = last_frag_for_seg (seg); + frag_ofs = get_frag_fix (frag, seg); + if (frag == last_frag && ! DWARF2_USE_FIXED_ADVANCE_PC) + out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs); + else + { + lab = symbol_temp_new (seg, frag_ofs, frag); + relax_inc_line_addr (INT_MAX, lab, last_lab); + } +} + +/* Emit the directory and file tables for .debug_line. */ + +static void +out_file_list (void) +{ + size_t size; + const char *dir; + char *cp; + unsigned int i; + + /* Emit directory list. */ + for (i = 1; i < dirs_in_use; ++i) + { + dir = remap_debug_filename (dirs[i]); + size = strlen (dir) + 1; + cp = frag_more (size); + memcpy (cp, dir, size); + } + /* Terminate it. */ + out_byte ('\0'); + + for (i = 1; i < files_in_use; ++i) + { + const char *fullfilename; + + if (files[i].filename == NULL) + { + as_bad (_("unassigned file number %ld"), (long) i); + /* Prevent a crash later, particularly for file 1. */ + files[i].filename = ""; + continue; + } + + fullfilename = DWARF2_FILE_NAME (files[i].filename, + files[i].dir ? dirs [files [i].dir] : ""); + size = strlen (fullfilename) + 1; + cp = frag_more (size); + memcpy (cp, fullfilename, size); + + out_uleb128 (files[i].dir); /* directory number */ + /* Output the last modification timestamp. */ + out_uleb128 (DWARF2_FILE_TIME_NAME (files[i].filename, + files[i].dir ? dirs [files [i].dir] : "")); + /* Output the filesize. */ + out_uleb128 (DWARF2_FILE_SIZE_NAME (files[i].filename, + files[i].dir ? dirs [files [i].dir] : "")); + } + + /* Terminate filename list. */ + out_byte (0); +} + +/* Switch to SEC and output a header length field. Return the size of + offsets used in SEC. The caller must set EXPR->X_add_symbol value + to the end of the section. */ + +static int +out_header (asection *sec, expressionS *exp) +{ + symbolS *start_sym; + symbolS *end_sym; + + subseg_set (sec, 0); + start_sym = symbol_temp_new_now (); + end_sym = symbol_temp_make (); + + /* Total length of the information. */ + exp->X_op = O_subtract; + exp->X_add_symbol = end_sym; + exp->X_op_symbol = start_sym; + + switch (DWARF2_FORMAT (sec)) + { + case dwarf2_format_32bit: + exp->X_add_number = -4; + emit_expr (exp, 4); + return 4; + + case dwarf2_format_64bit: + exp->X_add_number = -12; + out_four (-1); + emit_expr (exp, 8); + return 8; + + case dwarf2_format_64bit_irix: + exp->X_add_number = -8; + emit_expr (exp, 8); + return 8; + } + + as_fatal (_("internal error: unknown dwarf2 format")); + return 0; +} + +/* Emit the collected .debug_line data. */ + +static void +out_debug_line (segT line_seg) +{ + expressionS exp; + symbolS *prologue_end; + symbolS *line_end; + struct line_seg *s; + int sizeof_offset; + + sizeof_offset = out_header (line_seg, &exp); + line_end = exp.X_add_symbol; + + /* Version. */ + out_two (DWARF2_LINE_VERSION); + + /* Length of the prologue following this length. */ + prologue_end = symbol_temp_make (); + exp.X_add_symbol = prologue_end; + exp.X_add_number = - (4 + 2 + 4); + emit_expr (&exp, sizeof_offset); + + /* Parameters of the state machine. */ + out_byte (DWARF2_LINE_MIN_INSN_LENGTH); + out_byte (DWARF2_LINE_DEFAULT_IS_STMT); + out_byte (DWARF2_LINE_BASE); + out_byte (DWARF2_LINE_RANGE); + out_byte (DWARF2_LINE_OPCODE_BASE); + + /* Standard opcode lengths. */ + out_byte (0); /* DW_LNS_copy */ + out_byte (1); /* DW_LNS_advance_pc */ + out_byte (1); /* DW_LNS_advance_line */ + out_byte (1); /* DW_LNS_set_file */ + out_byte (1); /* DW_LNS_set_column */ + out_byte (0); /* DW_LNS_negate_stmt */ + out_byte (0); /* DW_LNS_set_basic_block */ + out_byte (0); /* DW_LNS_const_add_pc */ + out_byte (1); /* DW_LNS_fixed_advance_pc */ + out_byte (0); /* DW_LNS_set_prologue_end */ + out_byte (0); /* DW_LNS_set_epilogue_begin */ + out_byte (1); /* DW_LNS_set_isa */ + + out_file_list (); + + symbol_set_value_now (prologue_end); + + /* For each section, emit a statement program. */ + for (s = all_segs; s; s = s->next) + if (SEG_NORMAL (s->seg)) + process_entries (s->seg, s->head->head); + else + as_warn ("dwarf line number information for %s ignored", + segment_name (s->seg)); + + if (flag_dwarf_sections) + /* We have to switch to the special .debug_line_end section + before emitting the end-of-debug_line symbol. The linker + script arranges for this section to be placed after all the + (potentially garbage collected) .debug_line. sections. + This section contains the line_end symbol which is used to + compute the size of the linked .debug_line section, as seen + in the DWARF Line Number header. */ + subseg_set (subseg_get (".debug_line_end", FALSE), 0); + + symbol_set_value_now (line_end); +} + +static void +out_debug_ranges (segT ranges_seg) +{ + unsigned int addr_size = sizeof_address; + struct line_seg *s; + expressionS exp; + unsigned int i; + + subseg_set (ranges_seg, 0); + + /* Base Address Entry. */ + for (i = 0; i < addr_size; i++) + out_byte (0xff); + for (i = 0; i < addr_size; i++) + out_byte (0); + + /* Range List Entry. */ + for (s = all_segs; s; s = s->next) + { + fragS *frag; + symbolS *beg, *end; + + frag = first_frag_for_seg (s->seg); + beg = symbol_temp_new (s->seg, 0, frag); + s->text_start = beg; + + frag = last_frag_for_seg (s->seg); + end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag); + s->text_end = end; + + exp.X_op = O_symbol; + exp.X_add_symbol = beg; + exp.X_add_number = 0; + emit_expr (&exp, addr_size); + + exp.X_op = O_symbol; + exp.X_add_symbol = end; + exp.X_add_number = 0; + emit_expr (&exp, addr_size); + } + + /* End of Range Entry. */ + for (i = 0; i < addr_size; i++) + out_byte (0); + for (i = 0; i < addr_size; i++) + out_byte (0); +} + +/* Emit data for .debug_aranges. */ + +static void +out_debug_aranges (segT aranges_seg, segT info_seg) +{ + unsigned int addr_size = sizeof_address; + struct line_seg *s; + expressionS exp; + symbolS *aranges_end; + char *p; + int sizeof_offset; + + sizeof_offset = out_header (aranges_seg, &exp); + aranges_end = exp.X_add_symbol; + + /* Version. */ + out_two (DWARF2_ARANGES_VERSION); + + /* Offset to .debug_info. */ + TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), sizeof_offset); + + /* Size of an address (offset portion). */ + out_byte (addr_size); + + /* Size of a segment descriptor. */ + out_byte (0); + + /* Align the header. */ + frag_align (ffs (2 * addr_size) - 1, 0, 0); + + for (s = all_segs; s; s = s->next) + { + fragS *frag; + symbolS *beg, *end; + + frag = first_frag_for_seg (s->seg); + beg = symbol_temp_new (s->seg, 0, frag); + s->text_start = beg; + + frag = last_frag_for_seg (s->seg); + end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag); + s->text_end = end; + + exp.X_op = O_symbol; + exp.X_add_symbol = beg; + exp.X_add_number = 0; + emit_expr (&exp, addr_size); + + exp.X_op = O_subtract; + exp.X_add_symbol = end; + exp.X_op_symbol = beg; + exp.X_add_number = 0; + emit_expr (&exp, addr_size); + } + + p = frag_more (2 * addr_size); + md_number_to_chars (p, 0, addr_size); + md_number_to_chars (p + addr_size, 0, addr_size); + + symbol_set_value_now (aranges_end); +} + +/* Emit data for .debug_abbrev. Note that this must be kept in + sync with out_debug_info below. */ + +static void +out_debug_abbrev (segT abbrev_seg, + segT info_seg ATTRIBUTE_UNUSED, + segT line_seg ATTRIBUTE_UNUSED) +{ + subseg_set (abbrev_seg, 0); + + out_uleb128 (1); + out_uleb128 (DW_TAG_compile_unit); + out_byte (DW_CHILDREN_no); + if (DWARF2_FORMAT (line_seg) == dwarf2_format_32bit) + out_abbrev (DW_AT_stmt_list, DW_FORM_data4); + else + out_abbrev (DW_AT_stmt_list, DW_FORM_data8); + if (all_segs->next == NULL) + { + out_abbrev (DW_AT_low_pc, DW_FORM_addr); + if (DWARF2_VERSION < 4) + out_abbrev (DW_AT_high_pc, DW_FORM_addr); + else + out_abbrev (DW_AT_high_pc, (sizeof_address == 4 + ? DW_FORM_data4 : DW_FORM_data8)); + } + else + { + if (DWARF2_FORMAT (info_seg) == dwarf2_format_32bit) + out_abbrev (DW_AT_ranges, DW_FORM_data4); + else + out_abbrev (DW_AT_ranges, DW_FORM_data8); + } + out_abbrev (DW_AT_name, DW_FORM_string); + out_abbrev (DW_AT_comp_dir, DW_FORM_string); + out_abbrev (DW_AT_producer, DW_FORM_string); + out_abbrev (DW_AT_language, DW_FORM_data2); + out_abbrev (0, 0); + + /* Terminate the abbreviations for this compilation unit. */ + out_byte (0); +} + +/* Emit a description of this compilation unit for .debug_info. */ + +static void +out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg) +{ + char producer[128]; + const char *comp_dir; + const char *dirname; + expressionS exp; + symbolS *info_end; + char *p; + int len; + int sizeof_offset; + + sizeof_offset = out_header (info_seg, &exp); + info_end = exp.X_add_symbol; + + /* DWARF version. */ + out_two (DWARF2_VERSION); + + /* .debug_abbrev offset */ + TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); + + /* Target address size. */ + out_byte (sizeof_address); + + /* DW_TAG_compile_unit DIE abbrev */ + out_uleb128 (1); + + /* DW_AT_stmt_list */ + TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), + (DWARF2_FORMAT (line_seg) == dwarf2_format_32bit + ? 4 : 8)); + + /* These two attributes are emitted if all of the code is contiguous. */ + if (all_segs->next == NULL) + { + /* DW_AT_low_pc */ + exp.X_op = O_symbol; + exp.X_add_symbol = all_segs->text_start; + exp.X_add_number = 0; + emit_expr (&exp, sizeof_address); + + /* DW_AT_high_pc */ + if (DWARF2_VERSION < 4) + exp.X_op = O_symbol; + else + { + exp.X_op = O_subtract; + exp.X_op_symbol = all_segs->text_start; + } + exp.X_add_symbol = all_segs->text_end; + exp.X_add_number = 0; + emit_expr (&exp, sizeof_address); + } + else + { + /* This attribute is emitted if the code is disjoint. */ + /* DW_AT_ranges. */ + TC_DWARF2_EMIT_OFFSET (section_symbol (ranges_seg), sizeof_offset); + } + + /* DW_AT_name. We don't have the actual file name that was present + on the command line, so assume files[1] is the main input file. + We're not supposed to get called unless at least one line number + entry was emitted, so this should always be defined. */ + if (files_in_use == 0) + abort (); + if (files[1].dir) + { + dirname = remap_debug_filename (dirs[files[1].dir]); + len = strlen (dirname); +#ifdef TE_VMS + /* Already has trailing slash. */ + p = frag_more (len); + memcpy (p, dirname, len); +#else + p = frag_more (len + 1); + memcpy (p, dirname, len); + INSERT_DIR_SEPARATOR (p, len); +#endif + } + len = strlen (files[1].filename) + 1; + p = frag_more (len); + memcpy (p, files[1].filename, len); + + /* DW_AT_comp_dir */ + comp_dir = remap_debug_filename (getpwd ()); + len = strlen (comp_dir) + 1; + p = frag_more (len); + memcpy (p, comp_dir, len); + + /* DW_AT_producer */ + sprintf (producer, "GNU AS %s", VERSION); + len = strlen (producer) + 1; + p = frag_more (len); + memcpy (p, producer, len); + + /* DW_AT_language. Yes, this is probably not really MIPS, but the + dwarf2 draft has no standard code for assembler. */ + out_two (DW_LANG_Mips_Assembler); + + symbol_set_value_now (info_end); +} + +void +dwarf2_init (void) +{ + all_segs_hash = hash_new (); + last_seg_ptr = &all_segs; +} + + +/* Finish the dwarf2 debug sections. We emit .debug.line if there + were any .file/.loc directives, or --gdwarf2 was given, or if the + file has a non-empty .debug_info section and an empty .debug_line + section. If we emit .debug_line, and the .debug_info section is + empty, we also emit .debug_info, .debug_aranges and .debug_abbrev. + ALL_SEGS will be non-null if there were any .file/.loc directives, + or --gdwarf2 was given and there were any located instructions + emitted. */ + +void +dwarf2_finish (void) +{ + segT line_seg; + struct line_seg *s; + segT info_seg; + int emit_other_sections = 0; + int empty_debug_line = 0; + + info_seg = bfd_get_section_by_name (stdoutput, ".debug_info"); + emit_other_sections = info_seg == NULL || !seg_not_empty_p (info_seg); + + line_seg = bfd_get_section_by_name (stdoutput, ".debug_line"); + empty_debug_line = line_seg == NULL || !seg_not_empty_p (line_seg); + + /* We can't construct a new debug_line section if we already have one. + Give an error. */ + if (all_segs && !empty_debug_line) + as_fatal ("duplicate .debug_line sections"); + + if ((!all_segs && emit_other_sections) + || (!emit_other_sections && !empty_debug_line)) + /* If there is no line information and no non-empty .debug_info + section, or if there is both a non-empty .debug_info and a non-empty + .debug_line, then we do nothing. */ + return; + + /* Calculate the size of an address for the target machine. */ + sizeof_address = DWARF2_ADDR_SIZE (stdoutput); + + /* Create and switch to the line number section. */ + line_seg = subseg_new (".debug_line", 0); + bfd_set_section_flags (stdoutput, line_seg, SEC_READONLY | SEC_DEBUGGING); + + /* For each subsection, chain the debug entries together. */ + for (s = all_segs; s; s = s->next) + { + struct line_subseg *lss = s->head; + struct line_entry **ptail = lss->ptail; + + while ((lss = lss->next) != NULL) + { + *ptail = lss->head; + ptail = lss->ptail; + } + } + + out_debug_line (line_seg); + + /* If this is assembler generated line info, and there is no + debug_info already, we need .debug_info and .debug_abbrev + sections as well. */ + if (emit_other_sections) + { + segT abbrev_seg; + segT aranges_seg; + segT ranges_seg; + + gas_assert (all_segs); + + info_seg = subseg_new (".debug_info", 0); + abbrev_seg = subseg_new (".debug_abbrev", 0); + aranges_seg = subseg_new (".debug_aranges", 0); + + bfd_set_section_flags (stdoutput, info_seg, + SEC_READONLY | SEC_DEBUGGING); + bfd_set_section_flags (stdoutput, abbrev_seg, + SEC_READONLY | SEC_DEBUGGING); + bfd_set_section_flags (stdoutput, aranges_seg, + SEC_READONLY | SEC_DEBUGGING); + + record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1); + + if (all_segs->next == NULL) + ranges_seg = NULL; + else + { + ranges_seg = subseg_new (".debug_ranges", 0); + bfd_set_section_flags (stdoutput, ranges_seg, + SEC_READONLY | SEC_DEBUGGING); + record_alignment (ranges_seg, ffs (2 * sizeof_address) - 1); + out_debug_ranges (ranges_seg); + } + + out_debug_aranges (aranges_seg, info_seg); + out_debug_abbrev (abbrev_seg, info_seg, line_seg); + out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg); + } +} diff --git a/contrib/toolchain/binutils/gas/dwarf2dbg.h b/contrib/toolchain/binutils/gas/dwarf2dbg.h new file mode 100644 index 0000000000..84ef8f6d52 --- /dev/null +++ b/contrib/toolchain/binutils/gas/dwarf2dbg.h @@ -0,0 +1,116 @@ +/* dwarf2dbg.h - DWARF2 debug support + Copyright 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2009 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef AS_DWARF2DBG_H +#define AS_DWARF2DBG_H + +#include "as.h" + +#define DWARF2_FLAG_IS_STMT (1 << 0) +#define DWARF2_FLAG_BASIC_BLOCK (1 << 1) +#define DWARF2_FLAG_PROLOGUE_END (1 << 2) +#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3) + +struct dwarf2_line_info { + unsigned int filenum; + unsigned int line; + unsigned int column; + unsigned int isa; + unsigned int flags; + unsigned int discriminator; +}; + +/* Implements the .file FILENO "FILENAME" directive. FILENO can be 0 + to indicate that no file number has been assigned. All real file + number must be >0. */ +extern char *dwarf2_directive_file (int dummy); + +/* Implements the .loc FILENO LINENO [COLUMN] directive. FILENO is + the file number, LINENO the line number and the (optional) COLUMN + the column of the source code that the following instruction + corresponds to. FILENO can be 0 to indicate that the filename + specified by the textually most recent .file directive should be + used. */ +extern void dwarf2_directive_loc (int dummy); + +/* Implements the .loc_mark_labels {0,1} directive. */ +extern void dwarf2_directive_loc_mark_labels (int dummy); + +/* Returns the current source information. If .file directives have + been encountered, the info for the corresponding source file is + returned. Otherwise, the info for the assembly source file is + returned. */ +extern void dwarf2_where (struct dwarf2_line_info *l); + +/* A hook to allow the target backend to inform the line number state + machine of isa changes when assembler debug info is enabled. */ +extern void dwarf2_set_isa (unsigned int isa); + +/* This function generates .debug_line info based on the address and + source information passed in the arguments. ADDR should be the + frag-relative offset of the instruction the information is for and + L is the source information that should be associated with that + address. */ +extern void dwarf2_gen_line_info (addressT addr, struct dwarf2_line_info *l); + +/* Must be called for each generated instruction. */ +extern void dwarf2_emit_insn (int); + +void dwarf2_move_insn (int); + +/* Reset the state of the line number information to reflect that + it has been used. */ +extern void dwarf2_consume_line_info (void); + +/* Should be called for each code label. */ +extern void dwarf2_emit_label (symbolS *); + +/* True when we've seen a .loc directive recently. Used to avoid + doing work when there's nothing to do. */ +extern bfd_boolean dwarf2_loc_directive_seen; + +/* True when we're supposed to set the basic block mark whenever a label + is seen. Unless the target is doing Something Weird, just call + dwarf2_emit_label. */ +extern bfd_boolean dwarf2_loc_mark_labels; + +extern void dwarf2_init (void); + +extern void dwarf2_finish (void); + +extern int dwarf2dbg_estimate_size_before_relax (fragS *); +extern int dwarf2dbg_relax_frag (fragS *); +extern void dwarf2dbg_convert_frag (fragS *); + +/* An enumeration which describes the sizes of offsets (to DWARF sections) + and the mechanism by which the size is indicated. */ +enum dwarf2_format { + /* 32-bit format: the initial length field is 4 bytes long. */ + dwarf2_format_32bit, + /* DWARF3 64-bit format: the representation of the initial length + (of a DWARF section) is 0xffffffff (4 bytes) followed by eight + bytes indicating the actual length. */ + dwarf2_format_64bit, + /* SGI extension to DWARF2: The initial length is eight bytes. */ + dwarf2_format_64bit_irix +}; + +#endif /* AS_DWARF2DBG_H */ diff --git a/contrib/toolchain/binutils/gas/ecoff.c b/contrib/toolchain/binutils/gas/ecoff.c new file mode 100644 index 0000000000..821b02ce7d --- /dev/null +++ b/contrib/toolchain/binutils/gas/ecoff.c @@ -0,0 +1,5244 @@ +/* ECOFF debugging support. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 + Free Software Foundation, Inc. + Contributed by Cygnus Support. + This file was put together by Ian Lance Taylor . A + good deal of it comes directly from mips-tfile.c, by Michael + Meissner . + + This file is part of GAS. + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" + +/* This file is compiled conditionally for those targets which use + ECOFF debugging information (e.g., MIPS ELF, Alpha ECOFF). */ + +#include "ecoff.h" + +#ifdef ECOFF_DEBUGGING + +#include "coff/internal.h" +#include "coff/symconst.h" +#include "aout/stab_gnu.h" +#include "filenames.h" +#include "safe-ctype.h" + +/* Why isn't this in coff/sym.h? */ +#define ST_RFDESCAPE 0xfff + +/* This file constructs the information used by the ECOFF debugging + format. It just builds a large block of data. + + We support both ECOFF style debugging and stabs debugging (the + stabs symbols are encapsulated in ECOFF symbols). This should let + us handle anything the compiler might throw at us. */ + +/* Here is a brief description of the MIPS ECOFF symbol table, by + Michael Meissner. The MIPS symbol table has the following pieces: + + Symbolic Header + | + +-- Auxiliary Symbols + | + +-- Dense number table + | + +-- Optimizer Symbols + | + +-- External Strings + | + +-- External Symbols + | + +-- Relative file descriptors + | + +-- File table + | + +-- Procedure table + | + +-- Line number table + | + +-- Local Strings + | + +-- Local Symbols + + The symbolic header points to each of the other tables, and also + contains the number of entries. It also contains a magic number + and MIPS compiler version number, such as 2.0. + + The auxiliary table is a series of 32 bit integers, that are + referenced as needed from the local symbol table. Unlike standard + COFF, the aux. information does not follow the symbol that uses + it, but rather is a separate table. In theory, this would allow + the MIPS compilers to collapse duplicate aux. entries, but I've not + noticed this happening with the 1.31 compiler suite. The different + types of aux. entries are: + + 1) dnLow: Low bound on array dimension. + + 2) dnHigh: High bound on array dimension. + + 3) isym: Index to the local symbol which is the start of the + function for the end of function first aux. entry. + + 4) width: Width of structures and bitfields. + + 5) count: Count of ranges for variant part. + + 6) rndx: A relative index into the symbol table. The relative + index field has two parts: rfd which is a pointer into the + relative file index table or ST_RFDESCAPE which says the next + aux. entry is the file number, and index: which is the pointer + into the local symbol within a given file table. This is for + things like references to types defined in another file. + + 7) Type information: This is like the COFF type bits, except it + is 32 bits instead of 16; they still have room to add new + basic types; and they can handle more than 6 levels of array, + pointer, function, etc. Each type information field contains + the following structure members: + + a) fBitfield: a bit that says this is a bitfield, and the + size in bits follows as the next aux. entry. + + b) continued: a bit that says the next aux. entry is a + continuation of the current type information (in case + there are more than 6 levels of array/ptr/function). + + c) bt: an integer containing the base type before adding + array, pointer, function, etc. qualifiers. The + current base types that I have documentation for are: + + btNil -- undefined + btAdr -- address - integer same size as ptr + btChar -- character + btUChar -- unsigned character + btShort -- short + btUShort -- unsigned short + btInt -- int + btUInt -- unsigned int + btLong -- long + btULong -- unsigned long + btFloat -- float (real) + btDouble -- Double (real) + btStruct -- Structure (Record) + btUnion -- Union (variant) + btEnum -- Enumerated + btTypedef -- defined via a typedef isymRef + btRange -- subrange of int + btSet -- pascal sets + btComplex -- fortran complex + btDComplex -- fortran double complex + btIndirect -- forward or unnamed typedef + btFixedDec -- Fixed Decimal + btFloatDec -- Float Decimal + btString -- Varying Length Character String + btBit -- Aligned Bit String + btPicture -- Picture + btVoid -- Void (MIPS cc revision >= 2.00) + + d) tq0 - tq5: type qualifier fields as needed. The + current type qualifier fields I have documentation for + are: + + tqNil -- no more qualifiers + tqPtr -- pointer + tqProc -- procedure + tqArray -- array + tqFar -- 8086 far pointers + tqVol -- volatile + + The dense number table is used in the front ends, and disappears by + the time the .o is created. + + With the 1.31 compiler suite, the optimization symbols don't seem + to be used as far as I can tell. + + The linker is the first entity that creates the relative file + descriptor table, and I believe it is used so that the individual + file table pointers don't have to be rewritten when the objects are + merged together into the program file. + + Unlike COFF, the basic symbol & string tables are split into + external and local symbols/strings. The relocation information + only goes off of the external symbol table, and the debug + information only goes off of the internal symbol table. The + external symbols can have links to an appropriate file index and + symbol within the file to give it the appropriate type information. + Because of this, the external symbols are actually larger than the + internal symbols (to contain the link information), and contain the + local symbol structure as a member, though this member is not the + first member of the external symbol structure (!). I suspect this + split is to make strip easier to deal with. + + Each file table has offsets for where the line numbers, local + strings, local symbols, and procedure table starts from within the + global tables, and the indexs are reset to 0 for each of those + tables for the file. + + The procedure table contains the binary equivalents of the .ent + (start of the function address), .frame (what register is the + virtual frame pointer, constant offset from the register to obtain + the VFP, and what register holds the return address), .mask/.fmask + (bitmask of saved registers, and where the first register is stored + relative to the VFP) assembler directives. It also contains the + low and high bounds of the line numbers if debugging is turned on. + + The line number table is a compressed form of the normal COFF line + table. Each line number entry is either 1 or 3 bytes long, and + contains a signed delta from the previous line, and an unsigned + count of the number of instructions this statement takes. + + The local symbol table contains the following fields: + + 1) iss: index to the local string table giving the name of the + symbol. + + 2) value: value of the symbol (address, register number, etc.). + + 3) st: symbol type. The current symbol types are: + + stNil -- Nuthin' special + stGlobal -- external symbol + stStatic -- static + stParam -- procedure argument + stLocal -- local variable + stLabel -- label + stProc -- External Procedure + stBlock -- beginning of block + stEnd -- end (of anything) + stMember -- member (of anything) + stTypedef -- type definition + stFile -- file name + stRegReloc -- register relocation + stForward -- forwarding address + stStaticProc -- Static procedure + stConstant -- const + + 4) sc: storage class. The current storage classes are: + + scText -- text symbol + scData -- initialized data symbol + scBss -- un-initialized data symbol + scRegister -- value of symbol is register number + scAbs -- value of symbol is absolute + scUndefined -- who knows? + scCdbLocal -- variable's value is IN se->va.?? + scBits -- this is a bit field + scCdbSystem -- value is IN debugger's address space + scRegImage -- register value saved on stack + scInfo -- symbol contains debugger information + scUserStruct -- addr in struct user for current process + scSData -- load time only small data + scSBss -- load time only small common + scRData -- load time only read only data + scVar -- Var parameter (fortranpascal) + scCommon -- common variable + scSCommon -- small common + scVarRegister -- Var parameter in a register + scVariant -- Variant record + scSUndefined -- small undefined(external) data + scInit -- .init section symbol + + 5) index: pointer to a local symbol or aux. entry. + + For the following program: + + #include + + main(){ + printf("Hello World!\n"); + return 0; + } + + Mips-tdump produces the following information: + + Global file header: + magic number 0x162 + # sections 2 + timestamp 645311799, Wed Jun 13 17:16:39 1990 + symbolic header offset 284 + symbolic header size 96 + optional header 56 + flags 0x0 + + Symbolic header, magic number = 0x7009, vstamp = 1.31: + + Info Offset Number Bytes + ==== ====== ====== ===== + + Line numbers 380 4 4 [13] + Dense numbers 0 0 0 + Procedures Tables 384 1 52 + Local Symbols 436 16 192 + Optimization Symbols 0 0 0 + Auxiliary Symbols 628 39 156 + Local Strings 784 80 80 + External Strings 864 144 144 + File Tables 1008 2 144 + Relative Files 0 0 0 + External Symbols 1152 20 320 + + File #0, "hello2.c" + + Name index = 1 Readin = No + Merge = No Endian = LITTLE + Debug level = G2 Language = C + Adr = 0x00000000 + + Info Start Number Size Offset + ==== ===== ====== ==== ====== + Local strings 0 15 15 784 + Local symbols 0 6 72 436 + Line numbers 0 13 13 380 + Optimization symbols 0 0 0 0 + Procedures 0 1 52 384 + Auxiliary symbols 0 14 56 628 + Relative Files 0 0 0 0 + + There are 6 local symbols, starting at 436 + + Symbol# 0: "hello2.c" + End+1 symbol = 6 + String index = 1 + Storage class = Text Index = 6 + Symbol type = File Value = 0 + + Symbol# 1: "main" + End+1 symbol = 5 + Type = int + String index = 10 + Storage class = Text Index = 12 + Symbol type = Proc Value = 0 + + Symbol# 2: "" + End+1 symbol = 4 + String index = 0 + Storage class = Text Index = 4 + Symbol type = Block Value = 8 + + Symbol# 3: "" + First symbol = 2 + String index = 0 + Storage class = Text Index = 2 + Symbol type = End Value = 28 + + Symbol# 4: "main" + First symbol = 1 + String index = 10 + Storage class = Text Index = 1 + Symbol type = End Value = 52 + + Symbol# 5: "hello2.c" + First symbol = 0 + String index = 1 + Storage class = Text Index = 0 + Symbol type = End Value = 0 + + There are 14 auxiliary table entries, starting at 628. + + * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] + * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0] + * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0] + * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] + * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0] + * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0] + * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0] + * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0] + * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0] + * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0] + * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0] + #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0] + #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] + + There are 1 procedure descriptor entries, starting at 0. + + Procedure descriptor 0: + Name index = 10 Name = "main" + .mask 0x80000000,-4 .fmask 0x00000000,0 + .frame $29,24,$31 + Opt. start = -1 Symbols start = 1 + First line # = 3 Last line # = 6 + Line Offset = 0 Address = 0x00000000 + + There are 4 bytes holding line numbers, starting at 380. + Line 3, delta 0, count 2 + Line 4, delta 1, count 3 + Line 5, delta 1, count 2 + Line 6, delta 1, count 6 + + File #1, "/usr/include/stdio.h" + + Name index = 1 Readin = No + Merge = Yes Endian = LITTLE + Debug level = G2 Language = C + Adr = 0x00000000 + + Info Start Number Size Offset + ==== ===== ====== ==== ====== + Local strings 15 65 65 799 + Local symbols 6 10 120 508 + Line numbers 0 0 0 380 + Optimization symbols 0 0 0 0 + Procedures 1 0 0 436 + Auxiliary symbols 14 25 100 684 + Relative Files 0 0 0 0 + + There are 10 local symbols, starting at 442 + + Symbol# 0: "/usr/include/stdio.h" + End+1 symbol = 10 + String index = 1 + Storage class = Text Index = 10 + Symbol type = File Value = 0 + + Symbol# 1: "_iobuf" + End+1 symbol = 9 + String index = 22 + Storage class = Info Index = 9 + Symbol type = Block Value = 20 + + Symbol# 2: "_cnt" + Type = int + String index = 29 + Storage class = Info Index = 4 + Symbol type = Member Value = 0 + + Symbol# 3: "_ptr" + Type = ptr to char + String index = 34 + Storage class = Info Index = 15 + Symbol type = Member Value = 32 + + Symbol# 4: "_base" + Type = ptr to char + String index = 39 + Storage class = Info Index = 16 + Symbol type = Member Value = 64 + + Symbol# 5: "_bufsiz" + Type = int + String index = 45 + Storage class = Info Index = 4 + Symbol type = Member Value = 96 + + Symbol# 6: "_flag" + Type = short + String index = 53 + Storage class = Info Index = 3 + Symbol type = Member Value = 128 + + Symbol# 7: "_file" + Type = char + String index = 59 + Storage class = Info Index = 2 + Symbol type = Member Value = 144 + + Symbol# 8: "" + First symbol = 1 + String index = 0 + Storage class = Info Index = 1 + Symbol type = End Value = 0 + + Symbol# 9: "/usr/include/stdio.h" + First symbol = 0 + String index = 1 + Storage class = Text Index = 0 + Symbol type = End Value = 0 + + There are 25 auxiliary table entries, starting at 642. + + * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f] + #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0] + #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0] + * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0] + * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1] + * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0] + * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4] + * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0] + * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0] + * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0] + * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] + + There are 0 procedure descriptor entries, starting at 1. + + There are 20 external symbols, starting at 1152 + + Symbol# 0: "_iob" + Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 } + String index = 0 Ifd = 1 + Storage class = Nil Index = 17 + Symbol type = Global Value = 60 + + Symbol# 1: "fopen" + String index = 5 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 2: "fdopen" + String index = 11 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 3: "freopen" + String index = 18 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 4: "popen" + String index = 26 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 5: "tmpfile" + String index = 32 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 6: "ftell" + String index = 40 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 7: "rewind" + String index = 46 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 8: "setbuf" + String index = 53 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 9: "setbuffer" + String index = 60 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 10: "setlinebuf" + String index = 70 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 11: "fgets" + String index = 81 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 12: "gets" + String index = 87 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 13: "ctermid" + String index = 92 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 14: "cuserid" + String index = 100 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 15: "tempnam" + String index = 108 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 16: "tmpnam" + String index = 116 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 17: "sprintf" + String index = 123 Ifd = 1 + Storage class = Nil Index = 1048575 + Symbol type = Proc Value = 0 + + Symbol# 18: "main" + Type = int + String index = 131 Ifd = 0 + Storage class = Text Index = 1 + Symbol type = Proc Value = 0 + + Symbol# 19: "printf" + String index = 136 Ifd = 0 + Storage class = Undefined Index = 1048575 + Symbol type = Proc Value = 0 + + The following auxiliary table entries were unused: + + #0 0 0x00000000 void + #2 8 0x00000008 char + #3 16 0x00000010 short + #4 24 0x00000018 int + #5 32 0x00000020 long + #6 40 0x00000028 float + #7 44 0x0000002c double + #8 12 0x0000000c unsigned char + #9 20 0x00000014 unsigned short + #10 28 0x0000001c unsigned int + #11 36 0x00000024 unsigned long + #14 0 0x00000000 void + #15 24 0x00000018 int + #19 32 0x00000020 long + #20 40 0x00000028 float + #21 44 0x0000002c double + #22 12 0x0000000c unsigned char + #23 20 0x00000014 unsigned short + #24 28 0x0000001c unsigned int + #25 36 0x00000024 unsigned long + #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 } +*/ + +/* Redefinition of of storage classes as an enumeration for better + debugging. */ + +typedef enum sc { + sc_Nil = scNil, /* no storage class */ + sc_Text = scText, /* text symbol */ + sc_Data = scData, /* initialized data symbol */ + sc_Bss = scBss, /* un-initialized data symbol */ + sc_Register = scRegister, /* value of symbol is register number */ + sc_Abs = scAbs, /* value of symbol is absolute */ + sc_Undefined = scUndefined, /* who knows? */ + sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ + sc_Bits = scBits, /* this is a bit field */ + sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */ + sc_RegImage = scRegImage, /* register value saved on stack */ + sc_Info = scInfo, /* symbol contains debugger information */ + sc_UserStruct = scUserStruct, /* addr in struct user for current process */ + sc_SData = scSData, /* load time only small data */ + sc_SBss = scSBss, /* load time only small common */ + sc_RData = scRData, /* load time only read only data */ + sc_Var = scVar, /* Var parameter (fortran,pascal) */ + sc_Common = scCommon, /* common variable */ + sc_SCommon = scSCommon, /* small common */ + sc_VarRegister = scVarRegister, /* Var parameter in a register */ + sc_Variant = scVariant, /* Variant record */ + sc_SUndefined = scSUndefined, /* small undefined(external) data */ + sc_Init = scInit, /* .init section symbol */ + sc_Max = scMax /* Max storage class+1 */ +} sc_t; + +/* Redefinition of symbol type. */ + +typedef enum st { + st_Nil = stNil, /* Nuthin' special */ + st_Global = stGlobal, /* external symbol */ + st_Static = stStatic, /* static */ + st_Param = stParam, /* procedure argument */ + st_Local = stLocal, /* local variable */ + st_Label = stLabel, /* label */ + st_Proc = stProc, /* " " Procedure */ + st_Block = stBlock, /* beginning of block */ + st_End = stEnd, /* end (of anything) */ + st_Member = stMember, /* member (of anything - struct/union/enum */ + st_Typedef = stTypedef, /* type definition */ + st_File = stFile, /* file name */ + st_RegReloc = stRegReloc, /* register relocation */ + st_Forward = stForward, /* forwarding address */ + st_StaticProc = stStaticProc, /* load time only static procs */ + st_Constant = stConstant, /* const */ + st_Str = stStr, /* string */ + st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ + st_Expr = stExpr, /* 2+2 vs. 4 */ + st_Type = stType, /* post-coercion SER */ + st_Max = stMax /* max type+1 */ +} st_t; + +/* Redefinition of type qualifiers. */ + +typedef enum tq { + tq_Nil = tqNil, /* bt is what you see */ + tq_Ptr = tqPtr, /* pointer */ + tq_Proc = tqProc, /* procedure */ + tq_Array = tqArray, /* duh */ + tq_Far = tqFar, /* longer addressing - 8086/8 land */ + tq_Vol = tqVol, /* volatile */ + tq_Max = tqMax /* Max type qualifier+1 */ +} tq_t; + +/* Redefinition of basic types. */ + +typedef enum bt { + bt_Nil = btNil, /* undefined */ + bt_Adr = btAdr, /* address - integer same size as pointer */ + bt_Char = btChar, /* character */ + bt_UChar = btUChar, /* unsigned character */ + bt_Short = btShort, /* short */ + bt_UShort = btUShort, /* unsigned short */ + bt_Int = btInt, /* int */ + bt_UInt = btUInt, /* unsigned int */ + bt_Long = btLong, /* long */ + bt_ULong = btULong, /* unsigned long */ + bt_Float = btFloat, /* float (real) */ + bt_Double = btDouble, /* Double (real) */ + bt_Struct = btStruct, /* Structure (Record) */ + bt_Union = btUnion, /* Union (variant) */ + bt_Enum = btEnum, /* Enumerated */ + bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ + bt_Range = btRange, /* subrange of int */ + bt_Set = btSet, /* pascal sets */ + bt_Complex = btComplex, /* fortran complex */ + bt_DComplex = btDComplex, /* fortran double complex */ + bt_Indirect = btIndirect, /* forward or unnamed typedef */ + bt_FixedDec = btFixedDec, /* Fixed Decimal */ + bt_FloatDec = btFloatDec, /* Float Decimal */ + bt_String = btString, /* Varying Length Character String */ + bt_Bit = btBit, /* Aligned Bit String */ + bt_Picture = btPicture, /* Picture */ + bt_Void = btVoid, /* Void */ + bt_Max = btMax /* Max basic type+1 */ +} bt_t; + +#define N_TQ itqMax + +/* States for whether to hash type or not. */ +typedef enum hash_state { + hash_no = 0, /* Don't hash type */ + hash_yes = 1, /* OK to hash type, or use previous hash */ + hash_record = 2 /* OK to record hash, but don't use prev. */ +} hash_state_t; + +/* Types of different sized allocation requests. */ +enum alloc_type { + alloc_type_none, /* dummy value */ + alloc_type_scope, /* nested scopes linked list */ + alloc_type_vlinks, /* glue linking pages in varray */ + alloc_type_shash, /* string hash element */ + alloc_type_thash, /* type hash element */ + alloc_type_tag, /* struct/union/tag element */ + alloc_type_forward, /* element to hold unknown tag */ + alloc_type_thead, /* head of type hash list */ + alloc_type_varray, /* general varray allocation */ + alloc_type_lineno, /* line number list */ + alloc_type_last /* last+1 element for array bounds */ +}; + +/* Types of auxiliary type information. */ +enum aux_type { + aux_tir, /* TIR type information */ + aux_rndx, /* relative index into symbol table */ + aux_dnLow, /* low dimension */ + aux_dnHigh, /* high dimension */ + aux_isym, /* symbol table index (end of proc) */ + aux_iss, /* index into string space (not used) */ + aux_width, /* width for non-default sized struc fields */ + aux_count /* count of ranges for variant arm */ +}; + +/* Structures to provide n-number of virtual arrays, each of which can + grow linearly, and which are written in the object file as + sequential pages. On systems with a BSD malloc, the + MAX_CLUSTER_PAGES should be 1 less than a power of two, since + malloc adds it's overhead, and rounds up to the next power of 2. + Pages are linked together via a linked list. + + If PAGE_SIZE is > 4096, the string length in the shash_t structure + can't be represented (assuming there are strings > 4096 bytes). */ + +/* FIXME: Yes, there can be such strings while emitting C++ class debug + info. Templates are the offender here, the test case in question + having a mangled class name of + + t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\ + 2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey + + Repeat that a couple dozen times while listing the class members and + you've got strings over 4k. Hack around this for now by increasing + the page size. A proper solution would abandon this structure scheme + certainly for very large strings, and possibly entirely. */ + +#ifndef PAGE_SIZE +#define PAGE_SIZE (8*1024) /* size of varray pages */ +#endif + +#define PAGE_USIZE ((unsigned long) PAGE_SIZE) + +#ifndef MAX_CLUSTER_PAGES /* # pages to get from system */ +#define MAX_CLUSTER_PAGES 63 +#endif + +/* Linked list connecting separate page allocations. */ +typedef struct vlinks { + struct vlinks *prev; /* previous set of pages */ + struct vlinks *next; /* next set of pages */ + union page *datum; /* start of page */ + unsigned long start_index; /* starting index # of page */ +} vlinks_t; + +/* Virtual array header. */ +typedef struct varray { + vlinks_t *first; /* first page link */ + vlinks_t *last; /* last page link */ + unsigned long num_allocated; /* # objects allocated */ + unsigned short object_size; /* size in bytes of each object */ + unsigned short objects_per_page; /* # objects that can fit on a page */ + unsigned short objects_last_page; /* # objects allocated on last page */ +} varray_t; + +#ifndef MALLOC_CHECK +#define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type)) +#else +#define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE) +#endif + +#define INIT_VARRAY(type) { /* macro to initialize a varray */ \ + (vlinks_t *)0, /* first */ \ + (vlinks_t *)0, /* last */ \ + 0, /* num_allocated */ \ + sizeof (type), /* object_size */ \ + OBJECTS_PER_PAGE (type), /* objects_per_page */ \ + OBJECTS_PER_PAGE (type), /* objects_last_page */ \ +} + +/* Master type for indexes within the symbol table. */ +typedef unsigned long symint_t; + +/* Linked list support for nested scopes (file, block, structure, etc.). */ +typedef struct scope { + struct scope *prev; /* previous scope level */ + struct scope *free; /* free list pointer */ + struct localsym *lsym; /* pointer to local symbol node */ + st_t type; /* type of the node */ +} scope_t; + +/* For a local symbol we store a gas symbol as well as the debugging + information we generate. The gas symbol will be NULL if this is + only a debugging symbol. */ +typedef struct localsym { + const char *name; /* symbol name */ + symbolS *as_sym; /* symbol as seen by gas */ + bfd_vma addend; /* addend to as_sym value */ + struct efdr *file_ptr; /* file pointer */ + struct ecoff_proc *proc_ptr; /* proc pointer */ + struct localsym *begin_ptr; /* symbol at start of block */ + struct ecoff_aux *index_ptr; /* index value to be filled in */ + struct forward *forward_ref; /* forward references to this symbol */ + long sym_index; /* final symbol index */ + EXTR ecoff_sym; /* ECOFF debugging symbol */ +} localsym_t; + +/* For aux information we keep the type and the data. */ +typedef struct ecoff_aux { + enum aux_type type; /* aux type */ + AUXU data; /* aux data */ +} aux_t; + +/* For a procedure we store the gas symbol as well as the PDR + debugging information. */ +typedef struct ecoff_proc { + localsym_t *sym; /* associated symbol */ + PDR pdr; /* ECOFF debugging info */ +} proc_t; + +/* Number of proc_t structures allocated. */ +static unsigned long proc_cnt; + +/* Forward reference list for tags referenced, but not yet defined. */ +typedef struct forward { + struct forward *next; /* next forward reference */ + struct forward *free; /* free list pointer */ + aux_t *ifd_ptr; /* pointer to store file index */ + aux_t *index_ptr; /* pointer to store symbol index */ +} forward_t; + +/* Linked list support for tags. The first tag in the list is always + the current tag for that block. */ +typedef struct tag { + struct tag *free; /* free list pointer */ + struct shash *hash_ptr; /* pointer to the hash table head */ + struct tag *same_name; /* tag with same name in outer scope */ + struct tag *same_block; /* next tag defined in the same block. */ + struct forward *forward_ref; /* list of forward references */ + bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */ + symint_t ifd; /* file # tag defined in */ + localsym_t *sym; /* file's local symbols */ +} tag_t; + +/* Head of a block's linked list of tags. */ +typedef struct thead { + struct thead *prev; /* previous block */ + struct thead *free; /* free list pointer */ + struct tag *first_tag; /* first tag in block defined */ +} thead_t; + +/* Union containing pointers to each the small structures which are freed up. */ +typedef union small_free { + scope_t *f_scope; /* scope structure */ + thead_t *f_thead; /* tag head structure */ + tag_t *f_tag; /* tag element structure */ + forward_t *f_forward; /* forward tag reference */ +} small_free_t; + +/* String hash table entry. */ + +typedef struct shash { + char *string; /* string we are hashing */ + symint_t indx; /* index within string table */ + EXTR *esym_ptr; /* global symbol pointer */ + localsym_t *sym_ptr; /* local symbol pointer */ + localsym_t *end_ptr; /* symbol pointer to end block */ + tag_t *tag_ptr; /* tag pointer */ + proc_t *proc_ptr; /* procedure descriptor pointer */ +} shash_t; + +/* Type hash table support. The size of the hash table must fit + within a page with the other extended file descriptor information. + Because unique types which are hashed are fewer in number than + strings, we use a smaller hash value. */ + +#define HASHBITS 30 + +#ifndef THASH_SIZE +#define THASH_SIZE 113 +#endif + +typedef struct thash { + struct thash *next; /* next hash value */ + AUXU type; /* type we are hashing */ + symint_t indx; /* index within string table */ +} thash_t; + +/* Extended file descriptor that contains all of the support necessary + to add things to each file separately. */ +typedef struct efdr { + FDR fdr; /* File header to be written out */ + FDR *orig_fdr; /* original file header */ + char *name; /* filename */ + int fake; /* whether this is faked .file */ + symint_t void_type; /* aux. pointer to 'void' type */ + symint_t int_type; /* aux. pointer to 'int' type */ + scope_t *cur_scope; /* current nested scopes */ + symint_t file_index; /* current file number */ + int nested_scopes; /* # nested scopes */ + varray_t strings; /* local strings */ + varray_t symbols; /* local symbols */ + varray_t procs; /* procedures */ + varray_t aux_syms; /* auxiliary symbols */ + struct efdr *next_file; /* next file descriptor */ + /* string/type hash tables */ + struct hash_control *str_hash; /* string hash table */ + thash_t *thash_head[THASH_SIZE]; +} efdr_t; + +/* Pre-initialized extended file structure. */ +static const efdr_t init_file = { + { /* FDR structure */ + 0, /* adr: memory address of beginning of file */ + 0, /* rss: file name (of source, if known) */ + 0, /* issBase: file's string space */ + 0, /* cbSs: number of bytes in the ss */ + 0, /* isymBase: beginning of symbols */ + 0, /* csym: count file's of symbols */ + 0, /* ilineBase: file's line symbols */ + 0, /* cline: count of file's line symbols */ + 0, /* ioptBase: file's optimization entries */ + 0, /* copt: count of file's optimization entries */ + 0, /* ipdFirst: start of procedures for this file */ + 0, /* cpd: count of procedures for this file */ + 0, /* iauxBase: file's auxiliary entries */ + 0, /* caux: count of file's auxiliary entries */ + 0, /* rfdBase: index into the file indirect table */ + 0, /* crfd: count file indirect entries */ + langC, /* lang: language for this file */ + 1, /* fMerge: whether this file can be merged */ + 0, /* fReadin: true if read in (not just created) */ + TARGET_BYTES_BIG_ENDIAN, /* fBigendian: if 1, compiled on big endian machine */ + GLEVEL_2, /* glevel: level this file was compiled with */ + 0, /* reserved: reserved for future use */ + 0, /* cbLineOffset: byte offset from header for this file ln's */ + 0, /* cbLine: size of lines for this file */ + }, + + (FDR *)0, /* orig_fdr: original file header pointer */ + (char *)0, /* name: pointer to filename */ + 0, /* fake: whether this is a faked .file */ + 0, /* void_type: ptr to aux node for void type */ + 0, /* int_type: ptr to aux node for int type */ + (scope_t *)0, /* cur_scope: current scope being processed */ + 0, /* file_index: current file # */ + 0, /* nested_scopes: # nested scopes */ + INIT_VARRAY (char), /* strings: local string varray */ + INIT_VARRAY (localsym_t), /* symbols: local symbols varray */ + INIT_VARRAY (proc_t), /* procs: procedure varray */ + INIT_VARRAY (aux_t), /* aux_syms: auxiliary symbols varray */ + + (struct efdr *)0, /* next_file: next file structure */ + + (struct hash_control *)0, /* str_hash: string hash table */ + { 0 }, /* thash_head: type hash table */ +}; + +static efdr_t *first_file; /* first file descriptor */ +static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */ + +/* Line number information is kept in a list until the assembly is + finished. */ +typedef struct lineno_list { + struct lineno_list *next; /* next element in list */ + efdr_t *file; /* file this line is in */ + proc_t *proc; /* procedure this line is in */ + fragS *frag; /* fragment this line number is in */ + unsigned long paddr; /* offset within fragment */ + long lineno; /* actual line number */ +} lineno_list_t; + +static lineno_list_t *first_lineno; +static lineno_list_t *last_lineno; +static lineno_list_t **last_lineno_ptr = &first_lineno; + +/* Sometimes there will be some .loc statements before a .ent. We + keep them in this list so that we can fill in the procedure pointer + after we see the .ent. */ +static lineno_list_t *noproc_lineno; + +/* Union of various things that are held in pages. */ +typedef union page { + char byte [ PAGE_SIZE ]; + unsigned char ubyte [ PAGE_SIZE ]; + efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ]; + FDR ofile [ PAGE_SIZE / sizeof (FDR) ]; + proc_t proc [ PAGE_SIZE / sizeof (proc_t) ]; + localsym_t sym [ PAGE_SIZE / sizeof (localsym_t) ]; + aux_t aux [ PAGE_SIZE / sizeof (aux_t) ]; + DNR dense [ PAGE_SIZE / sizeof (DNR) ]; + scope_t scope [ PAGE_SIZE / sizeof (scope_t) ]; + vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ]; + shash_t shash [ PAGE_SIZE / sizeof (shash_t) ]; + thash_t thash [ PAGE_SIZE / sizeof (thash_t) ]; + tag_t tag [ PAGE_SIZE / sizeof (tag_t) ]; + forward_t forward [ PAGE_SIZE / sizeof (forward_t) ]; + thead_t thead [ PAGE_SIZE / sizeof (thead_t) ]; + lineno_list_t lineno [ PAGE_SIZE / sizeof (lineno_list_t) ]; +} page_type; + +/* Structure holding allocation information for small sized structures. */ +typedef struct alloc_info { + char *alloc_name; /* name of this allocation type (must be first) */ + page_type *cur_page; /* current page being allocated from */ + small_free_t free_list; /* current free list if any */ + int unallocated; /* number of elements unallocated on page */ + int total_alloc; /* total number of allocations */ + int total_free; /* total number of frees */ + int total_pages; /* total number of pages allocated */ +} alloc_info_t; + +/* Type information collected together. */ +typedef struct type_info { + bt_t basic_type; /* basic type */ + int orig_type; /* original COFF-based type */ + int num_tq; /* # type qualifiers */ + int num_dims; /* # dimensions */ + int num_sizes; /* # sizes */ + int extra_sizes; /* # extra sizes not tied with dims */ + tag_t * tag_ptr; /* tag pointer */ + int bitfield; /* symbol is a bitfield */ + tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/ + symint_t dimensions [N_TQ]; /* dimensions for each array */ + symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of + struct/union/enum + bitfield size */ +} type_info_t; + +/* Pre-initialized type_info struct. */ +static const type_info_t type_info_init = { + bt_Nil, /* basic type */ + T_NULL, /* original COFF-based type */ + 0, /* # type qualifiers */ + 0, /* # dimensions */ + 0, /* # sizes */ + 0, /* sizes not tied with dims */ + NULL, /* ptr to tag */ + 0, /* bitfield */ + { /* type qualifiers */ + tq_Nil, + tq_Nil, + tq_Nil, + tq_Nil, + tq_Nil, + tq_Nil, + }, + { /* dimensions */ + 0, + 0, + 0, + 0, + 0, + 0 + }, + { /* sizes */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + }, +}; + +/* Global hash table for the tags table and global table for file + descriptors. */ + +static varray_t file_desc = INIT_VARRAY (efdr_t); + +static struct hash_control *tag_hash; + +/* Static types for int and void. Also, remember the last function's + type (which is set up when we encounter the declaration for the + function, and used when the end block for the function is emitted. */ + +static type_info_t int_type_info; +static type_info_t void_type_info; +static type_info_t last_func_type_info; +static symbolS *last_func_sym_value; + +/* Convert COFF basic type to ECOFF basic type. The T_NULL type + really should use bt_Void, but this causes the current ecoff GDB to + issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS + 2.0) doesn't understand it, even though the compiler generates it. + Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler + suite, but for now go with what works. + + It would make sense for the .type and .scl directives to use the + ECOFF numbers directly, rather than using the COFF numbers and + mapping them. Unfortunately, this is historically what mips-tfile + expects, and changing gcc now would be a considerable pain (the + native compiler generates debugging information internally, rather + than via the assembler, so it will never use .type or .scl). */ + +static const bt_t map_coff_types[] = { + bt_Nil, /* T_NULL */ + bt_Nil, /* T_ARG */ + bt_Char, /* T_CHAR */ + bt_Short, /* T_SHORT */ + bt_Int, /* T_INT */ + bt_Long, /* T_LONG */ + bt_Float, /* T_FLOAT */ + bt_Double, /* T_DOUBLE */ + bt_Struct, /* T_STRUCT */ + bt_Union, /* T_UNION */ + bt_Enum, /* T_ENUM */ + bt_Enum, /* T_MOE */ + bt_UChar, /* T_UCHAR */ + bt_UShort, /* T_USHORT */ + bt_UInt, /* T_UINT */ + bt_ULong /* T_ULONG */ +}; + +/* Convert COFF storage class to ECOFF storage class. */ +static const sc_t map_coff_storage[] = { + sc_Nil, /* 0: C_NULL */ + sc_Abs, /* 1: C_AUTO auto var */ + sc_Undefined, /* 2: C_EXT external */ + sc_Data, /* 3: C_STAT static */ + sc_Register, /* 4: C_REG register */ + sc_Undefined, /* 5: C_EXTDEF ??? */ + sc_Text, /* 6: C_LABEL label */ + sc_Text, /* 7: C_ULABEL user label */ + sc_Info, /* 8: C_MOS member of struct */ + sc_Abs, /* 9: C_ARG argument */ + sc_Info, /* 10: C_STRTAG struct tag */ + sc_Info, /* 11: C_MOU member of union */ + sc_Info, /* 12: C_UNTAG union tag */ + sc_Info, /* 13: C_TPDEF typedef */ + sc_Data, /* 14: C_USTATIC ??? */ + sc_Info, /* 15: C_ENTAG enum tag */ + sc_Info, /* 16: C_MOE member of enum */ + sc_Register, /* 17: C_REGPARM register parameter */ + sc_Bits, /* 18; C_FIELD bitfield */ + sc_Nil, /* 19 */ + sc_Nil, /* 20 */ + sc_Nil, /* 21 */ + sc_Nil, /* 22 */ + sc_Nil, /* 23 */ + sc_Nil, /* 24 */ + sc_Nil, /* 25 */ + sc_Nil, /* 26 */ + sc_Nil, /* 27 */ + sc_Nil, /* 28 */ + sc_Nil, /* 29 */ + sc_Nil, /* 30 */ + sc_Nil, /* 31 */ + sc_Nil, /* 32 */ + sc_Nil, /* 33 */ + sc_Nil, /* 34 */ + sc_Nil, /* 35 */ + sc_Nil, /* 36 */ + sc_Nil, /* 37 */ + sc_Nil, /* 38 */ + sc_Nil, /* 39 */ + sc_Nil, /* 40 */ + sc_Nil, /* 41 */ + sc_Nil, /* 42 */ + sc_Nil, /* 43 */ + sc_Nil, /* 44 */ + sc_Nil, /* 45 */ + sc_Nil, /* 46 */ + sc_Nil, /* 47 */ + sc_Nil, /* 48 */ + sc_Nil, /* 49 */ + sc_Nil, /* 50 */ + sc_Nil, /* 51 */ + sc_Nil, /* 52 */ + sc_Nil, /* 53 */ + sc_Nil, /* 54 */ + sc_Nil, /* 55 */ + sc_Nil, /* 56 */ + sc_Nil, /* 57 */ + sc_Nil, /* 58 */ + sc_Nil, /* 59 */ + sc_Nil, /* 60 */ + sc_Nil, /* 61 */ + sc_Nil, /* 62 */ + sc_Nil, /* 63 */ + sc_Nil, /* 64 */ + sc_Nil, /* 65 */ + sc_Nil, /* 66 */ + sc_Nil, /* 67 */ + sc_Nil, /* 68 */ + sc_Nil, /* 69 */ + sc_Nil, /* 70 */ + sc_Nil, /* 71 */ + sc_Nil, /* 72 */ + sc_Nil, /* 73 */ + sc_Nil, /* 74 */ + sc_Nil, /* 75 */ + sc_Nil, /* 76 */ + sc_Nil, /* 77 */ + sc_Nil, /* 78 */ + sc_Nil, /* 79 */ + sc_Nil, /* 80 */ + sc_Nil, /* 81 */ + sc_Nil, /* 82 */ + sc_Nil, /* 83 */ + sc_Nil, /* 84 */ + sc_Nil, /* 85 */ + sc_Nil, /* 86 */ + sc_Nil, /* 87 */ + sc_Nil, /* 88 */ + sc_Nil, /* 89 */ + sc_Nil, /* 90 */ + sc_Nil, /* 91 */ + sc_Nil, /* 92 */ + sc_Nil, /* 93 */ + sc_Nil, /* 94 */ + sc_Nil, /* 95 */ + sc_Nil, /* 96 */ + sc_Nil, /* 97 */ + sc_Nil, /* 98 */ + sc_Nil, /* 99 */ + sc_Text, /* 100: C_BLOCK block start/end */ + sc_Text, /* 101: C_FCN function start/end */ + sc_Info, /* 102: C_EOS end of struct/union/enum */ + sc_Nil, /* 103: C_FILE file start */ + sc_Nil, /* 104: C_LINE line number */ + sc_Nil, /* 105: C_ALIAS combined type info */ + sc_Nil, /* 106: C_HIDDEN ??? */ +}; + +/* Convert COFF storage class to ECOFF symbol type. */ +static const st_t map_coff_sym_type[] = { + st_Nil, /* 0: C_NULL */ + st_Local, /* 1: C_AUTO auto var */ + st_Global, /* 2: C_EXT external */ + st_Static, /* 3: C_STAT static */ + st_Local, /* 4: C_REG register */ + st_Global, /* 5: C_EXTDEF ??? */ + st_Label, /* 6: C_LABEL label */ + st_Label, /* 7: C_ULABEL user label */ + st_Member, /* 8: C_MOS member of struct */ + st_Param, /* 9: C_ARG argument */ + st_Block, /* 10: C_STRTAG struct tag */ + st_Member, /* 11: C_MOU member of union */ + st_Block, /* 12: C_UNTAG union tag */ + st_Typedef, /* 13: C_TPDEF typedef */ + st_Static, /* 14: C_USTATIC ??? */ + st_Block, /* 15: C_ENTAG enum tag */ + st_Member, /* 16: C_MOE member of enum */ + st_Param, /* 17: C_REGPARM register parameter */ + st_Member, /* 18; C_FIELD bitfield */ + st_Nil, /* 19 */ + st_Nil, /* 20 */ + st_Nil, /* 21 */ + st_Nil, /* 22 */ + st_Nil, /* 23 */ + st_Nil, /* 24 */ + st_Nil, /* 25 */ + st_Nil, /* 26 */ + st_Nil, /* 27 */ + st_Nil, /* 28 */ + st_Nil, /* 29 */ + st_Nil, /* 30 */ + st_Nil, /* 31 */ + st_Nil, /* 32 */ + st_Nil, /* 33 */ + st_Nil, /* 34 */ + st_Nil, /* 35 */ + st_Nil, /* 36 */ + st_Nil, /* 37 */ + st_Nil, /* 38 */ + st_Nil, /* 39 */ + st_Nil, /* 40 */ + st_Nil, /* 41 */ + st_Nil, /* 42 */ + st_Nil, /* 43 */ + st_Nil, /* 44 */ + st_Nil, /* 45 */ + st_Nil, /* 46 */ + st_Nil, /* 47 */ + st_Nil, /* 48 */ + st_Nil, /* 49 */ + st_Nil, /* 50 */ + st_Nil, /* 51 */ + st_Nil, /* 52 */ + st_Nil, /* 53 */ + st_Nil, /* 54 */ + st_Nil, /* 55 */ + st_Nil, /* 56 */ + st_Nil, /* 57 */ + st_Nil, /* 58 */ + st_Nil, /* 59 */ + st_Nil, /* 60 */ + st_Nil, /* 61 */ + st_Nil, /* 62 */ + st_Nil, /* 63 */ + st_Nil, /* 64 */ + st_Nil, /* 65 */ + st_Nil, /* 66 */ + st_Nil, /* 67 */ + st_Nil, /* 68 */ + st_Nil, /* 69 */ + st_Nil, /* 70 */ + st_Nil, /* 71 */ + st_Nil, /* 72 */ + st_Nil, /* 73 */ + st_Nil, /* 74 */ + st_Nil, /* 75 */ + st_Nil, /* 76 */ + st_Nil, /* 77 */ + st_Nil, /* 78 */ + st_Nil, /* 79 */ + st_Nil, /* 80 */ + st_Nil, /* 81 */ + st_Nil, /* 82 */ + st_Nil, /* 83 */ + st_Nil, /* 84 */ + st_Nil, /* 85 */ + st_Nil, /* 86 */ + st_Nil, /* 87 */ + st_Nil, /* 88 */ + st_Nil, /* 89 */ + st_Nil, /* 90 */ + st_Nil, /* 91 */ + st_Nil, /* 92 */ + st_Nil, /* 93 */ + st_Nil, /* 94 */ + st_Nil, /* 95 */ + st_Nil, /* 96 */ + st_Nil, /* 97 */ + st_Nil, /* 98 */ + st_Nil, /* 99 */ + st_Block, /* 100: C_BLOCK block start/end */ + st_Proc, /* 101: C_FCN function start/end */ + st_End, /* 102: C_EOS end of struct/union/enum */ + st_File, /* 103: C_FILE file start */ + st_Nil, /* 104: C_LINE line number */ + st_Nil, /* 105: C_ALIAS combined type info */ + st_Nil, /* 106: C_HIDDEN ??? */ +}; + +/* Keep track of different sized allocation requests. */ +static alloc_info_t alloc_counts[(int) alloc_type_last]; + +/* Record whether we have seen any debugging information. */ +int ecoff_debugging_seen = 0; + +/* Various statics. */ +static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */ +static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */ +static proc_t *first_proc_ptr = (proc_t *) 0; /* first procedure header */ +static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */ +static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */ +#ifdef ECOFF_DEBUG +static int debug = 0; /* trace functions */ +#endif +static int stabs_seen = 0; /* != 0 if stabs have been seen */ + +static int current_file_idx; +static const char *current_stabs_filename; + +/* Pseudo symbol to use when putting stabs into the symbol table. */ +#ifndef STABS_SYMBOL +#define STABS_SYMBOL "@stabs" +#endif + +static char stabs_symbol[] = STABS_SYMBOL; + +/* Prototypes for functions defined in this file. */ + +static void add_varray_page (varray_t *vp); +static symint_t add_string (varray_t *vp, + struct hash_control *hash_tbl, + const char *str, + shash_t **ret_hash); +static localsym_t *add_ecoff_symbol (const char *str, st_t type, + sc_t storage, symbolS *sym, + bfd_vma addend, symint_t value, + symint_t indx); +static symint_t add_aux_sym_symint (symint_t aux_word); +static symint_t add_aux_sym_rndx (int file_index, symint_t sym_index); +static symint_t add_aux_sym_tir (type_info_t *t, + hash_state_t state, + thash_t **hash_tbl); +static tag_t *get_tag (const char *tag, localsym_t *sym, bt_t basic_type); +static void add_unknown_tag (tag_t *ptag); +static void add_procedure (char *func); +static void add_file (const char *file_name, int indx, int fake); +#ifdef ECOFF_DEBUG +static char *sc_to_string (sc_t storage_class); +static char *st_to_string (st_t symbol_type); +#endif +static void mark_stabs (int); +static char *ecoff_add_bytes (char **buf, char **bufend, + char *bufptr, unsigned long need); +static unsigned long ecoff_padding_adjust + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset, char **bufptrptr); +static unsigned long ecoff_build_lineno + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset, long *linecntptr); +static unsigned long ecoff_build_symbols + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset); +static unsigned long ecoff_build_procs + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset); +static unsigned long ecoff_build_aux + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset); +static unsigned long ecoff_build_strings (char **buf, char **bufend, + unsigned long offset, + varray_t *vp); +static unsigned long ecoff_build_ss + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset); +static unsigned long ecoff_build_fdr + (const struct ecoff_debug_swap *backend, char **buf, char **bufend, + unsigned long offset); +static void ecoff_setup_ext (void); +static page_type *allocate_cluster (unsigned long npages); +static page_type *allocate_page (void); +static scope_t *allocate_scope (void); +static void free_scope (scope_t *ptr); +static vlinks_t *allocate_vlinks (void); +static shash_t *allocate_shash (void); +static thash_t *allocate_thash (void); +static tag_t *allocate_tag (void); +static void free_tag (tag_t *ptr); +static forward_t *allocate_forward (void); +static thead_t *allocate_thead (void); +static void free_thead (thead_t *ptr); +static lineno_list_t *allocate_lineno_list (void); + +/* This function should be called when the assembler starts up. */ + +void +ecoff_read_begin_hook (void) +{ + tag_hash = hash_new (); + top_tag_head = allocate_thead (); + top_tag_head->first_tag = (tag_t *) NULL; + top_tag_head->free = (thead_t *) NULL; + top_tag_head->prev = cur_tag_head; + cur_tag_head = top_tag_head; +} + +/* This function should be called when a symbol is created. */ + +void +ecoff_symbol_new_hook (symbolS *symbolP) +{ + OBJ_SYMFIELD_TYPE *obj; + + /* Make sure that we have a file pointer, but only if we have seen a + file. If we haven't seen a file, then this is a probably special + symbol created by md_begin which may required special handling at + some point. Creating a dummy file with a dummy name is certainly + wrong. */ + if (cur_file_ptr == (efdr_t *) NULL + && seen_at_least_1_file ()) + add_file ((const char *) NULL, 0, 1); + obj = symbol_get_obj (symbolP); + obj->ecoff_file = cur_file_ptr; + obj->ecoff_symbol = NULL; + obj->ecoff_extern_size = 0; +} + +void +ecoff_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP) +{ + OBJ_SYMFIELD_TYPE *n, *o; + + n = symbol_get_obj (newsymP); + o = symbol_get_obj (orgsymP); + memcpy (n, o, sizeof *n); +} + +/* Add a page to a varray object. */ + +static void +add_varray_page (varray_t *vp /* varray to add page to */) +{ + vlinks_t *new_links = allocate_vlinks (); + +#ifdef MALLOC_CHECK + if (vp->object_size > 1) + new_links->datum = (page_type *) xcalloc (1, vp->object_size); + else +#endif + new_links->datum = allocate_page (); + + alloc_counts[(int) alloc_type_varray].total_alloc++; + alloc_counts[(int) alloc_type_varray].total_pages++; + + new_links->start_index = vp->num_allocated; + vp->objects_last_page = 0; + + if (vp->first == (vlinks_t *) NULL) /* first allocation? */ + vp->first = vp->last = new_links; + else + { /* 2nd or greater allocation */ + new_links->prev = vp->last; + vp->last->next = new_links; + vp->last = new_links; + } +} + +/* Add a string (and null pad) to one of the string tables. */ + +static symint_t +add_string (varray_t *vp, /* string obstack */ + struct hash_control *hash_tbl, /* ptr to hash table */ + const char *str, /* string */ + shash_t **ret_hash /* return hash pointer */) +{ + register unsigned long len = strlen (str); + register shash_t *hash_ptr; + + if (len >= PAGE_USIZE) + as_fatal (_("string too big (%lu bytes)"), len); + + hash_ptr = (shash_t *) hash_find (hash_tbl, str); + if (hash_ptr == (shash_t *) NULL) + { + register const char *err; + + if (vp->objects_last_page + len >= PAGE_USIZE) + { + vp->num_allocated = + ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE; + add_varray_page (vp); + } + + hash_ptr = allocate_shash (); + hash_ptr->indx = vp->num_allocated; + + hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page]; + + vp->objects_last_page += len + 1; + vp->num_allocated += len + 1; + + strcpy (hash_ptr->string, str); + + err = hash_insert (hash_tbl, str, (char *) hash_ptr); + if (err) + as_fatal (_("inserting \"%s\" into string hash table: %s"), + str, err); + } + + if (ret_hash != (shash_t **) NULL) + *ret_hash = hash_ptr; + + return hash_ptr->indx; +} + +/* Add debugging information for a symbol. */ + +static localsym_t * +add_ecoff_symbol (const char *str, /* symbol name */ + st_t type, /* symbol type */ + sc_t storage, /* storage class */ + symbolS *sym_value, /* associated symbol. */ + bfd_vma addend, /* addend to sym_value. */ + symint_t value, /* value of symbol */ + symint_t indx /* index to local/aux. syms */) +{ + localsym_t *psym; + register scope_t *pscope; + register thead_t *ptag_head; + register tag_t *ptag; + register tag_t *ptag_next; + register varray_t *vp; + register int scope_delta = 0; + shash_t *hash_ptr = (shash_t *) NULL; + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + vp = &cur_file_ptr->symbols; + + if (vp->objects_last_page == vp->objects_per_page) + add_varray_page (vp); + + psym = &vp->last->datum->sym[vp->objects_last_page++]; + + if (str == (const char *) NULL && sym_value != (symbolS *) NULL) + psym->name = S_GET_NAME (sym_value); + else + psym->name = str; + psym->as_sym = sym_value; + if (sym_value != (symbolS *) NULL) + symbol_get_obj (sym_value)->ecoff_symbol = psym; + psym->addend = addend; + psym->file_ptr = cur_file_ptr; + psym->proc_ptr = cur_proc_ptr; + psym->begin_ptr = (localsym_t *) NULL; + psym->index_ptr = (aux_t *) NULL; + psym->forward_ref = (forward_t *) NULL; + psym->sym_index = -1; + memset (&psym->ecoff_sym, 0, sizeof (EXTR)); + psym->ecoff_sym.asym.value = value; + psym->ecoff_sym.asym.st = (unsigned) type; + psym->ecoff_sym.asym.sc = (unsigned) storage; + psym->ecoff_sym.asym.index = indx; + + /* If there is an associated symbol, we wait until the end of the + assembly before deciding where to put the name (it may be just an + external symbol). Otherwise, this is just a debugging symbol and + the name should go with the current file. */ + if (sym_value == (symbolS *) NULL) + psym->ecoff_sym.asym.iss = ((str == (const char *) NULL) + ? 0 + : add_string (&cur_file_ptr->strings, + cur_file_ptr->str_hash, + str, + &hash_ptr)); + + ++vp->num_allocated; + + if (ECOFF_IS_STAB (&psym->ecoff_sym.asym)) + return psym; + + /* Save the symbol within the hash table if this is a static + item, and it has a name. */ + if (hash_ptr != (shash_t *) NULL + && (type == st_Global || type == st_Static || type == st_Label + || type == st_Proc || type == st_StaticProc)) + hash_ptr->sym_ptr = psym; + + /* push or pop a scope if appropriate. */ + switch (type) + { + default: + break; + + case st_File: /* beginning of file */ + case st_Proc: /* procedure */ + case st_StaticProc: /* static procedure */ + case st_Block: /* begin scope */ + pscope = allocate_scope (); + pscope->prev = cur_file_ptr->cur_scope; + pscope->lsym = psym; + pscope->type = type; + cur_file_ptr->cur_scope = pscope; + + if (type != st_File) + scope_delta = 1; + + /* For every block type except file, struct, union, or + enumeration blocks, push a level on the tag stack. We omit + file types, so that tags can span file boundaries. */ + if (type != st_File && storage != sc_Info) + { + ptag_head = allocate_thead (); + ptag_head->first_tag = 0; + ptag_head->prev = cur_tag_head; + cur_tag_head = ptag_head; + } + break; + + case st_End: + pscope = cur_file_ptr->cur_scope; + if (pscope == (scope_t *) NULL) + as_fatal (_("too many st_End's")); + else + { + st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st; + + psym->begin_ptr = pscope->lsym; + + if (begin_type != st_File) + scope_delta = -1; + + /* Except for file, structure, union, or enumeration end + blocks remove all tags created within this scope. */ + if (begin_type != st_File && storage != sc_Info) + { + ptag_head = cur_tag_head; + cur_tag_head = ptag_head->prev; + + for (ptag = ptag_head->first_tag; + ptag != (tag_t *) NULL; + ptag = ptag_next) + { + if (ptag->forward_ref != (forward_t *) NULL) + add_unknown_tag (ptag); + + ptag_next = ptag->same_block; + ptag->hash_ptr->tag_ptr = ptag->same_name; + free_tag (ptag); + } + + free_thead (ptag_head); + } + + cur_file_ptr->cur_scope = pscope->prev; + + /* block begin gets next sym #. This is set when we know + the symbol index value. */ + + /* Functions push two or more aux words as follows: + 1st word: index+1 of the end symbol (filled in later). + 2nd word: type of the function (plus any aux words needed). + Also, tie the external pointer back to the function begin symbol. */ + if (begin_type != st_File && begin_type != st_Block) + { + symint_t ty; + varray_t *svp = &cur_file_ptr->aux_syms; + + pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0); + pscope->lsym->index_ptr = + &svp->last->datum->aux[svp->objects_last_page - 1]; + ty = add_aux_sym_tir (&last_func_type_info, + hash_no, + &cur_file_ptr->thash_head[0]); + (void) ty; +/* This seems to be unnecessary. I'm not even sure what it is + * intended to do. It's from mips-tfile. + * if (last_func_sym_value != (symbolS *) NULL) + * { + * last_func_sym_value->ifd = cur_file_ptr->file_index; + * last_func_sym_value->index = ty; + * } + */ + } + + free_scope (pscope); + } + } + + cur_file_ptr->nested_scopes += scope_delta; + +#ifdef ECOFF_DEBUG + if (debug && type != st_File + && (debug > 2 || type == st_Block || type == st_End + || type == st_Proc || type == st_StaticProc)) + { + char *sc_str = sc_to_string (storage); + char *st_str = st_to_string (type); + int depth = cur_file_ptr->nested_scopes + (scope_delta < 0); + + fprintf (stderr, + "\tlsym\tv= %10ld, depth= %2d, sc= %-12s", + value, depth, sc_str); + + if (str_start && str_end_p1 - str_start > 0) + fprintf (stderr, " st= %-11s name= %.*s\n", + st_str, str_end_p1 - str_start, str_start); + else + { + unsigned long len = strlen (st_str); + fprintf (stderr, " st= %.*s\n", len - 1, st_str); + } + } +#endif + + return psym; +} + +/* Add an auxiliary symbol (passing a symint). This is actually used + for integral aux types, not just symints. */ + +static symint_t +add_aux_sym_symint (symint_t aux_word /* auxiliary information word */) +{ + register varray_t *vp; + register aux_t *aux_ptr; + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + vp = &cur_file_ptr->aux_syms; + + if (vp->objects_last_page == vp->objects_per_page) + add_varray_page (vp); + + aux_ptr = &vp->last->datum->aux[vp->objects_last_page++]; + aux_ptr->type = aux_isym; + aux_ptr->data.isym = aux_word; + + return vp->num_allocated++; +} + +/* Add an auxiliary symbol (passing a file/symbol index combo). */ + +static symint_t +add_aux_sym_rndx (int file_index, symint_t sym_index) +{ + register varray_t *vp; + register aux_t *aux_ptr; + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + vp = &cur_file_ptr->aux_syms; + + if (vp->objects_last_page == vp->objects_per_page) + add_varray_page (vp); + + aux_ptr = &vp->last->datum->aux[vp->objects_last_page++]; + aux_ptr->type = aux_rndx; + aux_ptr->data.rndx.rfd = file_index; + aux_ptr->data.rndx.index = sym_index; + + return vp->num_allocated++; +} + +/* Add an auxiliary symbol (passing the basic type and possibly + type qualifiers). */ + +static symint_t +add_aux_sym_tir (type_info_t *t, /* current type information */ + hash_state_t state, /* whether to hash type or not */ + thash_t **hash_tbl /* pointer to hash table to use */) +{ + register varray_t *vp; + register aux_t *aux_ptr; + static AUXU init_aux; + symint_t ret; + int i; + AUXU aux; + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + vp = &cur_file_ptr->aux_syms; + + aux = init_aux; + aux.ti.bt = (int) t->basic_type; + aux.ti.continued = 0; + aux.ti.fBitfield = t->bitfield; + + aux.ti.tq0 = (int) t->type_qualifiers[0]; + aux.ti.tq1 = (int) t->type_qualifiers[1]; + aux.ti.tq2 = (int) t->type_qualifiers[2]; + aux.ti.tq3 = (int) t->type_qualifiers[3]; + aux.ti.tq4 = (int) t->type_qualifiers[4]; + aux.ti.tq5 = (int) t->type_qualifiers[5]; + + /* For anything that adds additional information, we must not hash, + so check here, and reset our state. */ + + if (state != hash_no + && (t->type_qualifiers[0] == tq_Array + || t->type_qualifiers[1] == tq_Array + || t->type_qualifiers[2] == tq_Array + || t->type_qualifiers[3] == tq_Array + || t->type_qualifiers[4] == tq_Array + || t->type_qualifiers[5] == tq_Array + || t->basic_type == bt_Struct + || t->basic_type == bt_Union + || t->basic_type == bt_Enum + || t->bitfield + || t->num_dims > 0)) + state = hash_no; + + /* See if we can hash this type, and save some space, but some types + can't be hashed (because they contain arrays or continuations), + and others can be put into the hash list, but cannot use existing + types because other aux entries precede this one. */ + + if (state != hash_no) + { + register thash_t *hash_ptr; + register symint_t hi; + + hi = aux.isym & ((1 << HASHBITS) - 1); + hi %= THASH_SIZE; + + for (hash_ptr = hash_tbl[hi]; + hash_ptr != (thash_t *)0; + hash_ptr = hash_ptr->next) + { + if (aux.isym == hash_ptr->type.isym) + break; + } + + if (hash_ptr != (thash_t *) NULL && state == hash_yes) + return hash_ptr->indx; + + if (hash_ptr == (thash_t *) NULL) + { + hash_ptr = allocate_thash (); + hash_ptr->next = hash_tbl[hi]; + hash_ptr->type = aux; + hash_ptr->indx = vp->num_allocated; + hash_tbl[hi] = hash_ptr; + } + } + + /* Everything is set up, add the aux symbol. */ + if (vp->objects_last_page == vp->objects_per_page) + add_varray_page (vp); + + aux_ptr = &vp->last->datum->aux[vp->objects_last_page++]; + aux_ptr->type = aux_tir; + aux_ptr->data = aux; + + ret = vp->num_allocated++; + + /* Add bitfield length if it exists. + + NOTE: Mips documentation claims bitfield goes at the end of the + AUX record, but the DECstation compiler emits it here. + (This would only make a difference for enum bitfields.) + + Also note: We use the last size given since gcc may emit 2 + for an enum bitfield. */ + + if (t->bitfield) + (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes - 1]); + + /* Add tag information if needed. Structure, union, and enum + references add 2 aux symbols: a [file index, symbol index] + pointer to the structure type, and the current file index. */ + + if (t->basic_type == bt_Struct + || t->basic_type == bt_Union + || t->basic_type == bt_Enum) + { + register symint_t file_index = t->tag_ptr->ifd; + register localsym_t *sym = t->tag_ptr->sym; + register forward_t *forward_ref = allocate_forward (); + + if (sym != (localsym_t *) NULL) + { + forward_ref->next = sym->forward_ref; + sym->forward_ref = forward_ref; + } + else + { + forward_ref->next = t->tag_ptr->forward_ref; + t->tag_ptr->forward_ref = forward_ref; + } + + (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil); + forward_ref->index_ptr + = &vp->last->datum->aux[vp->objects_last_page - 1]; + + (void) add_aux_sym_symint (file_index); + forward_ref->ifd_ptr + = &vp->last->datum->aux[vp->objects_last_page - 1]; + } + + /* Add information about array bounds if they exist. */ + for (i = 0; i < t->num_dims; i++) + { + (void) add_aux_sym_rndx (ST_RFDESCAPE, + cur_file_ptr->int_type); + + (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/ + (void) add_aux_sym_symint ((symint_t) 0); /* low bound */ + (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/ + (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */ + ? 0 + : (t->sizes[i] * 8) / t->dimensions[i]); + }; + + /* NOTE: Mips documentation claims that the bitfield width goes here. + But it needs to be emitted earlier. */ + + return ret; +} + +/* Add a tag to the tag table (unless it already exists). */ + +static tag_t * +get_tag (const char *tag, /* tag name */ + localsym_t *sym, /* tag start block */ + bt_t basic_type /* bt_Struct, bt_Union, or bt_Enum */) +{ + shash_t *hash_ptr; + const char *err; + tag_t *tag_ptr; + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + hash_ptr = (shash_t *) hash_find (tag_hash, tag); + + if (hash_ptr != (shash_t *) NULL + && hash_ptr->tag_ptr != (tag_t *) NULL) + { + tag_ptr = hash_ptr->tag_ptr; + if (sym != (localsym_t *) NULL) + { + tag_ptr->basic_type = basic_type; + tag_ptr->ifd = cur_file_ptr->file_index; + tag_ptr->sym = sym; + } + return tag_ptr; + } + + if (hash_ptr == (shash_t *) NULL) + { + char *perm; + + perm = xstrdup (tag); + hash_ptr = allocate_shash (); + err = hash_insert (tag_hash, perm, (char *) hash_ptr); + if (err) + as_fatal (_("inserting \"%s\" into tag hash table: %s"), + tag, err); + hash_ptr->string = perm; + } + + tag_ptr = allocate_tag (); + tag_ptr->forward_ref = (forward_t *) NULL; + tag_ptr->hash_ptr = hash_ptr; + tag_ptr->same_name = hash_ptr->tag_ptr; + tag_ptr->basic_type = basic_type; + tag_ptr->sym = sym; + tag_ptr->ifd = ((sym == (localsym_t *) NULL) + ? (symint_t) -1 + : cur_file_ptr->file_index); + tag_ptr->same_block = cur_tag_head->first_tag; + + cur_tag_head->first_tag = tag_ptr; + hash_ptr->tag_ptr = tag_ptr; + + return tag_ptr; +} + +/* Add an unknown {struct, union, enum} tag. */ + +static void +add_unknown_tag (tag_t *ptag /* pointer to tag information */) +{ + shash_t *hash_ptr = ptag->hash_ptr; + char *name = hash_ptr->string; + localsym_t *sym; + forward_t **pf; + +#ifdef ECOFF_DEBUG + if (debug > 1) + { + char *agg_type = "{unknown aggregate type}"; + switch (ptag->basic_type) + { + case bt_Struct: agg_type = "struct"; break; + case bt_Union: agg_type = "union"; break; + case bt_Enum: agg_type = "enum"; break; + default: break; + } + + fprintf (stderr, "unknown %s %.*s found\n", agg_type, + hash_ptr->len, name_start); + } +#endif + + sym = add_ecoff_symbol (name, + st_Block, + sc_Info, + (symbolS *) NULL, + (bfd_vma) 0, + (symint_t) 0, + (symint_t) 0); + + (void) add_ecoff_symbol (name, + st_End, + sc_Info, + (symbolS *) NULL, + (bfd_vma) 0, + (symint_t) 0, + (symint_t) 0); + + for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next) + ; + *pf = ptag->forward_ref; +} + +/* Add a procedure to the current file's list of procedures, and record + this is the current procedure. */ + +static void +add_procedure (char *func /* func name */) +{ + register varray_t *vp; + register proc_t *new_proc_ptr; + symbolS *sym; + +#ifdef ECOFF_DEBUG + if (debug) + fputc ('\n', stderr); +#endif + + if (cur_file_ptr == (efdr_t *) NULL) + as_fatal (_("no current file pointer")); + + vp = &cur_file_ptr->procs; + + if (vp->objects_last_page == vp->objects_per_page) + add_varray_page (vp); + + cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++]; + + if (first_proc_ptr == (proc_t *) NULL) + first_proc_ptr = new_proc_ptr; + + vp->num_allocated++; + + new_proc_ptr->pdr.isym = -1; + new_proc_ptr->pdr.iline = -1; + new_proc_ptr->pdr.lnLow = -1; + new_proc_ptr->pdr.lnHigh = -1; + + /* Set the BSF_FUNCTION flag for the symbol. */ + sym = symbol_find_or_make (func); + symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; + + /* Push the start of the function. */ + new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text, + sym, (bfd_vma) 0, (symint_t) 0, + (symint_t) 0); + + ++proc_cnt; + + /* Fill in the linenos preceding the .ent, if any. */ + if (noproc_lineno != (lineno_list_t *) NULL) + { + lineno_list_t *l; + + for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next) + l->proc = new_proc_ptr; + *last_lineno_ptr = noproc_lineno; + while (*last_lineno_ptr != NULL) + { + last_lineno = *last_lineno_ptr; + last_lineno_ptr = &last_lineno->next; + } + noproc_lineno = (lineno_list_t *) NULL; + } +} + +symbolS * +ecoff_get_cur_proc_sym (void) +{ + return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL); +} + +/* Add a new filename, and set up all of the file relative + virtual arrays (strings, symbols, aux syms, etc.). Record + where the current file structure lives. */ + +static void +add_file (const char *file_name, int indx ATTRIBUTE_UNUSED, int fake) +{ + register int first_ch; + register efdr_t *fil_ptr; + +#ifdef ECOFF_DEBUG + if (debug) + fprintf (stderr, "\tfile\t%.*s\n", len, file_start); +#endif + + /* If the file name is NULL, then no .file symbol appeared, and we + want to use the actual file name. */ + if (file_name == (const char *) NULL) + { + char *file; + + if (first_file != (efdr_t *) NULL) + as_fatal (_("fake .file after real one")); + as_where (&file, (unsigned int *) NULL); + file_name = (const char *) file; + + /* Automatically generate ECOFF debugging information, since I + think that's what other ECOFF assemblers do. We don't do + this if we see a .file directive with a string, since that + implies that some sort of debugging information is being + provided. */ + if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED) + debug_type = DEBUG_ECOFF; + } + else if (debug_type == DEBUG_UNSPECIFIED) + debug_type = DEBUG_NONE; + +#ifndef NO_LISTING + if (listing) + listing_source_file (file_name); +#endif + + current_stabs_filename = file_name; + + /* If we're creating stabs, then we don't actually make a new FDR. + Instead, we just create a stabs symbol. */ + if (stabs_seen) + { + (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil, + symbol_new ("L0\001", now_seg, + (valueT) frag_now_fix (), + frag_now), + (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL)); + return; + } + + first_ch = *file_name; + + /* FIXME: We can't safely merge files which have line number + information (fMerge will be zero in this case). Otherwise, we + get incorrect line number debugging info. See for instance + ecoff_build_lineno, which will end up setting all file->fdr.* + fields multiple times, resulting in incorrect debug info. In + order to make this work right, all line number and symbol info + for the same source file has to be adjacent in the object file, + so that a single file descriptor can be used to point to them. + This would require maintaining file specific lists of line + numbers and symbols for each file, so that they can be merged + together (or output together) when two .file pseudo-ops are + merged into one file descriptor. */ + + /* See if the file has already been created. */ + for (fil_ptr = first_file; + fil_ptr != (efdr_t *) NULL; + fil_ptr = fil_ptr->next_file) + { + if (first_ch == fil_ptr->name[0] + && filename_cmp (file_name, fil_ptr->name) == 0 + && fil_ptr->fdr.fMerge) + { + cur_file_ptr = fil_ptr; + if (! fake) + cur_file_ptr->fake = 0; + break; + } + } + + /* If this is a new file, create it. */ + if (fil_ptr == (efdr_t *) NULL) + { + if (file_desc.objects_last_page == file_desc.objects_per_page) + add_varray_page (&file_desc); + + fil_ptr = cur_file_ptr = + &file_desc.last->datum->file[file_desc.objects_last_page++]; + *fil_ptr = init_file; + + fil_ptr->file_index = current_file_idx++; + ++file_desc.num_allocated; + + fil_ptr->fake = fake; + + /* Allocate the string hash table. */ + fil_ptr->str_hash = hash_new (); + + /* Make sure 0 byte in string table is null */ + add_string (&fil_ptr->strings, + fil_ptr->str_hash, + "", + (shash_t **)0); + + if (strlen (file_name) > PAGE_USIZE - 2) + as_fatal (_("filename goes over one page boundary")); + + /* Push the start of the filename. We assume that the filename + will be stored at string offset 1. */ + (void) add_ecoff_symbol (file_name, st_File, sc_Text, + (symbolS *) NULL, (bfd_vma) 0, + (symint_t) 0, (symint_t) 0); + fil_ptr->fdr.rss = 1; + fil_ptr->name = &fil_ptr->strings.last->datum->byte[1]; + + /* Update the linked list of file descriptors. */ + *last_file_ptr = fil_ptr; + last_file_ptr = &fil_ptr->next_file; + + /* Add void & int types to the file (void should be first to catch + errant 0's within the index fields). */ + fil_ptr->void_type = add_aux_sym_tir (&void_type_info, + hash_yes, + &cur_file_ptr->thash_head[0]); + + fil_ptr->int_type = add_aux_sym_tir (&int_type_info, + hash_yes, + &cur_file_ptr->thash_head[0]); + } +} + +/* This function is called when the assembler notices a preprocessor + directive switching to a new file. This will not happen in + compiler output, only in hand coded assembler. */ + +void +ecoff_new_file (const char *name, int appfile ATTRIBUTE_UNUSED) +{ + if (cur_file_ptr != NULL && filename_cmp (cur_file_ptr->name, name) == 0) + return; + add_file (name, 0, 0); + + /* This is a hand coded assembler file, so automatically turn on + debugging information. */ + if (debug_type == DEBUG_UNSPECIFIED) + debug_type = DEBUG_ECOFF; +} + +#ifdef ECOFF_DEBUG + +/* Convert storage class to string. */ + +static char * +sc_to_string (storage_class) + sc_t storage_class; +{ + switch (storage_class) + { + case sc_Nil: return "Nil,"; + case sc_Text: return "Text,"; + case sc_Data: return "Data,"; + case sc_Bss: return "Bss,"; + case sc_Register: return "Register,"; + case sc_Abs: return "Abs,"; + case sc_Undefined: return "Undefined,"; + case sc_CdbLocal: return "CdbLocal,"; + case sc_Bits: return "Bits,"; + case sc_CdbSystem: return "CdbSystem,"; + case sc_RegImage: return "RegImage,"; + case sc_Info: return "Info,"; + case sc_UserStruct: return "UserStruct,"; + case sc_SData: return "SData,"; + case sc_SBss: return "SBss,"; + case sc_RData: return "RData,"; + case sc_Var: return "Var,"; + case sc_Common: return "Common,"; + case sc_SCommon: return "SCommon,"; + case sc_VarRegister: return "VarRegister,"; + case sc_Variant: return "Variant,"; + case sc_SUndefined: return "SUndefined,"; + case sc_Init: return "Init,"; + case sc_Max: return "Max,"; + } + + return "???,"; +} + +#endif /* DEBUG */ + +#ifdef ECOFF_DEBUG + +/* Convert symbol type to string. */ + +static char * +st_to_string (symbol_type) + st_t symbol_type; +{ + switch (symbol_type) + { + case st_Nil: return "Nil,"; + case st_Global: return "Global,"; + case st_Static: return "Static,"; + case st_Param: return "Param,"; + case st_Local: return "Local,"; + case st_Label: return "Label,"; + case st_Proc: return "Proc,"; + case st_Block: return "Block,"; + case st_End: return "End,"; + case st_Member: return "Member,"; + case st_Typedef: return "Typedef,"; + case st_File: return "File,"; + case st_RegReloc: return "RegReloc,"; + case st_Forward: return "Forward,"; + case st_StaticProc: return "StaticProc,"; + case st_Constant: return "Constant,"; + case st_Str: return "String,"; + case st_Number: return "Number,"; + case st_Expr: return "Expr,"; + case st_Type: return "Type,"; + case st_Max: return "Max,"; + } + + return "???,"; +} + +#endif /* DEBUG */ + +/* Parse .begin directives which have a label as the first argument + which gives the location of the start of the block. */ + +void +ecoff_directive_begin (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + + if (cur_file_ptr == (efdr_t *) NULL) + { + as_warn (_(".begin directive without a preceding .file directive")); + demand_empty_rest_of_line (); + return; + } + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".begin directive without a preceding .ent directive")); + demand_empty_rest_of_line (); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text, + symbol_find_or_make (name), + (bfd_vma) 0, (symint_t) 0, (symint_t) 0); + + *input_line_pointer = name_end; + + /* The line number follows, but we don't use it. */ + (void) get_absolute_expression (); + demand_empty_rest_of_line (); +} + +/* Parse .bend directives which have a label as the first argument + which gives the location of the end of the block. */ + +void +ecoff_directive_bend (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + symbolS *endsym; + + if (cur_file_ptr == (efdr_t *) NULL) + { + as_warn (_(".bend directive without a preceding .file directive")); + demand_empty_rest_of_line (); + return; + } + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".bend directive without a preceding .ent directive")); + demand_empty_rest_of_line (); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + /* The value is the distance between the .bend directive and the + corresponding symbol. We fill in the offset when we write out + the symbol. */ + endsym = symbol_find (name); + if (endsym == (symbolS *) NULL) + as_warn (_(".bend directive names unknown symbol")); + else + (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym, + (bfd_vma) 0, (symint_t) 0, (symint_t) 0); + + *input_line_pointer = name_end; + + /* The line number follows, but we don't use it. */ + (void) get_absolute_expression (); + demand_empty_rest_of_line (); +} + +/* COFF debugging information is provided as a series of directives + (.def, .scl, etc.). We build up information as we read the + directives in the following static variables, and file it away when + we reach the .endef directive. */ +static char *coff_sym_name; +static type_info_t coff_type; +static sc_t coff_storage_class; +static st_t coff_symbol_typ; +static int coff_is_function; +static char *coff_tag; +static valueT coff_value; +static symbolS *coff_sym_value; +static bfd_vma coff_sym_addend; +static int coff_inside_enumeration; + +/* Handle a .def directive: start defining a symbol. */ + +void +ecoff_directive_def (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + + ecoff_debugging_seen = 1; + + SKIP_WHITESPACE (); + + name = input_line_pointer; + name_end = get_symbol_end (); + + if (coff_sym_name != (char *) NULL) + as_warn (_(".def pseudo-op used inside of .def/.endef; ignored")); + else if (*name == '\0') + as_warn (_("empty symbol name in .def; ignored")); + else + { + if (coff_sym_name != (char *) NULL) + free (coff_sym_name); + if (coff_tag != (char *) NULL) + free (coff_tag); + + coff_sym_name = xstrdup (name); + coff_type = type_info_init; + coff_storage_class = sc_Nil; + coff_symbol_typ = st_Nil; + coff_is_function = 0; + coff_tag = (char *) NULL; + coff_value = 0; + coff_sym_value = (symbolS *) NULL; + coff_sym_addend = 0; + } + + *input_line_pointer = name_end; + + demand_empty_rest_of_line (); +} + +/* Handle a .dim directive, used to give dimensions for an array. The + arguments are comma separated numbers. mips-tfile assumes that + there will not be more than 6 dimensions, and gdb won't read any + more than that anyhow, so I will also make that assumption. */ + +void +ecoff_directive_dim (int ignore ATTRIBUTE_UNUSED) +{ + int dimens[N_TQ]; + int i; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + for (i = 0; i < N_TQ; i++) + { + SKIP_WHITESPACE (); + dimens[i] = get_absolute_expression (); + if (*input_line_pointer == ',') + ++input_line_pointer; + else + { + if (*input_line_pointer != '\n' + && *input_line_pointer != ';') + as_warn (_("badly formed .dim directive")); + break; + } + } + + if (i == N_TQ) + --i; + + /* The dimensions are stored away in reverse order. */ + for (; i >= 0; i--) + { + if (coff_type.num_dims >= N_TQ) + { + as_warn (_("too many .dim entries")); + break; + } + coff_type.dimensions[coff_type.num_dims] = dimens[i]; + ++coff_type.num_dims; + } + + demand_empty_rest_of_line (); +} + +/* Handle a .scl directive, which sets the COFF storage class of the + symbol. */ + +void +ecoff_directive_scl (int ignore ATTRIBUTE_UNUSED) +{ + long val; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + val = get_absolute_expression (); + + coff_symbol_typ = map_coff_sym_type[val]; + coff_storage_class = map_coff_storage[val]; + + demand_empty_rest_of_line (); +} + +/* Handle a .size directive. For some reason mips-tfile.c thinks that + .size can have multiple arguments. We humor it, although gcc will + never generate more than one argument. */ + +void +ecoff_directive_size (int ignore ATTRIBUTE_UNUSED) +{ + int sizes[N_TQ]; + int i; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".size pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + for (i = 0; i < N_TQ; i++) + { + SKIP_WHITESPACE (); + sizes[i] = get_absolute_expression (); + if (*input_line_pointer == ',') + ++input_line_pointer; + else + { + if (*input_line_pointer != '\n' + && *input_line_pointer != ';') + as_warn (_("badly formed .size directive")); + break; + } + } + + if (i == N_TQ) + --i; + + /* The sizes are stored away in reverse order. */ + for (; i >= 0; i--) + { + if (coff_type.num_sizes >= N_TQ) + { + as_warn (_("too many .size entries")); + break; + } + coff_type.sizes[coff_type.num_sizes] = sizes[i]; + ++coff_type.num_sizes; + } + + demand_empty_rest_of_line (); +} + +/* Handle the .type directive, which gives the COFF type of the + symbol. */ + +void +ecoff_directive_type (int ignore ATTRIBUTE_UNUSED) +{ + long val; + tq_t *tq_ptr; + tq_t *tq_shft; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".type pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + val = get_absolute_expression (); + + coff_type.orig_type = BTYPE (val); + coff_type.basic_type = map_coff_types[coff_type.orig_type]; + + tq_ptr = &coff_type.type_qualifiers[N_TQ]; + while (val & ~N_BTMASK) + { + if (tq_ptr == &coff_type.type_qualifiers[0]) + { + /* FIXME: We could handle this by setting the continued bit. + There would still be a limit: the .type argument can not + be infinite. */ + as_warn (_("the type of %s is too complex; it will be simplified"), + coff_sym_name); + break; + } + if (ISPTR (val)) + *--tq_ptr = tq_Ptr; + else if (ISFCN (val)) + *--tq_ptr = tq_Proc; + else if (ISARY (val)) + *--tq_ptr = tq_Array; + else + as_fatal (_("Unrecognized .type argument")); + + val = DECREF (val); + } + + tq_shft = &coff_type.type_qualifiers[0]; + while (tq_ptr != &coff_type.type_qualifiers[N_TQ]) + *tq_shft++ = *tq_ptr++; + + if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc) + { + /* If this is a function, ignore it, so that we don't get two + entries (one from the .ent, and one for the .def that + precedes it). Save the type information so that the end + block can properly add it after the begin block index. For + MIPS knows what reason, we must strip off the function type + at this point. */ + coff_is_function = 1; + tq_shft[-1] = tq_Nil; + } + + while (tq_shft != &coff_type.type_qualifiers[N_TQ]) + *tq_shft++ = tq_Nil; + + demand_empty_rest_of_line (); +} + +/* Handle the .tag directive, which gives the name of a structure, + union or enum. */ + +void +ecoff_directive_tag (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + coff_tag = xstrdup (name); + + *input_line_pointer = name_end; + + demand_empty_rest_of_line (); +} + +/* Handle the .val directive, which gives the value of the symbol. It + may be the name of a static or global symbol. */ + +void +ecoff_directive_val (int ignore ATTRIBUTE_UNUSED) +{ + expressionS exp; + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".val pseudo-op used outside of .def/.endef; ignored")); + demand_empty_rest_of_line (); + return; + } + + expression (&exp); + if (exp.X_op != O_constant && exp.X_op != O_symbol) + { + as_bad (_(".val expression is too complex")); + demand_empty_rest_of_line (); + return; + } + + if (exp.X_op == O_constant) + coff_value = exp.X_add_number; + else + { + coff_sym_value = exp.X_add_symbol; + coff_sym_addend = exp.X_add_number; + } + + demand_empty_rest_of_line (); +} + +/* Handle the .endef directive, which terminates processing of COFF + debugging information for a symbol. */ + +void +ecoff_directive_endef (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + symint_t indx; + localsym_t *sym; + + demand_empty_rest_of_line (); + + if (coff_sym_name == (char *) NULL) + { + as_warn (_(".endef pseudo-op used before .def; ignored")); + return; + } + + name = coff_sym_name; + coff_sym_name = (char *) NULL; + + /* If the symbol is a static or external, we have already gotten the + appropriate type and class, so make sure we don't override those + values. This is needed because there are some type and classes + that are not in COFF, such as short data, etc. */ + if (coff_sym_value != (symbolS *) NULL) + { + coff_symbol_typ = st_Nil; + coff_storage_class = sc_Nil; + } + + coff_type.extra_sizes = coff_tag != (char *) NULL; + if (coff_type.num_dims > 0) + { + int diff = coff_type.num_dims - coff_type.num_sizes; + int i = coff_type.num_dims - 1; + int j; + + if (coff_type.num_sizes != 1 || diff < 0) + { + as_warn (_("bad COFF debugging information")); + return; + } + + /* If this is an array, make sure the same number of dimensions + and sizes were passed, creating extra sizes for multiply + dimensioned arrays if not passed. */ + coff_type.extra_sizes = 0; + if (diff) + { + j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1; + while (j >= 0) + { + coff_type.sizes[j] = (((j - diff) >= 0) + ? coff_type.sizes[j - diff] + : 0); + j--; + } + + coff_type.num_sizes = i + 1; + for (i--; i >= 0; i--) + coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0 + ? 0 + : (coff_type.sizes[i + 1] + / coff_type.dimensions[i + 1])); + } + } + else if (coff_symbol_typ == st_Member + && coff_type.num_sizes - coff_type.extra_sizes == 1) + { + /* Is this a bitfield? This is indicated by a structure member + having a size field that isn't an array. */ + coff_type.bitfield = 1; + } + + /* Except for enumeration members & begin/ending of scopes, put the + type word in the aux. symbol table. */ + if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End) + indx = 0; + else if (coff_inside_enumeration) + indx = cur_file_ptr->void_type; + else + { + if (coff_type.basic_type == bt_Struct + || coff_type.basic_type == bt_Union + || coff_type.basic_type == bt_Enum) + { + if (coff_tag == (char *) NULL) + { + as_warn (_("no tag specified for %s"), name); + return; + } + + coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL, + coff_type.basic_type); + } + + if (coff_is_function) + { + last_func_type_info = coff_type; + last_func_sym_value = coff_sym_value; + return; + } + + indx = add_aux_sym_tir (&coff_type, + hash_yes, + &cur_file_ptr->thash_head[0]); + } + + /* Do any last minute adjustments that are necessary. */ + switch (coff_symbol_typ) + { + default: + break; + + /* For the beginning of structs, unions, and enumerations, the + size info needs to be passed in the value field. */ + case st_Block: + if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes + != 1) + { + as_warn (_("bad COFF debugging information")); + return; + } + else + coff_value = coff_type.sizes[0]; + + coff_inside_enumeration = (coff_type.orig_type == T_ENUM); + break; + + /* For the end of structs, unions, and enumerations, omit the + name which is always ".eos". This needs to be done last, so + that any error reporting above gives the correct name. */ + case st_End: + free (name); + name = (char *) NULL; + coff_value = 0; + coff_inside_enumeration = 0; + break; + + /* Members of structures and unions that aren't bitfields, need + to adjust the value from a byte offset to a bit offset. + Members of enumerations do not have the value adjusted, and + can be distinguished by indx == indexNil. For enumerations, + update the maximum enumeration value. */ + case st_Member: + if (! coff_type.bitfield && ! coff_inside_enumeration) + coff_value *= 8; + + break; + } + + /* Add the symbol. */ + sym = add_ecoff_symbol (name, + coff_symbol_typ, + coff_storage_class, + coff_sym_value, + coff_sym_addend, + (symint_t) coff_value, + indx); + + /* deal with struct, union, and enum tags. */ + if (coff_symbol_typ == st_Block) + { + /* Create or update the tag information. */ + tag_t *tag_ptr = get_tag (name, + sym, + coff_type.basic_type); + forward_t **pf; + + /* Remember any forward references. */ + for (pf = &sym->forward_ref; + *pf != (forward_t *) NULL; + pf = &(*pf)->next) + ; + *pf = tag_ptr->forward_ref; + tag_ptr->forward_ref = (forward_t *) NULL; + } +} + +/* Parse .end directives. */ + +void +ecoff_directive_end (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + symbolS *ent; + + if (cur_file_ptr == (efdr_t *) NULL) + { + as_warn (_(".end directive without a preceding .file directive")); + demand_empty_rest_of_line (); + return; + } + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".end directive without a preceding .ent directive")); + demand_empty_rest_of_line (); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + if (name == input_line_pointer) + { + as_warn (_(".end directive has no name")); + *input_line_pointer = name_end; + demand_empty_rest_of_line (); + return; + } + + /* The value is the distance between the .end directive and the + corresponding symbol. We create a fake symbol to hold the + current location, and put in the offset when we write out the + symbol. */ + ent = symbol_find (name); + if (ent == (symbolS *) NULL) + as_warn (_(".end directive names unknown symbol")); + else + (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, + symbol_new ("L0\001", now_seg, + (valueT) frag_now_fix (), + frag_now), + (bfd_vma) 0, (symint_t) 0, (symint_t) 0); + + cur_proc_ptr = (proc_t *) NULL; + + *input_line_pointer = name_end; + demand_empty_rest_of_line (); +} + +/* Parse .ent directives. */ + +void +ecoff_directive_ent (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char name_end; + + if (cur_file_ptr == (efdr_t *) NULL) + add_file ((const char *) NULL, 0, 1); + + if (cur_proc_ptr != (proc_t *) NULL) + { + as_warn (_("second .ent directive found before .end directive")); + demand_empty_rest_of_line (); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + if (name == input_line_pointer) + { + as_warn (_(".ent directive has no name")); + *input_line_pointer = name_end; + demand_empty_rest_of_line (); + return; + } + + add_procedure (name); + + *input_line_pointer = name_end; + + /* The .ent directive is sometimes followed by a number. I'm not + really sure what the number means. I don't see any way to store + the information in the PDR. The Irix 4 assembler seems to ignore + the information. */ + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + ++input_line_pointer; + SKIP_WHITESPACE (); + } + if (ISDIGIT (*input_line_pointer) + || *input_line_pointer == '-') + (void) get_absolute_expression (); + + demand_empty_rest_of_line (); +} + +/* Parse .extern directives. */ + +void +ecoff_directive_extern (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + int c; + symbolS *symbolp; + valueT size; + + name = input_line_pointer; + c = get_symbol_end (); + symbolp = symbol_find_or_make (name); + *input_line_pointer = c; + + S_SET_EXTERNAL (symbolp); + + if (*input_line_pointer == ',') + ++input_line_pointer; + size = get_absolute_expression (); + + symbol_get_obj (symbolp)->ecoff_extern_size = size; +} + +/* Parse .file directives. */ + +void +ecoff_directive_file (int ignore ATTRIBUTE_UNUSED) +{ + int indx; + char *name; + int len; + + if (cur_proc_ptr != (proc_t *) NULL) + { + as_warn (_("no way to handle .file within .ent/.end section")); + demand_empty_rest_of_line (); + return; + } + + indx = (int) get_absolute_expression (); + + /* FIXME: we don't have to save the name here. */ + name = demand_copy_C_string (&len); + + add_file (name, indx - 1, 0); + + demand_empty_rest_of_line (); +} + +/* Parse .fmask directives. */ + +void +ecoff_directive_fmask (int ignore ATTRIBUTE_UNUSED) +{ + long val; + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".fmask outside of .ent")); + demand_empty_rest_of_line (); + return; + } + + if (get_absolute_expression_and_terminator (&val) != ',') + { + as_warn (_("bad .fmask directive")); + --input_line_pointer; + demand_empty_rest_of_line (); + return; + } + + cur_proc_ptr->pdr.fregmask = val; + cur_proc_ptr->pdr.fregoffset = get_absolute_expression (); + + demand_empty_rest_of_line (); +} + +/* Parse .frame directives. */ + +void +ecoff_directive_frame (int ignore ATTRIBUTE_UNUSED) +{ + long val; + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".frame outside of .ent")); + demand_empty_rest_of_line (); + return; + } + + cur_proc_ptr->pdr.framereg = tc_get_register (1); + + SKIP_WHITESPACE (); + if (*input_line_pointer++ != ',' + || get_absolute_expression_and_terminator (&val) != ',') + { + as_warn (_("bad .frame directive")); + --input_line_pointer; + demand_empty_rest_of_line (); + return; + } + + cur_proc_ptr->pdr.frameoffset = val; + + cur_proc_ptr->pdr.pcreg = tc_get_register (0); + + /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according to + Sandro. I don't yet know where this value should be stored, if + anywhere. Don't call demand_empty_rest_of_line (). */ + s_ignore (42); +} + +/* Parse .mask directives. */ + +void +ecoff_directive_mask (int ignore ATTRIBUTE_UNUSED) +{ + long val; + + if (cur_proc_ptr == (proc_t *) NULL) + { + as_warn (_(".mask outside of .ent")); + demand_empty_rest_of_line (); + return; + } + + if (get_absolute_expression_and_terminator (&val) != ',') + { + as_warn (_("bad .mask directive")); + --input_line_pointer; + demand_empty_rest_of_line (); + return; + } + + cur_proc_ptr->pdr.regmask = val; + cur_proc_ptr->pdr.regoffset = get_absolute_expression (); + + demand_empty_rest_of_line (); +} + +/* Parse .loc directives. */ + +void +ecoff_directive_loc (int ignore ATTRIBUTE_UNUSED) +{ + lineno_list_t *list; + symint_t lineno; + + if (cur_file_ptr == (efdr_t *) NULL) + { + as_warn (_(".loc before .file")); + demand_empty_rest_of_line (); + return; + } + + if (now_seg != text_section) + { + as_warn (_(".loc outside of .text")); + demand_empty_rest_of_line (); + return; + } + + /* Skip the file number. */ + SKIP_WHITESPACE (); + get_absolute_expression (); + SKIP_WHITESPACE (); + + lineno = get_absolute_expression (); + +#ifndef NO_LISTING + if (listing) + listing_source_line (lineno); +#endif + + /* If we're building stabs, then output a special label rather than + ECOFF line number info. */ + if (stabs_seen) + { + (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text, + symbol_new ("L0\001", now_seg, + (valueT) frag_now_fix (), + frag_now), + (bfd_vma) 0, 0, lineno); + return; + } + + list = allocate_lineno_list (); + + list->next = (lineno_list_t *) NULL; + list->file = cur_file_ptr; + list->proc = cur_proc_ptr; + list->frag = frag_now; + list->paddr = frag_now_fix (); + list->lineno = lineno; + + /* We don't want to merge files which have line numbers. */ + cur_file_ptr->fdr.fMerge = 0; + + /* A .loc directive will sometimes appear before a .ent directive, + which means that cur_proc_ptr will be NULL here. Arrange to + patch this up. */ + if (cur_proc_ptr == (proc_t *) NULL) + { + lineno_list_t **pl; + + pl = &noproc_lineno; + while (*pl != (lineno_list_t *) NULL) + pl = &(*pl)->next; + *pl = list; + } + else + { + last_lineno = list; + *last_lineno_ptr = list; + last_lineno_ptr = &list->next; + } +} + +/* The MIPS assembler sometimes inserts nop instructions in the + instruction stream. When this happens, we must patch up the .loc + information so that it points to the instruction after the nop. */ + +void +ecoff_fix_loc (fragS *old_frag, unsigned long old_frag_offset) +{ + if (last_lineno != NULL + && last_lineno->frag == old_frag + && last_lineno->paddr == old_frag_offset) + { + last_lineno->frag = frag_now; + last_lineno->paddr = frag_now_fix (); + } +} + +/* Make sure the @stabs symbol is emitted. */ + +static void +mark_stabs (int ignore ATTRIBUTE_UNUSED) +{ + if (! stabs_seen) + { + /* Add a dummy @stabs dymbol. */ + stabs_seen = 1; + (void) add_ecoff_symbol (stabs_symbol, st_Nil, sc_Info, + (symbolS *) NULL, + (bfd_vma) 0, (symint_t) -1, + ECOFF_MARK_STAB (0)); + } +} + +/* Parse .weakext directives. */ +#ifndef TC_MIPS +/* For TC_MIPS use the version in tc-mips.c. */ +void +ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + int c; + symbolS *symbolP; + expressionS exp; + + name = input_line_pointer; + c = get_symbol_end (); + symbolP = symbol_find_or_make (name); + *input_line_pointer = c; + + SKIP_WHITESPACE (); + + if (*input_line_pointer == ',') + { + if (S_IS_DEFINED (symbolP)) + { + as_bad (_("symbol `%s' is already defined"), + S_GET_NAME (symbolP)); + ignore_rest_of_line (); + return; + } + + ++input_line_pointer; + SKIP_WHITESPACE (); + if (! is_end_of_line[(unsigned char) *input_line_pointer]) + { + expression (&exp); + if (exp.X_op != O_symbol) + { + as_bad (_("bad .weakext directive")); + ignore_rest_of_line (); + return; + } + symbol_set_value_expression (symbolP, &exp); + } + } + + S_SET_WEAK (symbolP); + + demand_empty_rest_of_line (); +} +#endif /* not TC_MIPS */ + +/* Handle .stabs directives. The actual parsing routine is done by a + generic routine. This routine is called via OBJ_PROCESS_STAB. + When this is called, input_line_pointer will be pointing at the + value field of the stab. + + .stabs directives have five fields: + "string" a string, encoding the type information. + code a numeric code, defined in + 0 a zero + desc a zero or line number + value a numeric value or an address. + + If the value is relocatable, we transform this into: + iss points as an index into string space + value value from lookup of the name + st st from lookup of the name + sc sc from lookup of the name + index code|CODE_MASK + + If the value is not relocatable, we transform this into: + iss points as an index into string space + value value + st st_Nil + sc sc_Nil + index code|CODE_MASK + + .stabn directives have four fields (string is null): + code a numeric code, defined in + 0 a zero + desc a zero or a line number + value a numeric value or an address. */ + +void +ecoff_stab (segT sec ATTRIBUTE_UNUSED, + int what, + const char *string, + int type, + int other, + int desc) +{ + efdr_t *save_file_ptr = cur_file_ptr; + symbolS *sym; + symint_t value; + bfd_vma addend; + st_t st; + sc_t sc; + symint_t indx; + localsym_t *hold = NULL; + + ecoff_debugging_seen = 1; + + /* We don't handle .stabd. */ + if (what != 's' && what != 'n') + { + as_bad (_(".stab%c is not supported"), what); + return; + } + + /* A .stabn uses a null name, not an empty string. */ + if (what == 'n') + string = NULL; + + /* We ignore the other field. */ + if (other != 0) + as_warn (_(".stab%c: ignoring non-zero other field"), what); + + /* Make sure we have a current file. */ + if (cur_file_ptr == (efdr_t *) NULL) + { + add_file ((const char *) NULL, 0, 1); + save_file_ptr = cur_file_ptr; + } + + /* For stabs in ECOFF, the first symbol must be @stabs. This is a + signal to gdb. */ + if (stabs_seen == 0) + mark_stabs (0); + + /* Line number stabs are handled differently, since they have two + values, the line number and the address of the label. We use the + index field (aka desc) to hold the line number, and the value + field to hold the address. The symbol type is st_Label, which + should be different from the other stabs, so that gdb can + recognize it. */ + if (type == N_SLINE) + { + SYMR dummy_symr; + char *name; + char name_end; + +#ifndef NO_LISTING + if (listing) + listing_source_line ((unsigned int) desc); +#endif + + dummy_symr.index = desc; + if (dummy_symr.index != desc) + { + as_warn (_("line number (%d) for .stab%c directive cannot fit in index field (20 bits)"), + desc, what); + return; + } + + name = input_line_pointer; + name_end = get_symbol_end (); + + sym = symbol_find_or_make (name); + *input_line_pointer = name_end; + + value = 0; + addend = 0; + st = st_Label; + sc = sc_Text; + indx = desc; + } + else + { +#ifndef NO_LISTING + if (listing && (type == N_SO || type == N_SOL)) + listing_source_file (string); +#endif + + if (ISDIGIT (*input_line_pointer) + || *input_line_pointer == '-' + || *input_line_pointer == '+') + { + st = st_Nil; + sc = sc_Nil; + sym = (symbolS *) NULL; + value = get_absolute_expression (); + addend = 0; + } + else if (! is_name_beginner ((unsigned char) *input_line_pointer)) + { + as_warn (_("illegal .stab%c directive, bad character"), what); + return; + } + else + { + expressionS exp; + + sc = sc_Nil; + st = st_Nil; + + expression (&exp); + if (exp.X_op == O_constant) + { + sym = NULL; + value = exp.X_add_number; + addend = 0; + } + else if (exp.X_op == O_symbol) + { + sym = exp.X_add_symbol; + value = 0; + addend = exp.X_add_number; + } + else + { + sym = make_expr_symbol (&exp); + value = 0; + addend = 0; + } + } + + indx = ECOFF_MARK_STAB (type); + } + + /* Don't store the stabs symbol we are creating as the type of the + ECOFF symbol. We want to compute the type of the ECOFF symbol + independently. */ + if (sym != (symbolS *) NULL) + hold = symbol_get_obj (sym)->ecoff_symbol; + + (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx); + + if (sym != (symbolS *) NULL) + symbol_get_obj (sym)->ecoff_symbol = hold; + + /* Restore normal file type. */ + cur_file_ptr = save_file_ptr; +} + +/* Frob an ECOFF symbol. Small common symbols go into a special + .scommon section rather than bfd_com_section. */ + +void +ecoff_frob_symbol (symbolS *sym) +{ + if (S_IS_COMMON (sym) + && S_GET_VALUE (sym) > 0 + && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput)) + { + static asection scom_section; + static asymbol scom_symbol; + + /* We must construct a fake section similar to bfd_com_section + but with the name .scommon. */ + if (scom_section.name == NULL) + { + scom_section = *bfd_com_section_ptr; + scom_section.name = ".scommon"; + scom_section.output_section = &scom_section; + scom_section.symbol = &scom_symbol; + scom_section.symbol_ptr_ptr = &scom_section.symbol; + scom_symbol = *bfd_com_section_ptr->symbol; + scom_symbol.name = ".scommon"; + scom_symbol.section = &scom_section; + } + S_SET_SEGMENT (sym, &scom_section); + } + + /* Double check weak symbols. */ + if (S_IS_WEAK (sym)) + { + if (S_IS_COMMON (sym)) + as_bad (_("symbol `%s' can not be both weak and common"), + S_GET_NAME (sym)); + } +} + +/* Add bytes to the symbolic information buffer. */ + +static char * +ecoff_add_bytes (char **buf, + char **bufend, + char *bufptr, + unsigned long need) +{ + unsigned long at; + unsigned long want; + + at = bufptr - *buf; + need -= *bufend - bufptr; + if (need < PAGE_SIZE) + need = PAGE_SIZE; + want = (*bufend - *buf) + need; + *buf = (char *) xrealloc (*buf, want); + *bufend = *buf + want; + return *buf + at; +} + +/* Adjust the symbolic information buffer to the alignment required + for the ECOFF target debugging information. */ + +static unsigned long +ecoff_padding_adjust (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset, + char **bufptrptr) +{ + bfd_size_type align; + + align = backend->debug_align; + if ((offset & (align - 1)) != 0) + { + unsigned long add; + + add = align - (offset & (align - 1)); + if ((unsigned long) (*bufend - (*buf + offset)) < add) + (void) ecoff_add_bytes (buf, bufend, *buf + offset, add); + memset (*buf + offset, 0, add); + offset += add; + if (bufptrptr != (char **) NULL) + *bufptrptr = *buf + offset; + } + + return offset; +} + +/* Build the line number information. */ + +static unsigned long +ecoff_build_lineno (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset, + long *linecntptr) +{ + char *bufptr; + register lineno_list_t *l; + lineno_list_t *last; + efdr_t *file; + proc_t *proc; + unsigned long c; + long iline; + long totcount; + lineno_list_t first; + lineno_list_t *local_first_lineno = first_lineno; + + if (linecntptr != (long *) NULL) + *linecntptr = 0; + + bufptr = *buf + offset; + + file = (efdr_t *) NULL; + proc = (proc_t *) NULL; + last = (lineno_list_t *) NULL; + c = offset; + iline = 0; + totcount = 0; + + /* FIXME? Now that MIPS embedded-PIC is gone, it may be safe to + remove this code. */ + /* For some reason the address of the first procedure is ignored + when reading line numbers. This doesn't matter if the address of + the first procedure is 0, but when gcc is generating MIPS + embedded PIC code, it will put strings in the .text section + before the first procedure. We cope by inserting a dummy line if + the address of the first procedure is not 0. Hopefully this + won't screw things up too badly. + + Don't do this for ECOFF assembly source line numbers. They work + without this extra attention. */ + if (debug_type != DEBUG_ECOFF + && first_proc_ptr != (proc_t *) NULL + && local_first_lineno != (lineno_list_t *) NULL + && ((S_GET_VALUE (first_proc_ptr->sym->as_sym) + + bfd_get_section_vma (stdoutput, + S_GET_SEGMENT (first_proc_ptr->sym->as_sym))) + != 0)) + { + first.file = local_first_lineno->file; + first.proc = local_first_lineno->proc; + first.frag = &zero_address_frag; + first.paddr = 0; + first.lineno = 0; + + first.next = local_first_lineno; + local_first_lineno = &first; + } + + for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next) + { + long count; + long delta; + + /* Get the offset to the memory address of the next line number + (in words). Do this first, so that we can skip ahead to the + next useful line number entry. */ + if (l->next == (lineno_list_t *) NULL) + { + /* We want a count of zero, but it will be decremented + before it is used. */ + count = 1; + } + else if (l->next->frag->fr_address + l->next->paddr + > l->frag->fr_address + l->paddr) + { + count = ((l->next->frag->fr_address + l->next->paddr + - (l->frag->fr_address + l->paddr)) + >> 2); + } + else + { + /* Don't change last, so we still get the right delta. */ + continue; + } + + if (l->file != file || l->proc != proc) + { + if (l->proc != proc && proc != (proc_t *) NULL) + proc->pdr.lnHigh = last->lineno; + if (l->file != file && file != (efdr_t *) NULL) + { + file->fdr.cbLine = c - file->fdr.cbLineOffset; + file->fdr.cline = totcount + count; + if (linecntptr != (long *) NULL) + *linecntptr += totcount + count; + totcount = 0; + } + + if (l->file != file) + { + efdr_t *last_file = file; + + file = l->file; + if (last_file != (efdr_t *) NULL) + file->fdr.ilineBase + = last_file->fdr.ilineBase + last_file->fdr.cline; + else + file->fdr.ilineBase = 0; + file->fdr.cbLineOffset = c; + } + if (l->proc != proc) + { + proc = l->proc; + if (proc != (proc_t *) NULL) + { + proc->pdr.lnLow = l->lineno; + proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset; + proc->pdr.iline = totcount; + } + } + + last = (lineno_list_t *) NULL; + } + + totcount += count; + + /* Get the offset to this line number. */ + if (last == (lineno_list_t *) NULL) + delta = 0; + else + delta = l->lineno - last->lineno; + + /* Put in the offset to this line number. */ + while (delta != 0) + { + int setcount; + + /* 1 is added to each count read. */ + --count; + /* We can only adjust the word count by up to 15 words at a + time. */ + if (count <= 0x0f) + { + setcount = count; + count = 0; + } + else + { + setcount = 0x0f; + count -= 0x0f; + } + if (delta >= -7 && delta <= 7) + { + if (bufptr >= *bufend) + bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1); + *bufptr++ = setcount + (delta << 4); + delta = 0; + ++c; + } + else + { + int set; + + if (*bufend - bufptr < 3) + bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3); + *bufptr++ = setcount + (8 << 4); + if (delta < -0x8000) + { + set = -0x8000; + delta += 0x8000; + } + else if (delta > 0x7fff) + { + set = 0x7fff; + delta -= 0x7fff; + } + else + { + set = delta; + delta = 0; + } + *bufptr++ = set >> 8; + *bufptr++ = set & 0xffff; + c += 3; + } + } + + /* Finish adjusting the count. */ + while (count > 0) + { + if (bufptr >= *bufend) + bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1); + /* 1 is added to each count read. */ + --count; + if (count > 0x0f) + { + *bufptr++ = 0x0f; + count -= 0x0f; + } + else + { + *bufptr++ = count; + count = 0; + } + ++c; + } + + ++iline; + last = l; + } + + if (proc != (proc_t *) NULL) + proc->pdr.lnHigh = last->lineno; + if (file != (efdr_t *) NULL) + { + file->fdr.cbLine = c - file->fdr.cbLineOffset; + file->fdr.cline = totcount; + } + + if (linecntptr != (long *) NULL) + *linecntptr += totcount; + + c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr); + + return c; +} + +/* Build and swap out the symbols. */ + +static unsigned long +ecoff_build_symbols (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset) +{ + const bfd_size_type external_sym_size = backend->external_sym_size; + void (* const swap_sym_out) (bfd *, const SYMR *, void *) + = backend->swap_sym_out; + char *sym_out; + long isym; + vlinks_t *file_link; + + sym_out = *buf + offset; + + isym = 0; + + /* The symbols are stored by file. */ + for (file_link = file_desc.first; + file_link != (vlinks_t *) NULL; + file_link = file_link->next) + { + int ifilesym; + int fil_cnt; + efdr_t *fil_ptr; + efdr_t *fil_end; + + if (file_link->next == (vlinks_t *) NULL) + fil_cnt = file_desc.objects_last_page; + else + fil_cnt = file_desc.objects_per_page; + fil_ptr = file_link->datum->file; + fil_end = fil_ptr + fil_cnt; + for (; fil_ptr < fil_end; fil_ptr++) + { + vlinks_t *sym_link; + + fil_ptr->fdr.isymBase = isym; + ifilesym = isym; + for (sym_link = fil_ptr->symbols.first; + sym_link != (vlinks_t *) NULL; + sym_link = sym_link->next) + { + int sym_cnt; + localsym_t *sym_ptr; + localsym_t *sym_end; + + if (sym_link->next == (vlinks_t *) NULL) + sym_cnt = fil_ptr->symbols.objects_last_page; + else + sym_cnt = fil_ptr->symbols.objects_per_page; + sym_ptr = sym_link->datum->sym; + sym_end = sym_ptr + sym_cnt; + for (; sym_ptr < sym_end; sym_ptr++) + { + int local; + symbolS *as_sym; + forward_t *f; + + know (sym_ptr->file_ptr == fil_ptr); + + /* If there is no associated gas symbol, then this + is a pure debugging symbol. We have already + added the name (if any) to fil_ptr->strings. + Otherwise we must decide whether this is an + external or a local symbol (actually, it may be + both if the local provides additional debugging + information for the external). */ + local = 1; + as_sym = sym_ptr->as_sym; + if (as_sym != (symbolS *) NULL) + { + symint_t indx; + + /* The value of a block start symbol is the + offset from the start of the procedure. For + other symbols we just use the gas value (but + we must offset it by the vma of the section, + just as BFD does, because BFD will not see + this value). */ + if (sym_ptr->ecoff_sym.asym.st == (int) st_Block + && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text) + { + symbolS *begin_sym; + + know (sym_ptr->proc_ptr != (proc_t *) NULL); + begin_sym = sym_ptr->proc_ptr->sym->as_sym; + if (S_GET_SEGMENT (as_sym) + != S_GET_SEGMENT (begin_sym)) + as_warn (_(".begin/.bend in different segments")); + sym_ptr->ecoff_sym.asym.value = + S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym); + } + else + sym_ptr->ecoff_sym.asym.value = + (S_GET_VALUE (as_sym) + + bfd_get_section_vma (stdoutput, + S_GET_SEGMENT (as_sym)) + + sym_ptr->addend); + + sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym); + + /* Set st_Proc to st_StaticProc for local + functions. */ + if (sym_ptr->ecoff_sym.asym.st == st_Proc + && S_IS_DEFINED (as_sym) + && ! S_IS_EXTERNAL (as_sym) + && ! S_IS_WEAK (as_sym)) + sym_ptr->ecoff_sym.asym.st = st_StaticProc; + + /* Get the type and storage class based on where + the symbol actually wound up. Traditionally, + N_LBRAC and N_RBRAC are *not* relocated. */ + indx = sym_ptr->ecoff_sym.asym.index; + if (sym_ptr->ecoff_sym.asym.st == st_Nil + && sym_ptr->ecoff_sym.asym.sc == sc_Nil + && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym) + || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC) + && (ECOFF_UNMARK_STAB (indx) != N_RBRAC)))) + { + segT seg; + const char *segname; + st_t st; + sc_t sc; + + seg = S_GET_SEGMENT (as_sym); + segname = segment_name (seg); + + if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym) + && (S_IS_EXTERNAL (as_sym) + || S_IS_WEAK (as_sym) + || ! S_IS_DEFINED (as_sym))) + { + if ((symbol_get_bfdsym (as_sym)->flags + & BSF_FUNCTION) != 0) + st = st_Proc; + else + st = st_Global; + } + else if (seg == text_section) + st = st_Label; + else + st = st_Static; + + if (! S_IS_DEFINED (as_sym)) + { + valueT s; + + s = symbol_get_obj (as_sym)->ecoff_extern_size; + if (s == 0 + || s > bfd_get_gp_size (stdoutput)) + sc = sc_Undefined; + else + { + sc = sc_SUndefined; + sym_ptr->ecoff_sym.asym.value = s; + } +#ifdef S_SET_SIZE + S_SET_SIZE (as_sym, s); +#endif + } + else if (S_IS_COMMON (as_sym)) + { + if (S_GET_VALUE (as_sym) > 0 + && (S_GET_VALUE (as_sym) + <= bfd_get_gp_size (stdoutput))) + sc = sc_SCommon; + else + sc = sc_Common; + } + else if (seg == text_section) + sc = sc_Text; + else if (seg == data_section) + sc = sc_Data; + else if (strcmp (segname, ".rdata") == 0 + || strcmp (segname, ".rodata") == 0) + sc = sc_RData; + else if (strcmp (segname, ".sdata") == 0) + sc = sc_SData; + else if (seg == bss_section) + sc = sc_Bss; + else if (strcmp (segname, ".sbss") == 0) + sc = sc_SBss; + else if (seg == bfd_abs_section_ptr) + sc = sc_Abs; + else + { + /* This must be a user named section. + This is not possible in ECOFF, but it + is in ELF. */ + sc = sc_Data; + } + + sym_ptr->ecoff_sym.asym.st = (int) st; + sym_ptr->ecoff_sym.asym.sc = (int) sc; + } + + /* This is just an external symbol if it is + outside a procedure and it has a type. + FIXME: g++ will generate symbols which have + different names in the debugging information + than the actual symbol. Should we handle + them here? */ + if ((S_IS_EXTERNAL (as_sym) + || S_IS_WEAK (as_sym) + || ! S_IS_DEFINED (as_sym)) + && sym_ptr->proc_ptr == (proc_t *) NULL + && sym_ptr->ecoff_sym.asym.st != (int) st_Nil + && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)) + local = 0; + + /* This is just an external symbol if it is a + common symbol. */ + if (S_IS_COMMON (as_sym)) + local = 0; + + /* If an st_end symbol has an associated gas + symbol, then it is a local label created for + a .bend or .end directive. Stabs line + numbers will have \001 in the names. */ + if (local + && sym_ptr->ecoff_sym.asym.st != st_End + && strchr (sym_ptr->name, '\001') == 0) + sym_ptr->ecoff_sym.asym.iss = + add_string (&fil_ptr->strings, + fil_ptr->str_hash, + sym_ptr->name, + (shash_t **) NULL); + } + + /* We now know the index of this symbol; fill in + locations that have been waiting for that + information. */ + if (sym_ptr->begin_ptr != (localsym_t *) NULL) + { + localsym_t *begin_ptr; + st_t begin_type; + + know (local); + begin_ptr = sym_ptr->begin_ptr; + know (begin_ptr->sym_index != -1); + sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index; + if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info) + sym_ptr->ecoff_sym.asym.iss = + begin_ptr->ecoff_sym.asym.iss; + + begin_type = (st_t) begin_ptr->ecoff_sym.asym.st; + if (begin_type == st_File + || begin_type == st_Block) + { + begin_ptr->ecoff_sym.asym.index = + isym - ifilesym + 1; + (*swap_sym_out) (stdoutput, + &begin_ptr->ecoff_sym.asym, + (*buf + + offset + + (begin_ptr->sym_index + * external_sym_size))); + } + else + { + know (begin_ptr->index_ptr != (aux_t *) NULL); + begin_ptr->index_ptr->data.isym = + isym - ifilesym + 1; + } + + /* The value of the symbol marking the end of a + procedure is the size of the procedure. The + value of the symbol marking the end of a + block is the offset from the start of the + procedure to the block. */ + if (begin_type == st_Proc + || begin_type == st_StaticProc) + { + know (as_sym != (symbolS *) NULL); + know (begin_ptr->as_sym != (symbolS *) NULL); + if (S_GET_SEGMENT (as_sym) + != S_GET_SEGMENT (begin_ptr->as_sym)) + as_warn (_(".begin/.bend in different segments")); + sym_ptr->ecoff_sym.asym.value = + (S_GET_VALUE (as_sym) + - S_GET_VALUE (begin_ptr->as_sym)); + + /* If the size is odd, this is probably a + mips16 function; force it to be even. */ + if ((sym_ptr->ecoff_sym.asym.value & 1) != 0) + ++sym_ptr->ecoff_sym.asym.value; + +#ifdef S_SET_SIZE + S_SET_SIZE (begin_ptr->as_sym, + sym_ptr->ecoff_sym.asym.value); +#endif + } + else if (begin_type == st_Block + && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info) + { + symbolS *begin_sym; + + know (as_sym != (symbolS *) NULL); + know (sym_ptr->proc_ptr != (proc_t *) NULL); + begin_sym = sym_ptr->proc_ptr->sym->as_sym; + if (S_GET_SEGMENT (as_sym) + != S_GET_SEGMENT (begin_sym)) + as_warn (_(".begin/.bend in different segments")); + sym_ptr->ecoff_sym.asym.value = + S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym); + } + } + + for (f = sym_ptr->forward_ref; + f != (forward_t *) NULL; + f = f->next) + { + know (local); + f->ifd_ptr->data.isym = fil_ptr->file_index; + f->index_ptr->data.rndx.index = isym - ifilesym; + } + + if (local) + { + if ((bfd_size_type)(*bufend - sym_out) < external_sym_size) + sym_out = ecoff_add_bytes (buf, bufend, + sym_out, + external_sym_size); + (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym, + sym_out); + sym_out += external_sym_size; + + sym_ptr->sym_index = isym; + + if (sym_ptr->proc_ptr != (proc_t *) NULL + && sym_ptr->proc_ptr->sym == sym_ptr) + sym_ptr->proc_ptr->pdr.isym = isym - ifilesym; + + ++isym; + } + + /* Record the local symbol index and file number in + case this is an external symbol. Note that this + destroys the asym.index field. */ + if (as_sym != (symbolS *) NULL + && symbol_get_obj (as_sym)->ecoff_symbol == sym_ptr) + { + if ((sym_ptr->ecoff_sym.asym.st == st_Proc + || sym_ptr->ecoff_sym.asym.st == st_StaticProc) + && local) + sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1; + sym_ptr->ecoff_sym.ifd = fil_ptr->file_index; + + /* Don't try to merge an FDR which has an + external symbol attached to it. */ + if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym)) + fil_ptr->fdr.fMerge = 0; + } + } + } + fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase; + } + } + + return offset + isym * external_sym_size; +} + +/* Swap out the procedure information. */ + +static unsigned long +ecoff_build_procs (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset) +{ + const bfd_size_type external_pdr_size = backend->external_pdr_size; + void (* const swap_pdr_out) (bfd *, const PDR *, void *) + = backend->swap_pdr_out; + char *pdr_out; + long iproc; + vlinks_t *file_link; + + pdr_out = *buf + offset; + + iproc = 0; + + /* The procedures are stored by file. */ + for (file_link = file_desc.first; + file_link != (vlinks_t *) NULL; + file_link = file_link->next) + { + int fil_cnt; + efdr_t *fil_ptr; + efdr_t *fil_end; + + if (file_link->next == (vlinks_t *) NULL) + fil_cnt = file_desc.objects_last_page; + else + fil_cnt = file_desc.objects_per_page; + fil_ptr = file_link->datum->file; + fil_end = fil_ptr + fil_cnt; + for (; fil_ptr < fil_end; fil_ptr++) + { + vlinks_t *proc_link; + int first; + + fil_ptr->fdr.ipdFirst = iproc; + first = 1; + for (proc_link = fil_ptr->procs.first; + proc_link != (vlinks_t *) NULL; + proc_link = proc_link->next) + { + int prc_cnt; + proc_t *proc_ptr; + proc_t *proc_end; + + if (proc_link->next == (vlinks_t *) NULL) + prc_cnt = fil_ptr->procs.objects_last_page; + else + prc_cnt = fil_ptr->procs.objects_per_page; + proc_ptr = proc_link->datum->proc; + proc_end = proc_ptr + prc_cnt; + for (; proc_ptr < proc_end; proc_ptr++) + { + symbolS *adr_sym; + unsigned long adr; + + adr_sym = proc_ptr->sym->as_sym; + adr = (S_GET_VALUE (adr_sym) + + bfd_get_section_vma (stdoutput, + S_GET_SEGMENT (adr_sym))); + if (first) + { + /* This code used to force the adr of the very + first fdr to be 0. However, the native tools + don't do that, and I can't remember why it + used to work that way, so I took it out. */ + fil_ptr->fdr.adr = adr; + first = 0; + } + proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr; + if ((bfd_size_type)(*bufend - pdr_out) < external_pdr_size) + pdr_out = ecoff_add_bytes (buf, bufend, + pdr_out, + external_pdr_size); + (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out); + pdr_out += external_pdr_size; + ++iproc; + } + } + fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst; + } + } + + return offset + iproc * external_pdr_size; +} + +/* Swap out the aux information. */ + +static unsigned long +ecoff_build_aux (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset) +{ + int bigendian; + union aux_ext *aux_out; + long iaux; + vlinks_t *file_link; + + bigendian = bfd_big_endian (stdoutput); + + aux_out = (union aux_ext *) (*buf + offset); + + iaux = 0; + + /* The aux entries are stored by file. */ + for (file_link = file_desc.first; + file_link != (vlinks_t *) NULL; + file_link = file_link->next) + { + int fil_cnt; + efdr_t *fil_ptr; + efdr_t *fil_end; + + if (file_link->next == (vlinks_t *) NULL) + fil_cnt = file_desc.objects_last_page; + else + fil_cnt = file_desc.objects_per_page; + fil_ptr = file_link->datum->file; + fil_end = fil_ptr + fil_cnt; + for (; fil_ptr < fil_end; fil_ptr++) + { + vlinks_t *aux_link; + + fil_ptr->fdr.fBigendian = bigendian; + fil_ptr->fdr.iauxBase = iaux; + for (aux_link = fil_ptr->aux_syms.first; + aux_link != (vlinks_t *) NULL; + aux_link = aux_link->next) + { + int aux_cnt; + aux_t *aux_ptr; + aux_t *aux_end; + + if (aux_link->next == (vlinks_t *) NULL) + aux_cnt = fil_ptr->aux_syms.objects_last_page; + else + aux_cnt = fil_ptr->aux_syms.objects_per_page; + aux_ptr = aux_link->datum->aux; + aux_end = aux_ptr + aux_cnt; + for (; aux_ptr < aux_end; aux_ptr++) + { + if ((unsigned long) (*bufend - (char *) aux_out) + < sizeof (union aux_ext)) + aux_out = ((union aux_ext *) + ecoff_add_bytes (buf, bufend, + (char *) aux_out, + sizeof (union aux_ext))); + switch (aux_ptr->type) + { + case aux_tir: + (*backend->swap_tir_out) (bigendian, + &aux_ptr->data.ti, + &aux_out->a_ti); + break; + case aux_rndx: + (*backend->swap_rndx_out) (bigendian, + &aux_ptr->data.rndx, + &aux_out->a_rndx); + break; + case aux_dnLow: + AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow, + aux_out); + break; + case aux_dnHigh: + AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh, + aux_out); + break; + case aux_isym: + AUX_PUT_ISYM (bigendian, aux_ptr->data.isym, + aux_out); + break; + case aux_iss: + AUX_PUT_ISS (bigendian, aux_ptr->data.iss, + aux_out); + break; + case aux_width: + AUX_PUT_WIDTH (bigendian, aux_ptr->data.width, + aux_out); + break; + case aux_count: + AUX_PUT_COUNT (bigendian, aux_ptr->data.count, + aux_out); + break; + } + + ++aux_out; + ++iaux; + } + } + fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase; + } + } + + return ecoff_padding_adjust (backend, buf, bufend, + offset + iaux * sizeof (union aux_ext), + (char **) NULL); +} + +/* Copy out the strings from a varray_t. This returns the number of + bytes copied, rather than the new offset. */ + +static unsigned long +ecoff_build_strings (char **buf, + char **bufend, + unsigned long offset, + varray_t *vp) +{ + unsigned long istr; + char *str_out; + vlinks_t *str_link; + + str_out = *buf + offset; + + istr = 0; + + for (str_link = vp->first; + str_link != (vlinks_t *) NULL; + str_link = str_link->next) + { + unsigned long str_cnt; + + if (str_link->next == (vlinks_t *) NULL) + str_cnt = vp->objects_last_page; + else + str_cnt = vp->objects_per_page; + + if ((unsigned long)(*bufend - str_out) < str_cnt) + str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt); + + memcpy (str_out, str_link->datum->byte, str_cnt); + str_out += str_cnt; + istr += str_cnt; + } + + return istr; +} + +/* Dump out the local strings. */ + +static unsigned long +ecoff_build_ss (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset) +{ + long iss; + vlinks_t *file_link; + + iss = 0; + + for (file_link = file_desc.first; + file_link != (vlinks_t *) NULL; + file_link = file_link->next) + { + int fil_cnt; + efdr_t *fil_ptr; + efdr_t *fil_end; + + if (file_link->next == (vlinks_t *) NULL) + fil_cnt = file_desc.objects_last_page; + else + fil_cnt = file_desc.objects_per_page; + fil_ptr = file_link->datum->file; + fil_end = fil_ptr + fil_cnt; + for (; fil_ptr < fil_end; fil_ptr++) + { + long ss_cnt; + + fil_ptr->fdr.issBase = iss; + ss_cnt = ecoff_build_strings (buf, bufend, offset + iss, + &fil_ptr->strings); + fil_ptr->fdr.cbSs = ss_cnt; + iss += ss_cnt; + } + } + + return ecoff_padding_adjust (backend, buf, bufend, offset + iss, + (char **) NULL); +} + +/* Swap out the file descriptors. */ + +static unsigned long +ecoff_build_fdr (const struct ecoff_debug_swap *backend, + char **buf, + char **bufend, + unsigned long offset) +{ + const bfd_size_type external_fdr_size = backend->external_fdr_size; + void (* const swap_fdr_out) (bfd *, const FDR *, void *) + = backend->swap_fdr_out; + long ifile; + char *fdr_out; + vlinks_t *file_link; + + ifile = 0; + + fdr_out = *buf + offset; + + for (file_link = file_desc.first; + file_link != (vlinks_t *) NULL; + file_link = file_link->next) + { + int fil_cnt; + efdr_t *fil_ptr; + efdr_t *fil_end; + + if (file_link->next == (vlinks_t *) NULL) + fil_cnt = file_desc.objects_last_page; + else + fil_cnt = file_desc.objects_per_page; + fil_ptr = file_link->datum->file; + fil_end = fil_ptr + fil_cnt; + for (; fil_ptr < fil_end; fil_ptr++) + { + if ((bfd_size_type)(*bufend - fdr_out) < external_fdr_size) + fdr_out = ecoff_add_bytes (buf, bufend, fdr_out, + external_fdr_size); + (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out); + fdr_out += external_fdr_size; + ++ifile; + } + } + + return offset + ifile * external_fdr_size; +} + +/* Set up the external symbols. These are supposed to be handled by + the backend. This routine just gets the right information and + calls a backend function to deal with it. */ + +static void +ecoff_setup_ext (void) +{ + register symbolS *sym; + + for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym)) + { + if (symbol_get_obj (sym)->ecoff_symbol == NULL) + continue; + + /* If this is a local symbol, then force the fields to zero. */ + if (! S_IS_EXTERNAL (sym) + && ! S_IS_WEAK (sym) + && S_IS_DEFINED (sym)) + { + struct localsym *lsym; + + lsym = symbol_get_obj (sym)->ecoff_symbol; + lsym->ecoff_sym.asym.value = 0; + lsym->ecoff_sym.asym.st = (int) st_Nil; + lsym->ecoff_sym.asym.sc = (int) sc_Nil; + lsym->ecoff_sym.asym.index = indexNil; + } + + obj_ecoff_set_ext (sym, &symbol_get_obj (sym)->ecoff_symbol->ecoff_sym); + } +} + +/* Build the ECOFF debugging information. */ + +unsigned long +ecoff_build_debug (HDRR *hdr, + char **bufp, + const struct ecoff_debug_swap *backend) +{ + const bfd_size_type external_pdr_size = backend->external_pdr_size; + tag_t *ptag; + tag_t *ptag_next; + efdr_t *fil_ptr; + int end_warning; + efdr_t *hold_file_ptr; + proc_t *hold_proc_ptr; + symbolS *sym; + char *buf; + char *bufend; + unsigned long offset; + + /* Make sure we have a file. */ + if (first_file == (efdr_t *) NULL) + add_file ((const char *) NULL, 0, 1); + + /* Handle any top level tags. */ + for (ptag = top_tag_head->first_tag; + ptag != (tag_t *) NULL; + ptag = ptag_next) + { + if (ptag->forward_ref != (forward_t *) NULL) + add_unknown_tag (ptag); + + ptag_next = ptag->same_block; + ptag->hash_ptr->tag_ptr = ptag->same_name; + free_tag (ptag); + } + + free_thead (top_tag_head); + + /* Look through the symbols. Add debugging information for each + symbol that has not already received it. */ + hold_file_ptr = cur_file_ptr; + hold_proc_ptr = cur_proc_ptr; + cur_proc_ptr = (proc_t *) NULL; + for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym)) + { + if (symbol_get_obj (sym)->ecoff_symbol != NULL + || symbol_get_obj (sym)->ecoff_file == (efdr_t *) NULL + || (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0) + continue; + + cur_file_ptr = symbol_get_obj (sym)->ecoff_file; + add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym, + (bfd_vma) 0, S_GET_VALUE (sym), indexNil); + } + cur_proc_ptr = hold_proc_ptr; + cur_file_ptr = hold_file_ptr; + + /* Output an ending symbol for all the files. We have to do this + here for the last file, so we may as well do it for all of the + files. */ + end_warning = 0; + for (fil_ptr = first_file; + fil_ptr != (efdr_t *) NULL; + fil_ptr = fil_ptr->next_file) + { + cur_file_ptr = fil_ptr; + while (cur_file_ptr->cur_scope != (scope_t *) NULL + && cur_file_ptr->cur_scope->prev != (scope_t *) NULL) + { + cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev; + if (! end_warning && ! cur_file_ptr->fake) + { + as_warn (_("missing .end or .bend at end of file")); + end_warning = 1; + } + } + if (cur_file_ptr->cur_scope != (scope_t *) NULL) + (void) add_ecoff_symbol ((const char *) NULL, + st_End, sc_Text, + (symbolS *) NULL, + (bfd_vma) 0, + (symint_t) 0, + (symint_t) 0); + } + + /* Build the symbolic information. */ + offset = 0; + buf = (char *) xmalloc (PAGE_SIZE); + bufend = buf + PAGE_SIZE; + + /* Build the line number information. */ + hdr->cbLineOffset = offset; + offset = ecoff_build_lineno (backend, &buf, &bufend, offset, + &hdr->ilineMax); + hdr->cbLine = offset - hdr->cbLineOffset; + + /* We don't use dense numbers at all. */ + hdr->idnMax = 0; + hdr->cbDnOffset = 0; + + /* We can't build the PDR table until we have built the symbols, + because a PDR contains a symbol index. However, we set aside + space at this point. */ + hdr->ipdMax = proc_cnt; + hdr->cbPdOffset = offset; + if ((bfd_size_type)(bufend - (buf + offset)) < proc_cnt * external_pdr_size) + (void) ecoff_add_bytes (&buf, &bufend, buf + offset, + proc_cnt * external_pdr_size); + offset += proc_cnt * external_pdr_size; + + /* Build the local symbols. */ + hdr->cbSymOffset = offset; + offset = ecoff_build_symbols (backend, &buf, &bufend, offset); + hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size; + + /* Building the symbols initializes the symbol index in the PDR's. + Now we can swap out the PDR's. */ + (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset); + + /* We don't use optimization symbols. */ + hdr->ioptMax = 0; + hdr->cbOptOffset = 0; + + /* Swap out the auxiliary type information. */ + hdr->cbAuxOffset = offset; + offset = ecoff_build_aux (backend, &buf, &bufend, offset); + hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext); + + /* Copy out the local strings. */ + hdr->cbSsOffset = offset; + offset = ecoff_build_ss (backend, &buf, &bufend, offset); + hdr->issMax = offset - hdr->cbSsOffset; + + /* We don't use relative file descriptors. */ + hdr->crfd = 0; + hdr->cbRfdOffset = 0; + + /* Swap out the file descriptors. */ + hdr->cbFdOffset = offset; + offset = ecoff_build_fdr (backend, &buf, &bufend, offset); + hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size; + + /* Set up the external symbols, which are handled by the BFD back + end. */ + hdr->issExtMax = 0; + hdr->cbSsExtOffset = 0; + hdr->iextMax = 0; + hdr->cbExtOffset = 0; + ecoff_setup_ext (); + + know ((offset & (backend->debug_align - 1)) == 0); + + /* FIXME: This value should be determined from the .verstamp directive, + with reasonable defaults in config files. */ +#ifdef TC_ALPHA + hdr->vstamp = 0x030b; +#else + hdr->vstamp = 0x020b; +#endif + + *bufp = buf; + return offset; +} + +/* Allocate a cluster of pages. */ + +#ifndef MALLOC_CHECK + +static page_type * +allocate_cluster (unsigned long npages) +{ + register page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE); + +#ifdef ECOFF_DEBUG + if (debug > 3) + fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value); +#endif + + memset (value, 0, npages * PAGE_USIZE); + + return value; +} + +static page_type *cluster_ptr = NULL; +static unsigned long pages_left = 0; + +#endif /* MALLOC_CHECK */ + +/* Allocate one page (which is initialized to 0). */ + +static page_type * +allocate_page (void) +{ +#ifndef MALLOC_CHECK + + if (pages_left == 0) + { + pages_left = MAX_CLUSTER_PAGES; + cluster_ptr = allocate_cluster (pages_left); + } + + pages_left--; + return cluster_ptr++; + +#else /* MALLOC_CHECK */ + + page_type *ptr; + + ptr = xmalloc (PAGE_USIZE); + memset (ptr, 0, PAGE_USIZE); + return ptr; + +#endif /* MALLOC_CHECK */ +} + +/* Allocate scoping information. */ + +static scope_t * +allocate_scope (void) +{ + register scope_t *ptr; + static scope_t initial_scope; + +#ifndef MALLOC_CHECK + + ptr = alloc_counts[(int) alloc_type_scope].free_list.f_scope; + if (ptr != (scope_t *) NULL) + alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr->free; + else + { + register int unallocated = alloc_counts[(int) alloc_type_scope].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_scope].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (scope_t); + alloc_counts[(int) alloc_type_scope].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_scope].total_pages++; + } + + ptr = &cur_page->scope[--unallocated]; + alloc_counts[(int) alloc_type_scope].unallocated = unallocated; + } + +#else + + ptr = (scope_t *) xmalloc (sizeof (scope_t)); + +#endif + + alloc_counts[(int) alloc_type_scope].total_alloc++; + *ptr = initial_scope; + return ptr; +} + +/* Free scoping information. */ + +static void +free_scope (scope_t *ptr) +{ + alloc_counts[(int) alloc_type_scope].total_free++; + +#ifndef MALLOC_CHECK + ptr->free = alloc_counts[(int) alloc_type_scope].free_list.f_scope; + alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr; +#else + free ((void *) ptr); +#endif +} + +/* Allocate links for pages in a virtual array. */ + +static vlinks_t * +allocate_vlinks (void) +{ + register vlinks_t *ptr; + static vlinks_t initial_vlinks; + +#ifndef MALLOC_CHECK + + register int unallocated = alloc_counts[(int) alloc_type_vlinks].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_vlinks].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (vlinks_t); + alloc_counts[(int) alloc_type_vlinks].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_vlinks].total_pages++; + } + + ptr = &cur_page->vlinks[--unallocated]; + alloc_counts[(int) alloc_type_vlinks].unallocated = unallocated; + +#else + + ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t)); + +#endif + + alloc_counts[(int) alloc_type_vlinks].total_alloc++; + *ptr = initial_vlinks; + return ptr; +} + +/* Allocate string hash buckets. */ + +static shash_t * +allocate_shash (void) +{ + register shash_t *ptr; + static shash_t initial_shash; + +#ifndef MALLOC_CHECK + + register int unallocated = alloc_counts[(int) alloc_type_shash].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_shash].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (shash_t); + alloc_counts[(int) alloc_type_shash].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_shash].total_pages++; + } + + ptr = &cur_page->shash[--unallocated]; + alloc_counts[(int) alloc_type_shash].unallocated = unallocated; + +#else + + ptr = (shash_t *) xmalloc (sizeof (shash_t)); + +#endif + + alloc_counts[(int) alloc_type_shash].total_alloc++; + *ptr = initial_shash; + return ptr; +} + +/* Allocate type hash buckets. */ + +static thash_t * +allocate_thash (void) +{ + register thash_t *ptr; + static thash_t initial_thash; + +#ifndef MALLOC_CHECK + + register int unallocated = alloc_counts[(int) alloc_type_thash].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_thash].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (thash_t); + alloc_counts[(int) alloc_type_thash].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_thash].total_pages++; + } + + ptr = &cur_page->thash[--unallocated]; + alloc_counts[(int) alloc_type_thash].unallocated = unallocated; + +#else + + ptr = (thash_t *) xmalloc (sizeof (thash_t)); + +#endif + + alloc_counts[(int) alloc_type_thash].total_alloc++; + *ptr = initial_thash; + return ptr; +} + +/* Allocate structure, union, or enum tag information. */ + +static tag_t * +allocate_tag (void) +{ + register tag_t *ptr; + static tag_t initial_tag; + +#ifndef MALLOC_CHECK + + ptr = alloc_counts[(int) alloc_type_tag].free_list.f_tag; + if (ptr != (tag_t *) NULL) + alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr->free; + else + { + register int unallocated = alloc_counts[(int) alloc_type_tag].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_tag].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (tag_t); + alloc_counts[(int) alloc_type_tag].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_tag].total_pages++; + } + + ptr = &cur_page->tag[--unallocated]; + alloc_counts[(int) alloc_type_tag].unallocated = unallocated; + } + +#else + + ptr = (tag_t *) xmalloc (sizeof (tag_t)); + +#endif + + alloc_counts[(int) alloc_type_tag].total_alloc++; + *ptr = initial_tag; + return ptr; +} + +/* Free scoping information. */ + +static void +free_tag (tag_t *ptr) +{ + alloc_counts[(int) alloc_type_tag].total_free++; + +#ifndef MALLOC_CHECK + ptr->free = alloc_counts[(int) alloc_type_tag].free_list.f_tag; + alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr; +#else + free ((PTR_T) ptr); +#endif +} + +/* Allocate forward reference to a yet unknown tag. */ + +static forward_t * +allocate_forward (void) +{ + register forward_t *ptr; + static forward_t initial_forward; + +#ifndef MALLOC_CHECK + + register int unallocated = alloc_counts[(int) alloc_type_forward].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_forward].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (forward_t); + alloc_counts[(int) alloc_type_forward].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_forward].total_pages++; + } + + ptr = &cur_page->forward[--unallocated]; + alloc_counts[(int) alloc_type_forward].unallocated = unallocated; + +#else + + ptr = (forward_t *) xmalloc (sizeof (forward_t)); + +#endif + + alloc_counts[(int) alloc_type_forward].total_alloc++; + *ptr = initial_forward; + return ptr; +} + +/* Allocate head of type hash list. */ + +static thead_t * +allocate_thead (void) +{ + register thead_t *ptr; + static thead_t initial_thead; + +#ifndef MALLOC_CHECK + + ptr = alloc_counts[(int) alloc_type_thead].free_list.f_thead; + if (ptr != (thead_t *) NULL) + alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr->free; + else + { + register int unallocated = alloc_counts[(int) alloc_type_thead].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_thead].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (thead_t); + alloc_counts[(int) alloc_type_thead].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_thead].total_pages++; + } + + ptr = &cur_page->thead[--unallocated]; + alloc_counts[(int) alloc_type_thead].unallocated = unallocated; + } + +#else + + ptr = (thead_t *) xmalloc (sizeof (thead_t)); + +#endif + + alloc_counts[(int) alloc_type_thead].total_alloc++; + *ptr = initial_thead; + return ptr; +} + +/* Free scoping information. */ + +static void +free_thead (thead_t *ptr) +{ + alloc_counts[(int) alloc_type_thead].total_free++; + +#ifndef MALLOC_CHECK + ptr->free = (thead_t *) alloc_counts[(int) alloc_type_thead].free_list.f_thead; + alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr; +#else + free ((PTR_T) ptr); +#endif +} + +static lineno_list_t * +allocate_lineno_list (void) +{ + register lineno_list_t *ptr; + static lineno_list_t initial_lineno_list; + +#ifndef MALLOC_CHECK + + register int unallocated = alloc_counts[(int) alloc_type_lineno].unallocated; + register page_type *cur_page = alloc_counts[(int) alloc_type_lineno].cur_page; + + if (unallocated == 0) + { + unallocated = PAGE_SIZE / sizeof (lineno_list_t); + alloc_counts[(int) alloc_type_lineno].cur_page = cur_page = allocate_page (); + alloc_counts[(int) alloc_type_lineno].total_pages++; + } + + ptr = &cur_page->lineno[--unallocated]; + alloc_counts[(int) alloc_type_lineno].unallocated = unallocated; + +#else + + ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t)); + +#endif + + alloc_counts[(int) alloc_type_lineno].total_alloc++; + *ptr = initial_lineno_list; + return ptr; +} + +void +ecoff_set_gp_prolog_size (int sz) +{ + if (cur_proc_ptr == 0) + return; + + cur_proc_ptr->pdr.gp_prologue = sz; + if (cur_proc_ptr->pdr.gp_prologue != sz) + { + as_warn (_("GP prologue size exceeds field size, using 0 instead")); + cur_proc_ptr->pdr.gp_prologue = 0; + } + + cur_proc_ptr->pdr.gp_used = 1; +} + +int +ecoff_no_current_file (void) +{ + return cur_file_ptr == (efdr_t *) NULL; +} + +void +ecoff_generate_asm_lineno (void) +{ + unsigned int lineno; + char *filename; + lineno_list_t *list; + + as_where (&filename, &lineno); + + if (current_stabs_filename == (char *) NULL + || filename_cmp (current_stabs_filename, filename)) + add_file (filename, 0, 1); + + list = allocate_lineno_list (); + + list->next = (lineno_list_t *) NULL; + list->file = cur_file_ptr; + list->proc = cur_proc_ptr; + list->frag = frag_now; + list->paddr = frag_now_fix (); + list->lineno = lineno; + + /* We don't want to merge files which have line numbers. */ + cur_file_ptr->fdr.fMerge = 0; + + /* A .loc directive will sometimes appear before a .ent directive, + which means that cur_proc_ptr will be NULL here. Arrange to + patch this up. */ + if (cur_proc_ptr == (proc_t *) NULL) + { + lineno_list_t **pl; + + pl = &noproc_lineno; + while (*pl != (lineno_list_t *) NULL) + pl = &(*pl)->next; + *pl = list; + } + else + { + last_lineno = list; + *last_lineno_ptr = list; + last_lineno_ptr = &list->next; + } +} + +#else + +void +ecoff_generate_asm_lineno (void) +{ +} + +#endif /* ECOFF_DEBUGGING */ diff --git a/contrib/toolchain/binutils/gas/ecoff.h b/contrib/toolchain/binutils/gas/ecoff.h new file mode 100644 index 0000000000..f4f8356147 --- /dev/null +++ b/contrib/toolchain/binutils/gas/ecoff.h @@ -0,0 +1,113 @@ +/* ecoff.h -- header file for ECOFF debugging support + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004, 2005, + 2007, 2009 Free Software Foundation, Inc. + Contributed by Cygnus Support. + Put together by Ian Lance Taylor . + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef GAS_ECOFF_H +#define GAS_ECOFF_H + +#ifdef ECOFF_DEBUGGING + +#include "coff/sym.h" +#include "coff/ecoff.h" + +/* Whether we have seen any ECOFF debugging information. */ +extern int ecoff_debugging_seen; + +/* This function should be called at the start of assembly, by + obj_read_begin_hook. */ +extern void ecoff_read_begin_hook (void); + +/* This function should be called when the assembler switches to a new + file. */ +extern void ecoff_new_file (const char *, int); + +/* This function should be called when a new symbol is created, by + obj_symbol_new_hook. */ +extern void ecoff_symbol_new_hook (symbolS *); + +extern void ecoff_symbol_clone_hook (symbolS *, symbolS *); + +/* This function should be called by the obj_frob_symbol hook. */ +extern void ecoff_frob_symbol (symbolS *); + +/* Build the ECOFF debugging information. This should be called by + obj_frob_file. This fills in the counts in *HDR; the offsets are + filled in relative to the start of the *BUFP. It sets *BUFP to a + block of memory holding the debugging information. It returns the + length of *BUFP. */ +extern unsigned long ecoff_build_debug + (HDRR *hdr, char **bufp, const struct ecoff_debug_swap *); + +/* Functions to handle the ECOFF debugging directives. */ +extern void ecoff_directive_begin (int); +extern void ecoff_directive_bend (int); +extern void ecoff_directive_end (int); +extern void ecoff_directive_ent (int); +extern void ecoff_directive_fmask (int); +extern void ecoff_directive_frame (int); +extern void ecoff_directive_loc (int); +extern void ecoff_directive_mask (int); + +/* Other ECOFF directives. */ +extern void ecoff_directive_extern (int); +extern void ecoff_directive_weakext (int); + +/* Functions to handle the COFF debugging directives. */ +extern void ecoff_directive_def (int); +extern void ecoff_directive_dim (int); +extern void ecoff_directive_endef (int); +extern void ecoff_directive_file (int); +extern void ecoff_directive_scl (int); +extern void ecoff_directive_size (int); +extern void ecoff_directive_tag (int); +extern void ecoff_directive_type (int); +extern void ecoff_directive_val (int); + +/* Handle stabs. */ +extern void ecoff_stab (segT sec, int what, const char *string, + int type, int other, int desc); + +/* Set the GP prologue size. */ +extern void ecoff_set_gp_prolog_size (int sz); + +/* This routine is called from the ECOFF code to set the external + information for a symbol. */ +#ifndef obj_ecoff_set_ext +extern void obj_ecoff_set_ext (symbolS *, EXTR *); +#endif + +/* This routine is used to patch up a line number directive when + instructions are moved around. */ +extern void ecoff_fix_loc (fragS *, unsigned long); + +/* This function is called from read.c to peek at cur_file_ptr. */ +extern int ecoff_no_current_file (void); + +/* This function returns the symbol associated with the current proc. */ +extern symbolS *ecoff_get_cur_proc_sym (void); + +#endif /* ECOFF_DEBUGGING */ + +/* This routine is called from read.c to generate line number for .s file. */ +extern void ecoff_generate_asm_lineno (void); + +#endif /* ! GAS_ECOFF_H */ diff --git a/contrib/toolchain/binutils/gas/ehopt.c b/contrib/toolchain/binutils/gas/ehopt.c new file mode 100644 index 0000000000..70e1a00f4e --- /dev/null +++ b/contrib/toolchain/binutils/gas/ehopt.c @@ -0,0 +1,557 @@ +/* ehopt.c--optimize gcc exception frame information. + Copyright 1998, 2000, 2001, 2003, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. + Written by Ian Lance Taylor . + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "subsegs.h" +#include "struc-symbol.h" + +/* We include this ELF file, even though we may not be assembling for + ELF, since the exception frame information is always in a format + derived from DWARF. */ + +#include "dwarf2.h" + +/* Try to optimize gcc 2.8 exception frame information. + + Exception frame information is emitted for every function in the + .eh_frame or .debug_frame sections. Simple information for a function + with no exceptions looks like this: + +__FRAME_BEGIN__: + .4byte .LLCIE1 / Length of Common Information Entry +.LSCIE1: +#if .eh_frame + .4byte 0x0 / CIE Identifier Tag +#elif .debug_frame + .4byte 0xffffffff / CIE Identifier Tag +#endif + .byte 0x1 / CIE Version + .byte 0x0 / CIE Augmentation (none) + .byte 0x1 / ULEB128 0x1 (CIE Code Alignment Factor) + .byte 0x7c / SLEB128 -4 (CIE Data Alignment Factor) + .byte 0x8 / CIE RA Column + .byte 0xc / DW_CFA_def_cfa + .byte 0x4 / ULEB128 0x4 + .byte 0x4 / ULEB128 0x4 + .byte 0x88 / DW_CFA_offset, column 0x8 + .byte 0x1 / ULEB128 0x1 + .align 4 +.LECIE1: + .set .LLCIE1,.LECIE1-.LSCIE1 / CIE Length Symbol + .4byte .LLFDE1 / FDE Length +.LSFDE1: + .4byte .LSFDE1-__FRAME_BEGIN__ / FDE CIE offset + .4byte .LFB1 / FDE initial location + .4byte .LFE1-.LFB1 / FDE address range + .byte 0x4 / DW_CFA_advance_loc4 + .4byte .LCFI0-.LFB1 + .byte 0xe / DW_CFA_def_cfa_offset + .byte 0x8 / ULEB128 0x8 + .byte 0x85 / DW_CFA_offset, column 0x5 + .byte 0x2 / ULEB128 0x2 + .byte 0x4 / DW_CFA_advance_loc4 + .4byte .LCFI1-.LCFI0 + .byte 0xd / DW_CFA_def_cfa_register + .byte 0x5 / ULEB128 0x5 + .byte 0x4 / DW_CFA_advance_loc4 + .4byte .LCFI2-.LCFI1 + .byte 0x2e / DW_CFA_GNU_args_size + .byte 0x4 / ULEB128 0x4 + .byte 0x4 / DW_CFA_advance_loc4 + .4byte .LCFI3-.LCFI2 + .byte 0x2e / DW_CFA_GNU_args_size + .byte 0x0 / ULEB128 0x0 + .align 4 +.LEFDE1: + .set .LLFDE1,.LEFDE1-.LSFDE1 / FDE Length Symbol + + The immediate issue we can address in the assembler is the + DW_CFA_advance_loc4 followed by a four byte value. The value is + the difference of two addresses in the function. Since gcc does + not know this value, it always uses four bytes. We will know the + value at the end of assembly, so we can do better. */ + +struct cie_info +{ + unsigned code_alignment; + int z_augmentation; +}; + +static int get_cie_info (struct cie_info *); + +/* Extract information from the CIE. */ + +static int +get_cie_info (struct cie_info *info) +{ + fragS *f; + fixS *fix; + int offset; + char CIE_id; + char augmentation[10]; + int iaug; + int code_alignment = 0; + + /* We should find the CIE at the start of the section. */ + + f = seg_info (now_seg)->frchainP->frch_root; + fix = seg_info (now_seg)->frchainP->fix_root; + + /* Look through the frags of the section to find the code alignment. */ + + /* First make sure that the CIE Identifier Tag is 0/-1. */ + + if (strncmp (segment_name (now_seg), ".debug_frame", 12) == 0) + CIE_id = (char)0xff; + else + CIE_id = 0; + + offset = 4; + while (f != NULL && offset >= f->fr_fix) + { + offset -= f->fr_fix; + f = f->fr_next; + } + if (f == NULL + || f->fr_fix - offset < 4 + || f->fr_literal[offset] != CIE_id + || f->fr_literal[offset + 1] != CIE_id + || f->fr_literal[offset + 2] != CIE_id + || f->fr_literal[offset + 3] != CIE_id) + return 0; + + /* Next make sure the CIE version number is 1. */ + + offset += 4; + while (f != NULL && offset >= f->fr_fix) + { + offset -= f->fr_fix; + f = f->fr_next; + } + if (f == NULL + || f->fr_fix - offset < 1 + || f->fr_literal[offset] != 1) + return 0; + + /* Skip the augmentation (a null terminated string). */ + + iaug = 0; + ++offset; + while (1) + { + while (f != NULL && offset >= f->fr_fix) + { + offset -= f->fr_fix; + f = f->fr_next; + } + if (f == NULL) + return 0; + + while (offset < f->fr_fix && f->fr_literal[offset] != '\0') + { + if ((size_t) iaug < (sizeof augmentation) - 1) + { + augmentation[iaug] = f->fr_literal[offset]; + ++iaug; + } + ++offset; + } + if (offset < f->fr_fix) + break; + } + ++offset; + while (f != NULL && offset >= f->fr_fix) + { + offset -= f->fr_fix; + f = f->fr_next; + } + if (f == NULL) + return 0; + + augmentation[iaug] = '\0'; + if (augmentation[0] == '\0') + { + /* No augmentation. */ + } + else if (strcmp (augmentation, "eh") == 0) + { + /* We have to skip a pointer. Unfortunately, we don't know how + large it is. We find out by looking for a matching fixup. */ + while (fix != NULL + && (fix->fx_frag != f || fix->fx_where != offset)) + fix = fix->fx_next; + if (fix == NULL) + offset += 4; + else + offset += fix->fx_size; + while (f != NULL && offset >= f->fr_fix) + { + offset -= f->fr_fix; + f = f->fr_next; + } + if (f == NULL) + return 0; + } + else if (augmentation[0] != 'z') + return 0; + + /* We're now at the code alignment factor, which is a ULEB128. If + it isn't a single byte, forget it. */ + + code_alignment = f->fr_literal[offset] & 0xff; + if ((code_alignment & 0x80) != 0) + code_alignment = 0; + + info->code_alignment = code_alignment; + info->z_augmentation = (augmentation[0] == 'z'); + + return 1; +} + +enum frame_state +{ + state_idle, + state_saw_size, + state_saw_cie_offset, + state_saw_pc_begin, + state_seeing_aug_size, + state_skipping_aug, + state_wait_loc4, + state_saw_loc4, + state_error, +}; + +/* This function is called from emit_expr. It looks for cases which + we can optimize. + + Rather than try to parse all this information as we read it, we + look for a single byte DW_CFA_advance_loc4 followed by a 4 byte + difference. We turn that into a rs_cfa_advance frag, and handle + those frags at the end of the assembly. If the gcc output changes + somewhat, this optimization may stop working. + + This function returns non-zero if it handled the expression and + emit_expr should not do anything, or zero otherwise. It can also + change *EXP and *PNBYTES. */ + +int +check_eh_frame (expressionS *exp, unsigned int *pnbytes) +{ + struct frame_data + { + enum frame_state state; + + int cie_info_ok; + struct cie_info cie_info; + + symbolS *size_end_sym; + fragS *loc4_frag; + int loc4_fix; + + int aug_size; + int aug_shift; + }; + + static struct frame_data eh_frame_data; + static struct frame_data debug_frame_data; + struct frame_data *d; + + /* Don't optimize. */ + if (flag_traditional_format) + return 0; + +#ifdef md_allow_eh_opt + if (! md_allow_eh_opt) + return 0; +#endif + + /* Select the proper section data. */ + if (strncmp (segment_name (now_seg), ".eh_frame", 9) == 0 + && segment_name (now_seg)[9] != '_') + d = &eh_frame_data; + else if (strncmp (segment_name (now_seg), ".debug_frame", 12) == 0) + d = &debug_frame_data; + else + return 0; + + if (d->state >= state_saw_size && S_IS_DEFINED (d->size_end_sym)) + { + /* We have come to the end of the CIE or FDE. See below where + we set saw_size. We must check this first because we may now + be looking at the next size. */ + d->state = state_idle; + } + + switch (d->state) + { + case state_idle: + if (*pnbytes == 4) + { + /* This might be the size of the CIE or FDE. We want to know + the size so that we don't accidentally optimize across an FDE + boundary. We recognize the size in one of two forms: a + symbol which will later be defined as a difference, or a + subtraction of two symbols. Either way, we can tell when we + are at the end of the FDE because the symbol becomes defined + (in the case of a subtraction, the end symbol, from which the + start symbol is being subtracted). Other ways of describing + the size will not be optimized. */ + if ((exp->X_op == O_symbol || exp->X_op == O_subtract) + && ! S_IS_DEFINED (exp->X_add_symbol)) + { + d->state = state_saw_size; + d->size_end_sym = exp->X_add_symbol; + } + } + break; + + case state_saw_size: + case state_saw_cie_offset: + /* Assume whatever form it appears in, it appears atomically. */ + d->state = (enum frame_state) (d->state + 1); + break; + + case state_saw_pc_begin: + /* Decide whether we should see an augmentation. */ + if (! d->cie_info_ok + && ! (d->cie_info_ok = get_cie_info (&d->cie_info))) + d->state = state_error; + else if (d->cie_info.z_augmentation) + { + d->state = state_seeing_aug_size; + d->aug_size = 0; + d->aug_shift = 0; + } + else + d->state = state_wait_loc4; + break; + + case state_seeing_aug_size: + /* Bytes == -1 means this comes from an leb128 directive. */ + if ((int)*pnbytes == -1 && exp->X_op == O_constant) + { + d->aug_size = exp->X_add_number; + d->state = state_skipping_aug; + } + else if (*pnbytes == 1 && exp->X_op == O_constant) + { + unsigned char byte = exp->X_add_number; + d->aug_size |= (byte & 0x7f) << d->aug_shift; + d->aug_shift += 7; + if ((byte & 0x80) == 0) + d->state = state_skipping_aug; + } + else + d->state = state_error; + if (d->state == state_skipping_aug && d->aug_size == 0) + d->state = state_wait_loc4; + break; + + case state_skipping_aug: + if ((int)*pnbytes < 0) + d->state = state_error; + else + { + int left = (d->aug_size -= *pnbytes); + if (left == 0) + d->state = state_wait_loc4; + else if (left < 0) + d->state = state_error; + } + break; + + case state_wait_loc4: + if (*pnbytes == 1 + && exp->X_op == O_constant + && exp->X_add_number == DW_CFA_advance_loc4) + { + /* This might be a DW_CFA_advance_loc4. Record the frag and the + position within the frag, so that we can change it later. */ + frag_grow (1); + d->state = state_saw_loc4; + d->loc4_frag = frag_now; + d->loc4_fix = frag_now_fix (); + } + break; + + case state_saw_loc4: + d->state = state_wait_loc4; + if (*pnbytes != 4) + break; + if (exp->X_op == O_constant) + { + /* This is a case which we can optimize. The two symbols being + subtracted were in the same frag and the expression was + reduced to a constant. We can do the optimization entirely + in this function. */ + if (exp->X_add_number < 0x40) + { + d->loc4_frag->fr_literal[d->loc4_fix] + = DW_CFA_advance_loc | exp->X_add_number; + /* No more bytes needed. */ + return 1; + } + else if (exp->X_add_number < 0x100) + { + d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc1; + *pnbytes = 1; + } + else if (exp->X_add_number < 0x10000) + { + d->loc4_frag->fr_literal[d->loc4_fix] = DW_CFA_advance_loc2; + *pnbytes = 2; + } + } + else if (exp->X_op == O_subtract && d->cie_info.code_alignment == 1) + { + /* This is a case we can optimize. The expression was not + reduced, so we can not finish the optimization until the end + of the assembly. We set up a variant frag which we handle + later. */ + frag_var (rs_cfa, 4, 0, 1 << 3, make_expr_symbol (exp), + d->loc4_fix, (char *) d->loc4_frag); + return 1; + } + else if ((exp->X_op == O_divide + || exp->X_op == O_right_shift) + && d->cie_info.code_alignment > 1) + { + if (exp->X_add_symbol->bsym + && exp->X_op_symbol->bsym + && exp->X_add_symbol->sy_value.X_op == O_subtract + && exp->X_op_symbol->sy_value.X_op == O_constant + && ((exp->X_op == O_divide + ? exp->X_op_symbol->sy_value.X_add_number + : (offsetT) 1 << exp->X_op_symbol->sy_value.X_add_number) + == (offsetT) d->cie_info.code_alignment)) + { + /* This is a case we can optimize as well. The expression was + not reduced, so we can not finish the optimization until the + end of the assembly. We set up a variant frag which we + handle later. */ + frag_var (rs_cfa, 4, 0, d->cie_info.code_alignment << 3, + make_expr_symbol (&exp->X_add_symbol->sy_value), + d->loc4_fix, (char *) d->loc4_frag); + return 1; + } + } + break; + + case state_error: + /* Just skipping everything. */ + break; + } + + return 0; +} + +/* The function estimates the size of a rs_cfa variant frag based on + the current values of the symbols. It is called before the + relaxation loop. We set fr_subtype{0:2} to the expected length. */ + +int +eh_frame_estimate_size_before_relax (fragS *frag) +{ + offsetT diff; + int ca = frag->fr_subtype >> 3; + int ret; + + diff = resolve_symbol_value (frag->fr_symbol); + + gas_assert (ca > 0); + diff /= ca; + if (diff < 0x40) + ret = 0; + else if (diff < 0x100) + ret = 1; + else if (diff < 0x10000) + ret = 2; + else + ret = 4; + + frag->fr_subtype = (frag->fr_subtype & ~7) | ret; + + return ret; +} + +/* This function relaxes a rs_cfa variant frag based on the current + values of the symbols. fr_subtype{0:2} is the current length of + the frag. This returns the change in frag length. */ + +int +eh_frame_relax_frag (fragS *frag) +{ + int oldsize, newsize; + + oldsize = frag->fr_subtype & 7; + newsize = eh_frame_estimate_size_before_relax (frag); + return newsize - oldsize; +} + +/* This function converts a rs_cfa variant frag into a normal fill + frag. This is called after all relaxation has been done. + fr_subtype{0:2} will be the desired length of the frag. */ + +void +eh_frame_convert_frag (fragS *frag) +{ + offsetT diff; + fragS *loc4_frag; + int loc4_fix, ca; + + loc4_frag = (fragS *) frag->fr_opcode; + loc4_fix = (int) frag->fr_offset; + + diff = resolve_symbol_value (frag->fr_symbol); + + ca = frag->fr_subtype >> 3; + gas_assert (ca > 0); + diff /= ca; + switch (frag->fr_subtype & 7) + { + case 0: + gas_assert (diff < 0x40); + loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc | diff; + break; + + case 1: + gas_assert (diff < 0x100); + loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc1; + frag->fr_literal[frag->fr_fix] = diff; + break; + + case 2: + gas_assert (diff < 0x10000); + loc4_frag->fr_literal[loc4_fix] = DW_CFA_advance_loc2; + md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 2); + break; + + default: + md_number_to_chars (frag->fr_literal + frag->fr_fix, diff, 4); + break; + } + + frag->fr_fix += frag->fr_subtype & 7; + frag->fr_type = rs_fill; + frag->fr_subtype = 0; + frag->fr_offset = 0; +} diff --git a/contrib/toolchain/binutils/gas/expr.c b/contrib/toolchain/binutils/gas/expr.c new file mode 100644 index 0000000000..c4b2b756ba --- /dev/null +++ b/contrib/toolchain/binutils/gas/expr.c @@ -0,0 +1,2367 @@ +/* expr.c -operands, expressions- + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, + 2012 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* This is really a branch office of as-read.c. I split it out to clearly + distinguish the world of expressions from the world of statements. + (It also gives smaller files to re-compile.) + Here, "operand"s are of expressions, not instructions. */ + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +#include "as.h" +#include "safe-ctype.h" +#include "obstack.h" + +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +static void floating_constant (expressionS * expressionP); +static valueT generic_bignum_to_int32 (void); +#ifdef BFD64 +static valueT generic_bignum_to_int64 (void); +#endif +static void integer_constant (int radix, expressionS * expressionP); +static void mri_char_constant (expressionS *); +static void clean_up_expression (expressionS * expressionP); +static segT operand (expressionS *, enum expr_mode); +static operatorT operatorf (int *); + +extern const char EXP_CHARS[], FLT_CHARS[]; + +/* We keep a mapping of expression symbols to file positions, so that + we can provide better error messages. */ + +struct expr_symbol_line { + struct expr_symbol_line *next; + symbolS *sym; + char *file; + unsigned int line; +}; + +static struct expr_symbol_line *expr_symbol_lines; + +/* Build a dummy symbol to hold a complex expression. This is how we + build expressions up out of other expressions. The symbol is put + into the fake section expr_section. */ + +symbolS * +make_expr_symbol (expressionS *expressionP) +{ + expressionS zero; + symbolS *symbolP; + struct expr_symbol_line *n; + + if (expressionP->X_op == O_symbol + && expressionP->X_add_number == 0) + return expressionP->X_add_symbol; + + if (expressionP->X_op == O_big) + { + /* This won't work, because the actual value is stored in + generic_floating_point_number or generic_bignum, and we are + going to lose it if we haven't already. */ + if (expressionP->X_add_number > 0) + as_bad (_("bignum invalid")); + else + as_bad (_("floating point number invalid")); + zero.X_op = O_constant; + zero.X_add_number = 0; + zero.X_unsigned = 0; + zero.X_extrabit = 0; + clean_up_expression (&zero); + expressionP = &zero; + } + + /* Putting constant symbols in absolute_section rather than + expr_section is convenient for the old a.out code, for which + S_GET_SEGMENT does not always retrieve the value put in by + S_SET_SEGMENT. */ + symbolP = symbol_create (FAKE_LABEL_NAME, + (expressionP->X_op == O_constant + ? absolute_section + : expressionP->X_op == O_register + ? reg_section + : expr_section), + 0, &zero_address_frag); + symbol_set_value_expression (symbolP, expressionP); + + if (expressionP->X_op == O_constant) + resolve_symbol_value (symbolP); + + n = (struct expr_symbol_line *) xmalloc (sizeof *n); + n->sym = symbolP; + as_where (&n->file, &n->line); + n->next = expr_symbol_lines; + expr_symbol_lines = n; + + return symbolP; +} + +/* Return the file and line number for an expr symbol. Return + non-zero if something was found, 0 if no information is known for + the symbol. */ + +int +expr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline) +{ + register struct expr_symbol_line *l; + + for (l = expr_symbol_lines; l != NULL; l = l->next) + { + if (l->sym == sym) + { + *pfile = l->file; + *pline = l->line; + return 1; + } + } + + return 0; +} + +/* Utilities for building expressions. + Since complex expressions are recorded as symbols for use in other + expressions these return a symbolS * and not an expressionS *. + These explicitly do not take an "add_number" argument. */ +/* ??? For completeness' sake one might want expr_build_symbol. + It would just return its argument. */ + +/* Build an expression for an unsigned constant. + The corresponding one for signed constants is missing because + there's currently no need for it. One could add an unsigned_p flag + but that seems more clumsy. */ + +symbolS * +expr_build_uconstant (offsetT value) +{ + expressionS e; + + e.X_op = O_constant; + e.X_add_number = value; + e.X_unsigned = 1; + e.X_extrabit = 0; + return make_expr_symbol (&e); +} + +/* Build an expression for the current location ('.'). */ + +symbolS * +expr_build_dot (void) +{ + expressionS e; + + current_location (&e); + return symbol_clone_if_forward_ref (make_expr_symbol (&e)); +} + +/* Build any floating-point literal here. + Also build any bignum literal here. */ + +/* Seems atof_machine can backscan through generic_bignum and hit whatever + happens to be loaded before it in memory. And its way too complicated + for me to fix right. Thus a hack. JF: Just make generic_bignum bigger, + and never write into the early words, thus they'll always be zero. + I hate Dean's floating-point code. Bleh. */ +LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6]; + +FLONUM_TYPE generic_floating_point_number = { + &generic_bignum[6], /* low. (JF: Was 0) */ + &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high. JF: (added +6) */ + 0, /* leader. */ + 0, /* exponent. */ + 0 /* sign. */ +}; + + +static void +floating_constant (expressionS *expressionP) +{ + /* input_line_pointer -> floating-point constant. */ + int error_code; + + error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS, + &generic_floating_point_number); + + if (error_code) + { + if (error_code == ERROR_EXPONENT_OVERFLOW) + { + as_bad (_("bad floating-point constant: exponent overflow")); + } + else + { + as_bad (_("bad floating-point constant: unknown error code=%d"), + error_code); + } + } + expressionP->X_op = O_big; + /* input_line_pointer -> just after constant, which may point to + whitespace. */ + expressionP->X_add_number = -1; +} + +static valueT +generic_bignum_to_int32 (void) +{ + valueT number = + ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) + | (generic_bignum[0] & LITTLENUM_MASK); + number &= 0xffffffff; + return number; +} + +#ifdef BFD64 +static valueT +generic_bignum_to_int64 (void) +{ + valueT number = + ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK) + << LITTLENUM_NUMBER_OF_BITS) + | ((valueT) generic_bignum[2] & LITTLENUM_MASK)) + << LITTLENUM_NUMBER_OF_BITS) + | ((valueT) generic_bignum[1] & LITTLENUM_MASK)) + << LITTLENUM_NUMBER_OF_BITS) + | ((valueT) generic_bignum[0] & LITTLENUM_MASK)); + return number; +} +#endif + +static void +integer_constant (int radix, expressionS *expressionP) +{ + char *start; /* Start of number. */ + char *suffix = NULL; + char c; + valueT number; /* Offset or (absolute) value. */ + short int digit; /* Value of next digit in current radix. */ + short int maxdig = 0; /* Highest permitted digit value. */ + int too_many_digits = 0; /* If we see >= this number of. */ + char *name; /* Points to name of symbol. */ + symbolS *symbolP; /* Points to symbol. */ + + int small; /* True if fits in 32 bits. */ + + /* May be bignum, or may fit in 32 bits. */ + /* Most numbers fit into 32 bits, and we want this case to be fast. + so we pretend it will fit into 32 bits. If, after making up a 32 + bit number, we realise that we have scanned more digits than + comfortably fit into 32 bits, we re-scan the digits coding them + into a bignum. For decimal and octal numbers we are + conservative: Some numbers may be assumed bignums when in fact + they do fit into 32 bits. Numbers of any radix can have excess + leading zeros: We strive to recognise this and cast them back + into 32 bits. We must check that the bignum really is more than + 32 bits, and change it back to a 32-bit number if it fits. The + number we are looking for is expected to be positive, but if it + fits into 32 bits as an unsigned number, we let it be a 32-bit + number. The cavalier approach is for speed in ordinary cases. */ + /* This has been extended for 64 bits. We blindly assume that if + you're compiling in 64-bit mode, the target is a 64-bit machine. + This should be cleaned up. */ + +#ifdef BFD64 +#define valuesize 64 +#else /* includes non-bfd case, mostly */ +#define valuesize 32 +#endif + + if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0) + { + int flt = 0; + + /* In MRI mode, the number may have a suffix indicating the + radix. For that matter, it might actually be a floating + point constant. */ + for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++) + { + if (*suffix == 'e' || *suffix == 'E') + flt = 1; + } + + if (suffix == input_line_pointer) + { + radix = 10; + suffix = NULL; + } + else + { + c = *--suffix; + c = TOUPPER (c); + /* If we have both NUMBERS_WITH_SUFFIX and LOCAL_LABELS_FB, + we distinguish between 'B' and 'b'. This is the case for + Z80. */ + if ((NUMBERS_WITH_SUFFIX && LOCAL_LABELS_FB ? *suffix : c) == 'B') + radix = 2; + else if (c == 'D') + radix = 10; + else if (c == 'O' || c == 'Q') + radix = 8; + else if (c == 'H') + radix = 16; + else if (suffix[1] == '.' || c == 'E' || flt) + { + floating_constant (expressionP); + return; + } + else + { + radix = 10; + suffix = NULL; + } + } + } + + switch (radix) + { + case 2: + maxdig = 2; + too_many_digits = valuesize + 1; + break; + case 8: + maxdig = radix = 8; + too_many_digits = (valuesize + 2) / 3 + 1; + break; + case 16: + maxdig = radix = 16; + too_many_digits = (valuesize + 3) / 4 + 1; + break; + case 10: + maxdig = radix = 10; + too_many_digits = (valuesize + 11) / 4; /* Very rough. */ + } +#undef valuesize + start = input_line_pointer; + c = *input_line_pointer++; + for (number = 0; + (digit = hex_value (c)) < maxdig; + c = *input_line_pointer++) + { + number = number * radix + digit; + } + /* c contains character after number. */ + /* input_line_pointer->char after c. */ + small = (input_line_pointer - start - 1) < too_many_digits; + + if (radix == 16 && c == '_') + { + /* This is literal of the form 0x333_0_12345678_1. + This example is equivalent to 0x00000333000000001234567800000001. */ + + int num_little_digits = 0; + int i; + input_line_pointer = start; /* -> 1st digit. */ + + know (LITTLENUM_NUMBER_OF_BITS == 16); + + for (c = '_'; c == '_'; num_little_digits += 2) + { + + /* Convert one 64-bit word. */ + int ndigit = 0; + number = 0; + for (c = *input_line_pointer++; + (digit = hex_value (c)) < maxdig; + c = *(input_line_pointer++)) + { + number = number * radix + digit; + ndigit++; + } + + /* Check for 8 digit per word max. */ + if (ndigit > 8) + as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word")); + + /* Add this chunk to the bignum. + Shift things down 2 little digits. */ + know (LITTLENUM_NUMBER_OF_BITS == 16); + for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); + i >= 2; + i--) + generic_bignum[i] = generic_bignum[i - 2]; + + /* Add the new digits as the least significant new ones. */ + generic_bignum[0] = number & 0xffffffff; + generic_bignum[1] = number >> 16; + } + + /* Again, c is char after number, input_line_pointer->after c. */ + + if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1) + num_little_digits = SIZE_OF_LARGE_NUMBER - 1; + + gas_assert (num_little_digits >= 4); + + if (num_little_digits != 8) + as_bad (_("a bignum with underscores must have exactly 4 words")); + + /* We might have some leading zeros. These can be trimmed to give + us a change to fit this constant into a small number. */ + while (generic_bignum[num_little_digits - 1] == 0 + && num_little_digits > 1) + num_little_digits--; + + if (num_little_digits <= 2) + { + /* will fit into 32 bits. */ + number = generic_bignum_to_int32 (); + small = 1; + } +#ifdef BFD64 + else if (num_little_digits <= 4) + { + /* Will fit into 64 bits. */ + number = generic_bignum_to_int64 (); + small = 1; + } +#endif + else + { + small = 0; + + /* Number of littlenums in the bignum. */ + number = num_little_digits; + } + } + else if (!small) + { + /* We saw a lot of digits. manufacture a bignum the hard way. */ + LITTLENUM_TYPE *leader; /* -> high order littlenum of the bignum. */ + LITTLENUM_TYPE *pointer; /* -> littlenum we are frobbing now. */ + long carry; + + leader = generic_bignum; + generic_bignum[0] = 0; + generic_bignum[1] = 0; + generic_bignum[2] = 0; + generic_bignum[3] = 0; + input_line_pointer = start; /* -> 1st digit. */ + c = *input_line_pointer++; + for (; (carry = hex_value (c)) < maxdig; c = *input_line_pointer++) + { + for (pointer = generic_bignum; pointer <= leader; pointer++) + { + long work; + + work = carry + radix * *pointer; + *pointer = work & LITTLENUM_MASK; + carry = work >> LITTLENUM_NUMBER_OF_BITS; + } + if (carry) + { + if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1) + { + /* Room to grow a longer bignum. */ + *++leader = carry; + } + } + } + /* Again, c is char after number. */ + /* input_line_pointer -> after c. */ + know (LITTLENUM_NUMBER_OF_BITS == 16); + if (leader < generic_bignum + 2) + { + /* Will fit into 32 bits. */ + number = generic_bignum_to_int32 (); + small = 1; + } +#ifdef BFD64 + else if (leader < generic_bignum + 4) + { + /* Will fit into 64 bits. */ + number = generic_bignum_to_int64 (); + small = 1; + } +#endif + else + { + /* Number of littlenums in the bignum. */ + number = leader - generic_bignum + 1; + } + } + + if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) + && suffix != NULL + && input_line_pointer - 1 == suffix) + c = *input_line_pointer++; + + if (small) + { + /* Here with number, in correct radix. c is the next char. + Note that unlike un*x, we allow "011f" "0x9f" to both mean + the same as the (conventional) "9f". + This is simply easier than checking for strict canonical + form. Syntax sux! */ + + if (LOCAL_LABELS_FB && c == 'b') + { + /* Backward ref to local label. + Because it is backward, expect it to be defined. */ + /* Construct a local label. */ + name = fb_label_name ((int) number, 0); + + /* Seen before, or symbol is defined: OK. */ + symbolP = symbol_find (name); + if ((symbolP != NULL) && (S_IS_DEFINED (symbolP))) + { + /* Local labels are never absolute. Don't waste time + checking absoluteness. */ + know (SEG_NORMAL (S_GET_SEGMENT (symbolP))); + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + } + else + { + /* Either not seen or not defined. */ + /* @@ Should print out the original string instead of + the parsed number. */ + as_bad (_("backward ref to unknown label \"%d:\""), + (int) number); + expressionP->X_op = O_constant; + } + + expressionP->X_add_number = 0; + } /* case 'b' */ + else if (LOCAL_LABELS_FB && c == 'f') + { + /* Forward reference. Expect symbol to be undefined or + unknown. undefined: seen it before. unknown: never seen + it before. + + Construct a local label name, then an undefined symbol. + Don't create a xseg frag for it: caller may do that. + Just return it as never seen before. */ + name = fb_label_name ((int) number, 1); + symbolP = symbol_find_or_make (name); + /* We have no need to check symbol properties. */ +#ifndef many_segments + /* Since "know" puts its arg into a "string", we + can't have newlines in the argument. */ + know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section); +#endif + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + } /* case 'f' */ + else if (LOCAL_LABELS_DOLLAR && c == '$') + { + /* If the dollar label is *currently* defined, then this is just + another reference to it. If it is not *currently* defined, + then this is a fresh instantiation of that number, so create + it. */ + + if (dollar_label_defined ((long) number)) + { + name = dollar_label_name ((long) number, 0); + symbolP = symbol_find (name); + know (symbolP != NULL); + } + else + { + name = dollar_label_name ((long) number, 1); + symbolP = symbol_find_or_make (name); + } + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + } /* case '$' */ + else + { + expressionP->X_op = O_constant; + expressionP->X_add_number = number; + input_line_pointer--; /* Restore following character. */ + } /* Really just a number. */ + } + else + { + /* Not a small number. */ + expressionP->X_op = O_big; + expressionP->X_add_number = number; /* Number of littlenums. */ + input_line_pointer--; /* -> char following number. */ + } +} + +/* Parse an MRI multi character constant. */ + +static void +mri_char_constant (expressionS *expressionP) +{ + int i; + + if (*input_line_pointer == '\'' + && input_line_pointer[1] != '\'') + { + expressionP->X_op = O_constant; + expressionP->X_add_number = 0; + return; + } + + /* In order to get the correct byte ordering, we must build the + number in reverse. */ + for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--) + { + int j; + + generic_bignum[i] = 0; + for (j = 0; j < CHARS_PER_LITTLENUM; j++) + { + if (*input_line_pointer == '\'') + { + if (input_line_pointer[1] != '\'') + break; + ++input_line_pointer; + } + generic_bignum[i] <<= 8; + generic_bignum[i] += *input_line_pointer; + ++input_line_pointer; + } + + if (i < SIZE_OF_LARGE_NUMBER - 1) + { + /* If there is more than one littlenum, left justify the + last one to make it match the earlier ones. If there is + only one, we can just use the value directly. */ + for (; j < CHARS_PER_LITTLENUM; j++) + generic_bignum[i] <<= 8; + } + + if (*input_line_pointer == '\'' + && input_line_pointer[1] != '\'') + break; + } + + if (i < 0) + { + as_bad (_("character constant too large")); + i = 0; + } + + if (i > 0) + { + int c; + int j; + + c = SIZE_OF_LARGE_NUMBER - i; + for (j = 0; j < c; j++) + generic_bignum[j] = generic_bignum[i + j]; + i = c; + } + + know (LITTLENUM_NUMBER_OF_BITS == 16); + if (i > 2) + { + expressionP->X_op = O_big; + expressionP->X_add_number = i; + } + else + { + expressionP->X_op = O_constant; + if (i < 2) + expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK; + else + expressionP->X_add_number = + (((generic_bignum[1] & LITTLENUM_MASK) + << LITTLENUM_NUMBER_OF_BITS) + | (generic_bignum[0] & LITTLENUM_MASK)); + } + + /* Skip the final closing quote. */ + ++input_line_pointer; +} + +/* Return an expression representing the current location. This + handles the magic symbol `.'. */ + +void +current_location (expressionS *expressionp) +{ + if (now_seg == absolute_section) + { + expressionp->X_op = O_constant; + expressionp->X_add_number = abs_section_offset; + } + else + { + expressionp->X_op = O_symbol; + expressionp->X_add_symbol = &dot_symbol; + expressionp->X_add_number = 0; + } +} + +/* In: Input_line_pointer points to 1st char of operand, which may + be a space. + + Out: An expressionS. + The operand may have been empty: in this case X_op == O_absent. + Input_line_pointer->(next non-blank) char after operand. */ + +static segT +operand (expressionS *expressionP, enum expr_mode mode) +{ + char c; + symbolS *symbolP; /* Points to symbol. */ + char *name; /* Points to name of symbol. */ + segT segment; + + /* All integers are regarded as unsigned unless they are negated. + This is because the only thing which cares whether a number is + unsigned is the code in emit_expr which extends constants into + bignums. It should only sign extend negative numbers, so that + something like ``.quad 0x80000000'' is not sign extended even + though it appears negative if valueT is 32 bits. */ + expressionP->X_unsigned = 1; + expressionP->X_extrabit = 0; + + /* Digits, assume it is a bignum. */ + + SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */ + c = *input_line_pointer++; /* input_line_pointer -> past char in c. */ + + if (is_end_of_line[(unsigned char) c]) + goto eol; + + switch (c) + { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + input_line_pointer--; + + integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) + ? 0 : 10, + expressionP); + break; + +#ifdef LITERAL_PREFIXDOLLAR_HEX + case '$': + /* $L is the start of a local label, not a hex constant. */ + if (* input_line_pointer == 'L') + goto isname; + integer_constant (16, expressionP); + break; +#endif + +#ifdef LITERAL_PREFIXPERCENT_BIN + case '%': + integer_constant (2, expressionP); + break; +#endif + + case '0': + /* Non-decimal radix. */ + + if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) + { + char *s; + + /* Check for a hex or float constant. */ + for (s = input_line_pointer; hex_p (*s); s++) + ; + if (*s == 'h' || *s == 'H' || *input_line_pointer == '.') + { + --input_line_pointer; + integer_constant (0, expressionP); + break; + } + } + c = *input_line_pointer; + switch (c) + { + case 'o': + case 'O': + case 'q': + case 'Q': + case '8': + case '9': + if (NUMBERS_WITH_SUFFIX || flag_m68k_mri) + { + integer_constant (0, expressionP); + break; + } + /* Fall through. */ + default: + default_case: + if (c && strchr (FLT_CHARS, c)) + { + input_line_pointer++; + floating_constant (expressionP); + expressionP->X_add_number = - TOLOWER (c); + } + else + { + /* The string was only zero. */ + expressionP->X_op = O_constant; + expressionP->X_add_number = 0; + } + + break; + + case 'x': + case 'X': + if (flag_m68k_mri) + goto default_case; + input_line_pointer++; + integer_constant (16, expressionP); + break; + + case 'b': + if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX)) + { + /* This code used to check for '+' and '-' here, and, in + some conditions, fall through to call + integer_constant. However, that didn't make sense, + as integer_constant only accepts digits. */ + /* Some of our code elsewhere does permit digits greater + than the expected base; for consistency, do the same + here. */ + if (input_line_pointer[1] < '0' + || input_line_pointer[1] > '9') + { + /* Parse this as a back reference to label 0. */ + input_line_pointer--; + integer_constant (10, expressionP); + break; + } + /* Otherwise, parse this as a binary number. */ + } + /* Fall through. */ + case 'B': + input_line_pointer++; + if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) + goto default_case; + integer_constant (2, expressionP); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX) + ? 0 : 8, + expressionP); + break; + + case 'f': + if (LOCAL_LABELS_FB) + { + /* If it says "0f" and it could possibly be a floating point + number, make it one. Otherwise, make it a local label, + and try to deal with parsing the rest later. */ + if (!input_line_pointer[1] + || (is_end_of_line[0xff & input_line_pointer[1]]) + || strchr (FLT_CHARS, 'f') == NULL) + goto is_0f_label; + { + char *cp = input_line_pointer + 1; + int r = atof_generic (&cp, ".", EXP_CHARS, + &generic_floating_point_number); + switch (r) + { + case 0: + case ERROR_EXPONENT_OVERFLOW: + if (*cp == 'f' || *cp == 'b') + /* Looks like a difference expression. */ + goto is_0f_label; + else if (cp == input_line_pointer + 1) + /* No characters has been accepted -- looks like + end of operand. */ + goto is_0f_label; + else + goto is_0f_float; + default: + as_fatal (_("expr.c(operand): bad atof_generic return val %d"), + r); + } + } + + /* Okay, now we've sorted it out. We resume at one of these + two labels, depending on what we've decided we're probably + looking at. */ + is_0f_label: + input_line_pointer--; + integer_constant (10, expressionP); + break; + + is_0f_float: + /* Fall through. */ + ; + } + + case 'd': + case 'D': + if (flag_m68k_mri || NUMBERS_WITH_SUFFIX) + { + integer_constant (0, expressionP); + break; + } + /* Fall through. */ + case 'F': + case 'r': + case 'e': + case 'E': + case 'g': + case 'G': + input_line_pointer++; + floating_constant (expressionP); + expressionP->X_add_number = - TOLOWER (c); + break; + + case '$': + if (LOCAL_LABELS_DOLLAR) + { + integer_constant (10, expressionP); + break; + } + else + goto default_case; + } + + break; + +#ifndef NEED_INDEX_OPERATOR + case '[': +# ifdef md_need_index_operator + if (md_need_index_operator()) + goto de_fault; +# endif + /* FALLTHROUGH */ +#endif + case '(': + /* Didn't begin with digit & not a name. */ + segment = expr (0, expressionP, mode); + /* expression () will pass trailing whitespace. */ + if ((c == '(' && *input_line_pointer != ')') + || (c == '[' && *input_line_pointer != ']')) + as_bad (_("missing '%c'"), c == '(' ? ')' : ']'); + else + input_line_pointer++; + SKIP_WHITESPACE (); + /* Here with input_line_pointer -> char after "(...)". */ + return segment; + +#ifdef TC_M68K + case 'E': + if (! flag_m68k_mri || *input_line_pointer != '\'') + goto de_fault; + as_bad (_("EBCDIC constants are not supported")); + /* Fall through. */ + case 'A': + if (! flag_m68k_mri || *input_line_pointer != '\'') + goto de_fault; + ++input_line_pointer; + /* Fall through. */ +#endif + case '\'': + if (! flag_m68k_mri) + { + /* Warning: to conform to other people's assemblers NO + ESCAPEMENT is permitted for a single quote. The next + character, parity errors and all, is taken as the value + of the operand. VERY KINKY. */ + expressionP->X_op = O_constant; + expressionP->X_add_number = *input_line_pointer++; + break; + } + + mri_char_constant (expressionP); + break; + +#ifdef TC_M68K + case '"': + /* Double quote is the bitwise not operator in MRI mode. */ + if (! flag_m68k_mri) + goto de_fault; + /* Fall through. */ +#endif + case '~': + /* '~' is permitted to start a label on the Delta. */ + if (is_name_beginner (c)) + goto isname; + case '!': + case '-': + case '+': + { +#ifdef md_operator + unary: +#endif + operand (expressionP, mode); + if (expressionP->X_op == O_constant) + { + /* input_line_pointer -> char after operand. */ + if (c == '-') + { + expressionP->X_add_number = - expressionP->X_add_number; + /* Notice: '-' may overflow: no warning is given. + This is compatible with other people's + assemblers. Sigh. */ + expressionP->X_unsigned = 0; + if (expressionP->X_add_number) + expressionP->X_extrabit ^= 1; + } + else if (c == '~' || c == '"') + expressionP->X_add_number = ~ expressionP->X_add_number; + else if (c == '!') + expressionP->X_add_number = ! expressionP->X_add_number; + } + else if (expressionP->X_op == O_big + && expressionP->X_add_number <= 0 + && c == '-' + && (generic_floating_point_number.sign == '+' + || generic_floating_point_number.sign == 'P')) + { + /* Negative flonum (eg, -1.000e0). */ + if (generic_floating_point_number.sign == '+') + generic_floating_point_number.sign = '-'; + else + generic_floating_point_number.sign = 'N'; + } + else if (expressionP->X_op == O_big + && expressionP->X_add_number > 0) + { + int i; + + if (c == '~' || c == '-') + { + for (i = 0; i < expressionP->X_add_number; ++i) + generic_bignum[i] = ~generic_bignum[i]; + + /* Extend the bignum to at least the size of .octa. */ + if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER) + { + expressionP->X_add_number = SIZE_OF_LARGE_NUMBER; + for (; i < expressionP->X_add_number; ++i) + generic_bignum[i] = ~(LITTLENUM_TYPE) 0; + } + + if (c == '-') + for (i = 0; i < expressionP->X_add_number; ++i) + { + generic_bignum[i] += 1; + if (generic_bignum[i]) + break; + } + } + else if (c == '!') + { + for (i = 0; i < expressionP->X_add_number; ++i) + if (generic_bignum[i] != 0) + break; + expressionP->X_add_number = i >= expressionP->X_add_number; + expressionP->X_op = O_constant; + expressionP->X_unsigned = 1; + expressionP->X_extrabit = 0; + } + } + else if (expressionP->X_op != O_illegal + && expressionP->X_op != O_absent) + { + if (c != '+') + { + expressionP->X_add_symbol = make_expr_symbol (expressionP); + if (c == '-') + expressionP->X_op = O_uminus; + else if (c == '~' || c == '"') + expressionP->X_op = O_bit_not; + else + expressionP->X_op = O_logical_not; + expressionP->X_add_number = 0; + } + } + else + as_warn (_("Unary operator %c ignored because bad operand follows"), + c); + } + break; + +#if defined (DOLLAR_DOT) || defined (TC_M68K) + case '$': + /* '$' is the program counter when in MRI mode, or when + DOLLAR_DOT is defined. */ +#ifndef DOLLAR_DOT + if (! flag_m68k_mri) + goto de_fault; +#endif + if (DOLLAR_AMBIGU && hex_p (*input_line_pointer)) + { + /* In MRI mode and on Z80, '$' is also used as the prefix + for a hexadecimal constant. */ + integer_constant (16, expressionP); + break; + } + + if (is_part_of_name (*input_line_pointer)) + goto isname; + + current_location (expressionP); + break; +#endif + + case '.': + if (!is_part_of_name (*input_line_pointer)) + { + current_location (expressionP); + break; + } + else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0 + && ! is_part_of_name (input_line_pointer[8])) + || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0 + && ! is_part_of_name (input_line_pointer[7]))) + { + int start; + + start = (input_line_pointer[1] == 't' + || input_line_pointer[1] == 'T'); + input_line_pointer += start ? 8 : 7; + SKIP_WHITESPACE (); + if (*input_line_pointer != '(') + as_bad (_("syntax error in .startof. or .sizeof.")); + else + { + char *buf; + + ++input_line_pointer; + SKIP_WHITESPACE (); + name = input_line_pointer; + c = get_symbol_end (); + + buf = (char *) xmalloc (strlen (name) + 10); + if (start) + sprintf (buf, ".startof.%s", name); + else + sprintf (buf, ".sizeof.%s", name); + symbolP = symbol_make (buf); + free (buf); + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + + *input_line_pointer = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ')') + as_bad (_("syntax error in .startof. or .sizeof.")); + else + ++input_line_pointer; + } + break; + } + else + { + goto isname; + } + + case ',': + eol: + /* Can't imagine any other kind of operand. */ + expressionP->X_op = O_absent; + input_line_pointer--; + break; + +#ifdef TC_M68K + case '%': + if (! flag_m68k_mri) + goto de_fault; + integer_constant (2, expressionP); + break; + + case '@': + if (! flag_m68k_mri) + goto de_fault; + integer_constant (8, expressionP); + break; + + case ':': + if (! flag_m68k_mri) + goto de_fault; + + /* In MRI mode, this is a floating point constant represented + using hexadecimal digits. */ + + ++input_line_pointer; + integer_constant (16, expressionP); + break; + + case '*': + if (! flag_m68k_mri || is_part_of_name (*input_line_pointer)) + goto de_fault; + + current_location (expressionP); + break; +#endif + + default: +#if defined(md_need_index_operator) || defined(TC_M68K) + de_fault: +#endif + if (is_name_beginner (c)) /* Here if did not begin with a digit. */ + { + /* Identifier begins here. + This is kludged for speed, so code is repeated. */ + isname: + name = --input_line_pointer; + c = get_symbol_end (); + +#ifdef md_operator + { + operatorT op = md_operator (name, 1, &c); + + switch (op) + { + case O_uminus: + *input_line_pointer = c; + c = '-'; + goto unary; + case O_bit_not: + *input_line_pointer = c; + c = '~'; + goto unary; + case O_logical_not: + *input_line_pointer = c; + c = '!'; + goto unary; + case O_illegal: + as_bad (_("invalid use of operator \"%s\""), name); + break; + default: + break; + } + if (op != O_absent && op != O_illegal) + { + *input_line_pointer = c; + expr (9, expressionP, mode); + expressionP->X_add_symbol = make_expr_symbol (expressionP); + expressionP->X_op_symbol = NULL; + expressionP->X_add_number = 0; + expressionP->X_op = op; + break; + } + } +#endif + +#ifdef md_parse_name + /* This is a hook for the backend to parse certain names + specially in certain contexts. If a name always has a + specific value, it can often be handled by simply + entering it in the symbol table. */ + if (md_parse_name (name, expressionP, mode, &c)) + { + *input_line_pointer = c; + break; + } +#endif + +#ifdef TC_I960 + /* The MRI i960 assembler permits + lda sizeof code,g13 + FIXME: This should use md_parse_name. */ + if (flag_mri + && (strcasecmp (name, "sizeof") == 0 + || strcasecmp (name, "startof") == 0)) + { + int start; + char *buf; + + start = (name[1] == 't' + || name[1] == 'T'); + + *input_line_pointer = c; + SKIP_WHITESPACE (); + + name = input_line_pointer; + c = get_symbol_end (); + + buf = (char *) xmalloc (strlen (name) + 10); + if (start) + sprintf (buf, ".startof.%s", name); + else + sprintf (buf, ".sizeof.%s", name); + symbolP = symbol_make (buf); + free (buf); + + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + + *input_line_pointer = c; + SKIP_WHITESPACE (); + + break; + } +#endif + + symbolP = symbol_find_or_make (name); + + /* If we have an absolute symbol or a reg, then we know its + value now. */ + segment = S_GET_SEGMENT (symbolP); + if (mode != expr_defer + && segment == absolute_section + && !S_FORCE_RELOC (symbolP, 0)) + { + expressionP->X_op = O_constant; + expressionP->X_add_number = S_GET_VALUE (symbolP); + } + else if (mode != expr_defer && segment == reg_section) + { + expressionP->X_op = O_register; + expressionP->X_add_number = S_GET_VALUE (symbolP); + } + else + { + expressionP->X_op = O_symbol; + expressionP->X_add_symbol = symbolP; + expressionP->X_add_number = 0; + } + *input_line_pointer = c; + } + else + { + /* Let the target try to parse it. Success is indicated by changing + the X_op field to something other than O_absent and pointing + input_line_pointer past the expression. If it can't parse the + expression, X_op and input_line_pointer should be unchanged. */ + expressionP->X_op = O_absent; + --input_line_pointer; + md_operand (expressionP); + if (expressionP->X_op == O_absent) + { + ++input_line_pointer; + as_bad (_("bad expression")); + expressionP->X_op = O_constant; + expressionP->X_add_number = 0; + } + } + break; + } + + /* It is more 'efficient' to clean up the expressionS when they are + created. Doing it here saves lines of code. */ + clean_up_expression (expressionP); + SKIP_WHITESPACE (); /* -> 1st char after operand. */ + know (*input_line_pointer != ' '); + + /* The PA port needs this information. */ + if (expressionP->X_add_symbol) + symbol_mark_used (expressionP->X_add_symbol); + + if (mode != expr_defer) + { + expressionP->X_add_symbol + = symbol_clone_if_forward_ref (expressionP->X_add_symbol); + expressionP->X_op_symbol + = symbol_clone_if_forward_ref (expressionP->X_op_symbol); + } + + switch (expressionP->X_op) + { + default: + return absolute_section; + case O_symbol: + return S_GET_SEGMENT (expressionP->X_add_symbol); + case O_register: + return reg_section; + } +} + +/* Internal. Simplify a struct expression for use by expr (). */ + +/* In: address of an expressionS. + The X_op field of the expressionS may only take certain values. + Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT. + + Out: expressionS may have been modified: + Unused fields zeroed to help expr (). */ + +static void +clean_up_expression (expressionS *expressionP) +{ + switch (expressionP->X_op) + { + case O_illegal: + case O_absent: + expressionP->X_add_number = 0; + /* Fall through. */ + case O_big: + case O_constant: + case O_register: + expressionP->X_add_symbol = NULL; + /* Fall through. */ + case O_symbol: + case O_uminus: + case O_bit_not: + expressionP->X_op_symbol = NULL; + break; + default: + break; + } +} + +/* Expression parser. */ + +/* We allow an empty expression, and just assume (absolute,0) silently. + Unary operators and parenthetical expressions are treated as operands. + As usual, Q==quantity==operand, O==operator, X==expression mnemonics. + + We used to do an aho/ullman shift-reduce parser, but the logic got so + warped that I flushed it and wrote a recursive-descent parser instead. + Now things are stable, would anybody like to write a fast parser? + Most expressions are either register (which does not even reach here) + or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common. + So I guess it doesn't really matter how inefficient more complex expressions + are parsed. + + After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK. + Also, we have consumed any leading or trailing spaces (operand does that) + and done all intervening operators. + + This returns the segment of the result, which will be + absolute_section or the segment of a symbol. */ + +#undef __ +#define __ O_illegal +#ifndef O_SINGLE_EQ +#define O_SINGLE_EQ O_illegal +#endif + +/* Maps ASCII -> operators. */ +static const operatorT op_encoding[256] = { + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + + __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __, + __, __, O_multiply, O_add, __, O_subtract, __, O_divide, + __, __, __, __, __, __, __, __, + __, __, __, __, O_lt, O_SINGLE_EQ, O_gt, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, +#ifdef NEED_INDEX_OPERATOR + O_index, +#else + __, +#endif + __, __, O_bit_exclusive_or, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, O_bit_inclusive_or, __, __, __, + + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ +}; + +/* Rank Examples + 0 operand, (expression) + 1 || + 2 && + 3 == <> < <= >= > + 4 + - + 5 used for * / % in MRI mode + 6 & ^ ! | + 7 * / % << >> + 8 unary - unary ~ +*/ +static operator_rankT op_rank[O_max] = { + 0, /* O_illegal */ + 0, /* O_absent */ + 0, /* O_constant */ + 0, /* O_symbol */ + 0, /* O_symbol_rva */ + 0, /* O_register */ + 0, /* O_big */ + 9, /* O_uminus */ + 9, /* O_bit_not */ + 9, /* O_logical_not */ + 8, /* O_multiply */ + 8, /* O_divide */ + 8, /* O_modulus */ + 8, /* O_left_shift */ + 8, /* O_right_shift */ + 7, /* O_bit_inclusive_or */ + 7, /* O_bit_or_not */ + 7, /* O_bit_exclusive_or */ + 7, /* O_bit_and */ + 5, /* O_add */ + 5, /* O_subtract */ + 4, /* O_eq */ + 4, /* O_ne */ + 4, /* O_lt */ + 4, /* O_le */ + 4, /* O_ge */ + 4, /* O_gt */ + 3, /* O_logical_and */ + 2, /* O_logical_or */ + 1, /* O_index */ +}; + +/* Unfortunately, in MRI mode for the m68k, multiplication and + division have lower precedence than the bit wise operators. This + function sets the operator precedences correctly for the current + mode. Also, MRI uses a different bit_not operator, and this fixes + that as well. */ + +#define STANDARD_MUL_PRECEDENCE 8 +#define MRI_MUL_PRECEDENCE 6 + +void +expr_set_precedence (void) +{ + if (flag_m68k_mri) + { + op_rank[O_multiply] = MRI_MUL_PRECEDENCE; + op_rank[O_divide] = MRI_MUL_PRECEDENCE; + op_rank[O_modulus] = MRI_MUL_PRECEDENCE; + } + else + { + op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE; + op_rank[O_divide] = STANDARD_MUL_PRECEDENCE; + op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE; + } +} + +void +expr_set_rank (operatorT op, operator_rankT rank) +{ + gas_assert (op >= O_md1 && op < ARRAY_SIZE (op_rank)); + op_rank[op] = rank; +} + +/* Initialize the expression parser. */ + +void +expr_begin (void) +{ + expr_set_precedence (); + + /* Verify that X_op field is wide enough. */ + { + expressionS e; + e.X_op = O_max; + gas_assert (e.X_op == O_max); + } +} + +/* Return the encoding for the operator at INPUT_LINE_POINTER, and + sets NUM_CHARS to the number of characters in the operator. + Does not advance INPUT_LINE_POINTER. */ + +static inline operatorT +operatorf (int *num_chars) +{ + int c; + operatorT ret; + + c = *input_line_pointer & 0xff; + *num_chars = 1; + + if (is_end_of_line[c]) + return O_illegal; + +#ifdef md_operator + if (is_name_beginner (c)) + { + char *name = input_line_pointer; + char ec = get_symbol_end (); + + ret = md_operator (name, 2, &ec); + switch (ret) + { + case O_absent: + *input_line_pointer = ec; + input_line_pointer = name; + break; + case O_uminus: + case O_bit_not: + case O_logical_not: + as_bad (_("invalid use of operator \"%s\""), name); + ret = O_illegal; + /* FALLTHROUGH */ + default: + *input_line_pointer = ec; + *num_chars = input_line_pointer - name; + input_line_pointer = name; + return ret; + } + } +#endif + + switch (c) + { + default: + ret = op_encoding[c]; +#ifdef md_operator + if (ret == O_illegal) + { + char *start = input_line_pointer; + + ret = md_operator (NULL, 2, NULL); + if (ret != O_illegal) + *num_chars = input_line_pointer - start; + input_line_pointer = start; + } +#endif + return ret; + + case '+': + case '-': + return op_encoding[c]; + + case '<': + switch (input_line_pointer[1]) + { + default: + return op_encoding[c]; + case '<': + ret = O_left_shift; + break; + case '>': + ret = O_ne; + break; + case '=': + ret = O_le; + break; + } + *num_chars = 2; + return ret; + + case '=': + if (input_line_pointer[1] != '=') + return op_encoding[c]; + + *num_chars = 2; + return O_eq; + + case '>': + switch (input_line_pointer[1]) + { + default: + return op_encoding[c]; + case '>': + ret = O_right_shift; + break; + case '=': + ret = O_ge; + break; + } + *num_chars = 2; + return ret; + + case '!': + switch (input_line_pointer[1]) + { + case '!': + /* We accept !! as equivalent to ^ for MRI compatibility. */ + *num_chars = 2; + return O_bit_exclusive_or; + case '=': + /* We accept != as equivalent to <>. */ + *num_chars = 2; + return O_ne; + default: + if (flag_m68k_mri) + return O_bit_inclusive_or; + return op_encoding[c]; + } + + case '|': + if (input_line_pointer[1] != '|') + return op_encoding[c]; + + *num_chars = 2; + return O_logical_or; + + case '&': + if (input_line_pointer[1] != '&') + return op_encoding[c]; + + *num_chars = 2; + return O_logical_and; + } + + /* NOTREACHED */ +} + +/* Implement "word-size + 1 bit" addition for + {resultP->X_extrabit:resultP->X_add_number} + {rhs_highbit:amount}. This + is used so that the full range of unsigned word values and the full range of + signed word values can be represented in an O_constant expression, which is + useful e.g. for .sleb128 directives. */ + +void +add_to_result (expressionS *resultP, offsetT amount, int rhs_highbit) +{ + valueT ures = resultP->X_add_number; + valueT uamount = amount; + + resultP->X_add_number += amount; + + resultP->X_extrabit ^= rhs_highbit; + + if (ures + uamount < ures) + resultP->X_extrabit ^= 1; +} + +/* Similarly, for subtraction. */ + +void +subtract_from_result (expressionS *resultP, offsetT amount, int rhs_highbit) +{ + valueT ures = resultP->X_add_number; + valueT uamount = amount; + + resultP->X_add_number -= amount; + + resultP->X_extrabit ^= rhs_highbit; + + if (ures < uamount) + resultP->X_extrabit ^= 1; +} + +/* Parse an expression. */ + +segT +expr (int rankarg, /* Larger # is higher rank. */ + expressionS *resultP, /* Deliver result here. */ + enum expr_mode mode /* Controls behavior. */) +{ + operator_rankT rank = (operator_rankT) rankarg; + segT retval; + expressionS right; + operatorT op_left; + operatorT op_right; + int op_chars; + + know (rankarg >= 0); + + /* Save the value of dot for the fixup code. */ + if (rank == 0) + { + dot_value = frag_now_fix (); + dot_frag = frag_now; + } + + retval = operand (resultP, mode); + + /* operand () gobbles spaces. */ + know (*input_line_pointer != ' '); + + op_left = operatorf (&op_chars); + while (op_left != O_illegal && op_rank[(int) op_left] > rank) + { + segT rightseg; + offsetT frag_off; + + input_line_pointer += op_chars; /* -> after operator. */ + + right.X_md = 0; + rightseg = expr (op_rank[(int) op_left], &right, mode); + if (right.X_op == O_absent) + { + as_warn (_("missing operand; zero assumed")); + right.X_op = O_constant; + right.X_add_number = 0; + right.X_add_symbol = NULL; + right.X_op_symbol = NULL; + } + + know (*input_line_pointer != ' '); + + if (op_left == O_index) + { + if (*input_line_pointer != ']') + as_bad ("missing right bracket"); + else + { + ++input_line_pointer; + SKIP_WHITESPACE (); + } + } + + op_right = operatorf (&op_chars); + + know (op_right == O_illegal || op_left == O_index + || op_rank[(int) op_right] <= op_rank[(int) op_left]); + know ((int) op_left >= (int) O_multiply); +#ifndef md_operator + know ((int) op_left <= (int) O_index); +#else + know ((int) op_left < (int) O_max); +#endif + + /* input_line_pointer->after right-hand quantity. */ + /* left-hand quantity in resultP. */ + /* right-hand quantity in right. */ + /* operator in op_left. */ + + if (resultP->X_op == O_big) + { + if (resultP->X_add_number > 0) + as_warn (_("left operand is a bignum; integer 0 assumed")); + else + as_warn (_("left operand is a float; integer 0 assumed")); + resultP->X_op = O_constant; + resultP->X_add_number = 0; + resultP->X_add_symbol = NULL; + resultP->X_op_symbol = NULL; + } + if (right.X_op == O_big) + { + if (right.X_add_number > 0) + as_warn (_("right operand is a bignum; integer 0 assumed")); + else + as_warn (_("right operand is a float; integer 0 assumed")); + right.X_op = O_constant; + right.X_add_number = 0; + right.X_add_symbol = NULL; + right.X_op_symbol = NULL; + } + + /* Optimize common cases. */ +#ifdef md_optimize_expr + if (md_optimize_expr (resultP, op_left, &right)) + { + /* Skip. */ + ; + } + else +#endif +#ifndef md_register_arithmetic +# define md_register_arithmetic 1 +#endif + if (op_left == O_add && right.X_op == O_constant + && (md_register_arithmetic || resultP->X_op != O_register)) + { + /* X + constant. */ + add_to_result (resultP, right.X_add_number, right.X_extrabit); + } + /* This case comes up in PIC code. */ + else if (op_left == O_subtract + && right.X_op == O_symbol + && resultP->X_op == O_symbol + && retval == rightseg +#ifdef md_allow_local_subtract + && md_allow_local_subtract (resultP, & right, rightseg) +#endif + && ((SEG_NORMAL (rightseg) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) + || right.X_add_symbol == resultP->X_add_symbol) + && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol), + symbol_get_frag (right.X_add_symbol), + &frag_off)) + { + offsetT symval_diff = S_GET_VALUE (resultP->X_add_symbol) + - S_GET_VALUE (right.X_add_symbol); + subtract_from_result (resultP, right.X_add_number, right.X_extrabit); + subtract_from_result (resultP, frag_off / OCTETS_PER_BYTE, 0); + add_to_result (resultP, symval_diff, symval_diff < 0); + resultP->X_op = O_constant; + resultP->X_add_symbol = 0; + } + else if (op_left == O_subtract && right.X_op == O_constant + && (md_register_arithmetic || resultP->X_op != O_register)) + { + /* X - constant. */ + subtract_from_result (resultP, right.X_add_number, right.X_extrabit); + } + else if (op_left == O_add && resultP->X_op == O_constant + && (md_register_arithmetic || right.X_op != O_register)) + { + /* Constant + X. */ + resultP->X_op = right.X_op; + resultP->X_add_symbol = right.X_add_symbol; + resultP->X_op_symbol = right.X_op_symbol; + add_to_result (resultP, right.X_add_number, right.X_extrabit); + retval = rightseg; + } + else if (resultP->X_op == O_constant && right.X_op == O_constant) + { + /* Constant OP constant. */ + offsetT v = right.X_add_number; + if (v == 0 && (op_left == O_divide || op_left == O_modulus)) + { + as_warn (_("division by zero")); + v = 1; + } + if ((valueT) v >= sizeof(valueT) * CHAR_BIT + && (op_left == O_left_shift || op_left == O_right_shift)) + { + as_warn_value_out_of_range (_("shift count"), v, 0, + sizeof(valueT) * CHAR_BIT - 1, + NULL, 0); + resultP->X_add_number = v = 0; + } + switch (op_left) + { + default: goto general; + case O_multiply: resultP->X_add_number *= v; break; + case O_divide: resultP->X_add_number /= v; break; + case O_modulus: resultP->X_add_number %= v; break; + case O_left_shift: resultP->X_add_number <<= v; break; + case O_right_shift: + /* We always use unsigned shifts, to avoid relying on + characteristics of the compiler used to compile gas. */ + resultP->X_add_number = + (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); + break; + case O_bit_inclusive_or: resultP->X_add_number |= v; break; + case O_bit_or_not: resultP->X_add_number |= ~v; break; + case O_bit_exclusive_or: resultP->X_add_number ^= v; break; + case O_bit_and: resultP->X_add_number &= v; break; + /* Constant + constant (O_add) is handled by the + previous if statement for constant + X, so is omitted + here. */ + case O_subtract: + subtract_from_result (resultP, v, 0); + break; + case O_eq: + resultP->X_add_number = + resultP->X_add_number == v ? ~ (offsetT) 0 : 0; + break; + case O_ne: + resultP->X_add_number = + resultP->X_add_number != v ? ~ (offsetT) 0 : 0; + break; + case O_lt: + resultP->X_add_number = + resultP->X_add_number < v ? ~ (offsetT) 0 : 0; + break; + case O_le: + resultP->X_add_number = + resultP->X_add_number <= v ? ~ (offsetT) 0 : 0; + break; + case O_ge: + resultP->X_add_number = + resultP->X_add_number >= v ? ~ (offsetT) 0 : 0; + break; + case O_gt: + resultP->X_add_number = + resultP->X_add_number > v ? ~ (offsetT) 0 : 0; + break; + case O_logical_and: + resultP->X_add_number = resultP->X_add_number && v; + break; + case O_logical_or: + resultP->X_add_number = resultP->X_add_number || v; + break; + } + } + else if (resultP->X_op == O_symbol + && right.X_op == O_symbol + && (op_left == O_add + || op_left == O_subtract + || (resultP->X_add_number == 0 + && right.X_add_number == 0))) + { + /* Symbol OP symbol. */ + resultP->X_op = op_left; + resultP->X_op_symbol = right.X_add_symbol; + if (op_left == O_add) + add_to_result (resultP, right.X_add_number, right.X_extrabit); + else if (op_left == O_subtract) + { + subtract_from_result (resultP, right.X_add_number, + right.X_extrabit); + if (retval == rightseg + && SEG_NORMAL (retval) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) + { + retval = absolute_section; + rightseg = absolute_section; + } + } + } + else + { + general: + /* The general case. */ + resultP->X_add_symbol = make_expr_symbol (resultP); + resultP->X_op_symbol = make_expr_symbol (&right); + resultP->X_op = op_left; + resultP->X_add_number = 0; + resultP->X_unsigned = 1; + resultP->X_extrabit = 0; + } + + if (retval != rightseg) + { + if (retval == undefined_section) + ; + else if (rightseg == undefined_section) + retval = rightseg; + else if (retval == expr_section) + ; + else if (rightseg == expr_section) + retval = rightseg; + else if (retval == reg_section) + ; + else if (rightseg == reg_section) + retval = rightseg; + else if (rightseg == absolute_section) + ; + else if (retval == absolute_section) + retval = rightseg; +#ifdef DIFF_EXPR_OK + else if (op_left == O_subtract) + ; +#endif + else + as_bad (_("operation combines symbols in different segments")); + } + + op_left = op_right; + } /* While next operator is >= this rank. */ + + /* The PA port needs this information. */ + if (resultP->X_add_symbol) + symbol_mark_used (resultP->X_add_symbol); + + if (rank == 0 && mode == expr_evaluate) + resolve_expression (resultP); + + return resultP->X_op == O_constant ? absolute_section : retval; +} + +/* Resolve an expression without changing any symbols/sub-expressions + used. */ + +int +resolve_expression (expressionS *expressionP) +{ + /* Help out with CSE. */ + valueT final_val = expressionP->X_add_number; + symbolS *add_symbol = expressionP->X_add_symbol; + symbolS *orig_add_symbol = add_symbol; + symbolS *op_symbol = expressionP->X_op_symbol; + operatorT op = expressionP->X_op; + valueT left, right; + segT seg_left, seg_right; + fragS *frag_left, *frag_right; + offsetT frag_off; + + switch (op) + { + default: + return 0; + + case O_constant: + case O_register: + left = 0; + break; + + case O_symbol: + case O_symbol_rva: + if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left)) + return 0; + + break; + + case O_uminus: + case O_bit_not: + case O_logical_not: + if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left)) + return 0; + + if (seg_left != absolute_section) + return 0; + + if (op == O_logical_not) + left = !left; + else if (op == O_uminus) + left = -left; + else + left = ~left; + op = O_constant; + break; + + case O_multiply: + case O_divide: + case O_modulus: + case O_left_shift: + case O_right_shift: + case O_bit_inclusive_or: + case O_bit_or_not: + case O_bit_exclusive_or: + case O_bit_and: + case O_add: + case O_subtract: + case O_eq: + case O_ne: + case O_lt: + case O_le: + case O_ge: + case O_gt: + case O_logical_and: + case O_logical_or: + if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left) + || !snapshot_symbol (&op_symbol, &right, &seg_right, &frag_right)) + return 0; + + /* Simplify addition or subtraction of a constant by folding the + constant into X_add_number. */ + if (op == O_add) + { + if (seg_right == absolute_section) + { + final_val += right; + op = O_symbol; + break; + } + else if (seg_left == absolute_section) + { + final_val += left; + left = right; + seg_left = seg_right; + add_symbol = op_symbol; + orig_add_symbol = expressionP->X_op_symbol; + op = O_symbol; + break; + } + } + else if (op == O_subtract) + { + if (seg_right == absolute_section) + { + final_val -= right; + op = O_symbol; + break; + } + } + + /* Equality and non-equality tests are permitted on anything. + Subtraction, and other comparison operators are permitted if + both operands are in the same section. + Shifts by constant zero are permitted on anything. + Multiplies, bit-ors, and bit-ands with constant zero are + permitted on anything. + Multiplies and divides by constant one are permitted on + anything. + Binary operations with both operands being the same register + or undefined symbol are permitted if the result doesn't depend + on the input value. + Otherwise, both operands must be absolute. We already handled + the case of addition or subtraction of a constant above. */ + frag_off = 0; + if (!(seg_left == absolute_section + && seg_right == absolute_section) + && !(op == O_eq || op == O_ne) + && !((op == O_subtract + || op == O_lt || op == O_le || op == O_ge || op == O_gt) + && seg_left == seg_right + && (finalize_syms + || frag_offset_fixed_p (frag_left, frag_right, &frag_off)) + && (seg_left != reg_section || left == right) + && (seg_left != undefined_section || add_symbol == op_symbol))) + { + if ((seg_left == absolute_section && left == 0) + || (seg_right == absolute_section && right == 0)) + { + if (op == O_bit_exclusive_or || op == O_bit_inclusive_or) + { + if (!(seg_right == absolute_section && right == 0)) + { + seg_left = seg_right; + left = right; + add_symbol = op_symbol; + orig_add_symbol = expressionP->X_op_symbol; + } + op = O_symbol; + break; + } + else if (op == O_left_shift || op == O_right_shift) + { + if (!(seg_left == absolute_section && left == 0)) + { + op = O_symbol; + break; + } + } + else if (op != O_multiply + && op != O_bit_or_not && op != O_bit_and) + return 0; + } + else if (op == O_multiply + && seg_left == absolute_section && left == 1) + { + seg_left = seg_right; + left = right; + add_symbol = op_symbol; + orig_add_symbol = expressionP->X_op_symbol; + op = O_symbol; + break; + } + else if ((op == O_multiply || op == O_divide) + && seg_right == absolute_section && right == 1) + { + op = O_symbol; + break; + } + else if (!(left == right + && ((seg_left == reg_section && seg_right == reg_section) + || (seg_left == undefined_section + && seg_right == undefined_section + && add_symbol == op_symbol)))) + return 0; + else if (op == O_bit_and || op == O_bit_inclusive_or) + { + op = O_symbol; + break; + } + else if (op != O_bit_exclusive_or && op != O_bit_or_not) + return 0; + } + + right += frag_off / OCTETS_PER_BYTE; + switch (op) + { + case O_add: left += right; break; + case O_subtract: left -= right; break; + case O_multiply: left *= right; break; + case O_divide: + if (right == 0) + return 0; + left = (offsetT) left / (offsetT) right; + break; + case O_modulus: + if (right == 0) + return 0; + left = (offsetT) left % (offsetT) right; + break; + case O_left_shift: left <<= right; break; + case O_right_shift: left >>= right; break; + case O_bit_inclusive_or: left |= right; break; + case O_bit_or_not: left |= ~right; break; + case O_bit_exclusive_or: left ^= right; break; + case O_bit_and: left &= right; break; + case O_eq: + case O_ne: + left = (left == right + && seg_left == seg_right + && (finalize_syms || frag_left == frag_right) + && (seg_left != undefined_section + || add_symbol == op_symbol) + ? ~ (valueT) 0 : 0); + if (op == O_ne) + left = ~left; + break; + case O_lt: + left = (offsetT) left < (offsetT) right ? ~ (valueT) 0 : 0; + break; + case O_le: + left = (offsetT) left <= (offsetT) right ? ~ (valueT) 0 : 0; + break; + case O_ge: + left = (offsetT) left >= (offsetT) right ? ~ (valueT) 0 : 0; + break; + case O_gt: + left = (offsetT) left > (offsetT) right ? ~ (valueT) 0 : 0; + break; + case O_logical_and: left = left && right; break; + case O_logical_or: left = left || right; break; + default: abort (); + } + + op = O_constant; + break; + } + + if (op == O_symbol) + { + if (seg_left == absolute_section) + op = O_constant; + else if (seg_left == reg_section && final_val == 0) + op = O_register; + else if (!symbol_same_p (add_symbol, orig_add_symbol)) + final_val += left; + expressionP->X_add_symbol = add_symbol; + } + expressionP->X_op = op; + + if (op == O_constant || op == O_register) + final_val += left; + expressionP->X_add_number = final_val; + + return 1; +} + +/* This lives here because it belongs equally in expr.c & read.c. + expr.c is just a branch office read.c anyway, and putting it + here lessens the crowd at read.c. + + Assume input_line_pointer is at start of symbol name. + Advance input_line_pointer past symbol name. + Turn that character into a '\0', returning its former value. + This allows a string compare (RMS wants symbol names to be strings) + of the symbol name. + There will always be a char following symbol name, because all good + lines end in end-of-line. */ + +char +get_symbol_end (void) +{ + char c; + + /* We accept \001 in a name in case this is being called with a + constructed string. */ + if (is_name_beginner (c = *input_line_pointer++) || c == '\001') + { + while (is_part_of_name (c = *input_line_pointer++) + || c == '\001') + ; + if (is_name_ender (c)) + c = *input_line_pointer++; + } + *--input_line_pointer = 0; + return (c); +} + +unsigned int +get_single_number (void) +{ + expressionS exp; + operand (&exp, expr_normal); + return exp.X_add_number; +} diff --git a/contrib/toolchain/binutils/gas/expr.h b/contrib/toolchain/binutils/gas/expr.h new file mode 100644 index 0000000000..438ac0dcc1 --- /dev/null +++ b/contrib/toolchain/binutils/gas/expr.h @@ -0,0 +1,189 @@ +/* expr.h -> header file for expr.c + Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2002, 2003, 2005, 2007, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* + * By popular demand, we define a struct to represent an expression. + * This will no doubt mutate as expressions become baroque. + * + * Currently, we support expressions like "foo OP bar + 42". In other + * words we permit a (possibly undefined) symbol, a (possibly + * undefined) symbol and the operation used to combine the symbols, + * and an (absolute) augend. RMS says this is so we can have 1-pass + * assembly for any compiler emissions, and a 'case' statement might + * emit 'undefined1 - undefined2'. + * + * The type of an expression used to be stored as a segment. That got + * confusing because it overloaded the concept of a segment. I added + * an operator field, instead. + */ + +/* This is the type of an expression. The operator types are also + used while parsing an expression. + + NOTE: This enumeration must match the op_rank array in expr.c. */ + +typedef enum { + /* An illegal expression. */ + O_illegal, + /* A nonexistent expression. */ + O_absent, + /* X_add_number (a constant expression). */ + O_constant, + /* X_add_symbol + X_add_number. */ + O_symbol, + /* X_add_symbol + X_add_number - the base address of the image. */ + O_symbol_rva, + /* A register (X_add_number is register number). */ + O_register, + /* A big value. If X_add_number is negative or 0, the value is in + generic_floating_point_number. Otherwise the value is in + generic_bignum, and X_add_number is the number of LITTLENUMs in + the value. */ + O_big, + /* (- X_add_symbol) + X_add_number. */ + O_uminus, + /* (~ X_add_symbol) + X_add_number. */ + O_bit_not, + /* (! X_add_symbol) + X_add_number. */ + O_logical_not, + /* (X_add_symbol * X_op_symbol) + X_add_number. */ + O_multiply, + /* (X_add_symbol / X_op_symbol) + X_add_number. */ + O_divide, + /* (X_add_symbol % X_op_symbol) + X_add_number. */ + O_modulus, + /* (X_add_symbol << X_op_symbol) + X_add_number. */ + O_left_shift, + /* (X_add_symbol >> X_op_symbol) + X_add_number. */ + O_right_shift, + /* (X_add_symbol | X_op_symbol) + X_add_number. */ + O_bit_inclusive_or, + /* (X_add_symbol |~ X_op_symbol) + X_add_number. */ + O_bit_or_not, + /* (X_add_symbol ^ X_op_symbol) + X_add_number. */ + O_bit_exclusive_or, + /* (X_add_symbol & X_op_symbol) + X_add_number. */ + O_bit_and, + /* (X_add_symbol + X_op_symbol) + X_add_number. */ + O_add, + /* (X_add_symbol - X_op_symbol) + X_add_number. */ + O_subtract, + /* (X_add_symbol == X_op_symbol) + X_add_number. */ + O_eq, + /* (X_add_symbol != X_op_symbol) + X_add_number. */ + O_ne, + /* (X_add_symbol < X_op_symbol) + X_add_number. */ + O_lt, + /* (X_add_symbol <= X_op_symbol) + X_add_number. */ + O_le, + /* (X_add_symbol >= X_op_symbol) + X_add_number. */ + O_ge, + /* (X_add_symbol > X_op_symbol) + X_add_number. */ + O_gt, + /* (X_add_symbol && X_op_symbol) + X_add_number. */ + O_logical_and, + /* (X_add_symbol || X_op_symbol) + X_add_number. */ + O_logical_or, + /* X_op_symbol [ X_add_symbol ] */ + O_index, + /* machine dependent operators */ + O_md1, O_md2, O_md3, O_md4, O_md5, O_md6, O_md7, O_md8, + O_md9, O_md10, O_md11, O_md12, O_md13, O_md14, O_md15, O_md16, + O_md17, O_md18, O_md19, O_md20, O_md21, O_md22, O_md23, O_md24, + O_md25, O_md26, O_md27, O_md28, O_md29, O_md30, O_md31, O_md32, + /* this must be the largest value */ + O_max +} operatorT; + +typedef struct expressionS { + /* The main symbol. */ + symbolS *X_add_symbol; + /* The second symbol, if needed. */ + symbolS *X_op_symbol; + /* A number to add. */ + offsetT X_add_number; + + /* The type of the expression. We can't assume that an arbitrary + compiler can handle a bitfield of enum type. FIXME: We could + check this using autoconf. */ +#ifdef __GNUC__ + operatorT X_op : 8; +#else + unsigned char X_op; +#endif + + /* Non-zero if X_add_number should be regarded as unsigned. This is + only valid for O_constant expressions. It is only used when an + O_constant must be extended into a bignum (i.e., it is not used + when performing arithmetic on these values). + FIXME: This field is not set very reliably. */ + unsigned int X_unsigned : 1; + /* This is used to implement "word size + 1 bit" arithmetic, so that e.g. + expressions used with .sleb128 directives can use the full range available + for an unsigned word, but can also properly represent all values of a + signed word. */ + unsigned int X_extrabit : 1; + + /* 7 additional bits can be defined if needed. */ + + /* Machine dependent field */ + unsigned short X_md; +} expressionS; + +enum expr_mode +{ + expr_evaluate, + expr_normal, + expr_defer +}; + +/* "result" should be type (expressionS *). */ +#define expression(result) expr (0, result, expr_normal) +#define expression_and_evaluate(result) expr (0, result, expr_evaluate) +#define deferred_expression(result) expr (0, result, expr_defer) + +/* If an expression is O_big, look here for its value. These common + data may be clobbered whenever expr() is called. */ +/* Flonums returned here. Big enough to hold most precise flonum. */ +extern FLONUM_TYPE generic_floating_point_number; +/* Bignums returned here. */ +extern LITTLENUM_TYPE generic_bignum[]; +/* Number of littlenums in above. */ +#define SIZE_OF_LARGE_NUMBER (20) + +typedef char operator_rankT; + +extern char get_symbol_end (void); +extern void expr_begin (void); +extern void expr_set_precedence (void); +extern void expr_set_rank (operatorT, operator_rankT); +extern void add_to_result (expressionS *, offsetT, int); +extern void subtract_from_result (expressionS *, offsetT, int); +extern segT expr (int, expressionS *, enum expr_mode); +extern unsigned int get_single_number (void); +extern symbolS *make_expr_symbol (expressionS * expressionP); +extern int expr_symbol_where (symbolS *, char **, unsigned int *); +extern void current_location (expressionS *); + +extern symbolS *expr_build_uconstant (offsetT); +extern symbolS *expr_build_dot (void); + +int resolve_expression (expressionS *); diff --git a/contrib/toolchain/binutils/gas/flonum-copy.c b/contrib/toolchain/binutils/gas/flonum-copy.c new file mode 100644 index 0000000000..c1131b1250 --- /dev/null +++ b/contrib/toolchain/binutils/gas/flonum-copy.c @@ -0,0 +1,71 @@ +/* flonum_copy.c - copy a flonum + Copyright 1987, 1990, 1991, 1992, 1993, 2000, 2003, 2005, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" + +void +flonum_copy (FLONUM_TYPE *in, FLONUM_TYPE *out) +{ + unsigned int in_length; /* 0 origin */ + unsigned int out_length; /* 0 origin */ + + out->sign = in->sign; + in_length = in->leader - in->low; + + if (in->leader < in->low) + { + out->leader = out->low - 1; /* 0.0 case */ + } + else + { + out_length = out->high - out->low; + /* Assume no GAPS in packing of littlenums. + I.e. sizeof(array) == sizeof(element) * number_of_elements. */ + if (in_length <= out_length) + { + { + /* For defensive programming, zero any high-order + littlenums we don't need. This is destroying evidence + and wasting time, so why bother??? */ + if (in_length < out_length) + { + memset ((char *) (out->low + in_length + 1), '\0', + out_length - in_length); + } + } + memcpy ((void *) (out->low), (void *) (in->low), + ((in_length + 1) * sizeof (LITTLENUM_TYPE))); + out->exponent = in->exponent; + out->leader = in->leader - in->low + out->low; + } + else + { + int shorten; /* 1-origin. Number of littlenums we drop. */ + + shorten = in_length - out_length; + /* Assume out_length >= 0 ! */ + memcpy ((void *) (out->low), (void *) (in->low + shorten), + ((out_length + 1) * sizeof (LITTLENUM_TYPE))); + out->leader = out->high; + out->exponent = in->exponent + shorten; + } + } /* if any significant bits */ +} diff --git a/contrib/toolchain/binutils/gas/flonum-konst.c b/contrib/toolchain/binutils/gas/flonum-konst.c new file mode 100644 index 0000000000..cb60beaa66 --- /dev/null +++ b/contrib/toolchain/binutils/gas/flonum-konst.c @@ -0,0 +1,228 @@ +/* flonum_const.c - Useful Flonum constants + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2000, 2002, + 2005, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "ansidecl.h" +#include "flonum.h" +/* JF: I added the last entry to this table, and I'm not + sure if its right or not. Could go either way. I wish + I really understood this stuff. */ + +const int table_size_of_flonum_powers_of_ten = 13; + +static const LITTLENUM_TYPE zero[] = { + 1 +}; + +/***********************************************************************\ + * * + * Warning: the low order bits may be WRONG here. * + * I took this from a suspect bc(1) script. * + * "minus_X"[] is supposed to be 10^(2^-X) expressed in base 2^16. * + * The radix point is just AFTER the highest element of the [] * + * * + * Because bc rounds DOWN for printing (I think), the lowest * + * significance littlenums should probably have 1 added to them. * + * * + \***********************************************************************/ + +/* JF: If this equals 6553/(2^16)+39321/(2^32)+... it approaches .1 */ +static const LITTLENUM_TYPE minus_1[] = { + 39322, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, + 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 6553 +}; + +static const LITTLENUM_TYPE plus_1[] = { + 10 +}; + +/* JF: If this equals 655/(2^16) + 23592/(2^32) + ... it approaches .01 */ +static const LITTLENUM_TYPE minus_2[] = { + 10486, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 49807, + 10485, 36700, 62914, 23592, 49807, 10485, 36700, 62914, 23592, 655 +}; + +static const LITTLENUM_TYPE plus_2[] = { + 100 +}; + +/* This approaches .0001 */ +static const LITTLENUM_TYPE minus_3[] = { + 52534, 20027, 37329, 65116, 64067, 60397, 14784, 18979, 33659, 19503, + 2726, 9542, 629, 2202, 40475, 10590, 4299, 47815, 36280, 6 +}; + +static const LITTLENUM_TYPE plus_3[] = { + 10000 +}; + +/* JF: this approaches 1e-8 */ +static const LITTLENUM_TYPE minus_4[] = { + 22517, 49501, 54293, 19424, 60699, 6716, 24348, 22618, 23904, 21327, + 3919, 44703, 19149, 28803, 48959, 6259, 50273, 62237, 42 +}; + +/* This equals 1525 * 2^16 + 57600 */ +static const LITTLENUM_TYPE plus_4[] = { + 57600, 1525 +}; + +/* This approaches 1e-16 */ +static const LITTLENUM_TYPE minus_5[] = { + 22199, 45957, 17005, 26266, 10526, 16260, 55017, 35680, 40443, 19789, + 17356, 30195, 55905, 28426, 63010, 44197, 1844 +}; + +static const LITTLENUM_TYPE plus_5[] = { + 28609, 34546, 35 +}; + +static const LITTLENUM_TYPE minus_6[] = { + 30926, 26518, 13110, 43018, 54982, 48258, 24658, 15209, 63366, 11929, + 20069, 43857, 60487, 51 +}; + +static const LITTLENUM_TYPE plus_6[] = { + 61313, 34220, 16731, 11629, 1262 +}; + +static const LITTLENUM_TYPE minus_7[] = { + 29819, 14733, 21490, 40602, 31315, 65186, 2695 +}; + +static const LITTLENUM_TYPE plus_7[] = { + 7937, 49002, 60772, 28216, 38893, 55975, 63988, 59711, 20227, 24 +}; + +static const LITTLENUM_TYPE minus_8[] = { + 27579, 64807, 12543, 794, 13907, 61297, 12013, 64360, 15961, 20566, + 24178, 15922, 59427, 110 +}; + +static const LITTLENUM_TYPE plus_8[] = { + 15873, 11925, 39177, 991, 14589, 3861, 58415, 9076, 62956, 54223, + 56328, 50180, 45274, 48333, 32537, 42547, 9731, 59679, 590 +}; + +static const LITTLENUM_TYPE minus_9[] = { + 11042, 8464, 58971, 63429, 6022, 63485, 5500, 53464, 47545, 50068, + 56988, 22819, 49708, 54493, 9920, 47667, 40409, 35764, 10383, 54466, + 32702, 17493, 32420, 34382, 22750, 20681, 12300 +}; + +static const LITTLENUM_TYPE plus_9[] = { + 20678, 27614, 28272, 53066, 55311, 54677, 29038, 9906, 26288, 44486, + 13860, 7445, 54106, 15426, 21518, 25599, 29632, 52309, 61207, 26105, + 10482, 21948, 51191, 32988, 60892, 62574, 61390, 24540, 21495, 5 +}; + +static const LITTLENUM_TYPE minus_10[] = { + 6214, 48771, 23471, 30163, 31763, 38013, 57001, 11770, 18263, 36366, + 20742, 45086, 56969, 53231, 37856, 55814, 38057, 15692, 46761, 8713, + 6102, 20083, 8269, 11839, 11571, 50963, 15649, 11698, 40675, 2308 +}; + +static const LITTLENUM_TYPE plus_10[] = { + 63839, 36576, 45712, 44516, 37803, 29482, 4966, 30556, 37961, 23310, + 27070, 44972, 29507, 48257, 45209, 7494, 17831, 38728, 41577, 29443, + 36016, 7955, 35339, 35479, 36011, 14553, 49618, 5588, 25396, 28 +}; + +static const LITTLENUM_TYPE minus_11[] = { + 16663, 56882, 61983, 7804, 36555, 32060, 34502, 1000, 14356, 21681, + 6605, 34767, 51411, 59048, 53614, 39850, 30079, 6496, 6846, 26841, + 40778, 19578, 59899, 44085, 54016, 24259, 11232, 21229, 21313, 81 +}; + +static const LITTLENUM_TYPE plus_11[] = { + 92, 9054, 62707, 17993, 7821, 56838, 13992, 21321, 29637, 48426, + 42982, 38668, 49574, 28820, 18200, 18927, 53979, 16219, 37484, 2516, + 44642, 14665, 11587, 41926, 13556, 23956, 54320, 6661, 55766, 805 +}; + +static const LITTLENUM_TYPE minus_12[] = { + 33202, 45969, 58804, 56734, 16482, 26007, 44984, 49334, 31007, 32944, + 44517, 63329, 47131, 15291, 59465, 2264, 23218, 11829, 59771, 38798, + 31051, 28748, 23129, 40541, 41562, 35108, 50620, 59014, 51817, 6613 +}; + +static const LITTLENUM_TYPE plus_12[] = { + 10098, 37922, 58070, 7432, 10470, 63465, 23718, 62190, 47420, 7009, + 38443, 4587, 45596, 38472, 52129, 52779, 29012, 13559, 48688, 31678, + 41753, 58662, 10668, 36067, 29906, 56906, 21461, 46556, 59571, 9 +}; + +static const LITTLENUM_TYPE minus_13[] = { + 45309, 27592, 37144, 34637, 34328, 41671, 34620, 24135, 53401, 22112, + 21576, 45147, 39310, 44051, 48572, 3676, 46544, 59768, 33350, 2323, + 49524, 61568, 3903, 36487, 36356, 30903, 14975, 9035, 29715, 667 +}; + +static const LITTLENUM_TYPE plus_13[] = { + 18788, 16960, 6318, 45685, 55400, 46230, 35794, 25588, 7253, 55541, + 49716, 59760, 63592, 8191, 63765, 58530, 44667, 13294, 10001, 55586, + 47887, 18738, 9509, 40896, 42506, 52580, 4171, 325, 12329, 98 +}; + +/* Shut up complaints about differing pointer types. They only differ + in the const attribute, but there isn't any easy way to do this + */ +#define X (LITTLENUM_TYPE *) + +const FLONUM_TYPE flonum_negative_powers_of_ten[] = { + {X zero, X zero, X zero, 0, '+'}, + {X minus_1, X minus_1 + 19, X minus_1 + 19, -20, '+'}, + {X minus_2, X minus_2 + 19, X minus_2 + 19, -20, '+'}, + {X minus_3, X minus_3 + 19, X minus_3 + 19, -20, '+'}, + {X minus_4, X minus_4 + 18, X minus_4 + 18, -20, '+'}, + {X minus_5, X minus_5 + 16, X minus_5 + 16, -20, '+'}, + {X minus_6, X minus_6 + 13, X minus_6 + 13, -20, '+'}, + {X minus_7, X minus_7 + 6, X minus_7 + 6, -20, '+'}, + {X minus_8, X minus_8 + 13, X minus_8 + 13, -40, '+'}, + {X minus_9, X minus_9 + 26, X minus_9 + 26, -80, '+'}, + {X minus_10, X minus_10 + 29, X minus_10 + 29, -136, '+'}, + {X minus_11, X minus_11 + 29, X minus_11 + 29, -242, '+'}, + {X minus_12, X minus_12 + 29, X minus_12 + 29, -455, '+'}, + {X minus_13, X minus_13 + 29, X minus_13 + 29, -880, '+'}, +}; + +const FLONUM_TYPE flonum_positive_powers_of_ten[] = { + {X zero, X zero, X zero, 0, '+'}, + {X plus_1, X plus_1 + 0, X plus_1 + 0, 0, '+'}, + {X plus_2, X plus_2 + 0, X plus_2 + 0, 0, '+'}, + {X plus_3, X plus_3 + 0, X plus_3 + 0, 0, '+'}, + {X plus_4, X plus_4 + 1, X plus_4 + 1, 0, '+'}, + {X plus_5, X plus_5 + 2, X plus_5 + 2, 1, '+'}, + {X plus_6, X plus_6 + 4, X plus_6 + 4, 2, '+'}, + {X plus_7, X plus_7 + 9, X plus_7 + 9, 4, '+'}, + {X plus_8, X plus_8 + 18, X plus_8 + 18, 8, '+'}, + {X plus_9, X plus_9 + 29, X plus_9 + 29, 24, '+'}, + {X plus_10, X plus_10 + 29, X plus_10 + 29, 77, '+'}, + {X plus_11, X plus_11 + 29, X plus_11 + 29, 183, '+'}, + {X plus_12, X plus_12 + 29, X plus_12 + 29, 396, '+'}, + {X plus_13, X plus_13 + 29, X plus_13 + 29, 821, '+'}, +}; + +#ifdef VMS +void +dummy1 () +{ +} +#endif diff --git a/contrib/toolchain/binutils/gas/flonum-mult.c b/contrib/toolchain/binutils/gas/flonum-mult.c new file mode 100644 index 0000000000..e5f32fca2e --- /dev/null +++ b/contrib/toolchain/binutils/gas/flonum-mult.c @@ -0,0 +1,188 @@ +/* flonum_mult.c - multiply two flonums + Copyright 1987, 1990, 1991, 1992, 1995, 2000, 2002, 2003, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "ansidecl.h" +#include "flonum.h" + +/* plan for a . b => p(roduct) + + +-------+-------+-/ /-+-------+-------+ + | a | a | ... | a | a | + | A | A-1 | | 1 | 0 | + +-------+-------+-/ /-+-------+-------+ + + +-------+-------+-/ /-+-------+-------+ + | b | b | ... | b | b | + | B | B-1 | | 1 | 0 | + +-------+-------+-/ /-+-------+-------+ + + +-------+-------+-/ /-+-------+-/ /-+-------+-------+ + | p | p | ... | p | ... | p | p | + | A+B+1| A+B | | N | | 1 | 0 | + +-------+-------+-/ /-+-------+-/ /-+-------+-------+ + + /^\ + (carry) a .b ... | ... a .b a .b + A B | 0 1 0 0 + | + ... | ... a .b + | 1 0 + | + | ... + | + | + | + | ___ + | \ + +----- P = > a .b + N /__ i j + + N = 0 ... A+B + + for all i,j where i+j=N + [i,j integers > 0] + + a[], b[], p[] may not intersect. + Zero length factors signify 0 significant bits: treat as 0.0. + 0.0 factors do the right thing. + Zero length product OK. + + I chose the ForTran accent "foo[bar]" instead of the C accent "*garply" + because I felt the ForTran way was more intuitive. The C way would + probably yield better code on most C compilers. Dean Elsner. + (C style also gives deeper insight [to me] ... oh well ...) */ + +void +flonum_multip (const FLONUM_TYPE *a, const FLONUM_TYPE *b, + FLONUM_TYPE *product) +{ + int size_of_a; /* 0 origin */ + int size_of_b; /* 0 origin */ + int size_of_product; /* 0 origin */ + int size_of_sum; /* 0 origin */ + int extra_product_positions; /* 1 origin */ + unsigned long work; + unsigned long carry; + long exponent; + LITTLENUM_TYPE *q; + long significant; /* TRUE when we emit a non-0 littlenum */ + /* ForTran accent follows. */ + int P; /* Scan product low-order -> high. */ + int N; /* As in sum above. */ + int A; /* Which [] of a? */ + int B; /* Which [] of b? */ + + if ((a->sign != '-' && a->sign != '+') + || (b->sign != '-' && b->sign != '+')) + { + /* Got to fail somehow. Any suggestions? */ + product->sign = 0; + return; + } + product->sign = (a->sign == b->sign) ? '+' : '-'; + size_of_a = a->leader - a->low; + size_of_b = b->leader - b->low; + exponent = a->exponent + b->exponent; + size_of_product = product->high - product->low; + size_of_sum = size_of_a + size_of_b; + extra_product_positions = size_of_product - size_of_sum; + if (extra_product_positions < 0) + { + P = extra_product_positions; /* P < 0 */ + exponent -= extra_product_positions; /* Increases exponent. */ + } + else + { + P = 0; + } + carry = 0; + significant = 0; + for (N = 0; N <= size_of_sum; N++) + { + work = carry; + carry = 0; + for (A = 0; A <= N; A++) + { + B = N - A; + if (A <= size_of_a && B <= size_of_b && B >= 0) + { +#ifdef TRACE + printf ("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n", + A, a->low[A], B, b->low[B], work); +#endif + /* Watch out for sign extension! Without the casts, on + the DEC Alpha, the multiplication result is *signed* + int, which gets sign-extended to convert to the + unsigned long! */ + work += (unsigned long) a->low[A] * (unsigned long) b->low[B]; + carry += work >> LITTLENUM_NUMBER_OF_BITS; + work &= LITTLENUM_MASK; +#ifdef TRACE + printf ("work=%08x carry=%04x\n", work, carry); +#endif + } + } + significant |= work; + if (significant || P < 0) + { + if (P >= 0) + { + product->low[P] = work; +#ifdef TRACE + printf ("P=%d. work[p]:=%04x\n", P, work); +#endif + } + P++; + } + else + { + extra_product_positions++; + exponent++; + } + } + /* [P]-> position # size_of_sum + 1. + This is where 'carry' should go. */ +#ifdef TRACE + printf ("final carry =%04x\n", carry); +#endif + if (carry) + { + if (extra_product_positions > 0) + product->low[P] = carry; + else + { + /* No room at high order for carry littlenum. */ + /* Shift right 1 to make room for most significant littlenum. */ + exponent++; + P--; + for (q = product->low + P; q >= product->low; q--) + { + work = *q; + *q = carry; + carry = work; + } + } + } + else + P--; + product->leader = product->low + P; + product->exponent = exponent; +} diff --git a/contrib/toolchain/binutils/gas/flonum.h b/contrib/toolchain/binutils/gas/flonum.h new file mode 100644 index 0000000000..c27dd22235 --- /dev/null +++ b/contrib/toolchain/binutils/gas/flonum.h @@ -0,0 +1,102 @@ +/* flonum.h - Floating point package + Copyright 1987, 1990, 1991, 1992, 1994, 1996, 2000, 2003, 2005, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/***********************************************************************\ + * * + * Arbitrary-precision floating point arithmetic. * + * * + * * + * Notation: a floating point number is expressed as * + * MANTISSA * (2 ** EXPONENT). * + * * + * If this offends more traditional mathematicians, then * + * please tell me your nomenclature for flonums! * + * * + \***********************************************************************/ + +#include "bignum.h" + +/***********************************************************************\ + * * + * Variable precision floating point numbers. * + * * + * Exponent is the place value of the low littlenum. E.g.: * + * If 0: low points to the units littlenum. * + * If 1: low points to the LITTLENUM_RADIX littlenum. * + * If -1: low points to the 1/LITTLENUM_RADIX littlenum. * + * * + \***********************************************************************/ + +/* JF: A sign value of 0 means we have been asked to assemble NaN + A sign value of 'P' means we've been asked to assemble +Inf + A sign value of 'N' means we've been asked to assemble -Inf + */ +struct FLONUM_STRUCT { + LITTLENUM_TYPE *low; /* low order littlenum of a bignum */ + LITTLENUM_TYPE *high; /* high order littlenum of a bignum */ + LITTLENUM_TYPE *leader; /* -> 1st non-zero littlenum */ + /* If flonum is 0.0, leader==low-1 */ + long exponent; /* base LITTLENUM_RADIX */ + char sign; /* '+' or '-' */ +}; + +typedef struct FLONUM_STRUCT FLONUM_TYPE; + +/***********************************************************************\ + * * + * Since we can (& do) meet with exponents like 10^5000, it * + * is silly to make a table of ~ 10,000 entries, one for each * + * power of 10. We keep a table where item [n] is a struct * + * FLONUM_FLOATING_POINT representing 10^(2^n). We then * + * multiply appropriate entries from this table to get any * + * particular power of 10. For the example of 10^5000, a table * + * of just 25 entries suffices: 10^(2^-12)...10^(2^+12). * + * * + \***********************************************************************/ + +extern const FLONUM_TYPE flonum_positive_powers_of_ten[]; +extern const FLONUM_TYPE flonum_negative_powers_of_ten[]; +extern const int table_size_of_flonum_powers_of_ten; +/* Flonum_XXX_powers_of_ten[] table has legal indices from 0 to + + this number inclusive. */ + +/***********************************************************************\ + * * + * Declare worker functions. * + * * + \***********************************************************************/ + +int atof_generic (char **address_of_string_pointer, + const char *string_of_decimal_marks, + const char *string_of_decimal_exponent_marks, + FLONUM_TYPE * address_of_generic_floating_point_number); + +void flonum_copy (FLONUM_TYPE * in, FLONUM_TYPE * out); +void flonum_multip (const FLONUM_TYPE * a, const FLONUM_TYPE * b, + FLONUM_TYPE * product); + +/***********************************************************************\ + * * + * Declare error codes. * + * * + \***********************************************************************/ + +#define ERROR_EXPONENT_OVERFLOW (2) diff --git a/contrib/toolchain/binutils/gas/frags.c b/contrib/toolchain/binutils/gas/frags.c new file mode 100644 index 0000000000..beb251bb01 --- /dev/null +++ b/contrib/toolchain/binutils/gas/frags.c @@ -0,0 +1,445 @@ +/* frags.c - manage frags - + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "subsegs.h" +#include "obstack.h" + +extern fragS zero_address_frag; +extern fragS predefined_address_frag; + +/* Initialization for frag routines. */ + +void +frag_init (void) +{ + zero_address_frag.fr_type = rs_fill; + predefined_address_frag.fr_type = rs_fill; +} + +/* Check that we're not trying to assemble into a section that can't + allocate frags (currently, this is only possible in the absolute + section), or into an mri common. */ + +static void +frag_alloc_check (const struct obstack *ob) +{ + if (ob->chunk_size == 0) + { + as_bad (_("attempt to allocate data in absolute section")); + subseg_set (text_section, 0); + } + + if (mri_common_symbol != NULL) + { + as_bad (_("attempt to allocate data in common section")); + mri_common_symbol = NULL; + } +} + +/* Allocate a frag on the specified obstack. + Call this routine from everywhere else, so that all the weird alignment + hackery can be done in just one place. */ + +fragS * +frag_alloc (struct obstack *ob) +{ + fragS *ptr; + int oalign; + + (void) obstack_alloc (ob, 0); + oalign = obstack_alignment_mask (ob); + obstack_alignment_mask (ob) = 0; + ptr = (fragS *) obstack_alloc (ob, SIZEOF_STRUCT_FRAG); + obstack_alignment_mask (ob) = oalign; + memset (ptr, 0, SIZEOF_STRUCT_FRAG); + return ptr; +} + +/* Try to augment current frag by nchars chars. + If there is no room, close of the current frag with a ".fill 0" + and begin a new frag. Unless the new frag has nchars chars available + do not return. Do not set up any fields of *now_frag. */ + +void +frag_grow (unsigned int nchars) +{ + if (obstack_room (&frchain_now->frch_obstack) < nchars) + { + long oldc; + long newc; + + /* Try to allocate a bit more than needed right now. But don't do + this if we would waste too much memory. Especially necessary + for extremely big (like 2GB initialized) frags. */ + if (nchars < 0x10000) + newc = 2 * nchars; + else + newc = nchars + 0x10000; + newc += SIZEOF_STRUCT_FRAG; + + /* Check for possible overflow. */ + if (newc < 0) + as_fatal (_("can't extend frag %u chars"), nchars); + + /* Force to allocate at least NEWC bytes, but not less than the + default. */ + oldc = obstack_chunk_size (&frchain_now->frch_obstack); + if (newc > oldc) + obstack_chunk_size (&frchain_now->frch_obstack) = newc; + + while (obstack_room (&frchain_now->frch_obstack) < nchars) + { + /* Not enough room in this frag. Close it and start a new one. + This must be done in a loop because the created frag may not + be big enough if the current obstack chunk is used. */ + frag_wane (frag_now); + frag_new (0); + } + + /* Restore the old chunk size. */ + obstack_chunk_size (&frchain_now->frch_obstack) = oldc; + } +} + +/* Call this to close off a completed frag, and start up a new (empty) + frag, in the same subsegment as the old frag. + [frchain_now remains the same but frag_now is updated.] + Because this calculates the correct value of fr_fix by + looking at the obstack 'frags', it needs to know how many + characters at the end of the old frag belong to the maximal + variable part; The rest must belong to fr_fix. + It doesn't actually set up the old frag's fr_var. You may have + set fr_var == 1, but allocated 10 chars to the end of the frag; + In this case you pass old_frags_var_max_size == 10. + In fact, you may use fr_var for something totally unrelated to the + size of the variable part of the frag; None of the generic frag + handling code makes use of fr_var. + + Make a new frag, initialising some components. Link new frag at end + of frchain_now. */ + +void +frag_new (int old_frags_var_max_size + /* Number of chars (already allocated on obstack frags) in + variable_length part of frag. */) +{ + fragS *former_last_fragP; + frchainS *frchP; + + gas_assert (frchain_now->frch_last == frag_now); + + /* Fix up old frag's fr_fix. */ + frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size; + /* Make sure its type is valid. */ + gas_assert (frag_now->fr_type != 0); + + /* This will align the obstack so the next struct we allocate on it + will begin at a correct boundary. */ + obstack_finish (&frchain_now->frch_obstack); + frchP = frchain_now; + know (frchP); + former_last_fragP = frchP->frch_last; + gas_assert (former_last_fragP != 0); + gas_assert (former_last_fragP == frag_now); + frag_now = frag_alloc (&frchP->frch_obstack); + + as_where (&frag_now->fr_file, &frag_now->fr_line); + + /* Generally, frag_now->points to an address rounded up to next + alignment. However, characters will add to obstack frags + IMMEDIATELY after the struct frag, even if they are not starting + at an alignment address. */ + former_last_fragP->fr_next = frag_now; + frchP->frch_last = frag_now; + +#ifndef NO_LISTING + { + extern struct list_info_struct *listing_tail; + frag_now->line = listing_tail; + } +#endif + + gas_assert (frchain_now->frch_last == frag_now); + + frag_now->fr_next = NULL; +} + +/* Start a new frag unless we have n more chars of room in the current frag. + Close off the old frag with a .fill 0. + + Return the address of the 1st char to write into. Advance + frag_now_growth past the new chars. */ + +char * +frag_more (int nchars) +{ + register char *retval; + + frag_alloc_check (&frchain_now->frch_obstack); + frag_grow (nchars); + retval = obstack_next_free (&frchain_now->frch_obstack); + obstack_blank_fast (&frchain_now->frch_obstack, nchars); + return (retval); +} + +/* Close the current frag, setting its fields for a relaxable frag. Start a + new frag. */ + +static void +frag_var_init (relax_stateT type, int max_chars, int var, + relax_substateT subtype, symbolS *symbol, offsetT offset, + char *opcode) +{ + frag_now->fr_var = var; + frag_now->fr_type = type; + frag_now->fr_subtype = subtype; + frag_now->fr_symbol = symbol; + frag_now->fr_offset = offset; + frag_now->fr_opcode = opcode; +#ifdef USING_CGEN + frag_now->fr_cgen.insn = 0; + frag_now->fr_cgen.opindex = 0; + frag_now->fr_cgen.opinfo = 0; +#endif +#ifdef TC_FRAG_INIT + TC_FRAG_INIT (frag_now); +#endif + as_where (&frag_now->fr_file, &frag_now->fr_line); + + frag_new (max_chars); +} + +/* Start a new frag unless we have max_chars more chars of room in the + current frag. Close off the old frag with a .fill 0. + + Set up a machine_dependent relaxable frag, then start a new frag. + Return the address of the 1st char of the var part of the old frag + to write into. */ + +char * +frag_var (relax_stateT type, int max_chars, int var, relax_substateT subtype, + symbolS *symbol, offsetT offset, char *opcode) +{ + register char *retval; + + frag_grow (max_chars); + retval = obstack_next_free (&frchain_now->frch_obstack); + obstack_blank_fast (&frchain_now->frch_obstack, max_chars); + frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode); + return retval; +} + +/* OVE: This variant of frag_var assumes that space for the tail has been + allocated by caller. + No call to frag_grow is done. */ + +char * +frag_variant (relax_stateT type, int max_chars, int var, + relax_substateT subtype, symbolS *symbol, offsetT offset, + char *opcode) +{ + register char *retval; + + retval = obstack_next_free (&frchain_now->frch_obstack); + frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode); + + return retval; +} + +/* Reduce the variable end of a frag to a harmless state. */ + +void +frag_wane (register fragS *fragP) +{ + fragP->fr_type = rs_fill; + fragP->fr_offset = 0; + fragP->fr_var = 0; +} + +/* Return the number of bytes by which the current frag can be grown. */ + +int +frag_room (void) +{ + return obstack_room (&frchain_now->frch_obstack); +} + +/* Make an alignment frag. The size of this frag will be adjusted to + force the next frag to have the appropriate alignment. ALIGNMENT + is the power of two to which to align. FILL_CHARACTER is the + character to use to fill in any bytes which are skipped. MAX is + the maximum number of characters to skip when doing the alignment, + or 0 if there is no maximum. */ + +void +frag_align (int alignment, int fill_character, int max) +{ + if (now_seg == absolute_section) + { + addressT new_off; + addressT mask; + + mask = (~(addressT) 0) << alignment; + new_off = (abs_section_offset + ~mask) & mask; + if (max == 0 || new_off - abs_section_offset <= (addressT) max) + abs_section_offset = new_off; + } + else + { + char *p; + + p = frag_var (rs_align, 1, 1, (relax_substateT) max, + (symbolS *) 0, (offsetT) alignment, (char *) 0); + *p = fill_character; + } +} + +/* Make an alignment frag like frag_align, but fill with a repeating + pattern rather than a single byte. ALIGNMENT is the power of two + to which to align. FILL_PATTERN is the fill pattern to repeat in + the bytes which are skipped. N_FILL is the number of bytes in + FILL_PATTERN. MAX is the maximum number of characters to skip when + doing the alignment, or 0 if there is no maximum. */ + +void +frag_align_pattern (int alignment, const char *fill_pattern, + int n_fill, int max) +{ + char *p; + + p = frag_var (rs_align, n_fill, n_fill, (relax_substateT) max, + (symbolS *) 0, (offsetT) alignment, (char *) 0); + memcpy (p, fill_pattern, n_fill); +} + +/* The NOP_OPCODE is for the alignment fill value. Fill it with a nop + instruction so that the disassembler does not choke on it. */ +#ifndef NOP_OPCODE +#define NOP_OPCODE 0x00 +#endif + +/* Use this to restrict the amount of memory allocated for representing + the alignment code. Needs to be large enough to hold any fixed sized + prologue plus the replicating portion. */ +#ifndef MAX_MEM_FOR_RS_ALIGN_CODE + /* Assume that if HANDLE_ALIGN is not defined then no special action + is required to code fill, which means that we get just repeat the + one NOP_OPCODE byte. */ +# ifndef HANDLE_ALIGN +# define MAX_MEM_FOR_RS_ALIGN_CODE 1 +# else +# define MAX_MEM_FOR_RS_ALIGN_CODE ((1 << alignment) - 1) +# endif +#endif + +void +frag_align_code (int alignment, int max) +{ + char *p; + + p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1, + (relax_substateT) max, (symbolS *) 0, + (offsetT) alignment, (char *) 0); + *p = NOP_OPCODE; +} + +addressT +frag_now_fix_octets (void) +{ + if (now_seg == absolute_section) + return abs_section_offset; + + return ((char *) obstack_next_free (&frchain_now->frch_obstack) + - frag_now->fr_literal); +} + +addressT +frag_now_fix (void) +{ + return frag_now_fix_octets () / OCTETS_PER_BYTE; +} + +void +frag_append_1_char (int datum) +{ + frag_alloc_check (&frchain_now->frch_obstack); + if (obstack_room (&frchain_now->frch_obstack) <= 1) + { + frag_wane (frag_now); + frag_new (0); + } + obstack_1grow (&frchain_now->frch_obstack, datum); +} + +/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between + their start addresses. Set OFFSET to the difference in address + not already accounted for in the frag FR_ADDRESS. */ + +bfd_boolean +frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset) +{ + const fragS *frag; + offsetT off; + + /* Start with offset initialised to difference between the two frags. + Prior to assigning frag addresses this will be zero. */ + off = frag1->fr_address - frag2->fr_address; + if (frag1 == frag2) + { + *offset = off; + return TRUE; + } + + /* Maybe frag2 is after frag1. */ + frag = frag1; + while (frag->fr_type == rs_fill) + { + off += frag->fr_fix + frag->fr_offset * frag->fr_var; + frag = frag->fr_next; + if (frag == NULL) + break; + if (frag == frag2) + { + *offset = off; + return TRUE; + } + } + + /* Maybe frag1 is after frag2. */ + off = frag1->fr_address - frag2->fr_address; + frag = frag2; + while (frag->fr_type == rs_fill) + { + off -= frag->fr_fix + frag->fr_offset * frag->fr_var; + frag = frag->fr_next; + if (frag == NULL) + break; + if (frag == frag1) + { + *offset = off; + return TRUE; + } + } + + return FALSE; +} diff --git a/contrib/toolchain/binutils/gas/frags.h b/contrib/toolchain/binutils/gas/frags.h new file mode 100644 index 0000000000..f5846be5a5 --- /dev/null +++ b/contrib/toolchain/binutils/gas/frags.h @@ -0,0 +1,160 @@ +/* frags.h - Header file for the frag concept. + Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef FRAGS_H +#define FRAGS_H + +struct obstack; + +/* A code fragment (frag) is some known number of chars, followed by some + unknown number of chars. Typically the unknown number of chars is an + instruction address whose size is yet unknown. We always know the greatest + possible size the unknown number of chars may become, and reserve that + much room at the end of the frag. + Once created, frags do not change address during assembly. + We chain the frags in (a) forward-linked list(s). The object-file address + of the 1st char of a frag is generally not known until after relax(). + Many things at assembly time describe an address by {object-file-address + of a particular frag}+offset. + + BUG: it may be smarter to have a single pointer off to various different + notes for different frag kinds. See how code pans. */ + +struct frag { + /* Object file address (as an octet offset). */ + addressT fr_address; + /* When relaxing multiple times, remember the address the frag had + in the last relax pass. */ + addressT last_fr_address; + + /* (Fixed) number of octets we know we have. May be 0. */ + offsetT fr_fix; + /* May be used for (Variable) number of octets after above. + The generic frag handling code no longer makes any use of fr_var. */ + offsetT fr_var; + /* For variable-length tail. */ + offsetT fr_offset; + /* For variable-length tail. */ + symbolS *fr_symbol; + /* Points to opcode low addr byte, for relaxation. */ + char *fr_opcode; + + /* Chain forward; ascending address order. Rooted in frch_root. */ + struct frag *fr_next; + + /* Where the frag was created, or where it became a variant frag. */ + char *fr_file; + unsigned int fr_line; + +#ifndef NO_LISTING + struct list_info_struct *line; +#endif + + /* A serial number for a sequence of frags having at most one alignment + or org frag, and that at the tail of the sequence. */ + unsigned int region:16; + + /* Flipped each relax pass so we can easily determine whether + fr_address has been adjusted. */ + unsigned int relax_marker:1; + + /* Used to ensure that all insns are emitted on proper address + boundaries. */ + unsigned int has_code:1; + unsigned int insn_addr:6; + + /* What state is my tail in? */ + relax_stateT fr_type; + relax_substateT fr_subtype; + +#ifdef USING_CGEN + /* Don't include this unless using CGEN to keep frag size down. */ + struct { + /* CGEN_INSN entry for this instruction. */ + const struct cgen_insn *insn; + /* Index into operand table. */ + int opindex; + /* Target specific data, usually reloc number. */ + int opinfo; + } fr_cgen; +#endif + +#ifdef TC_FRAG_TYPE + TC_FRAG_TYPE tc_frag_data; +#endif +#ifdef OBJ_FRAG_TYPE + OBJ_FRAG_TYPE obj_frag_data; +#endif + + /* Data begins here. */ + char fr_literal[1]; +}; + +#define SIZEOF_STRUCT_FRAG \ +((char *) zero_address_frag.fr_literal - (char *) &zero_address_frag) +/* We want to say fr_literal[0] above. */ + +/* Current frag we are building. This frag is incomplete. It is, + however, included in frchain_now. The fr_fix field is bogus; + instead, use frag_now_fix (). */ +COMMON fragS *frag_now; +extern addressT frag_now_fix (void); +extern addressT frag_now_fix_octets (void); + +/* For foreign-segment symbol fixups. */ +COMMON fragS zero_address_frag; +COMMON fragS predefined_address_frag; + +extern void frag_append_1_char (int); +#define FRAG_APPEND_1_CHAR(X) frag_append_1_char (X) + +void frag_init (void); +fragS *frag_alloc (struct obstack *); +void frag_grow (unsigned int nchars); +char *frag_more (int nchars); +void frag_align (int alignment, int fill_character, int max); +void frag_align_pattern (int alignment, const char *fill_pattern, + int n_fill, int max); +void frag_align_code (int alignment, int max); +void frag_new (int old_frags_var_max_size); +void frag_wane (fragS * fragP); +int frag_room (void); + +char *frag_variant (relax_stateT type, + int max_chars, + int var, + relax_substateT subtype, + symbolS * symbol, + offsetT offset, + char *opcode); + +char *frag_var (relax_stateT type, + int max_chars, + int var, + relax_substateT subtype, + symbolS * symbol, + offsetT offset, + char *opcode); + +bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); + +#endif /* FRAGS_H */ diff --git a/contrib/toolchain/binutils/gas/hash.c b/contrib/toolchain/binutils/gas/hash.c new file mode 100644 index 0000000000..bae83867d5 --- /dev/null +++ b/contrib/toolchain/binutils/gas/hash.c @@ -0,0 +1,597 @@ +/* hash.c -- gas hash table code + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, + 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011, 2013 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* This version of the hash table code is a wholescale replacement of + the old hash table code, which was fairly bad. This is based on + the hash table code in BFD, but optimized slightly for the + assembler. The assembler does not need to derive structures that + are stored in the hash table. Instead, it always stores a pointer. + The assembler uses the hash table mostly to store symbols, and we + don't need to confuse the symbol structure with a hash table + structure. */ + +#include "as.h" +#include "safe-ctype.h" +#include "obstack.h" + +/* An entry in a hash table. */ + +struct hash_entry { + /* Next entry for this hash code. */ + struct hash_entry *next; + /* String being hashed. */ + const char *string; + /* Hash code. This is the full hash code, not the index into the + table. */ + unsigned long hash; + /* Pointer being stored in the hash table. */ + void *data; +}; + +/* A hash table. */ + +struct hash_control { + /* The hash array. */ + struct hash_entry **table; + /* The number of slots in the hash table. */ + unsigned int size; + /* An obstack for this hash table. */ + struct obstack memory; + +#ifdef HASH_STATISTICS + /* Statistics. */ + unsigned long lookups; + unsigned long hash_compares; + unsigned long string_compares; + unsigned long insertions; + unsigned long replacements; + unsigned long deletions; +#endif /* HASH_STATISTICS */ +}; + +/* The default number of entries to use when creating a hash table. + Note this value can be reduced to 4051 by using the command line + switch --reduce-memory-overheads, or set to other values by using + the --hash-size= switch. */ + +static unsigned long gas_hash_table_size = 65537; + +void +set_gas_hash_table_size (unsigned long size) +{ + gas_hash_table_size = bfd_hash_set_default_size (size); +} + +/* Create a hash table. This return a control block. */ + +struct hash_control * +hash_new_sized (unsigned long size) +{ + unsigned long alloc; + struct hash_control *ret; + + ret = (struct hash_control *) xmalloc (sizeof *ret); + obstack_begin (&ret->memory, chunksize); + alloc = size * sizeof (struct hash_entry *); + ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc); + memset (ret->table, 0, alloc); + ret->size = size; + +#ifdef HASH_STATISTICS + ret->lookups = 0; + ret->hash_compares = 0; + ret->string_compares = 0; + ret->insertions = 0; + ret->replacements = 0; + ret->deletions = 0; +#endif + + return ret; +} + +struct hash_control * +hash_new (void) +{ + return hash_new_sized (gas_hash_table_size); +} + +/* Delete a hash table, freeing all allocated memory. */ + +void +hash_die (struct hash_control *table) +{ + obstack_free (&table->memory, 0); + free (table); +} + +/* Look up a string in a hash table. This returns a pointer to the + hash_entry, or NULL if the string is not in the table. If PLIST is + not NULL, this sets *PLIST to point to the start of the list which + would hold this hash entry. If PHASH is not NULL, this sets *PHASH + to the hash code for KEY. + + Each time we look up a string, we move it to the start of the list + for its hash code, to take advantage of referential locality. */ + +static struct hash_entry * +hash_lookup (struct hash_control *table, const char *key, size_t len, + struct hash_entry ***plist, unsigned long *phash) +{ + unsigned long hash; + size_t n; + unsigned int c; + unsigned int hindex; + struct hash_entry **list; + struct hash_entry *p; + struct hash_entry *prev; + +#ifdef HASH_STATISTICS + ++table->lookups; +#endif + + hash = 0; + for (n = 0; n < len; n++) + { + c = key[n]; + hash += c + (c << 17); + hash ^= hash >> 2; + } + hash += len + (len << 17); + hash ^= hash >> 2; + + if (phash != NULL) + *phash = hash; + + hindex = hash % table->size; + list = table->table + hindex; + + if (plist != NULL) + *plist = list; + + prev = NULL; + for (p = *list; p != NULL; p = p->next) + { +#ifdef HASH_STATISTICS + ++table->hash_compares; +#endif + + if (p->hash == hash) + { +#ifdef HASH_STATISTICS + ++table->string_compares; +#endif + + if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0') + { + if (prev != NULL) + { + prev->next = p->next; + p->next = *list; + *list = p; + } + + return p; + } + } + + prev = p; + } + + return NULL; +} + +/* Insert an entry into a hash table. This returns NULL on success. + On error, it returns a printable string indicating the error. It + is considered to be an error if the entry already exists in the + hash table. */ + +const char * +hash_insert (struct hash_control *table, const char *key, void *val) +{ + struct hash_entry *p; + struct hash_entry **list; + unsigned long hash; + + p = hash_lookup (table, key, strlen (key), &list, &hash); + if (p != NULL) + return "exists"; + +#ifdef HASH_STATISTICS + ++table->insertions; +#endif + + p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p)); + p->string = key; + p->hash = hash; + p->data = val; + + p->next = *list; + *list = p; + + return NULL; +} + +/* Insert or replace an entry in a hash table. This returns NULL on + success. On error, it returns a printable string indicating the + error. If an entry already exists, its value is replaced. */ + +const char * +hash_jam (struct hash_control *table, const char *key, void *val) +{ + struct hash_entry *p; + struct hash_entry **list; + unsigned long hash; + + p = hash_lookup (table, key, strlen (key), &list, &hash); + if (p != NULL) + { +#ifdef HASH_STATISTICS + ++table->replacements; +#endif + + p->data = val; + } + else + { +#ifdef HASH_STATISTICS + ++table->insertions; +#endif + + p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p)); + p->string = key; + p->hash = hash; + p->data = val; + + p->next = *list; + *list = p; + } + + return NULL; +} + +/* Replace an existing entry in a hash table. This returns the old + value stored for the entry. If the entry is not found in the hash + table, this does nothing and returns NULL. */ + +void * +hash_replace (struct hash_control *table, const char *key, void *value) +{ + struct hash_entry *p; + void *ret; + + p = hash_lookup (table, key, strlen (key), NULL, NULL); + if (p == NULL) + return NULL; + +#ifdef HASH_STATISTICS + ++table->replacements; +#endif + + ret = p->data; + + p->data = value; + + return ret; +} + +/* Find an entry in a hash table, returning its value. Returns NULL + if the entry is not found. */ + +void * +hash_find (struct hash_control *table, const char *key) +{ + struct hash_entry *p; + + p = hash_lookup (table, key, strlen (key), NULL, NULL); + if (p == NULL) + return NULL; + + return p->data; +} + +/* As hash_find, but KEY is of length LEN and is not guaranteed to be + NUL-terminated. */ + +void * +hash_find_n (struct hash_control *table, const char *key, size_t len) +{ + struct hash_entry *p; + + p = hash_lookup (table, key, len, NULL, NULL); + if (p == NULL) + return NULL; + + return p->data; +} + +/* Delete an entry from a hash table. This returns the value stored + for that entry, or NULL if there is no such entry. */ + +void * +hash_delete (struct hash_control *table, const char *key, int freeme) +{ + struct hash_entry *p; + struct hash_entry **list; + + p = hash_lookup (table, key, strlen (key), &list, NULL); + if (p == NULL) + return NULL; + + if (p != *list) + abort (); + +#ifdef HASH_STATISTICS + ++table->deletions; +#endif + + *list = p->next; + + if (freeme) + obstack_free (&table->memory, p); + + return p->data; +} + +/* Traverse a hash table. Call the function on every entry in the + hash table. */ + +void +hash_traverse (struct hash_control *table, + void (*pfn) (const char *key, void *value)) +{ + unsigned int i; + + for (i = 0; i < table->size; ++i) + { + struct hash_entry *p; + + for (p = table->table[i]; p != NULL; p = p->next) + (*pfn) (p->string, p->data); + } +} + +/* Print hash table statistics on the specified file. NAME is the + name of the hash table, used for printing a header. */ + +void +hash_print_statistics (FILE *f ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + struct hash_control *table ATTRIBUTE_UNUSED) +{ +#ifdef HASH_STATISTICS + unsigned int i; + unsigned long total; + unsigned long empty; + + fprintf (f, "%s hash statistics:\n", name); + fprintf (f, "\t%lu lookups\n", table->lookups); + fprintf (f, "\t%lu hash comparisons\n", table->hash_compares); + fprintf (f, "\t%lu string comparisons\n", table->string_compares); + fprintf (f, "\t%lu insertions\n", table->insertions); + fprintf (f, "\t%lu replacements\n", table->replacements); + fprintf (f, "\t%lu deletions\n", table->deletions); + + total = 0; + empty = 0; + for (i = 0; i < table->size; ++i) + { + struct hash_entry *p; + + if (table->table[i] == NULL) + ++empty; + else + { + for (p = table->table[i]; p != NULL; p = p->next) + ++total; + } + } + + fprintf (f, "\t%g average chain length\n", (double) total / table->size); + fprintf (f, "\t%lu empty slots\n", empty); +#endif +} + +#ifdef TEST + +/* This test program is left over from the old hash table code. */ + +/* Number of hash tables to maintain (at once) in any testing. */ +#define TABLES (6) + +/* We can have 12 statistics. */ +#define STATBUFSIZE (12) + +/* Display statistics here. */ +int statbuf[STATBUFSIZE]; + +/* Human farts here. */ +char answer[100]; + +/* We test many hash tables at once. */ +char *hashtable[TABLES]; + +/* Points to current hash_control. */ +char *h; +char **pp; +char *p; +char *name; +char *value; +int size; +int used; +char command; + +/* Number 0:TABLES-1 of current hashed symbol table. */ +int number; + +int +main () +{ + void applicatee (); + void destroy (); + char *what (); + int *ip; + + number = 0; + h = 0; + printf ("type h for help\n"); + for (;;) + { + printf ("hash_test command: "); + gets (answer); + command = answer[0]; + command = TOLOWER (command); /* Ecch! */ + switch (command) + { + case '#': + printf ("old hash table #=%d.\n", number); + whattable (); + break; + case '?': + for (pp = hashtable; pp < hashtable + TABLES; pp++) + { + printf ("address of hash table #%d control block is %xx\n", + pp - hashtable, *pp); + } + break; + case 'a': + hash_traverse (h, applicatee); + break; + case 'd': + hash_traverse (h, destroy); + hash_die (h); + break; + case 'f': + p = hash_find (h, name = what ("symbol")); + printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT"); + break; + case 'h': + printf ("# show old, select new default hash table number\n"); + printf ("? display all hashtable control block addresses\n"); + printf ("a apply a simple display-er to each symbol in table\n"); + printf ("d die: destroy hashtable\n"); + printf ("f find value of nominated symbol\n"); + printf ("h this help\n"); + printf ("i insert value into symbol\n"); + printf ("j jam value into symbol\n"); + printf ("n new hashtable\n"); + printf ("r replace a value with another\n"); + printf ("s say what %% of table is used\n"); + printf ("q exit this program\n"); + printf ("x delete a symbol from table, report its value\n"); + break; + case 'i': + p = hash_insert (h, name = what ("symbol"), value = what ("value")); + if (p) + { + printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, + p); + } + break; + case 'j': + p = hash_jam (h, name = what ("symbol"), value = what ("value")); + if (p) + { + printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p); + } + break; + case 'n': + h = hashtable[number] = (char *) hash_new (); + break; + case 'q': + exit (EXIT_SUCCESS); + case 'r': + p = hash_replace (h, name = what ("symbol"), value = what ("value")); + printf ("old value was \"%s\"\n", p ? p : "{}"); + break; + case 's': + hash_say (h, statbuf, STATBUFSIZE); + for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++) + { + printf ("%d ", *ip); + } + printf ("\n"); + break; + case 'x': + p = hash_delete (h, name = what ("symbol")); + printf ("old value was \"%s\"\n", p ? p : "{}"); + break; + default: + printf ("I can't understand command \"%c\"\n", command); + break; + } + } +} + +char * +what (description) + char *description; +{ + printf (" %s : ", description); + gets (answer); + return xstrdup (answer); +} + +void +destroy (string, value) + char *string; + char *value; +{ + free (string); + free (value); +} + +void +applicatee (string, value) + char *string; + char *value; +{ + printf ("%.20s-%.20s\n", string, value); +} + +/* Determine number: what hash table to use. + Also determine h: points to hash_control. */ + +void +whattable () +{ + for (;;) + { + printf (" what hash table (%d:%d) ? ", 0, TABLES - 1); + gets (answer); + sscanf (answer, "%d", &number); + if (number >= 0 && number < TABLES) + { + h = hashtable[number]; + if (!h) + { + printf ("warning: current hash-table-#%d. has no hash-control\n", number); + } + return; + } + else + { + printf ("invalid hash table number: %d\n", number); + } + } +} + +#endif /* TEST */ diff --git a/contrib/toolchain/binutils/gas/hash.h b/contrib/toolchain/binutils/gas/hash.h new file mode 100644 index 0000000000..c7ea7b57c7 --- /dev/null +++ b/contrib/toolchain/binutils/gas/hash.h @@ -0,0 +1,89 @@ +/* hash.h -- header file for gas hash table routines + Copyright 1987, 1992, 1993, 1995, 1999, 2003, 2005, 2007, 2008, 2013 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef HASH_H +#define HASH_H + +struct hash_control; + +/* Set the size of the hash table used. */ + +void set_gas_hash_table_size (unsigned long); + +/* Create a hash table. This return a control block. */ + +extern struct hash_control *hash_new (void); +extern struct hash_control *hash_new_sized (unsigned long); + +/* Delete a hash table, freeing all allocated memory. */ + +extern void hash_die (struct hash_control *); + +/* Insert an entry into a hash table. This returns NULL on success. + On error, it returns a printable string indicating the error. It + is considered to be an error if the entry already exists in the + hash table. */ + +extern const char *hash_insert (struct hash_control *, + const char *key, void *value); + +/* Insert or replace an entry in a hash table. This returns NULL on + success. On error, it returns a printable string indicating the + error. If an entry already exists, its value is replaced. */ + +extern const char *hash_jam (struct hash_control *, + const char *key, void *value); + +/* Replace an existing entry in a hash table. This returns the old + value stored for the entry. If the entry is not found in the hash + table, this does nothing and returns NULL. */ + +extern void *hash_replace (struct hash_control *, const char *key, + void *value); + +/* Find an entry in a hash table, returning its value. Returns NULL + if the entry is not found. */ + +extern void *hash_find (struct hash_control *, const char *key); + +/* As hash_find, but KEY is of length LEN and is not guaranteed to be + NUL-terminated. */ + +extern void *hash_find_n (struct hash_control *, const char *key, size_t len); + +/* Delete an entry from a hash table. This returns the value stored + for that entry, or NULL if there is no such entry. */ + +extern void *hash_delete (struct hash_control *, const char *key, int); + +/* Traverse a hash table. Call the function on every entry in the + hash table. */ + +extern void hash_traverse (struct hash_control *, + void (*pfn) (const char *key, void *value)); + +/* Print hash table statistics on the specified file. NAME is the + name of the hash table, used for printing a header. */ + +extern void hash_print_statistics (FILE *, const char *name, + struct hash_control *); + +#endif /* HASH_H */ diff --git a/contrib/toolchain/binutils/gas/input-file.c b/contrib/toolchain/binutils/gas/input-file.c new file mode 100644 index 0000000000..ecf1b44be9 --- /dev/null +++ b/contrib/toolchain/binutils/gas/input-file.c @@ -0,0 +1,259 @@ +/* input_file.c - Deal with Input Files - + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, + 2002, 2003, 2005, 2006, 2007, 2009, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Confines all details of reading source bytes to this module. + All O/S specific crocks should live here. + What we lose in "efficiency" we gain in modularity. + Note we don't need to #include the "as.h" file. No common coupling! */ + +#include "as.h" +#include "input-file.h" +#include "safe-ctype.h" + +/* This variable is non-zero if the file currently being read should be + preprocessed by app. It is zero if the file can be read straight in. */ +int preprocess = 0; + +/* This code opens a file, then delivers BUFFER_SIZE character + chunks of the file on demand. + BUFFER_SIZE is supposed to be a number chosen for speed. + The caller only asks once what BUFFER_SIZE is, and asks before + the nature of the input files (if any) is known. */ + +#define BUFFER_SIZE (32 * 1024) + +/* We use static data: the data area is not sharable. */ + +static FILE *f_in; +static char *file_name; + +/* Struct for saving the state of this module for file includes. */ +struct saved_file + { + FILE * f_in; + char * file_name; + int preprocess; + char * app_save; + }; + +/* These hooks accommodate most operating systems. */ + +void +input_file_begin (void) +{ + f_in = (FILE *) 0; +} + +void +input_file_end (void) +{ +} + +/* Return BUFFER_SIZE. */ +size_t +input_file_buffer_size (void) +{ + return (BUFFER_SIZE); +} + +/* Push the state of our input, returning a pointer to saved info that + can be restored with input_file_pop (). */ + +char * +input_file_push (void) +{ + register struct saved_file *saved; + + saved = (struct saved_file *) xmalloc (sizeof *saved); + + saved->f_in = f_in; + saved->file_name = file_name; + saved->preprocess = preprocess; + if (preprocess) + saved->app_save = app_push (); + + /* Initialize for new file. */ + input_file_begin (); + + return (char *) saved; +} + +void +input_file_pop (char *arg) +{ + register struct saved_file *saved = (struct saved_file *) arg; + + input_file_end (); /* Close out old file. */ + + f_in = saved->f_in; + file_name = saved->file_name; + preprocess = saved->preprocess; + if (preprocess) + app_pop (saved->app_save); + + free (arg); +} + +void +input_file_open (char *filename, /* "" means use stdin. Must not be 0. */ + int pre) +{ + int c; + char buf[80]; + + preprocess = pre; + + gas_assert (filename != 0); /* Filename may not be NULL. */ + if (filename[0]) + { + f_in = fopen (filename, FOPEN_RT); + file_name = filename; + } + else + { + /* Use stdin for the input file. */ + f_in = stdin; + /* For error messages. */ + file_name = _("{standard input}"); + } + + if (f_in == NULL) + { + as_bad (_("can't open %s for reading: %s"), + file_name, xstrerror (errno)); + return; + } + + c = getc (f_in); + + if (ferror (f_in)) + { + as_bad (_("can't read from %s: %s"), + file_name, xstrerror (errno)); + + fclose (f_in); + f_in = NULL; + return; + } + + /* Check for an empty input file. */ + if (feof (f_in)) + { + fclose (f_in); + f_in = NULL; + return; + } + gas_assert (c != EOF); + + if (c == '#') + { + /* Begins with comment, may not want to preprocess. */ + c = getc (f_in); + if (c == 'N') + { + if (fgets (buf, sizeof (buf), f_in) + && !strncmp (buf, "O_APP", 5) && ISSPACE (buf[5])) + preprocess = 0; + if (!strchr (buf, '\n')) + ungetc ('#', f_in); /* It was longer. */ + else + ungetc ('\n', f_in); + } + else if (c == 'A') + { + if (fgets (buf, sizeof (buf), f_in) + && !strncmp (buf, "PP", 2) && ISSPACE (buf[2])) + preprocess = 1; + if (!strchr (buf, '\n')) + ungetc ('#', f_in); + else + ungetc ('\n', f_in); + } + else if (c == '\n') + ungetc ('\n', f_in); + else + ungetc ('#', f_in); + } + else + ungetc (c, f_in); +} + +/* Close input file. */ + +void +input_file_close (void) +{ + /* Don't close a null file pointer. */ + if (f_in != NULL) + fclose (f_in); + + f_in = 0; +} + +/* This function is passed to do_scrub_chars. */ + +static size_t +input_file_get (char *buf, size_t buflen) +{ + size_t size; + + if (feof (f_in)) + return 0; + + size = fread (buf, sizeof (char), buflen, f_in); + if (ferror (f_in)) + as_bad (_("can't read from %s: %s"), file_name, xstrerror (errno)); + return size; +} + +/* Read a buffer from the input file. */ + +char * +input_file_give_next_buffer (char *where /* Where to place 1st character of new buffer. */) +{ + char *return_value; /* -> Last char of what we read, + 1. */ + size_t size; + + if (f_in == (FILE *) 0) + return 0; + /* fflush (stdin); could be done here if you want to synchronise + stdin and stdout, for the case where our input file is stdin. + Since the assembler shouldn't do any output to stdout, we + don't bother to synch output and input. */ + if (preprocess) + size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); + else + size = input_file_get (where, BUFFER_SIZE); + + if (size) + return_value = where + size; + else + { + if (fclose (f_in)) + as_warn (_("can't close %s: %s"), file_name, xstrerror (errno)); + + f_in = (FILE *) 0; + return_value = 0; + } + + return return_value; +} diff --git a/contrib/toolchain/binutils/gas/input-file.h b/contrib/toolchain/binutils/gas/input-file.h new file mode 100644 index 0000000000..7148cc548b --- /dev/null +++ b/contrib/toolchain/binutils/gas/input-file.h @@ -0,0 +1,66 @@ +/* input_file.h header for input-file.c + Copyright 1987, 1992, 1993, 2000, 2003, 2005, 2006, 2007, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/*"input_file.c":Operating-system dependant functions to read source files.*/ + +/* + * No matter what the operating system, this module must provide the + * following services to its callers. + * + * input_file_begin() Call once before anything else. + * + * input_file_end() Call once after everything else. + * + * input_file_buffer_size() Call anytime. Returns largest possible + * delivery from + * input_file_give_next_buffer(). + * + * input_file_open(name) Call once for each input file. + * + * input_file_give_next_buffer(where) Call once to get each new buffer. + * Return 0: no more chars left in file, + * the file has already been closed. + * Otherwise: return a pointer to just + * after the last character we read + * into the buffer. + * If we can only read 0 characters, then + * end-of-file is faked. + * + * input_file_push() Push state, which can be restored + * later. Does implicit input_file_begin. + * Returns char * to saved state. + * + * input_file_pop (arg) Pops previously saved state. + * + * input_file_close () Closes opened file. + * + * All errors are reported so caller doesn't have to think + * about I/O errors. + */ + +char *input_file_give_next_buffer (char *where); +char *input_file_push (void); +size_t input_file_buffer_size (void); +void input_file_begin (void); +void input_file_close (void); +void input_file_end (void); +void input_file_open (char *filename, int pre); +void input_file_pop (char *arg); diff --git a/contrib/toolchain/binutils/gas/input-scrub.c b/contrib/toolchain/binutils/gas/input-scrub.c new file mode 100644 index 0000000000..adae4d4dcd --- /dev/null +++ b/contrib/toolchain/binutils/gas/input-scrub.c @@ -0,0 +1,523 @@ +/* input_scrub.c - Break up input buffers into whole numbers of lines. + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "filenames.h" +#include "input-file.h" +#include "sb.h" +#include "listing.h" + +/* + * O/S independent module to supply buffers of sanitised source code + * to rest of assembler. We get sanitised input data of arbitrary length. + * We break these buffers on line boundaries, recombine pieces that + * were broken across buffers, and return a buffer of full lines to + * the caller. + * The last partial line begins the next buffer we build and return to caller. + * The buffer returned to caller is preceded by BEFORE_STRING and followed + * by AFTER_STRING, as sentinels. The last character before AFTER_STRING + * is a newline. + * Also looks after line numbers, for e.g. error messages. + */ + +/* + * We don't care how filthy our buffers are, but our callers assume + * that the following sanitation has already been done. + * + * No comments, reduce a comment to a space. + * Reduce a tab to a space unless it is 1st char of line. + * All multiple tabs and spaces collapsed into 1 char. Tab only + * legal if 1st char of line. + * # line file statements converted to .line x;.file y; statements. + * Escaped newlines at end of line: remove them but add as many newlines + * to end of statement as you removed in the middle, to synch line numbers. + */ + +#define BEFORE_STRING ("\n") +#define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */ +#define BEFORE_SIZE (1) +#define AFTER_SIZE (1) + +#ifndef TC_EOL_IN_INSN +#define TC_EOL_IN_INSN(P) 0 +#endif + +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. */ + +/* 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 char save_source[AFTER_SIZE]; + +/* What is the largest size buffer that input_file_give_next_buffer() + could return to us? */ +static unsigned int buffer_length; + +/* The index into an sb structure we are reading from. -1 if none. */ +static size_t sb_index = -1; + +/* If we are reading from an sb structure, this is it. */ +static sb from_sb; + +/* Should we do a conditional check on from_sb? */ +static int from_sb_is_expansion = 1; + +/* The number of nested sb structures we have included. */ +int macro_nest; + +/* We can have more than one source file open at once, though the info for all + but the latest one are saved off in a struct input_save. These files remain + open, so we are limited by the number of open files allowed by the + underlying OS. We may also sequentially read more than one source file in an + assembly. */ + +/* We must track the physical file and line number for error messages. We also + track a "logical" file and line number corresponding to (C?) compiler + 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. */ + +static char *physical_input_file; +static char *logical_input_file; + +/* 1-origin line number in a source file. */ +/* A line ends in '\n' or eof. */ +static unsigned int 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]; + size_t buffer_length; + char * physical_input_file; + char * logical_input_file; + unsigned int physical_input_line; + int logical_input_line; + size_t sb_index; + sb from_sb; + int from_sb_is_expansion; /* Should we do a conditional check? */ + struct input_save * 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. */ +}; + +static struct input_save *input_scrub_push (char *saved_position); +static char *input_scrub_pop (struct input_save *arg); + +/* Saved information about the file that .include'd this one. When we hit EOF, + we automatically pop to that file. */ + +static struct input_save *next_saved_file; + +/* 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(). */ + +static struct input_save * +input_scrub_push (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; + saved->sb_index = sb_index; + saved->from_sb = from_sb; + saved->from_sb_is_expansion = from_sb_is_expansion; + 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 (); + sb_index = -1; + + buffer_start = (char *) xmalloc ((BEFORE_SIZE + buffer_length + + buffer_length + AFTER_SIZE)); + memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); + + return saved; +} + +static char * +input_scrub_pop (struct input_save *saved) +{ + char *saved_position; + + input_scrub_end (); /* Finish off old buffer */ + + 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; + sb_index = saved->sb_index; + from_sb = saved->from_sb; + from_sb_is_expansion = saved->from_sb_is_expansion; + 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 (saved); + return saved_position; +} + +void +input_scrub_begin (void) +{ + 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 = (char *) 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 (flag_m68k_mri); +} + +void +input_scrub_end (void) +{ + if (buffer_start) + { + free (buffer_start); + buffer_start = 0; + input_file_end (); + } +} + +/* Start reading input from a new file. + Return start of caller's part of buffer. */ + +char * +input_scrub_new_file (char *filename) +{ + input_file_open (filename, !flag_no_comments); + physical_input_file = filename[0] ? filename : _("{standard input}"); + physical_input_line = 0; + + partial_size = 0; + return (buffer_start + BEFORE_SIZE); +} + +/* Include a file from the current file. Save our state, cause it to + be restored on EOF, and begin handling a new file. Same result as + input_scrub_new_file. */ + +char * +input_scrub_include_file (char *filename, char *position) +{ + next_saved_file = input_scrub_push (position); + return input_scrub_new_file (filename); +} + +/* Start getting input from an sb structure. This is used when + expanding a macro. */ + +void +input_scrub_include_sb (sb *from, char *position, int is_expansion) +{ + int newline; + + if (macro_nest > max_macro_nest) + as_fatal (_("macros nested too deeply")); + ++macro_nest; + +#ifdef md_macro_start + if (is_expansion) + { + md_macro_start (); + } +#endif + + next_saved_file = input_scrub_push (position); + + /* Allocate sufficient space: from->len + optional newline. */ + newline = from->len >= 1 && from->ptr[0] != '\n'; + sb_build (&from_sb, from->len + newline); + from_sb_is_expansion = is_expansion; + if (newline) + { + /* Add the sentinel required by read.c. */ + sb_add_char (&from_sb, '\n'); + } + sb_scrub_and_add_sb (&from_sb, from); + + /* Make sure the parser looks at defined contents when it scans for + e.g. end-of-line at the end of a macro. */ + sb_terminate (&from_sb); + + sb_index = 1; + + /* These variables are reset by input_scrub_push. Restore them + since we are, after all, still at the same point in the file. */ + logical_input_line = next_saved_file->logical_input_line; + logical_input_file = next_saved_file->logical_input_file; +} + +void +input_scrub_close (void) +{ + input_file_close (); + physical_input_line = 0; + logical_input_line = -1; +} + +char * +input_scrub_next_buffer (char **bufp) +{ + register char *limit; /*->just after last char of buffer. */ + + if (sb_index != (size_t) -1) + { + if (sb_index >= from_sb.len) + { + sb_kill (&from_sb); + if (from_sb_is_expansion) + { + cond_finish_check (macro_nest); +#ifdef md_macro_end + /* Allow the target to clean up per-macro expansion + data. */ + md_macro_end (); +#endif + } + --macro_nest; + partial_where = NULL; + if (next_saved_file != NULL) + *bufp = input_scrub_pop (next_saved_file); + return partial_where; + } + + partial_where = from_sb.ptr + from_sb.len; + partial_size = 0; + *bufp = from_sb.ptr + sb_index; + sb_index = from_sb.len; + return partial_where; + } + + *bufp = buffer_start + BEFORE_SIZE; + + if (partial_size) + { + memmove (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. */ + /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ + *limit = '\0'; + for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) + ; + ++p; + + while (p <= buffer_start + BEFORE_SIZE) + { + int limoff; + + limoff = limit - buffer_start; + buffer_length += input_file_buffer_size (); + buffer_start = (char *) xrealloc (buffer_start, + (BEFORE_SIZE + + 2 * buffer_length + + AFTER_SIZE)); + *bufp = buffer_start + BEFORE_SIZE; + limit = input_file_give_next_buffer (buffer_start + limoff); + + if (limit == NULL) + { + as_warn (_("partial line at end of file ignored")); + partial_where = NULL; + if (next_saved_file) + *bufp = input_scrub_pop (next_saved_file); + return NULL; + } + + /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ + *limit = '\0'; + for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) + ; + ++p; + } + + 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")); + } + + /* Tell the listing we've finished the file. */ + LISTING_EOF (); + + /* 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); +} + +/* The remaining part of this file deals with line numbers, error + messages and so on. Return TRUE if we opened any file. */ + +int +seen_at_least_1_file (void) +{ + return (physical_input_file != NULL); +} + +void +bump_line_counters (void) +{ + if (sb_index == (size_t) -1) + { + ++physical_input_line; + if (logical_input_line >= 0) + ++logical_input_line; + } +} + +/* Tells us what the new logical line number and file are. + 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_chars). + If the fname is NULL, we don't change the current logical file name. + Returns nonzero if the filename actually changes. */ + +int +new_logical_line_flags (char *fname, /* DON'T destroy it! We point to it! */ + int line_number, + int flags) +{ + switch (flags) + { + case 0: + break; + case 1: + if (line_number != -1) + abort (); + break; + case 1 << 1: + case 1 << 2: + /* FIXME: we could check that include nesting is correct. */ + break; + default: + abort (); + } + + if (line_number >= 0) + logical_input_line = line_number; + else if (line_number == -1 && fname && !*fname && (flags & (1 << 2))) + { + logical_input_file = physical_input_file; + logical_input_line = physical_input_line; + fname = NULL; + } + + if (fname + && (logical_input_file == NULL + || filename_cmp (logical_input_file, fname))) + { + logical_input_file = fname; + return 1; + } + else + return 0; +} + +int +new_logical_line (char *fname, int line_number) +{ + return new_logical_line_flags (fname, line_number, 0); +} + + +/* 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 **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 = 0; + if (linep != NULL) + *linep = 0; + } +} diff --git a/contrib/toolchain/binutils/gas/itbl-cpu.h b/contrib/toolchain/binutils/gas/itbl-cpu.h new file mode 100644 index 0000000000..54880214c7 --- /dev/null +++ b/contrib/toolchain/binutils/gas/itbl-cpu.h @@ -0,0 +1 @@ +#include "itbl-i386.h" diff --git a/contrib/toolchain/binutils/gas/listing.c b/contrib/toolchain/binutils/gas/listing.c new file mode 100644 index 0000000000..182d504691 --- /dev/null +++ b/contrib/toolchain/binutils/gas/listing.c @@ -0,0 +1,1660 @@ +/* listing.c - maintain assembly listings + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Contributed by Steve Chamberlain + + 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 remembers 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 continuation + LISTING_RHS_WIDTH Number of chars from the input file to print + on a line. */ + +#include "as.h" +#include "filenames.h" +#include "obstack.h" +#include "safe-ctype.h" +#include "input-file.h" +#include "subsegs.h" +#include "bfdver.h" +#include +#include + +#ifndef NO_LISTING + +#ifndef LISTING_HEADER +#define LISTING_HEADER "GAS LISTING" +#endif +#ifndef LISTING_WORD_SIZE +#define LISTING_WORD_SIZE 4 +#endif +#ifndef LISTING_LHS_WIDTH +#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE)) +#endif +#ifndef LISTING_LHS_WIDTH_SECOND +#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH +#endif +#ifndef LISTING_RHS_WIDTH +#define LISTING_RHS_WIDTH 100 +#endif +#ifndef LISTING_LHS_CONT_LINES +#define LISTING_LHS_CONT_LINES 4 +#endif +#define MAX_DATELEN 30 + +/* This structure remembers which .s were used. */ +typedef struct file_info_struct +{ + struct file_info_struct * next; + char * filename; + long pos; + unsigned int linenum; + int at_end; +} file_info_type; + +enum edict_enum +{ + EDICT_NONE, + EDICT_SBTTL, + EDICT_TITLE, + EDICT_NOLIST, + EDICT_LIST, + EDICT_NOLIST_NEXT, + EDICT_EJECT +}; + + +struct list_message +{ + char *message; + struct list_message *next; +}; + +/* This structure remembers which line from which file goes into which + frag. */ +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; + + /* The expanded text of any macro that may have been executing. */ + char *line_contents; + + /* 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. */ + unsigned int hll_line; + + /* Pointers to linked list of messages associated with this line. */ + struct list_message *messages, *last_message; + + enum edict_enum edict; + char *edict_arg; + + /* Nonzero if this line is to be omitted because it contains + debugging information. This can become a flags field if we come + up with more information to store here. */ + int debugging; +}; + +typedef struct list_info_struct list_info_type; + +int listing_lhs_width = LISTING_LHS_WIDTH; +int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; +int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; +int listing_rhs_width = LISTING_RHS_WIDTH; + +struct list_info_struct * listing_tail; + +static file_info_type * file_info_head; +static file_info_type * last_open_file_info; +static FILE * last_open_file; +static struct list_info_struct * head; +static int paper_width = 200; +static int paper_height = 60; + +extern int listing; + +/* File to output listings to. */ +static FILE *list_file; + +/* This static array is used to keep the text of data to be printed + before the start of the line. */ + +#define MAX_BYTES \ + (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ + + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ + * listing_lhs_cont_lines) \ + + 20) + +static char *data_buffer; + +/* Prototypes. */ +static void listing_message (const char *, const char *); +static file_info_type *file_info (const char *); +static void new_frag (void); +static void listing_page (list_info_type *); +static unsigned int calc_hex (list_info_type *); +static void print_lines (list_info_type *, unsigned int, char *, unsigned int); +static void list_symbol_table (void); +static int debugging_pseudo (list_info_type *, const char *); +static void listing_listing (char *); + +static void +listing_message (const char *name, const char *message) +{ + if (listing_tail != (list_info_type *) NULL) + { + unsigned int l = strlen (name) + strlen (message) + 1; + char *n = (char *) xmalloc (l); + struct list_message *lm = xmalloc (sizeof *lm); + strcpy (n, name); + strcat (n, message); + lm->message = n; + lm->next = NULL; + + if (listing_tail->last_message) + listing_tail->last_message->next = lm; + else + listing_tail->messages = lm; + listing_tail->last_message = lm; + } +} + +void +listing_warning (const char *message) +{ + listing_message (_("Warning:"), message); +} + +void +listing_error (const char *message) +{ + listing_message (_("Error:"), message); +} + +static file_info_type * +file_info (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 (filename_cmp (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 = xstrdup (file_name); + p->pos = 0; + p->linenum = 0; + p->at_end = 0; + + return p; +} + +static void +new_frag (void) +{ + frag_wane (frag_now); + frag_new (0); +} + +void +listing_newline (char *ps) +{ + char *file; + unsigned int line; + static unsigned int last_line = 0xffff; + static char *last_file = NULL; + list_info_type *new_i = NULL; + + if (listing == 0) + return; + + if (now_seg == absolute_section) + return; + +#ifdef OBJ_ELF + /* In ELF, anything in a section beginning with .debug or .line is + considered to be debugging information. This includes the + statement which switches us into the debugging section, which we + can only set after we are already in the debugging section. */ + if ((listing & LISTING_NODEBUG) != 0 + && listing_tail != NULL + && ! listing_tail->debugging) + { + const char *segname; + + segname = segment_name (now_seg); + if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 + || strncmp (segname, ".line", sizeof ".line" - 1) == 0) + listing_tail->debugging = 1; + } +#endif + + as_where (&file, &line); + if (ps == NULL) + { + if (line == last_line + && !(last_file && file && filename_cmp (file, last_file))) + return; + + new_i = (list_info_type *) xmalloc (sizeof (list_info_type)); + + /* Detect if we are reading from stdin by examining the file + name returned by as_where(). + + [FIXME: We rely upon the name in the strcmp below being the + same as the one used by input_scrub_new_file(), if that is + not true, then this code will fail]. + + If we are reading from stdin, then we need to save each input + line here (assuming of course that we actually have a line of + input to read), so that it can be displayed in the listing + that is produced at the end of the assembly. */ + if (strcmp (file, _("{standard input}")) == 0 + && input_line_pointer != NULL) + { + char *copy; + int len; + int seen_quote = 0; + int seen_slash = 0; + + for (copy = input_line_pointer; + *copy && (seen_quote + || is_end_of_line [(unsigned char) *copy] != 1); + copy++) + { + if (seen_slash) + seen_slash = 0; + else if (*copy == '\\') + seen_slash = 1; + else if (*copy == '"') + seen_quote = !seen_quote; + } + + len = copy - input_line_pointer + 1; + + copy = (char *) xmalloc (len); + + if (copy != NULL) + { + char *src = input_line_pointer; + char *dest = copy; + + while (--len) + { + unsigned char c = *src++; + + /* Omit control characters in the listing. */ + if (!ISCNTRL (c)) + *dest++ = c; + } + + *dest = 0; + } + + new_i->line_contents = copy; + } + else + new_i->line_contents = NULL; + } + else + { + new_i = (list_info_type *) xmalloc (sizeof (list_info_type)); + new_i->line_contents = ps; + } + + last_line = line; + last_file = file; + + new_frag (); + + if (listing_tail) + listing_tail->next = new_i; + else + head = new_i; + + listing_tail = new_i; + + new_i->frag = frag_now; + new_i->line = line; + new_i->file = file_info (file); + new_i->next = (list_info_type *) NULL; + new_i->messages = NULL; + new_i->last_message = NULL; + new_i->edict = EDICT_NONE; + new_i->hll_file = (file_info_type *) NULL; + new_i->hll_line = 0; + new_i->debugging = 0; + + new_frag (); + +#ifdef OBJ_ELF + /* In ELF, anything in a section beginning with .debug or .line is + considered to be debugging information. */ + if ((listing & LISTING_NODEBUG) != 0) + { + const char *segname; + + segname = segment_name (now_seg); + if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 + || strncmp (segname, ".line", sizeof ".line" - 1) == 0) + new_i->debugging = 1; + } +#endif +} + +/* 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 (void) +{ + list_info_type *l; + fragS *f; + + 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 using the returned buffer simpler. */ + +static char * +buffer_line (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->at_end) + return ""; + + /* Check the cache and see if we last used this file. */ + if (!last_open_file_info || file != last_open_file_info) + { + if (last_open_file) + { + last_open_file_info->pos = ftell (last_open_file); + fclose (last_open_file); + } + + /* Open the file in the binary mode so that ftell above can + return a reliable value that we can feed to fseek below. */ + last_open_file_info = file; + last_open_file = fopen (file->filename, FOPEN_RB); + if (last_open_file == NULL) + { + file->at_end = 1; + return ""; + } + + /* Seek to where we were last time this file was open. */ + if (file->pos) + fseek (last_open_file, file->pos, SEEK_SET); + } + + /* Leave room for null. */ + size -= 1; + + c = fgetc (last_open_file); + + while (c != EOF && c != '\n' && c != '\r') + { + if (count < size) + *p++ = c; + count++; + + c = fgetc (last_open_file); + } + + /* If '\r' is followed by '\n', swallow that. Likewise, if '\n' + is followed by '\r', swallow that as well. */ + if (c == '\r' || c == '\n') + { + int next = fgetc (last_open_file); + + if ((c == '\r' && next != '\n') + || (c == '\n' && next != '\r')) + ungetc (next, last_open_file); + } + + if (c == EOF) + { + file->at_end = 1; + if (count + 2 < size) + { + *p++ = '.'; + *p++ = '.'; + *p++ = '.'; + } + } + file->linenum++; + *p++ = 0; + return line; +} + + +/* This function rewinds the requested file back to the line requested, + reads it in again into the buffer provided and then restores the file + back to its original location. Returns the buffer pointer upon success + or an empty string if an error occurs. */ + +static char * +rebuffer_line (file_info_type * file, + unsigned int linenum, + char * buffer, + unsigned int size) +{ + unsigned int count = 0; + unsigned int current_line; + char * p = buffer; + long pos; + long pos2; + int c; + bfd_boolean found = FALSE; + + /* Sanity checks. */ + if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum) + return ""; + + /* Check the cache and see if we last used this file. */ + if (last_open_file_info == NULL || file != last_open_file_info) + { + if (last_open_file) + { + last_open_file_info->pos = ftell (last_open_file); + fclose (last_open_file); + } + + /* Open the file in the binary mode so that ftell above can + return a reliable value that we can feed to fseek below. */ + last_open_file_info = file; + last_open_file = fopen (file->filename, FOPEN_RB); + if (last_open_file == NULL) + { + file->at_end = 1; + return ""; + } + + /* Seek to where we were last time this file was open. */ + if (file->pos) + fseek (last_open_file, file->pos, SEEK_SET); + } + + /* Remember where we are in the current file. */ + pos2 = pos = ftell (last_open_file); + if (pos < 3) + return ""; + current_line = file->linenum; + + /* Leave room for the nul at the end of the buffer. */ + size -= 1; + buffer[size] = 0; + + /* Increment the current line count by one. + This is to allow for the fact that we are searching for the + start of a previous line, but we do this by detecting end-of-line + character(s) not start-of-line characters. */ + ++ current_line; + + while (pos2 > 0 && ! found) + { + char * ptr; + + /* Move backwards through the file, looking for earlier lines. */ + pos2 = (long) size > pos2 ? 0 : pos2 - size; + fseek (last_open_file, pos2, SEEK_SET); + + /* Our caller has kindly provided us with a buffer, so we use it. */ + if (fread (buffer, 1, size, last_open_file) != size) + { + as_warn (_("unable to rebuffer file: %s\n"), file->filename); + return ""; + } + + for (ptr = buffer + size; ptr >= buffer; -- ptr) + { + if (*ptr == '\n') + { + -- current_line; + + if (current_line == linenum) + { + /* We have found the start of the line we seek. */ + found = TRUE; + + /* FIXME: We could skip the read-in-the-line code + below if we know that we already have the whole + line in the buffer. */ + + /* Advance pos2 to the newline character we have just located. */ + pos2 += (ptr - buffer); + + /* Skip the newline and, if present, the carriage return. */ + if (ptr + 1 == buffer + size) + { + ++pos2; + if (fgetc (last_open_file) == '\r') + ++ pos2; + } + else + pos2 += (ptr[1] == '\r' ? 2 : 1); + + /* Move the file pointer to this location. */ + fseek (last_open_file, pos2, SEEK_SET); + break; + } + } + } + } + + /* Read in the line. */ + c = fgetc (last_open_file); + + while (c != EOF && c != '\n' && c != '\r') + { + if (count < size) + *p++ = c; + count++; + + c = fgetc (last_open_file); + } + + /* If '\r' is followed by '\n', swallow that. Likewise, if '\n' + is followed by '\r', swallow that as well. */ + if (c == '\r' || c == '\n') + { + int next = fgetc (last_open_file); + + if ((c == '\r' && next != '\n') + || (c == '\n' && next != '\r')) + ungetc (next, last_open_file); + } + + /* Terminate the line. */ + *p++ = 0; + + /* Reset the file position. */ + fseek (last_open_file, pos, SEEK_SET); + + return buffer; +} + +static const char *fn; + +static unsigned int eject; /* Eject pending */ +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_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 >= (unsigned int) 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) + { + fprintf (list_file, "\f"); + } + + fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); + fprintf (list_file, "%s\n", title); + fprintf (list_file, "%s\n", subtitle); + on_page = 3; + eject = 0; + } +} + +/* Print a line into the list_file. Update the line count + and if necessary start a new page. */ + +static void +emit_line (list_info_type * list, const char * format, ...) +{ + va_list args; + + va_start (args, format); + + vfprintf (list_file, format, args); + on_page++; + listing_page (list); + + va_end (args); +} + +static unsigned int +calc_hex (list_info_type *list) +{ + int data_buffer_size; + list_info_type *first = list; + unsigned int address = ~(unsigned int) 0; + fragS *frag; + fragS *frag_ptr; + unsigned int octet_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. */ + octet_in_frag = 0; + while ((offsetT) octet_in_frag < frag_ptr->fr_fix + && data_buffer_size < MAX_BYTES - 3) + { + if (address == ~(unsigned int) 0) + address = frag_ptr->fr_address / OCTETS_PER_BYTE; + + sprintf (data_buffer + data_buffer_size, + "%02X", + (frag_ptr->fr_literal[octet_in_frag]) & 0xff); + data_buffer_size += 2; + octet_in_frag++; + } + if (frag_ptr->fr_type == rs_fill) + { + unsigned int var_rep_max = octet_in_frag; + unsigned int var_rep_idx = octet_in_frag; + + /* Print as many bytes from the variable part as is sensible. */ + while (((offsetT) octet_in_frag + < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) + && data_buffer_size < MAX_BYTES - 3) + { + if (address == ~(unsigned int) 0) + address = frag_ptr->fr_address / OCTETS_PER_BYTE; + + sprintf (data_buffer + data_buffer_size, + "%02X", + (frag_ptr->fr_literal[var_rep_idx]) & 0xff); + data_buffer_size += 2; + + var_rep_idx++; + octet_in_frag++; + + if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + 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_info_type *list, unsigned int lineno, + char *string, unsigned int address) +{ + unsigned int idx; + unsigned int nchars; + unsigned int lines; + unsigned int octet_in_word = 0; + char *src = data_buffer; + int cur; + struct list_message *msg; + + /* 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 == ~(unsigned int) 0) + { + fprintf (list_file, "% 4d ", lineno); + for (idx = 0; idx < nchars; idx++) + fprintf (list_file, " "); + + emit_line (NULL, "\t%s\n", string ? string : ""); + return; + } + + if (had_errors ()) + fprintf (list_file, "% 4d ???? ", lineno); + else + fprintf (list_file, "% 4d %04x ", lineno, address); + + /* And the data to go along with it. */ + idx = 0; + cur = 0; + while (src[cur] && idx < nchars) + { + int offset; + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset + 1]); + cur += 2; + octet_in_word++; + + if (octet_in_word == LISTING_WORD_SIZE) + { + fprintf (list_file, " "); + idx++; + octet_in_word = 0; + } + + idx += 2; + } + + for (; idx < nchars; idx++) + fprintf (list_file, " "); + + emit_line (list, "\t%s\n", string ? string : ""); + + for (msg = list->messages; msg; msg = msg->next) + emit_line (list, "**** %s\n", msg->message); + + for (lines = 0; + lines < (unsigned int) listing_lhs_cont_lines + && src[cur]; + lines++) + { + nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1; + idx = 0; + + /* Print any more lines of data, but more compactly. */ + fprintf (list_file, "% 4d ", lineno); + + while (src[cur] && idx < nchars) + { + int offset; + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset + 1]); + cur += 2; + idx += 2; + octet_in_word++; + + if (octet_in_word == LISTING_WORD_SIZE) + { + fprintf (list_file, " "); + idx++; + octet_in_word = 0; + } + } + + emit_line (list, "\n"); + } +} + +static void +list_symbol_table (void) +{ + extern symbolS *symbol_rootP; + int got_some = 0; + + symbolS *ptr; + eject = 1; + listing_page (NULL); + + for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) + { + if (SEG_NORMAL (S_GET_SEGMENT (ptr)) + || S_GET_SEGMENT (ptr) == absolute_section) + { + /* Don't report section symbols. They are not interesting. */ + if (symbol_section_p (ptr)) + continue; + + if (S_GET_NAME (ptr)) + { + char buf[30], fmt[8]; + 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); + else if (sizeof (val) <= sizeof (unsigned long)) + { + sprintf (fmt, "%%0%lulx", + (unsigned long) (sizeof (val) * 2)); + sprintf (buf, fmt, (unsigned long) val); + } +#if defined (BFD64) + else if (sizeof (val) > 4) + sprintf_vma (buf, val); +#endif + else + abort (); + + if (!got_some) + { + fprintf (list_file, "DEFINED SYMBOLS\n"); + on_page++; + got_some = 1; + } + + if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) + { + fprintf (list_file, "%20s:%-5d %s:%s %s\n", + symbol_get_frag (ptr)->line->file->filename, + symbol_get_frag (ptr)->line->line, + segment_name (S_GET_SEGMENT (ptr)), + buf, S_GET_NAME (ptr)); + } + else + { + fprintf (list_file, "%33s:%s %s\n", + segment_name (S_GET_SEGMENT (ptr)), + buf, S_GET_NAME (ptr)); + } + + on_page++; + listing_page (NULL); + } + } + + } + if (!got_some) + { + fprintf (list_file, "NO DEFINED SYMBOLS\n"); + on_page++; + } + emit_line (NULL, "\n"); + + 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 (S_GET_SEGMENT (ptr) == undefined_section) + { + if (!got_some) + { + got_some = 1; + + emit_line (NULL, "UNDEFINED SYMBOLS\n"); + } + + emit_line (NULL, "%s\n", S_GET_NAME (ptr)); + } + } + } + + if (!got_some) + emit_line (NULL, "NO UNDEFINED SYMBOLS\n"); +} + +typedef struct cached_line +{ + file_info_type * file; + unsigned int line; + char buffer [LISTING_RHS_WIDTH]; +} cached_line; + +static void +print_source (file_info_type * current_file, + list_info_type * list, + unsigned int width) +{ +#define NUM_CACHE_LINES 3 + static cached_line cached_lines[NUM_CACHE_LINES]; + static int next_free_line = 0; + cached_line * cache = NULL; + + if (current_file->linenum > list->hll_line + && list->hll_line > 0) + { + /* This can happen with modern optimizing compilers. The source + lines from the high level language input program are split up + and interleaved, meaning the line number we want to display + (list->hll_line) can have already been displayed. We have + three choices: + + a. Do nothing, since we have already displayed the source + line. This was the old behaviour. + + b. Display the particular line requested again, but only + that line. This is the new behaviour. + + c. Display the particular line requested again and reset + the current_file->line_num value so that we redisplay + all the following lines as well the next time we + encounter a larger line number. */ + int i; + + /* Check the cache, maybe we already have the line saved. */ + for (i = 0; i < NUM_CACHE_LINES; i++) + if (cached_lines[i].file == current_file + && cached_lines[i].line == list->hll_line) + { + cache = cached_lines + i; + break; + } + + if (i == NUM_CACHE_LINES) + { + cache = cached_lines + next_free_line; + next_free_line ++; + if (next_free_line == NUM_CACHE_LINES) + next_free_line = 0; + + cache->file = current_file; + cache->line = list->hll_line; + cache->buffer[0] = 0; + rebuffer_line (current_file, cache->line, cache->buffer, width); + } + + emit_line (list, "%4u:%-13s **** %s\n", + cache->line, cache->file->filename, cache->buffer); + return; + } + + if (!current_file->at_end) + { + int num_lines_shown = 0; + + while (current_file->linenum < list->hll_line + && !current_file->at_end) + { + char *p; + + cache = cached_lines + next_free_line; + cache->file = current_file; + cache->line = current_file->linenum + 1; + cache->buffer[0] = 0; + p = buffer_line (current_file, cache->buffer, width); + + /* Cache optimization: If printing a group of lines + cache the first and last lines in the group. */ + if (num_lines_shown == 0) + { + next_free_line ++; + if (next_free_line == NUM_CACHE_LINES) + next_free_line = 0; + } + + emit_line (list, "%4u:%-13s **** %s\n", + cache->line, cache->file->filename, p); + num_lines_shown ++; + } + } +} + +/* Sometimes the user doesn't want to be bothered by the debugging + records inserted by the compiler, see if the line is suspicious. */ + +static int +debugging_pseudo (list_info_type *list, const char *line) +{ +#ifdef OBJ_ELF + static int in_debug; + int was_debug; +#endif + + if (list->debugging) + { +#ifdef OBJ_ELF + in_debug = 1; +#endif + return 1; + } +#ifdef OBJ_ELF + was_debug = in_debug; + in_debug = 0; +#endif + + while (ISSPACE (*line)) + line++; + + if (*line != '.') + { +#ifdef OBJ_ELF + /* The ELF compiler sometimes emits blank lines after switching + out of a debugging section. If the next line drops us back + into debugging information, then don't print the blank line. + This is a hack for a particular compiler behaviour, not a + general case. */ + if (was_debug + && *line == '\0' + && list->next != NULL + && list->next->debugging) + { + in_debug = 1; + return 1; + } +#endif + + 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; + if (strncmp (line, "stabs", 5) == 0) + return 1; + if (strncmp (line, "stabn", 5) == 0) + return 1; + + return 0; +} + +static void +listing_listing (char *name ATTRIBUTE_UNUSED) +{ + list_info_type *list = head; + file_info_type *current_hll_file = (file_info_type *) NULL; + char *buffer; + char *p; + int show_listing = 1; + unsigned int width; + + buffer = (char *) xmalloc (listing_rhs_width); + data_buffer = (char *) xmalloc (MAX_BYTES); + eject = 1; + list = head->next; + + while (list) + { + unsigned int list_line; + + width = listing_rhs_width > paper_width ? paper_width : + listing_rhs_width; + + list_line = list->line; + switch (list->edict) + { + case EDICT_LIST: + /* Skip all lines up to the current. */ + list_line--; + break; + case EDICT_NOLIST: + show_listing--; + break; + case EDICT_NOLIST_NEXT: + if (show_listing == 0) + list_line--; + 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) + { + while (list->file->linenum < list_line + && !list->file->at_end) + p = buffer_line (list->file, buffer, width); + } + + if (list->edict == EDICT_LIST + || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0)) + { + /* Enable listing for the single line that caused the enable. */ + list_line++; + show_listing++; + } + + if (show_listing > 0) + { + /* Scan down the list and print all the stuff which can be done + with this line (or lines). */ + 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, width); + + if (list->line_contents) + { + if (!((listing & LISTING_NODEBUG) + && debugging_pseudo (list, list->line_contents))) + print_lines (list, + list->file->linenum == 0 ? list->line : list->file->linenum, + list->line_contents, calc_hex (list)); + + free (list->line_contents); + list->line_contents = NULL; + } + else + { + while (list->file->linenum < list_line + && !list->file->at_end) + { + unsigned int address; + + p = buffer_line (list->file, buffer, width); + + if (list->file->linenum < list_line) + address = ~(unsigned int) 0; + else + address = calc_hex (list); + + if (!((listing & LISTING_NODEBUG) + && debugging_pseudo (list, p))) + print_lines (list, list->file->linenum, p, address); + } + } + + if (list->edict == EDICT_EJECT) + eject = 1; + } + + if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1) + --show_listing; + + list = list->next; + } + + free (buffer); + free (data_buffer); + data_buffer = NULL; +} + +/* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */ + +static void +print_timestamp (void) +{ + const time_t now = time (NULL); + struct tm * timestamp; + char stampstr[MAX_DATELEN]; + + /* Any portable way to obtain subsecond values??? */ + timestamp = localtime (&now); + strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp); + fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr); +} + +static void +print_single_option (char * opt, int *pos) +{ + int opt_len = strlen (opt); + + if ((*pos + opt_len) < paper_width) + { + fprintf (list_file, _("%s "), opt); + *pos = *pos + opt_len; + } + else + { + fprintf (list_file, _("\n\t%s "), opt); + *pos = opt_len; + } +} + +/* Print options passed to as. */ + +static void +print_options (char ** argv) +{ + const char *field_name = _("\n options passed\t: "); + int pos = strlen (field_name); + char **p; + + fputs (field_name, list_file); + for (p = &argv[1]; *p != NULL; p++) + if (**p == '-') + { + /* Ignore these. */ + if (strcmp (*p, "-o") == 0) + { + if (p[1] != NULL) + p++; + continue; + } + if (strcmp (*p, "-v") == 0) + continue; + + print_single_option (*p, &pos); + } +} + +/* Print a first section with basic info like file names, as version, + options passed, target, and timestamp. + The format of this section is as follows: + + AS VERSION + + fieldname TAB ':' fieldcontents + { TAB fieldcontents-cont } */ + +static void +listing_general_info (char ** argv) +{ + /* Print the stuff on the first line. */ + eject = 1; + listing_page (NULL); + + fprintf (list_file, + _(" GNU assembler version %s (%s)\n\t using BFD version %s."), + VERSION, TARGET_ALIAS, BFD_VERSION_STRING); + print_options (argv); + fprintf (list_file, _("\n input file \t: %s"), fn); + fprintf (list_file, _("\n output file \t: %s"), out_file_name); + fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL); + print_timestamp (); +} + +void +listing_print (char *name, char **argv) +{ + int using_stdout; + + title = ""; + subtitle = ""; + + if (name == NULL) + { + list_file = stdout; + using_stdout = 1; + } + else + { + list_file = fopen (name, FOPEN_WT); + if (list_file != NULL) + using_stdout = 0; + else + { + as_warn (_("can't open %s: %s"), name, xstrerror (errno)); + list_file = stdout; + using_stdout = 1; + } + } + + if (listing & LISTING_NOFORM) + paper_height = 0; + + if (listing & LISTING_GENERAL) + listing_general_info (argv); + + if (listing & LISTING_LISTING) + listing_listing (name); + + if (listing & LISTING_SYMBOLS) + list_symbol_table (); + + if (! using_stdout) + { + if (fclose (list_file) == EOF) + as_warn (_("can't close %s: %s"), name, xstrerror (errno)); + } + + if (last_open_file) + fclose (last_open_file); +} + +void +listing_file (const char *name) +{ + fn = name; +} + +void +listing_eject (int ignore ATTRIBUTE_UNUSED) +{ + if (listing) + listing_tail->edict = EDICT_EJECT; +} + +/* Turn listing on or off. An argument of 0 means to turn off + listing. An argument of 1 means to turn on listing. An argument + of 2 means to turn off listing, but as of the next line; that is, + the current line should be listed, but the next line should not. */ + +void +listing_list (int on) +{ + if (listing) + { + switch (on) + { + case 0: + if (listing_tail->edict == EDICT_LIST) + listing_tail->edict = EDICT_NONE; + else + listing_tail->edict = EDICT_NOLIST; + break; + case 1: + if (listing_tail->edict == EDICT_NOLIST + || listing_tail->edict == EDICT_NOLIST_NEXT) + listing_tail->edict = EDICT_NONE; + else + listing_tail->edict = EDICT_LIST; + break; + case 2: + listing_tail->edict = EDICT_NOLIST_NEXT; + break; + default: + abort (); + } + } +} + +void +listing_psize (int width_only) +{ + if (! width_only) + { + 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 != ',') + { + demand_empty_rest_of_line (); + return; + } + + ++input_line_pointer; + } + + paper_width = get_absolute_expression (); + + demand_empty_rest_of_line (); +} + +void +listing_nopage (int ignore ATTRIBUTE_UNUSED) +{ + paper_height = 0; +} + +void +listing_title (int depth) +{ + int quoted; + char *start; + char *ttl; + unsigned int length; + + SKIP_WHITESPACE (); + if (*input_line_pointer != '\"') + quoted = 0; + else + { + quoted = 1; + ++input_line_pointer; + } + + start = input_line_pointer; + + while (*input_line_pointer) + { + if (quoted + ? *input_line_pointer == '\"' + : is_end_of_line[(unsigned char) *input_line_pointer]) + { + if (listing) + { + length = input_line_pointer - start; + ttl = (char *) xmalloc (length + 1); + memcpy (ttl, start, length); + ttl[length] = 0; + listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; + listing_tail->edict_arg = ttl; + } + if (quoted) + 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++; + } + } +} + +void +listing_source_line (unsigned int line) +{ + if (listing) + { + new_frag (); + listing_tail->hll_line = line; + new_frag (); + } +} + +void +listing_source_file (const char *file) +{ + if (listing) + listing_tail->hll_file = file_info (file); +} + +#else + +/* Dummy functions for when compiled without listing enabled. */ + +void +listing_list (int on) +{ + s_ignore (0); +} + +void +listing_eject (int ignore) +{ + s_ignore (0); +} + +void +listing_psize (int ignore) +{ + s_ignore (0); +} + +void +listing_nopage (int ignore) +{ + s_ignore (0); +} + +void +listing_title (int depth) +{ + s_ignore (0); +} + +void +listing_file (const char *name) +{ +} + +void +listing_newline (char *name) +{ +} + +void +listing_source_line (unsigned int n) +{ +} + +void +listing_source_file (const char *n) +{ +} + +#endif diff --git a/contrib/toolchain/binutils/gas/listing.h b/contrib/toolchain/binutils/gas/listing.h new file mode 100644 index 0000000000..79afdac6b6 --- /dev/null +++ b/contrib/toolchain/binutils/gas/listing.h @@ -0,0 +1,67 @@ +/* This file is listing.h + Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1997, 1998, + 2003, 2005, 2007, 2008, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef __listing_h__ +#define __listing_h__ + +#define LISTING_LISTING 1 +#define LISTING_SYMBOLS 2 +#define LISTING_NOFORM 4 +#define LISTING_HLL 8 +#define LISTING_NODEBUG 16 +#define LISTING_NOCOND 32 +#define LISTING_MACEXP 64 +#define LISTING_GENERAL 128 + +#define LISTING_DEFAULT (LISTING_LISTING | LISTING_HLL | LISTING_SYMBOLS) + +#ifndef NO_LISTING +#define LISTING_NEWLINE() { if (listing) listing_newline (NULL); } +#else +#define LISTING_NEWLINE() {;} +#endif +#define LISTING_EOF() LISTING_NEWLINE() + +#define LISTING_SKIP_COND() ((listing & LISTING_NOCOND) != 0) + +void listing_eject (int); +void listing_error (const char *message); +void listing_file (const char *name); +void listing_list (int on); +void listing_newline (char *ps); +void listing_prev_line (void); +void listing_print (char *, char **); +void listing_psize (int); +void listing_nopage (int); +void listing_source_file (const char *); +void listing_source_line (unsigned int); +void listing_title (int depth); +void listing_warning (const char *message); +void listing_width (unsigned int x); + +extern int listing_lhs_width; +extern int listing_lhs_width_second; +extern int listing_lhs_cont_lines; +extern int listing_rhs_width; + +#endif /* __listing_h__ */ + +/* end of listing.h */ diff --git a/contrib/toolchain/binutils/gas/literal.c b/contrib/toolchain/binutils/gas/literal.c new file mode 100644 index 0000000000..6cbbe7e54a --- /dev/null +++ b/contrib/toolchain/binutils/gas/literal.c @@ -0,0 +1,96 @@ +/* literal.c - GAS literal pool management. + Copyright 1994, 2000, 2005, 2007 Free Software Foundation, Inc. + Written by Ken Raeburn (raeburn@cygnus.com). + + 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 3, 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, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* This isn't quite a "constant" pool. Some of the values may get + adjusted at run time, e.g., for symbolic relocations when shared + libraries are in use. It's more of a "literal" pool. + + On the Alpha, this should be used for .lita and .lit8. (Is there + ever a .lit4?) On the MIPS, it could be used for .lit4 as well. + + The expressions passed here should contain either constants or symbols, + not a combination of both. Typically, the constant pool is accessed + with some sort of GP register, so the size of the pool must be kept down + if possible. The exception is section offsets -- if you're storing a + pointer to the start of .data, for example, and your machine provides + for 16-bit signed addends, you might want to store .data+32K, so that + you can access all of the first 64K of .data with the one pointer. + + This isn't a requirement, just a guideline that can help keep .o file + size down. */ + +#include "as.h" +#include "subsegs.h" + +#ifdef NEED_LITERAL_POOL + +valueT +add_to_literal_pool (sym, addend, sec, size) + symbolS *sym; + valueT addend; + segT sec; + int size; +{ + segT current_section = now_seg; + int current_subsec = now_subseg; + valueT offset; + bfd_reloc_code_real_type reloc_type; + char *p; + segment_info_type *seginfo = seg_info (sec); + fixS *fixp; + + offset = 0; + /* @@ This assumes all entries in a given section will be of the same + size... Probably correct, but unwise to rely on. */ + /* This must always be called with the same subsegment. */ + if (seginfo->frchainP) + for (fixp = seginfo->frchainP->fix_root; + fixp != (fixS *) NULL; + fixp = fixp->fx_next, offset += size) + { + if (fixp->fx_addsy == sym && fixp->fx_offset == addend) + return offset; + } + + subseg_set (sec, 0); + p = frag_more (size); + memset (p, 0, size); + + switch (size) + { + case 4: + reloc_type = BFD_RELOC_32; + break; + case 8: + reloc_type = BFD_RELOC_64; + break; + default: + abort (); + } + fix_new (frag_now, p - frag_now->fr_literal, size, sym, addend, 0, + reloc_type); + + subseg_set (current_section, current_subsec); + offset = seginfo->literal_pool_size; + seginfo->literal_pool_size += size; + return offset; +} +#endif diff --git a/contrib/toolchain/binutils/gas/macro.c b/contrib/toolchain/binutils/gas/macro.c new file mode 100644 index 0000000000..75b9b7ef93 --- /dev/null +++ b/contrib/toolchain/binutils/gas/macro.c @@ -0,0 +1,1382 @@ +/* macro.c - macro support for gas + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013 Free Software Foundation, Inc. + + Written by Steve and Judy Chamberlain of Cygnus Support, + sac@cygnus.com + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "safe-ctype.h" +#include "sb.h" +#include "macro.h" + +/* The routines in this file handle macro definition and expansion. + They are called by gas. */ + +#define ISWHITE(x) ((x) == ' ' || (x) == '\t') + +#define ISSEP(x) \ + ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \ + || (x) == ')' || (x) == '(' \ + || ((macro_alternate || macro_mri) && ((x) == '<' || (x) == '>'))) + +#define ISBASE(x) \ + ((x) == 'b' || (x) == 'B' \ + || (x) == 'q' || (x) == 'Q' \ + || (x) == 'h' || (x) == 'H' \ + || (x) == 'd' || (x) == 'D') + +/* The macro hash table. */ + +struct hash_control *macro_hash; + +/* Whether any macros have been defined. */ + +int macro_defined; + +/* Whether we are in alternate syntax mode. */ + +static int macro_alternate; + +/* Whether we are in MRI mode. */ + +static int macro_mri; + +/* Whether we should strip '@' characters. */ + +static int macro_strip_at; + +/* Function to use to parse an expression. */ + +static size_t (*macro_expr) (const char *, size_t, sb *, offsetT *); + +/* Number of macro expansions that have been done. */ + +static int macro_number; + +/* Initialize macro processing. */ + +void +macro_init (int alternate, int mri, int strip_at, + size_t (*exp) (const char *, size_t, sb *, offsetT *)) +{ + macro_hash = hash_new (); + macro_defined = 0; + macro_alternate = alternate; + macro_mri = mri; + macro_strip_at = strip_at; + macro_expr = exp; +} + +/* Switch in and out of alternate mode on the fly. */ + +void +macro_set_alternate (int alternate) +{ + macro_alternate = alternate; +} + +/* Switch in and out of MRI mode on the fly. */ + +void +macro_mri_mode (int mri) +{ + macro_mri = mri; +} + +/* Read input lines till we get to a TO string. + Increase nesting depth if we get a FROM string. + Put the results into sb at PTR. + FROM may be NULL (or will be ignored) if TO is "ENDR". + Add a new input line to an sb using GET_LINE. + Return 1 on success, 0 on unexpected EOF. */ + +int +buffer_and_nest (const char *from, const char *to, sb *ptr, + size_t (*get_line) (sb *)) +{ + size_t from_len; + size_t to_len = strlen (to); + int depth = 1; + size_t line_start = ptr->len; + size_t more = get_line (ptr); + + if (to_len == 4 && strcasecmp (to, "ENDR") == 0) + { + from = NULL; + from_len = 0; + } + else + from_len = strlen (from); + + while (more) + { + /* Try to find the first pseudo op on the line. */ + size_t i = line_start; + bfd_boolean had_colon = FALSE; + + /* With normal syntax we can suck what we want till we get + to the dot. With the alternate, labels have to start in + the first column, since we can't tell what's a label and + what's a pseudoop. */ + + if (! LABELS_WITHOUT_COLONS) + { + /* Skip leading whitespace. */ + while (i < ptr->len && ISWHITE (ptr->ptr[i])) + i++; + } + + for (;;) + { + /* Skip over a label, if any. */ + if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i])) + break; + i++; + while (i < ptr->len && is_part_of_name (ptr->ptr[i])) + i++; + if (i < ptr->len && is_name_ender (ptr->ptr[i])) + i++; + /* Skip whitespace. */ + while (i < ptr->len && ISWHITE (ptr->ptr[i])) + i++; + /* Check for the colon. */ + if (i >= ptr->len || ptr->ptr[i] != ':') + { + /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a + colon after a label. If we do have a colon on the + first label then handle more than one label on the + line, assuming that each label has a colon. */ + if (LABELS_WITHOUT_COLONS && !had_colon) + break; + i = line_start; + break; + } + i++; + line_start = i; + had_colon = TRUE; + } + + /* Skip trailing whitespace. */ + while (i < ptr->len && ISWHITE (ptr->ptr[i])) + i++; + + if (i < ptr->len && (ptr->ptr[i] == '.' + || NO_PSEUDO_DOT + || macro_mri)) + { + if (! flag_m68k_mri && ptr->ptr[i] == '.') + i++; + if (from == NULL + && strncasecmp (ptr->ptr + i, "IRPC", from_len = 4) != 0 + && strncasecmp (ptr->ptr + i, "IRP", from_len = 3) != 0 + && strncasecmp (ptr->ptr + i, "IREPC", from_len = 5) != 0 + && strncasecmp (ptr->ptr + i, "IREP", from_len = 4) != 0 + && strncasecmp (ptr->ptr + i, "REPT", from_len = 4) != 0 + && strncasecmp (ptr->ptr + i, "REP", from_len = 3) != 0) + from_len = 0; + if ((from != NULL + ? strncasecmp (ptr->ptr + i, from, from_len) == 0 + : from_len > 0) + && (ptr->len == (i + from_len) + || ! (is_part_of_name (ptr->ptr[i + from_len]) + || is_name_ender (ptr->ptr[i + from_len])))) + depth++; + if (strncasecmp (ptr->ptr + i, to, to_len) == 0 + && (ptr->len == (i + to_len) + || ! (is_part_of_name (ptr->ptr[i + to_len]) + || is_name_ender (ptr->ptr[i + to_len])))) + { + depth--; + if (depth == 0) + { + /* Reset the string to not include the ending rune. */ + ptr->len = line_start; + break; + } + } + } + + /* Add the original end-of-line char to the end and keep running. */ + sb_add_char (ptr, more); + line_start = ptr->len; + more = get_line (ptr); + } + + /* Return 1 on success, 0 on unexpected EOF. */ + return depth == 0; +} + +/* Pick up a token. */ + +static size_t +get_token (size_t idx, sb *in, sb *name) +{ + if (idx < in->len + && is_name_beginner (in->ptr[idx])) + { + sb_add_char (name, in->ptr[idx++]); + while (idx < in->len + && is_part_of_name (in->ptr[idx])) + { + sb_add_char (name, in->ptr[idx++]); + } + if (idx < in->len + && is_name_ender (in->ptr[idx])) + { + sb_add_char (name, in->ptr[idx++]); + } + } + /* Ignore trailing &. */ + if (macro_alternate && idx < in->len && in->ptr[idx] == '&') + idx++; + return idx; +} + +/* Pick up a string. */ + +static size_t +getstring (size_t idx, sb *in, sb *acc) +{ + while (idx < in->len + && (in->ptr[idx] == '"' + || (in->ptr[idx] == '<' && (macro_alternate || macro_mri)) + || (in->ptr[idx] == '\'' && macro_alternate))) + { + if (in->ptr[idx] == '<') + { + int nest = 0; + idx++; + while ((in->ptr[idx] != '>' || nest) + && idx < in->len) + { + if (in->ptr[idx] == '!') + { + idx++; + sb_add_char (acc, in->ptr[idx++]); + } + else + { + if (in->ptr[idx] == '>') + nest--; + if (in->ptr[idx] == '<') + nest++; + sb_add_char (acc, in->ptr[idx++]); + } + } + idx++; + } + else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'') + { + char tchar = in->ptr[idx]; + int escaped = 0; + + idx++; + + while (idx < in->len) + { + if (in->ptr[idx - 1] == '\\') + escaped ^= 1; + else + escaped = 0; + + if (macro_alternate && in->ptr[idx] == '!') + { + idx ++; + + sb_add_char (acc, in->ptr[idx]); + + idx ++; + } + else if (escaped && in->ptr[idx] == tchar) + { + sb_add_char (acc, tchar); + idx ++; + } + else + { + if (in->ptr[idx] == tchar) + { + idx ++; + + if (idx >= in->len || in->ptr[idx] != tchar) + break; + } + + sb_add_char (acc, in->ptr[idx]); + idx ++; + } + } + } + } + + return idx; +} + +/* Fetch string from the input stream, + rules: + 'Bxyx -> return 'Bxyza + % -> return string of decimal value of + "string" -> return string + (string) -> return (string-including-whitespaces) + xyx -> return xyz. */ + +static size_t +get_any_string (size_t idx, sb *in, sb *out) +{ + sb_reset (out); + idx = sb_skip_white (idx, in); + + if (idx < in->len) + { + if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx])) + { + while (!ISSEP (in->ptr[idx])) + sb_add_char (out, in->ptr[idx++]); + } + else if (in->ptr[idx] == '%' && macro_alternate) + { + offsetT val; + char buf[20]; + + /* Turns the next expression into a string. */ + /* xgettext: no-c-format */ + idx = (*macro_expr) (_("% operator needs absolute expression"), + idx + 1, + in, + &val); + sprintf (buf, "%" BFD_VMA_FMT "d", val); + sb_add_string (out, buf); + } + else if (in->ptr[idx] == '"' + || (in->ptr[idx] == '<' && (macro_alternate || macro_mri)) + || (macro_alternate && in->ptr[idx] == '\'')) + { + if (macro_alternate && ! macro_strip_at && in->ptr[idx] != '<') + { + /* Keep the quotes. */ + sb_add_char (out, '"'); + idx = getstring (idx, in, out); + sb_add_char (out, '"'); + } + else + { + idx = getstring (idx, in, out); + } + } + else + { + char *br_buf = (char *) xmalloc (1); + char *in_br = br_buf; + + *in_br = '\0'; + while (idx < in->len + && (*in_br + || (in->ptr[idx] != ' ' + && in->ptr[idx] != '\t')) + && in->ptr[idx] != ',' + && (in->ptr[idx] != '<' + || (! macro_alternate && ! macro_mri))) + { + char tchar = in->ptr[idx]; + + switch (tchar) + { + case '"': + case '\'': + sb_add_char (out, in->ptr[idx++]); + while (idx < in->len + && in->ptr[idx] != tchar) + sb_add_char (out, in->ptr[idx++]); + if (idx == in->len) + { + free (br_buf); + return idx; + } + break; + case '(': + case '[': + if (in_br > br_buf) + --in_br; + else + { + br_buf = (char *) xmalloc (strlen (in_br) + 2); + strcpy (br_buf + 1, in_br); + free (in_br); + in_br = br_buf; + } + *in_br = tchar; + break; + case ')': + if (*in_br == '(') + ++in_br; + break; + case ']': + if (*in_br == '[') + ++in_br; + break; + } + sb_add_char (out, tchar); + ++idx; + } + free (br_buf); + } + } + + return idx; +} + +/* Allocate a new formal. */ + +static formal_entry * +new_formal (void) +{ + formal_entry *formal; + + formal = (formal_entry *) xmalloc (sizeof (formal_entry)); + + sb_new (&formal->name); + sb_new (&formal->def); + sb_new (&formal->actual); + formal->next = NULL; + formal->type = FORMAL_OPTIONAL; + return formal; +} + +/* Free a formal. */ + +static void +del_formal (formal_entry *formal) +{ + sb_kill (&formal->actual); + sb_kill (&formal->def); + sb_kill (&formal->name); + free (formal); +} + +/* Pick up the formal parameters of a macro definition. */ + +static size_t +do_formals (macro_entry *macro, size_t idx, sb *in) +{ + formal_entry **p = ¯o->formals; + const char *name; + + idx = sb_skip_white (idx, in); + while (idx < in->len) + { + formal_entry *formal = new_formal (); + size_t cidx; + + idx = get_token (idx, in, &formal->name); + if (formal->name.len == 0) + { + if (macro->formal_count) + --idx; + del_formal (formal); /* 'formal' goes out of scope. */ + break; + } + idx = sb_skip_white (idx, in); + /* This is a formal. */ + name = sb_terminate (&formal->name); + if (! macro_mri + && idx < in->len + && in->ptr[idx] == ':' + && (! is_name_beginner (':') + || idx + 1 >= in->len + || ! is_part_of_name (in->ptr[idx + 1]))) + { + /* Got a qualifier. */ + sb qual; + + sb_new (&qual); + idx = get_token (sb_skip_white (idx + 1, in), in, &qual); + sb_terminate (&qual); + if (qual.len == 0) + as_bad_where (macro->file, + macro->line, + _("Missing parameter qualifier for `%s' in macro `%s'"), + name, + macro->name); + else if (strcmp (qual.ptr, "req") == 0) + formal->type = FORMAL_REQUIRED; + else if (strcmp (qual.ptr, "vararg") == 0) + formal->type = FORMAL_VARARG; + else + as_bad_where (macro->file, + macro->line, + _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"), + qual.ptr, + name, + macro->name); + sb_kill (&qual); + idx = sb_skip_white (idx, in); + } + if (idx < in->len && in->ptr[idx] == '=') + { + /* Got a default. */ + idx = get_any_string (idx + 1, in, &formal->def); + idx = sb_skip_white (idx, in); + if (formal->type == FORMAL_REQUIRED) + { + sb_reset (&formal->def); + as_warn_where (macro->file, + macro->line, + _("Pointless default value for required parameter `%s' in macro `%s'"), + name, + macro->name); + } + } + + /* Add to macro's hash table. */ + if (! hash_find (macro->formal_hash, name)) + hash_jam (macro->formal_hash, name, formal); + else + as_bad_where (macro->file, + macro->line, + _("A parameter named `%s' already exists for macro `%s'"), + name, + macro->name); + + formal->index = macro->formal_count++; + *p = formal; + p = &formal->next; + if (formal->type == FORMAL_VARARG) + break; + cidx = idx; + idx = sb_skip_comma (idx, in); + if (idx != cidx && idx >= in->len) + { + idx = cidx; + break; + } + } + + if (macro_mri) + { + formal_entry *formal = new_formal (); + + /* Add a special NARG formal, which macro_expand will set to the + number of arguments. */ + /* The same MRI assemblers which treat '@' characters also use + the name $NARG. At least until we find an exception. */ + if (macro_strip_at) + name = "$NARG"; + else + name = "NARG"; + + sb_add_string (&formal->name, name); + + /* Add to macro's hash table. */ + if (hash_find (macro->formal_hash, name)) + as_bad_where (macro->file, + macro->line, + _("Reserved word `%s' used as parameter in macro `%s'"), + name, + macro->name); + hash_jam (macro->formal_hash, name, formal); + + formal->index = NARG_INDEX; + *p = formal; + } + + return idx; +} + +/* Free the memory allocated to a macro. */ + +static void +free_macro (macro_entry *macro) +{ + formal_entry *formal; + + for (formal = macro->formals; formal; ) + { + formal_entry *f; + + f = formal; + formal = formal->next; + del_formal (f); + } + hash_die (macro->formal_hash); + sb_kill (¯o->sub); + free (macro); +} + +/* Define a new macro. Returns NULL on success, otherwise returns an + error message. If NAMEP is not NULL, *NAMEP is set to the name of + the macro which was defined. */ + +const char * +define_macro (size_t idx, sb *in, sb *label, + size_t (*get_line) (sb *), + char *file, unsigned int line, + const char **namep) +{ + macro_entry *macro; + sb name; + const char *error = NULL; + + macro = (macro_entry *) xmalloc (sizeof (macro_entry)); + sb_new (¯o->sub); + sb_new (&name); + macro->file = file; + macro->line = line; + + macro->formal_count = 0; + macro->formals = 0; + macro->formal_hash = hash_new_sized (7); + + idx = sb_skip_white (idx, in); + if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line)) + error = _("unexpected end of file in macro `%s' definition"); + if (label != NULL && label->len != 0) + { + sb_add_sb (&name, label); + macro->name = sb_terminate (&name); + if (idx < in->len && in->ptr[idx] == '(') + { + /* It's the label: MACRO (formals,...) sort */ + idx = do_formals (macro, idx + 1, in); + if (idx < in->len && in->ptr[idx] == ')') + idx = sb_skip_white (idx + 1, in); + else if (!error) + error = _("missing `)' after formals in macro definition `%s'"); + } + else + { + /* It's the label: MACRO formals,... sort */ + idx = do_formals (macro, idx, in); + } + } + else + { + size_t cidx; + + idx = get_token (idx, in, &name); + macro->name = sb_terminate (&name); + if (name.len == 0) + error = _("Missing macro name"); + cidx = sb_skip_white (idx, in); + idx = sb_skip_comma (cidx, in); + if (idx == cidx || idx < in->len) + idx = do_formals (macro, idx, in); + else + idx = cidx; + } + if (!error && idx < in->len) + error = _("Bad parameter list for macro `%s'"); + + /* And stick it in the macro hash table. */ + for (idx = 0; idx < name.len; idx++) + name.ptr[idx] = TOLOWER (name.ptr[idx]); + if (hash_find (macro_hash, macro->name)) + error = _("Macro `%s' was already defined"); + if (!error) + error = hash_jam (macro_hash, macro->name, (void *) macro); + + if (namep != NULL) + *namep = macro->name; + + if (!error) + macro_defined = 1; + else + free_macro (macro); + + return error; +} + +/* Scan a token, and then skip KIND. */ + +static size_t +get_apost_token (size_t idx, sb *in, sb *name, int kind) +{ + idx = get_token (idx, in, name); + if (idx < in->len + && in->ptr[idx] == kind + && (! macro_mri || macro_strip_at) + && (! macro_strip_at || kind == '@')) + idx++; + return idx; +} + +/* Substitute the actual value for a formal parameter. */ + +static size_t +sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash, + int kind, sb *out, int copyifnotthere) +{ + size_t src; + formal_entry *ptr; + + src = get_apost_token (start, in, t, kind); + /* See if it's in the macro's hash table, unless this is + macro_strip_at and kind is '@' and the token did not end in '@'. */ + if (macro_strip_at + && kind == '@' + && (src == start || in->ptr[src - 1] != '@')) + ptr = NULL; + else + ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t)); + if (ptr) + { + if (ptr->actual.len) + { + sb_add_sb (out, &ptr->actual); + } + else + { + sb_add_sb (out, &ptr->def); + } + } + else if (kind == '&') + { + /* Doing this permits people to use & in macro bodies. */ + sb_add_char (out, '&'); + sb_add_sb (out, t); + if (src != start && in->ptr[src - 1] == '&') + sb_add_char (out, '&'); + } + else if (copyifnotthere) + { + sb_add_sb (out, t); + } + else + { + sb_add_char (out, '\\'); + sb_add_sb (out, t); + } + return src; +} + +/* Expand the body of a macro. */ + +static const char * +macro_expand_body (sb *in, sb *out, formal_entry *formals, + struct hash_control *formal_hash, const macro_entry *macro) +{ + sb t; + size_t src = 0; + int inquote = 0, macro_line = 0; + formal_entry *loclist = NULL; + const char *err = NULL; + + sb_new (&t); + + while (src < in->len && !err) + { + if (in->ptr[src] == '&') + { + sb_reset (&t); + if (macro_mri) + { + if (src + 1 < in->len && in->ptr[src + 1] == '&') + src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1); + else + sb_add_char (out, in->ptr[src++]); + } + else + { + /* Permit macro parameter substition delineated with + an '&' prefix and optional '&' suffix. */ + src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0); + } + } + else if (in->ptr[src] == '\\') + { + src++; + if (src < in->len && in->ptr[src] == '(') + { + /* Sub in till the next ')' literally. */ + src++; + while (src < in->len && in->ptr[src] != ')') + { + sb_add_char (out, in->ptr[src++]); + } + if (src < in->len) + src++; + else if (!macro) + err = _("missing `)'"); + else + as_bad_where (macro->file, macro->line + macro_line, _("missing `)'")); + } + else if (src < in->len && in->ptr[src] == '@') + { + /* Sub in the macro invocation number. */ + + char buffer[10]; + src++; + sprintf (buffer, "%d", macro_number); + sb_add_string (out, buffer); + } + else if (src < in->len && in->ptr[src] == '&') + { + /* This is a preprocessor variable name, we don't do them + here. */ + sb_add_char (out, '\\'); + sb_add_char (out, '&'); + src++; + } + else if (macro_mri && src < in->len && ISALNUM (in->ptr[src])) + { + int ind; + formal_entry *f; + + if (ISDIGIT (in->ptr[src])) + ind = in->ptr[src] - '0'; + else if (ISUPPER (in->ptr[src])) + ind = in->ptr[src] - 'A' + 10; + else + ind = in->ptr[src] - 'a' + 10; + ++src; + for (f = formals; f != NULL; f = f->next) + { + if (f->index == ind - 1) + { + if (f->actual.len != 0) + sb_add_sb (out, &f->actual); + else + sb_add_sb (out, &f->def); + break; + } + } + } + else + { + sb_reset (&t); + src = sub_actual (src, in, &t, formal_hash, '\'', out, 0); + } + } + else if ((macro_alternate || macro_mri) + && is_name_beginner (in->ptr[src]) + && (! inquote + || ! macro_strip_at + || (src > 0 && in->ptr[src - 1] == '@'))) + { + if (! macro + || src + 5 >= in->len + || strncasecmp (in->ptr + src, "LOCAL", 5) != 0 + || ! ISWHITE (in->ptr[src + 5]) + /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string. */ + || inquote) + { + sb_reset (&t); + src = sub_actual (src, in, &t, formal_hash, + (macro_strip_at && inquote) ? '@' : '\'', + out, 1); + } + else + { + src = sb_skip_white (src + 5, in); + while (in->ptr[src] != '\n') + { + const char *name; + formal_entry *f = new_formal (); + + src = get_token (src, in, &f->name); + name = sb_terminate (&f->name); + if (! hash_find (formal_hash, name)) + { + static int loccnt; + char buf[20]; + + f->index = LOCAL_INDEX; + f->next = loclist; + loclist = f; + + sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt); + sb_add_string (&f->actual, buf); + + err = hash_jam (formal_hash, name, f); + if (err != NULL) + break; + } + else + { + as_bad_where (macro->file, + macro->line + macro_line, + _("`%s' was already used as parameter (or another local) name"), + name); + del_formal (f); + } + + src = sb_skip_comma (src, in); + } + } + } + else if (in->ptr[src] == '"' + || (macro_mri && in->ptr[src] == '\'')) + { + inquote = !inquote; + sb_add_char (out, in->ptr[src++]); + } + else if (in->ptr[src] == '@' && macro_strip_at) + { + ++src; + if (src < in->len + && in->ptr[src] == '@') + { + sb_add_char (out, '@'); + ++src; + } + } + else if (macro_mri + && in->ptr[src] == '=' + && src + 1 < in->len + && in->ptr[src + 1] == '=') + { + formal_entry *ptr; + + sb_reset (&t); + src = get_token (src + 2, in, &t); + ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t)); + if (ptr == NULL) + { + /* FIXME: We should really return a warning string here, + but we can't, because the == might be in the MRI + comment field, and, since the nature of the MRI + comment field depends upon the exact instruction + being used, we don't have enough information here to + figure out whether it is or not. Instead, we leave + the == in place, which should cause a syntax error if + it is not in a comment. */ + sb_add_char (out, '='); + sb_add_char (out, '='); + sb_add_sb (out, &t); + } + else + { + if (ptr->actual.len) + { + sb_add_string (out, "-1"); + } + else + { + sb_add_char (out, '0'); + } + } + } + else + { + if (in->ptr[src] == '\n') + ++macro_line; + sb_add_char (out, in->ptr[src++]); + } + } + + sb_kill (&t); + + while (loclist != NULL) + { + formal_entry *f; + const char *name; + + f = loclist->next; + name = sb_terminate (&loclist->name); + hash_delete (formal_hash, name, f == NULL); + del_formal (loclist); + loclist = f; + } + + return err; +} + +/* Assign values to the formal parameters of a macro, and expand the + body. */ + +static const char * +macro_expand (size_t idx, sb *in, macro_entry *m, sb *out) +{ + sb t; + formal_entry *ptr; + formal_entry *f; + int is_keyword = 0; + int narg = 0; + const char *err = NULL; + + sb_new (&t); + + /* Reset any old value the actuals may have. */ + for (f = m->formals; f; f = f->next) + sb_reset (&f->actual); + f = m->formals; + while (f != NULL && f->index < 0) + f = f->next; + + if (macro_mri) + { + /* The macro may be called with an optional qualifier, which may + be referred to in the macro body as \0. */ + if (idx < in->len && in->ptr[idx] == '.') + { + /* The Microtec assembler ignores this if followed by a white space. + (Macro invocation with empty extension) */ + idx++; + if ( idx < in->len + && in->ptr[idx] != ' ' + && in->ptr[idx] != '\t') + { + formal_entry *n = new_formal (); + + n->index = QUAL_INDEX; + + n->next = m->formals; + m->formals = n; + + idx = get_any_string (idx, in, &n->actual); + } + } + } + + /* Peel off the actuals and store them away in the hash tables' actuals. */ + idx = sb_skip_white (idx, in); + while (idx < in->len) + { + size_t scan; + + /* Look and see if it's a positional or keyword arg. */ + scan = idx; + while (scan < in->len + && !ISSEP (in->ptr[scan]) + && !(macro_mri && in->ptr[scan] == '\'') + && (!macro_alternate && in->ptr[scan] != '=')) + scan++; + if (scan < in->len && !macro_alternate && in->ptr[scan] == '=') + { + is_keyword = 1; + + /* It's OK to go from positional to keyword. */ + + /* This is a keyword arg, fetch the formal name and + then the actual stuff. */ + sb_reset (&t); + idx = get_token (idx, in, &t); + if (in->ptr[idx] != '=') + { + err = _("confusion in formal parameters"); + break; + } + + /* Lookup the formal in the macro's list. */ + ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t)); + if (!ptr) + { + as_bad (_("Parameter named `%s' does not exist for macro `%s'"), + t.ptr, + m->name); + sb_reset (&t); + idx = get_any_string (idx + 1, in, &t); + } + else + { + /* Insert this value into the right place. */ + if (ptr->actual.len) + { + as_warn (_("Value for parameter `%s' of macro `%s' was already specified"), + ptr->name.ptr, + m->name); + sb_reset (&ptr->actual); + } + idx = get_any_string (idx + 1, in, &ptr->actual); + if (ptr->actual.len > 0) + ++narg; + } + } + else + { + if (is_keyword) + { + err = _("can't mix positional and keyword arguments"); + break; + } + + if (!f) + { + formal_entry **pf; + int c; + + if (!macro_mri) + { + err = _("too many positional arguments"); + break; + } + + f = new_formal (); + + c = -1; + for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next) + if ((*pf)->index >= c) + c = (*pf)->index + 1; + if (c == -1) + c = 0; + *pf = f; + f->index = c; + } + + if (f->type != FORMAL_VARARG) + idx = get_any_string (idx, in, &f->actual); + else + { + sb_add_buffer (&f->actual, in->ptr + idx, in->len - idx); + idx = in->len; + } + if (f->actual.len > 0) + ++narg; + do + { + f = f->next; + } + while (f != NULL && f->index < 0); + } + + if (! macro_mri) + idx = sb_skip_comma (idx, in); + else + { + if (in->ptr[idx] == ',') + ++idx; + if (ISWHITE (in->ptr[idx])) + break; + } + } + + if (! err) + { + for (ptr = m->formals; ptr; ptr = ptr->next) + { + if (ptr->type == FORMAL_REQUIRED && ptr->actual.len == 0) + as_bad (_("Missing value for required parameter `%s' of macro `%s'"), + ptr->name.ptr, + m->name); + } + + if (macro_mri) + { + char buffer[20]; + + sb_reset (&t); + sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG"); + ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t)); + sprintf (buffer, "%d", narg); + sb_add_string (&ptr->actual, buffer); + } + + err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m); + } + + /* Discard any unnamed formal arguments. */ + if (macro_mri) + { + formal_entry **pf; + + pf = &m->formals; + while (*pf != NULL) + { + if ((*pf)->name.len != 0) + pf = &(*pf)->next; + else + { + f = (*pf)->next; + del_formal (*pf); + *pf = f; + } + } + } + + sb_kill (&t); + if (!err) + macro_number++; + + return err; +} + +/* Check for a macro. If one is found, put the expansion into + *EXPAND. Return 1 if a macro is found, 0 otherwise. */ + +int +check_macro (const char *line, sb *expand, + const char **error, macro_entry **info) +{ + const char *s; + char *copy, *cls; + macro_entry *macro; + sb line_sb; + + if (! is_name_beginner (*line) + && (! macro_mri || *line != '.')) + return 0; + + s = line + 1; + while (is_part_of_name (*s)) + ++s; + if (is_name_ender (*s)) + ++s; + + copy = (char *) alloca (s - line + 1); + memcpy (copy, line, s - line); + copy[s - line] = '\0'; + for (cls = copy; *cls != '\0'; cls ++) + *cls = TOLOWER (*cls); + + macro = (macro_entry *) hash_find (macro_hash, copy); + + if (macro == NULL) + return 0; + + /* Wrap the line up in an sb. */ + sb_new (&line_sb); + while (*s != '\0' && *s != '\n' && *s != '\r') + sb_add_char (&line_sb, *s++); + + sb_new (expand); + *error = macro_expand (0, &line_sb, macro, expand); + + sb_kill (&line_sb); + + /* Export the macro information if requested. */ + if (info) + *info = macro; + + return 1; +} + +/* Delete a macro. */ + +void +delete_macro (const char *name) +{ + char *copy; + size_t i, len; + macro_entry *macro; + + len = strlen (name); + copy = (char *) alloca (len + 1); + for (i = 0; i < len; ++i) + copy[i] = TOLOWER (name[i]); + copy[i] = '\0'; + + /* We can only ask hash_delete to free memory if we are deleting + macros in reverse order to their definition. + So just clear out the entry. */ + if ((macro = (macro_entry *) hash_find (macro_hash, copy)) != NULL) + { + hash_jam (macro_hash, copy, NULL); + free_macro (macro); + } + else + as_warn (_("Attempt to purge non-existant macro `%s'"), copy); +} + +/* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a + combined macro definition and execution. This returns NULL on + success, or an error message otherwise. */ + +const char * +expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *)) +{ + sb sub; + formal_entry f; + struct hash_control *h; + const char *err; + + idx = sb_skip_white (idx, in); + + sb_new (&sub); + if (! buffer_and_nest (NULL, "ENDR", &sub, get_line)) + return _("unexpected end of file in irp or irpc"); + + sb_new (&f.name); + sb_new (&f.def); + sb_new (&f.actual); + + idx = get_token (idx, in, &f.name); + if (f.name.len == 0) + return _("missing model parameter"); + + h = hash_new (); + err = hash_jam (h, sb_terminate (&f.name), &f); + if (err != NULL) + return err; + + f.index = 1; + f.next = NULL; + f.type = FORMAL_OPTIONAL; + + sb_reset (out); + + idx = sb_skip_comma (idx, in); + if (idx >= in->len) + { + /* Expand once with a null string. */ + err = macro_expand_body (&sub, out, &f, h, 0); + } + else + { + bfd_boolean in_quotes = FALSE; + + if (irpc && in->ptr[idx] == '"') + { + in_quotes = TRUE; + ++idx; + } + + while (idx < in->len) + { + if (!irpc) + idx = get_any_string (idx, in, &f.actual); + else + { + if (in->ptr[idx] == '"') + { + size_t nxt; + + if (irpc) + in_quotes = ! in_quotes; + + nxt = sb_skip_white (idx + 1, in); + if (nxt >= in->len) + { + idx = nxt; + break; + } + } + sb_reset (&f.actual); + sb_add_char (&f.actual, in->ptr[idx]); + ++idx; + } + + err = macro_expand_body (&sub, out, &f, h, 0); + if (err != NULL) + break; + if (!irpc) + idx = sb_skip_comma (idx, in); + else if (! in_quotes) + idx = sb_skip_white (idx, in); + } + } + + hash_die (h); + sb_kill (&f.actual); + sb_kill (&f.def); + sb_kill (&f.name); + sb_kill (&sub); + + return err; +} diff --git a/contrib/toolchain/binutils/gas/macro.h b/contrib/toolchain/binutils/gas/macro.h new file mode 100644 index 0000000000..b109178262 --- /dev/null +++ b/contrib/toolchain/binutils/gas/macro.h @@ -0,0 +1,97 @@ +/* macro.h - header file for macro support for gas + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, + 2007, 2012 Free Software Foundation, Inc. + + Written by Steve and Judy Chamberlain of Cygnus Support, + sac@cygnus.com + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef MACRO_H + +#define MACRO_H + +/* Structures used to store macros. + + Each macro knows its name and included text. It gets built with a + list of formal arguments, and also keeps a hash table which points + into the list to speed up formal search. Each formal knows its + name and its default value. Each time the macro is expanded, the + formals get the actual values attached to them. */ + +enum formal_type + { + FORMAL_OPTIONAL, + FORMAL_REQUIRED, + FORMAL_VARARG + }; + +/* Describe the formal arguments to a macro. */ + +typedef struct formal_struct { + struct formal_struct *next; /* Next formal in list. */ + sb name; /* Name of the formal. */ + sb def; /* The default value. */ + sb actual; /* The actual argument (changed on each expansion). */ + int index; /* The index of the formal 0..formal_count - 1. */ + enum formal_type type; /* The kind of the formal. */ +} formal_entry; + +/* Other values found in the index field of a formal_entry. */ +#define QUAL_INDEX (-1) +#define NARG_INDEX (-2) +#define LOCAL_INDEX (-3) + +/* Describe the macro. */ + +typedef struct macro_struct +{ + sb sub; /* Substitution text. */ + int formal_count; /* Number of formal args. */ + formal_entry *formals; /* Pointer to list of formal_structs. */ + struct hash_control *formal_hash; /* Hash table of formals. */ + const char *name; /* Macro name. */ + char *file; /* File the macro was defined in. */ + unsigned int line; /* Line number of definition. */ +} macro_entry; + +/* Whether any macros have been defined. */ + +extern int macro_defined; + +/* The macro nesting level. */ + +extern int macro_nest; + +/* The macro hash table. */ + +extern struct hash_control *macro_hash; + +extern int buffer_and_nest (const char *, const char *, sb *, + size_t (*) (sb *)); +extern void macro_init (int, int, int, + size_t (*) (const char *, size_t, sb *, offsetT *)); +extern void macro_set_alternate (int); +extern void macro_mri_mode (int); +extern const char *define_macro (size_t, sb *, sb *, size_t (*) (sb *), + char *, unsigned int, const char **); +extern int check_macro (const char *, sb *, const char **, macro_entry **); +extern void delete_macro (const char *); +extern const char *expand_irp (int, size_t, sb *, sb *, size_t (*) (sb *)); + +#endif diff --git a/contrib/toolchain/binutils/gas/messages.c b/contrib/toolchain/binutils/gas/messages.c new file mode 100644 index 0000000000..e1734f2506 --- /dev/null +++ b/contrib/toolchain/binutils/gas/messages.c @@ -0,0 +1,440 @@ +/* messages.c - error reporter - + Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" + +static void identify (char *); +static void as_show_where (void); +static void as_warn_internal (char *, unsigned int, char *); +static void as_bad_internal (char *, unsigned int, char *); + +/* Despite the rest of the comments in this file, (FIXME-SOON), + here is the current scheme for error messages etc: + + as_fatal() is used when gas is quite confused and + continuing the assembly is pointless. In this case we + exit immediately with error status. + + as_bad() is used to mark errors that result in what we + presume to be a useless object file. Say, we ignored + something that might have been vital. If we see any of + these, assembly will continue to the end of the source, + no object file will be produced, and we will terminate + with error status. The new option, -Z, tells us to + produce an object file anyway but we still exit with + error status. The assumption here is that you don't want + this object file but we could be wrong. + + as_warn() is used when we have an error from which we + have a plausible error recovery. eg, masking the top + bits of a constant that is longer than will fit in the + destination. In this case we will continue to assemble + the source, although we may have made a bad assumption, + and we will produce an object file and return normal exit + status (ie, no error). The new option -X tells us to + treat all as_warn() errors as as_bad() errors. That is, + no object file will be produced and we will exit with + error status. The idea here is that we don't kill an + entire make because of an error that we knew how to + correct. On the other hand, sometimes you might want to + stop the make at these points. + + as_tsktsk() is used when we see a minor error for which + our error recovery action is almost certainly correct. + In this case, we print a message and then assembly + continues as though no error occurred. */ + +static void +identify (char *file) +{ + static int identified; + + if (identified) + return; + identified++; + + if (!file) + { + unsigned int x; + as_where (&file, &x); + } + + if (file) + fprintf (stderr, "%s: ", file); + fprintf (stderr, _("Assembler messages:\n")); +} + +/* The number of warnings issued. */ +static int warning_count; + +int +had_warnings (void) +{ + return warning_count; +} + +/* 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; + +int +had_errors (void) +{ + return error_count; +} + +/* Print the current location to stderr. */ + +static void +as_show_where (void) +{ + char *file; + unsigned int line; + + as_where (&file, &line); + identify (file); + if (file) + { + if (line != 0) + fprintf (stderr, "%s:%u: ", file, line); + else + fprintf (stderr, "%s: ", file); + } +} + +/* 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. */ + +void +as_tsktsk (const char *format, ...) +{ + va_list args; + + as_show_where (); + va_start (args, format); + vfprintf (stderr, format, args); + va_end (args); + (void) putc ('\n', stderr); +} + +/* The common portion of as_warn and as_warn_where. */ + +static void +as_warn_internal (char *file, unsigned int line, char *buffer) +{ + ++warning_count; + + if (file == NULL) + as_where (&file, &line); + + identify (file); + if (file) + { + if (line != 0) + fprintf (stderr, "%s:%u: ", file, line); + else + fprintf (stderr, "%s: ", file); + } + fprintf (stderr, _("Warning: ")); + fputs (buffer, stderr); + (void) putc ('\n', stderr); +#ifndef NO_LISTING + listing_warning (buffer); +#endif +} + +/* 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. */ + +void +as_warn (const char *format, ...) +{ + va_list args; + char buffer[2000]; + + if (!flag_no_warnings) + { + va_start (args, format); + vsnprintf (buffer, sizeof (buffer), format, args); + va_end (args); + as_warn_internal ((char *) NULL, 0, buffer); + } +} + +/* 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. */ + +void +as_warn_where (char *file, unsigned int line, const char *format, ...) +{ + va_list args; + char buffer[2000]; + + if (!flag_no_warnings) + { + va_start (args, format); + vsnprintf (buffer, sizeof (buffer), format, args); + va_end (args); + as_warn_internal (file, line, buffer); + } +} + +/* The common portion of as_bad and as_bad_where. */ + +static void +as_bad_internal (char *file, unsigned int line, char *buffer) +{ + ++error_count; + + if (file == NULL) + as_where (&file, &line); + + identify (file); + if (file) + { + if (line != 0) + fprintf (stderr, "%s:%u: ", file, line); + else + fprintf (stderr, "%s: ", file); + } + fprintf (stderr, _("Error: ")); + fputs (buffer, stderr); + (void) putc ('\n', stderr); +#ifndef NO_LISTING + listing_error (buffer); +#endif +} + +/* 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. */ + +void +as_bad (const char *format, ...) +{ + va_list args; + char buffer[2000]; + + va_start (args, format); + vsnprintf (buffer, sizeof (buffer), format, args); + va_end (args); + + as_bad_internal ((char *) NULL, 0, buffer); +} + +/* 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. */ + +void +as_bad_where (char *file, unsigned int line, const char *format, ...) +{ + va_list args; + char buffer[2000]; + + va_start (args, format); + vsnprintf (buffer, sizeof (buffer), format, args); + va_end (args); + + as_bad_internal (file, line, buffer); +} + +/* 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 xexit()s with a warning status. */ + +void +as_fatal (const char *format, ...) +{ + 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); + /* Delete the output file, if it exists. This will prevent make from + thinking that a file was created and hence does not need rebuilding. */ + if (out_file_name != NULL) + unlink_if_ordinary (out_file_name); + xexit (EXIT_FAILURE); +} + +/* Indicate assertion failure. + Arguments: Filename, line number, optional function name. */ + +void +as_assert (const char *file, int line, const char *fn) +{ + as_show_where (); + fprintf (stderr, _("Internal error!\n")); + if (fn) + fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), + fn, file, line); + else + fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); + fprintf (stderr, _("Please report this bug.\n")); + xexit (EXIT_FAILURE); +} + +/* as_abort: Print a friendly message saying how totally hosed we are, + and exit without producing a core file. */ + +void +as_abort (const char *file, int line, const char *fn) +{ + as_show_where (); + if (fn) + fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), + file, line, fn); + else + fprintf (stderr, _("Internal error, aborting at %s line %d\n"), + file, line); + fprintf (stderr, _("Please report this bug.\n")); + xexit (EXIT_FAILURE); +} + +/* Support routines. */ + +void +sprint_value (char *buf, valueT val) +{ + if (sizeof (val) <= sizeof (long)) + { + sprintf (buf, "%ld", (long) val); + return; + } + if (sizeof (val) <= sizeof (bfd_vma)) + { + sprintf_vma (buf, val); + return; + } + abort (); +} + +#define HEX_MAX_THRESHOLD 1024 +#define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD) + +static void +as_internal_value_out_of_range (char * prefix, + offsetT val, + offsetT min, + offsetT max, + char * file, + unsigned line, + int bad) +{ + const char * err; + + if (prefix == NULL) + prefix = ""; + + if (val >= min && val <= max) + { + addressT right = max & -max; + + if (max <= 1) + abort (); + + /* xgettext:c-format */ + err = _("%s out of domain (%d is not a multiple of %d)"); + if (bad) + as_bad_where (file, line, err, + prefix, (int) val, (int) right); + else + as_warn_where (file, line, err, + prefix, (int) val, (int) right); + return; + } + + if ( val < HEX_MAX_THRESHOLD + && min < HEX_MAX_THRESHOLD + && max < HEX_MAX_THRESHOLD + && val > HEX_MIN_THRESHOLD + && min > HEX_MIN_THRESHOLD + && max > HEX_MIN_THRESHOLD) + { + /* xgettext:c-format */ + err = _("%s out of range (%d is not between %d and %d)"); + + if (bad) + as_bad_where (file, line, err, + prefix, (int) val, (int) min, (int) max); + else + as_warn_where (file, line, err, + prefix, (int) val, (int) min, (int) max); + } + else + { + char val_buf [sizeof (val) * 3 + 2]; + char min_buf [sizeof (val) * 3 + 2]; + char max_buf [sizeof (val) * 3 + 2]; + + if (sizeof (val) > sizeof (bfd_vma)) + abort (); + + sprintf_vma (val_buf, (bfd_vma) val); + sprintf_vma (min_buf, (bfd_vma) min); + sprintf_vma (max_buf, (bfd_vma) max); + + /* xgettext:c-format. */ + err = _("%s out of range (0x%s is not between 0x%s and 0x%s)"); + + if (bad) + as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf); + else + as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf); + } +} + +void +as_warn_value_out_of_range (char * prefix, + offsetT value, + offsetT min, + offsetT max, + char * file, + unsigned line) +{ + as_internal_value_out_of_range (prefix, value, min, max, file, line, 0); +} + +void +as_bad_value_out_of_range (char * prefix, + offsetT value, + offsetT min, + offsetT max, + char * file, + unsigned line) +{ + as_internal_value_out_of_range (prefix, value, min, max, file, line, 1); +} diff --git a/contrib/toolchain/binutils/gas/obj-format.h b/contrib/toolchain/binutils/gas/obj-format.h new file mode 100644 index 0000000000..53f9f60e7f --- /dev/null +++ b/contrib/toolchain/binutils/gas/obj-format.h @@ -0,0 +1 @@ +#include "obj-coff.h" diff --git a/contrib/toolchain/binutils/gas/obj.h b/contrib/toolchain/binutils/gas/obj.h new file mode 100644 index 0000000000..c2d4836a62 --- /dev/null +++ b/contrib/toolchain/binutils/gas/obj.h @@ -0,0 +1,87 @@ +/* obj.h - defines the object dependent hooks for all object + format backends. + + Copyright 1987, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1999, 2000, + 2002, 2003, 2004, 2005, 2007, 2009, 2010 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +char *obj_default_output_file_name (void); +void obj_emit_relocations (char **where, fixS * fixP, + relax_addressT segment_address_in_file); +void obj_emit_strings (char **where); +void obj_emit_symbols (char **where, symbolS * symbols); +#ifndef obj_read_begin_hook +void obj_read_begin_hook (void); +#endif + +#ifndef obj_symbol_new_hook +void obj_symbol_new_hook (symbolS * symbolP); +#endif + +void obj_symbol_to_chars (char **where, symbolS * symbolP); + +extern const pseudo_typeS obj_pseudo_table[]; + +struct format_ops { + int flavor; + unsigned dfl_leading_underscore : 1; + unsigned emit_section_symbols : 1; + void (*begin) (void); + void (*app_file) (const char *, int); + void (*frob_symbol) (symbolS *, int *); + void (*frob_file) (void); + void (*frob_file_before_adjust) (void); + void (*frob_file_before_fix) (void); + void (*frob_file_after_relocs) (void); + bfd_vma (*s_get_size) (symbolS *); + void (*s_set_size) (symbolS *, bfd_vma); + bfd_vma (*s_get_align) (symbolS *); + void (*s_set_align) (symbolS *, bfd_vma); + int (*s_get_other) (symbolS *); + void (*s_set_other) (symbolS *, int); + int (*s_get_desc) (symbolS *); + void (*s_set_desc) (symbolS *, int); + int (*s_get_type) (symbolS *); + void (*s_set_type) (symbolS *, int); + void (*copy_symbol_attributes) (symbolS *, symbolS *); + void (*generate_asm_lineno) (void); + void (*process_stab) (segT, int, const char *, int, int, int); + int (*separate_stab_sections) (void); + void (*init_stab_section) (segT); + int (*sec_sym_ok_for_reloc) (asection *); + void (*pop_insert) (void); + /* For configurations using ECOFF_DEBUGGING, this callback is used. */ + void (*ecoff_set_ext) (symbolS *, struct ecoff_extr *); + + void (*read_begin_hook) (void); + void (*symbol_new_hook) (symbolS *); + void (*symbol_clone_hook) (symbolS *, symbolS *); + void (*adjust_symtab) (void); +}; + +extern const struct format_ops elf_format_ops; +extern const struct format_ops ecoff_format_ops; +extern const struct format_ops coff_format_ops; +extern const struct format_ops aout_format_ops; + +#ifndef this_format +COMMON const struct format_ops *this_format; +#endif + +/* end of obj.h */ diff --git a/contrib/toolchain/binutils/gas/output-file.c b/contrib/toolchain/binutils/gas/output-file.c new file mode 100644 index 0000000000..25bd291d98 --- /dev/null +++ b/contrib/toolchain/binutils/gas/output-file.c @@ -0,0 +1,74 @@ +/* output-file.c - Deal with the output file + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2001, + 2003, 2004, 2005, 2006, 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "output-file.h" + +#ifndef TARGET_MACH +#define TARGET_MACH 0 +#endif + +bfd *stdoutput; + +void +output_file_create (char *name) +{ + if (name[0] == '-' && name[1] == '\0') + as_fatal (_("can't open a bfd on stdout %s"), name); + + else if (!(stdoutput = bfd_openw (name, TARGET_FORMAT))) + { + bfd_error_type err = bfd_get_error (); + + if (err == bfd_error_invalid_target) + as_fatal (_("selected target format '%s' unknown"), TARGET_FORMAT); + else + as_fatal (_("can't create %s: %s"), name, bfd_errmsg (err)); + } + + bfd_set_format (stdoutput, bfd_object); + bfd_set_arch_mach (stdoutput, TARGET_ARCH, TARGET_MACH); + if (flag_traditional_format) + stdoutput->flags |= BFD_TRADITIONAL_FORMAT; +} + +void +output_file_close (char *filename) +{ + bfd_boolean res; + + if (stdoutput == NULL) + return; + + /* Close the bfd. */ + if (had_errors ()) + res = bfd_cache_close_all (); + else + res = bfd_close (stdoutput); + + /* Prevent an infinite loop - if the close failed we will call as_fatal + which will call xexit() which may call this function again... */ + stdoutput = NULL; + + if (! res) + as_fatal (_("can't close %s: %s"), filename, + bfd_errmsg (bfd_get_error ())); +} diff --git a/contrib/toolchain/binutils/gas/output-file.h b/contrib/toolchain/binutils/gas/output-file.h new file mode 100644 index 0000000000..d276d28e62 --- /dev/null +++ b/contrib/toolchain/binutils/gas/output-file.h @@ -0,0 +1,26 @@ +/* This file is output-file.h + + Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2003, 2005, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +void output_file_append (char *where, long length, char *filename); +void output_file_close (char *filename); +void output_file_create (char *name); + +/* end of output-file.h */ diff --git a/contrib/toolchain/binutils/gas/read.c b/contrib/toolchain/binutils/gas/read.c new file mode 100644 index 0000000000..082670c445 --- /dev/null +++ b/contrib/toolchain/binutils/gas/read.c @@ -0,0 +1,6107 @@ +/* read.c - read a source file - + Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* If your chars aren't 8 bits, you will change this a bit (eg. to 0xFF). + But then, GNU isn't spozed to run on your machine anyway. + (RMS is so shortsighted sometimes.) */ +#define MASK_CHAR ((int)(unsigned char) -1) + +/* This is the largest known floating point format (for now). It will + grow when we do 4361 style flonums. */ +#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16) + +/* Routines that read assembler source text to build spaghetti in memory. + Another group of these functions is in the expr.c module. */ + +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "sb.h" +#include "macro.h" +#include "obstack.h" +#include "ecoff.h" +#include "dw2gencfi.h" +#include "wchar.h" + +#ifndef TC_START_LABEL +#define TC_START_LABEL(x,y,z) (x == ':') +#endif + +/* Set by the object-format or the target. */ +#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT +#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \ + do \ + { \ + if ((SIZE) >= 8) \ + (P2VAR) = 3; \ + else if ((SIZE) >= 4) \ + (P2VAR) = 2; \ + else if ((SIZE) >= 2) \ + (P2VAR) = 1; \ + else \ + (P2VAR) = 0; \ + } \ + while (0) +#endif + +char *input_line_pointer; /*->next char of source file to parse. */ + +#if BITS_PER_CHAR != 8 +/* The following table is indexed by[(char)] and will break if + a char does not have exactly 256 states (hopefully 0:255!)! */ +die horribly; +#endif + +#ifndef LEX_AT +#define LEX_AT 0 +#endif + +#ifndef LEX_BR +/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */ +#define LEX_BR 0 +#endif + +#ifndef LEX_PCT +/* The Delta 68k assembler permits % inside label names. */ +#define LEX_PCT 0 +#endif + +#ifndef LEX_QM +/* The PowerPC Windows NT assemblers permits ? inside label names. */ +#define LEX_QM 0 +#endif + +#ifndef LEX_HASH +/* The IA-64 assembler uses # as a suffix designating a symbol. We include + it in the symbol and strip it out in tc_canonicalize_symbol_name. */ +#define LEX_HASH 0 +#endif + +#ifndef LEX_DOLLAR +#define LEX_DOLLAR 3 +#endif + +#ifndef LEX_TILDE +/* The Delta 68k assembler permits ~ at start of label names. */ +#define LEX_TILDE 0 +#endif + +/* Used by is_... macros. our ctype[]. */ +char lex_type[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */ + 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */ + LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */ + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; + +/* In: a character. + Out: 1 if this character ends a line. + 2 if this character is a line separator. */ +char is_end_of_line[256] = { +#ifdef CR_EOL + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, /* @abcdefghijklmno */ +#else + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* @abcdefghijklmno */ +#endif + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* _!"#$%&'()*+,-./ */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* */ +}; + +#ifndef TC_CASE_SENSITIVE +char original_case_string[128]; +#endif + +/* Functions private to this file. */ + +static char *buffer; /* 1st char of each buffer of lines is here. */ +static char *buffer_limit; /*->1 + last char in buffer. */ + +/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 + in the tc-.h file. See the "Porting GAS" section of the + internals manual. */ +int target_big_endian = TARGET_BYTES_BIG_ENDIAN; + +/* Variables for handling include file directory table. */ + +/* Table of pointers to directories to search for .include's. */ +char **include_dirs; + +/* How many are in the table. */ +int include_dir_count; + +/* Length of longest in table. */ +int include_dir_maxlen = 1; + +#ifndef WORKING_DOT_WORD +struct broken_word *broken_words; +int new_broken_words; +#endif + +/* The current offset into the absolute section. We don't try to + build frags in the absolute section, since no data can be stored + there. We just keep track of the current offset. */ +addressT abs_section_offset; + +/* If this line had an MRI style label, it is stored in this variable. + This is used by some of the MRI pseudo-ops. */ +symbolS *line_label; + +/* This global variable is used to support MRI common sections. We + translate such sections into a common symbol. This variable is + non-NULL when we are in an MRI common section. */ +symbolS *mri_common_symbol; + +/* In MRI mode, after a dc.b pseudo-op with an odd number of bytes, we + need to align to an even byte boundary unless the next pseudo-op is + dc.b, ds.b, or dcb.b. This variable is set to 1 if an alignment + may be needed. */ +static int mri_pending_align; + +#ifndef NO_LISTING +#ifdef OBJ_ELF +/* This variable is set to be non-zero if the next string we see might + be the name of the source file in DWARF debugging information. See + the comment in emit_expr for the format we look for. */ +static int dwarf_file_string; +#endif +#endif + +/* If the target defines the md_frag_max_var hook then we know + enough to implement the .bundle_align_mode features. */ +#ifdef md_frag_max_var +# define HANDLE_BUNDLE +#endif + +#ifdef HANDLE_BUNDLE +/* .bundle_align_mode sets this. Normally it's zero. When nonzero, + it's the exponent of the bundle size, and aligned instruction bundle + mode is in effect. */ +static unsigned int bundle_align_p2; + +/* These are set by .bundle_lock and .bundle_unlock. .bundle_lock sets + bundle_lock_frag to frag_now and then starts a new frag with + frag_align_code. At the same time, bundle_lock_frain gets frchain_now, + so that .bundle_unlock can verify that we didn't change segments. + .bundle_unlock resets both to NULL. If we detect a bundling violation, + then we reset bundle_lock_frchain to NULL as an indicator that we've + already diagnosed the error with as_bad and don't need a cascade of + redundant errors, but bundle_lock_frag remains set to indicate that + we are expecting to see .bundle_unlock. */ +static fragS *bundle_lock_frag; +static frchainS *bundle_lock_frchain; + +/* This is incremented by .bundle_lock and decremented by .bundle_unlock, + to allow nesting. */ +static unsigned int bundle_lock_depth; +#endif + +static void do_s_func (int end_p, const char *default_prefix); +static void do_align (int, char *, int, int); +static void s_align (int, int); +static void s_altmacro (int); +static void s_bad_end (int); +static void s_reloc (int); +static int hex_float (int, char *); +static segT get_known_segmented_expression (expressionS * expP); +static void pobegin (void); +static size_t get_non_macro_line_sb (sb *); +static void generate_file_debug (void); +static char *_find_end_of_line (char *, int, int, int); + +void +read_begin (void) +{ + const char *p; + + pobegin (); + obj_read_begin_hook (); + + /* Something close -- but not too close -- to a multiple of 1024. + The debugging malloc I'm using has 24 bytes of overhead. */ + obstack_begin (¬es, chunksize); + obstack_begin (&cond_obstack, chunksize); + + /* Use machine dependent syntax. */ + for (p = line_separator_chars; *p; p++) + is_end_of_line[(unsigned char) *p] = 2; + /* Use more. FIXME-SOMEDAY. */ + + if (flag_mri) + lex_type['?'] = 3; +} + +#ifndef TC_ADDRESS_BYTES +#define TC_ADDRESS_BYTES address_bytes + +static inline int +address_bytes (void) +{ + /* Choose smallest of 1, 2, 4, 8 bytes that is large enough to + contain an address. */ + int n = (stdoutput->arch_info->bits_per_address - 1) / 8; + n |= n >> 1; + n |= n >> 2; + n += 1; + return n; +} +#endif + +/* Set up pseudo-op tables. */ + +static struct hash_control *po_hash; + +static const pseudo_typeS potable[] = { + {"abort", s_abort, 0}, + {"align", s_align_ptwo, 0}, + {"altmacro", s_altmacro, 1}, + {"ascii", stringer, 8+0}, + {"asciz", stringer, 8+1}, + {"balign", s_align_bytes, 0}, + {"balignw", s_align_bytes, -2}, + {"balignl", s_align_bytes, -4}, +/* block */ +#ifdef HANDLE_BUNDLE + {"bundle_align_mode", s_bundle_align_mode, 0}, + {"bundle_lock", s_bundle_lock, 0}, + {"bundle_unlock", s_bundle_unlock, 0}, +#endif + {"byte", cons, 1}, + {"comm", s_comm, 0}, + {"common", s_mri_common, 0}, + {"common.s", s_mri_common, 1}, + {"data", s_data, 0}, + {"dc", cons, 2}, +#ifdef TC_ADDRESS_BYTES + {"dc.a", cons, 0}, +#endif + {"dc.b", cons, 1}, + {"dc.d", float_cons, 'd'}, + {"dc.l", cons, 4}, + {"dc.s", float_cons, 'f'}, + {"dc.w", cons, 2}, + {"dc.x", float_cons, 'x'}, + {"dcb", s_space, 2}, + {"dcb.b", s_space, 1}, + {"dcb.d", s_float_space, 'd'}, + {"dcb.l", s_space, 4}, + {"dcb.s", s_float_space, 'f'}, + {"dcb.w", s_space, 2}, + {"dcb.x", s_float_space, 'x'}, + {"ds", s_space, 2}, + {"ds.b", s_space, 1}, + {"ds.d", s_space, 8}, + {"ds.l", s_space, 4}, + {"ds.p", s_space, 12}, + {"ds.s", s_space, 4}, + {"ds.w", s_space, 2}, + {"ds.x", s_space, 12}, + {"debug", s_ignore, 0}, +#ifdef S_SET_DESC + {"desc", s_desc, 0}, +#endif +/* dim */ + {"double", float_cons, 'd'}, +/* dsect */ + {"eject", listing_eject, 0}, /* Formfeed listing. */ + {"else", s_else, 0}, + {"elsec", s_else, 0}, + {"elseif", s_elseif, (int) O_ne}, + {"end", s_end, 0}, + {"endc", s_endif, 0}, + {"endfunc", s_func, 1}, + {"endif", s_endif, 0}, + {"endm", s_bad_end, 0}, + {"endr", s_bad_end, 1}, +/* endef */ + {"equ", s_set, 0}, + {"equiv", s_set, 1}, + {"eqv", s_set, -1}, + {"err", s_err, 0}, + {"error", s_errwarn, 1}, + {"exitm", s_mexit, 0}, +/* extend */ + {"extern", s_ignore, 0}, /* We treat all undef as ext. */ + {"appfile", s_app_file, 1}, + {"appline", s_app_line, 1}, + {"fail", s_fail, 0}, + {"file", s_app_file, 0}, + {"fill", s_fill, 0}, + {"float", float_cons, 'f'}, + {"format", s_ignore, 0}, + {"func", s_func, 0}, + {"global", s_globl, 0}, + {"globl", s_globl, 0}, + {"hword", cons, 2}, + {"if", s_if, (int) O_ne}, + {"ifb", s_ifb, 1}, + {"ifc", s_ifc, 0}, + {"ifdef", s_ifdef, 0}, + {"ifeq", s_if, (int) O_eq}, + {"ifeqs", s_ifeqs, 0}, + {"ifge", s_if, (int) O_ge}, + {"ifgt", s_if, (int) O_gt}, + {"ifle", s_if, (int) O_le}, + {"iflt", s_if, (int) O_lt}, + {"ifnb", s_ifb, 0}, + {"ifnc", s_ifc, 1}, + {"ifndef", s_ifdef, 1}, + {"ifne", s_if, (int) O_ne}, + {"ifnes", s_ifeqs, 1}, + {"ifnotdef", s_ifdef, 1}, + {"incbin", s_incbin, 0}, + {"include", s_include, 0}, + {"int", cons, 4}, + {"irp", s_irp, 0}, + {"irep", s_irp, 0}, + {"irpc", s_irp, 1}, + {"irepc", s_irp, 1}, + {"lcomm", s_lcomm, 0}, + {"lflags", s_ignore, 0}, /* Listing flags. */ + {"linefile", s_app_line, 0}, + {"linkonce", s_linkonce, 0}, + {"list", listing_list, 1}, /* Turn listing on. */ + {"llen", listing_psize, 1}, + {"long", cons, 4}, + {"lsym", s_lsym, 0}, + {"macro", s_macro, 0}, + {"mexit", s_mexit, 0}, + {"mri", s_mri, 0}, + {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */ + {"name", s_ignore, 0}, + {"noaltmacro", s_altmacro, 0}, + {"noformat", s_ignore, 0}, + {"nolist", listing_list, 0}, /* Turn listing off. */ + {"nopage", listing_nopage, 0}, + {"octa", cons, 16}, + {"offset", s_struct, 0}, + {"org", s_org, 0}, + {"p2align", s_align_ptwo, 0}, + {"p2alignw", s_align_ptwo, -2}, + {"p2alignl", s_align_ptwo, -4}, + {"page", listing_eject, 0}, + {"plen", listing_psize, 0}, + {"print", s_print, 0}, + {"psize", listing_psize, 0}, /* Set paper size. */ + {"purgem", s_purgem, 0}, + {"quad", cons, 8}, + {"reloc", s_reloc, 0}, + {"rep", s_rept, 0}, + {"rept", s_rept, 0}, + {"rva", s_rva, 4}, + {"sbttl", listing_title, 1}, /* Subtitle of listing. */ +/* scl */ +/* sect */ + {"set", s_set, 0}, + {"short", cons, 2}, + {"single", float_cons, 'f'}, +/* size */ + {"space", s_space, 0}, + {"skip", s_space, 0}, + {"sleb128", s_leb128, 1}, + {"spc", s_ignore, 0}, + {"stabd", s_stab, 'd'}, + {"stabn", s_stab, 'n'}, + {"stabs", s_stab, 's'}, + {"string", stringer, 8+1}, + {"string8", stringer, 8+1}, + {"string16", stringer, 16+1}, + {"string32", stringer, 32+1}, + {"string64", stringer, 64+1}, + {"struct", s_struct, 0}, +/* tag */ + {"text", s_text, 0}, + + /* This is for gcc to use. It's only just been added (2/94), so gcc + won't be able to use it for a while -- probably a year or more. + But once this has been released, check with gcc maintainers + before deleting it or even changing the spelling. */ + {"this_GCC_requires_the_GNU_assembler", s_ignore, 0}, + /* If we're folding case -- done for some targets, not necessarily + all -- the above string in an input file will be converted to + this one. Match it either way... */ + {"this_gcc_requires_the_gnu_assembler", s_ignore, 0}, + + {"title", listing_title, 0}, /* Listing title. */ + {"ttl", listing_title, 0}, +/* type */ + {"uleb128", s_leb128, 0}, +/* use */ +/* val */ + {"xcom", s_comm, 0}, + {"xdef", s_globl, 0}, + {"xref", s_ignore, 0}, + {"xstabs", s_xstab, 's'}, + {"warning", s_errwarn, 0}, + {"weakref", s_weakref, 0}, + {"word", cons, 2}, + {"zero", s_space, 0}, + {NULL, NULL, 0} /* End sentinel. */ +}; + +static offsetT +get_absolute_expr (expressionS *exp) +{ + expression_and_evaluate (exp); + if (exp->X_op != O_constant) + { + if (exp->X_op != O_absent) + as_bad (_("bad or irreducible absolute expression")); + exp->X_add_number = 0; + } + return exp->X_add_number; +} + +offsetT +get_absolute_expression (void) +{ + expressionS exp; + + return get_absolute_expr (&exp); +} + +static int pop_override_ok = 0; +static const char *pop_table_name; + +void +pop_insert (const pseudo_typeS *table) +{ + const char *errtxt; + const pseudo_typeS *pop; + for (pop = table; pop->poc_name; pop++) + { + errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop); + if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists"))) + as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name, + errtxt); + } +} + +#ifndef md_pop_insert +#define md_pop_insert() pop_insert(md_pseudo_table) +#endif + +#ifndef obj_pop_insert +#define obj_pop_insert() pop_insert(obj_pseudo_table) +#endif + +#ifndef cfi_pop_insert +#define cfi_pop_insert() pop_insert(cfi_pseudo_table) +#endif + +static void +pobegin (void) +{ + po_hash = hash_new (); + + /* Do the target-specific pseudo ops. */ + pop_table_name = "md"; + md_pop_insert (); + + /* Now object specific. Skip any that were in the target table. */ + pop_table_name = "obj"; + pop_override_ok = 1; + obj_pop_insert (); + + /* Now portable ones. Skip any that we've seen already. */ + pop_table_name = "standard"; + pop_insert (potable); + + /* Now CFI ones. */ + pop_table_name = "cfi"; + pop_override_ok = 1; + cfi_pop_insert (); +} + +#define HANDLE_CONDITIONAL_ASSEMBLY() \ + if (ignore_input ()) \ + { \ + char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \ + input_line_pointer = (input_line_pointer <= buffer_limit \ + && eol >= buffer_limit) \ + ? buffer_limit \ + : eol + 1; \ + continue; \ + } + +/* This function is used when scrubbing the characters between #APP + and #NO_APP. */ + +static char *scrub_string; +static char *scrub_string_end; + +static size_t +scrub_from_string (char *buf, size_t buflen) +{ + size_t copy; + + copy = scrub_string_end - scrub_string; + if (copy > buflen) + copy = buflen; + memcpy (buf, scrub_string, copy); + scrub_string += copy; + return copy; +} + +/* Helper function of read_a_source_file, which tries to expand a macro. */ +static int +try_macro (char term, const char *line) +{ + sb out; + const char *err; + macro_entry *macro; + + if (check_macro (line, &out, &err, ¯o)) + { + if (err != NULL) + as_bad ("%s", err); + *input_line_pointer++ = term; + input_scrub_include_sb (&out, + input_line_pointer, 1); + sb_kill (&out); + buffer_limit = + input_scrub_next_buffer (&input_line_pointer); +#ifdef md_macro_info + md_macro_info (macro); +#endif + return 1; + } + return 0; +} + +#ifdef HANDLE_BUNDLE +/* Start a new instruction bundle. Returns the rs_align_code frag that + will be used to align the new bundle. */ +static fragS * +start_bundle (void) +{ + fragS *frag = frag_now; + + frag_align_code (0, 0); + + while (frag->fr_type != rs_align_code) + frag = frag->fr_next; + + gas_assert (frag != frag_now); + + return frag; +} + +/* Calculate the maximum size after relaxation of the region starting + at the given frag and extending through frag_now (which is unfinished). */ +static unsigned int +pending_bundle_size (fragS *frag) +{ + unsigned int offset = frag->fr_fix; + unsigned int size = 0; + + gas_assert (frag != frag_now); + gas_assert (frag->fr_type == rs_align_code); + + while (frag != frag_now) + { + /* This should only happen in what will later become an error case. */ + if (frag == NULL) + return 0; + + size += frag->fr_fix; + if (frag->fr_type == rs_machine_dependent) + size += md_frag_max_var (frag); + + frag = frag->fr_next; + } + + gas_assert (frag == frag_now); + size += frag_now_fix (); + if (frag->fr_type == rs_machine_dependent) + size += md_frag_max_var (frag); + + gas_assert (size >= offset); + + return size - offset; +} + +/* Finish off the frag created to ensure bundle alignment. */ +static void +finish_bundle (fragS *frag, unsigned int size) +{ + gas_assert (bundle_align_p2 > 0); + gas_assert (frag->fr_type == rs_align_code); + + if (size > 1) + { + /* If there is more than a single byte, then we need to set up the + alignment frag. Otherwise we leave it at its initial state from + calling frag_align_code (0, 0), so that it does nothing. */ + frag->fr_offset = bundle_align_p2; + frag->fr_subtype = size - 1; + } + + /* We do this every time rather than just in s_bundle_align_mode + so that we catch any affected section without needing hooks all + over for all paths that do section changes. It's cheap enough. */ + record_alignment (now_seg, bundle_align_p2 - OCTETS_PER_BYTE_POWER); +} + +/* Assemble one instruction. This takes care of the bundle features + around calling md_assemble. */ +static void +assemble_one (char *line) +{ + fragS *insn_start_frag = NULL; + + if (bundle_lock_frchain != NULL && bundle_lock_frchain != frchain_now) + { + as_bad (_("cannot change section or subsection inside .bundle_lock")); + /* Clearing this serves as a marker that we have already complained. */ + bundle_lock_frchain = NULL; + } + + if (bundle_lock_frchain == NULL && bundle_align_p2 > 0) + insn_start_frag = start_bundle (); + + md_assemble (line); + + if (bundle_lock_frchain != NULL) + { + /* Make sure this hasn't pushed the locked sequence + past the bundle size. */ + unsigned int bundle_size = pending_bundle_size (bundle_lock_frag); + if (bundle_size > (1U << bundle_align_p2)) + as_bad (_("\ +.bundle_lock sequence at %u bytes but .bundle_align_mode limit is %u bytes"), + bundle_size, 1U << bundle_align_p2); + } + else if (bundle_align_p2 > 0) + { + unsigned int insn_size = pending_bundle_size (insn_start_frag); + + if (insn_size > (1U << bundle_align_p2)) + as_bad (_("\ +single instruction is %u bytes long but .bundle_align_mode limit is %u"), + (unsigned int) insn_size, 1U << bundle_align_p2); + + finish_bundle (insn_start_frag, insn_size); + } +} + +#else /* !HANDLE_BUNDLE */ + +# define assemble_one(line) md_assemble(line) + +#endif /* HANDLE_BUNDLE */ + +/* We read the file, putting things into a web that represents what we + have been reading. */ +void +read_a_source_file (char *name) +{ + char c; + char *s; /* String of symbol, '\0' appended. */ + int temp; + pseudo_typeS *pop; + +#ifdef WARN_COMMENTS + found_comment = 0; +#endif + + buffer = input_scrub_new_file (name); + + listing_file (name); + listing_newline (NULL); + register_dependency (name); + + /* Generate debugging information before we've read anything in to denote + this file as the "main" source file and not a subordinate one + (e.g. N_SO vs N_SOL in stabs). */ + generate_file_debug (); + + while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0) + { /* We have another line to parse. */ +#ifndef NO_LISTING + /* In order to avoid listing macro expansion lines with labels + multiple times, keep track of which line was last issued. */ + static char *last_eol; + + last_eol = NULL; +#endif + while (input_line_pointer < buffer_limit) + { + bfd_boolean was_new_line; + /* We have more of this buffer to parse. */ + + /* We now have input_line_pointer->1st char of next line. + If input_line_pointer [-1] == '\n' then we just + scanned another line: so bump line counters. */ + was_new_line = is_end_of_line[(unsigned char) input_line_pointer[-1]]; + if (was_new_line) + { + symbol_set_value_now (&dot_symbol); +#ifdef md_start_line_hook + md_start_line_hook (); +#endif + if (input_line_pointer[-1] == '\n') + bump_line_counters (); + } + +#ifndef NO_LISTING + /* If listing is on, and we are expanding a macro, then give + the listing code the contents of the expanded line. */ + if (listing) + { + if ((listing & LISTING_MACEXP) && macro_nest > 0) + { + /* Find the end of the current expanded macro line. */ + s = find_end_of_line (input_line_pointer, flag_m68k_mri); + + if (s != last_eol) + { + char *copy; + int len; + + last_eol = s; + /* Copy it for safe keeping. Also give an indication of + how much macro nesting is involved at this point. */ + len = s - input_line_pointer; + copy = (char *) xmalloc (len + macro_nest + 2); + memset (copy, '>', macro_nest); + copy[macro_nest] = ' '; + memcpy (copy + macro_nest + 1, input_line_pointer, len); + copy[macro_nest + 1 + len] = '\0'; + + /* Install the line with the listing facility. */ + listing_newline (copy); + } + } + else + listing_newline (NULL); + } +#endif + if (was_new_line) + { + line_label = NULL; + + if (LABELS_WITHOUT_COLONS || flag_m68k_mri) + { + /* Text at the start of a line must be a label, we + run down and stick a colon in. */ + if (is_name_beginner (*input_line_pointer)) + { + char *line_start = input_line_pointer; + int mri_line_macro; + + HANDLE_CONDITIONAL_ASSEMBLY (); + + c = get_symbol_end (); + + /* In MRI mode, the EQU and MACRO pseudoops must + be handled specially. */ + mri_line_macro = 0; + if (flag_m68k_mri) + { + char *rest = input_line_pointer + 1; + + if (*rest == ':') + ++rest; + if (*rest == ' ' || *rest == '\t') + ++rest; + if ((strncasecmp (rest, "EQU", 3) == 0 + || strncasecmp (rest, "SET", 3) == 0) + && (rest[3] == ' ' || rest[3] == '\t')) + { + input_line_pointer = rest + 3; + equals (line_start, + strncasecmp (rest, "SET", 3) == 0); + continue; + } + if (strncasecmp (rest, "MACRO", 5) == 0 + && (rest[5] == ' ' + || rest[5] == '\t' + || is_end_of_line[(unsigned char) rest[5]])) + mri_line_macro = 1; + } + + /* In MRI mode, we need to handle the MACRO + pseudo-op specially: we don't want to put the + symbol in the symbol table. */ + if (!mri_line_macro +#ifdef TC_START_LABEL_WITHOUT_COLON + && TC_START_LABEL_WITHOUT_COLON(c, + input_line_pointer) +#endif + ) + line_label = colon (line_start); + else + line_label = symbol_create (line_start, + absolute_section, + (valueT) 0, + &zero_address_frag); + + *input_line_pointer = c; + if (c == ':') + input_line_pointer++; + } + } + } + + /* We are at the beginning of a line, or similar place. + We expect a well-formed assembler statement. + A "symbol-name:" is a statement. + + Depending on what compiler is used, the order of these tests + may vary to catch most common case 1st. + Each test is independent of all other tests at the (top) + level. */ + do + c = *input_line_pointer++; + while (c == '\t' || c == ' ' || c == '\f'); + + /* C is the 1st significant character. + Input_line_pointer points after that character. */ + if (is_name_beginner (c)) + { + /* Want user-defined label or pseudo/opcode. */ + HANDLE_CONDITIONAL_ASSEMBLY (); + + s = --input_line_pointer; + c = get_symbol_end (); /* name's delimiter. */ + + /* C is character after symbol. + That character's place in the input line is now '\0'. + S points to the beginning of the symbol. + [In case of pseudo-op, s->'.'.] + Input_line_pointer->'\0' where c was. */ + if (TC_START_LABEL (c, s, input_line_pointer)) + { + if (flag_m68k_mri) + { + char *rest = input_line_pointer + 1; + + /* In MRI mode, \tsym: set 0 is permitted. */ + if (*rest == ':') + ++rest; + + if (*rest == ' ' || *rest == '\t') + ++rest; + + if ((strncasecmp (rest, "EQU", 3) == 0 + || strncasecmp (rest, "SET", 3) == 0) + && (rest[3] == ' ' || rest[3] == '\t')) + { + input_line_pointer = rest + 3; + equals (s, 1); + continue; + } + } + + line_label = colon (s); /* User-defined label. */ + /* Put ':' back for error messages' sake. */ + *input_line_pointer++ = ':'; +#ifdef tc_check_label + tc_check_label (line_label); +#endif + /* Input_line_pointer->after ':'. */ + SKIP_WHITESPACE (); + } + else if ((c == '=' && input_line_pointer[1] == '=') + || ((c == ' ' || c == '\t') + && input_line_pointer[1] == '=' + && input_line_pointer[2] == '=')) + { + equals (s, -1); + demand_empty_rest_of_line (); + } + else if ((c == '=' + || ((c == ' ' || c == '\t') + && input_line_pointer[1] == '=')) +#ifdef TC_EQUAL_IN_INSN + && !TC_EQUAL_IN_INSN (c, s) +#endif + ) + { + equals (s, 1); + demand_empty_rest_of_line (); + } + else + { + /* Expect pseudo-op or machine instruction. */ + pop = NULL; + +#ifndef TC_CASE_SENSITIVE + { + char *s2 = s; + + strncpy (original_case_string, s2, sizeof (original_case_string)); + original_case_string[sizeof (original_case_string) - 1] = 0; + + while (*s2) + { + *s2 = TOLOWER (*s2); + s2++; + } + } +#endif + if (NO_PSEUDO_DOT || flag_m68k_mri) + { + /* The MRI assembler uses pseudo-ops without + a period. */ + pop = (pseudo_typeS *) hash_find (po_hash, s); + if (pop != NULL && pop->poc_handler == NULL) + pop = NULL; + } + + if (pop != NULL + || (!flag_m68k_mri && *s == '.')) + { + /* PSEUDO - OP. + + WARNING: c has next char, which may be end-of-line. + We lookup the pseudo-op table with s+1 because we + already know that the pseudo-op begins with a '.'. */ + + if (pop == NULL) + pop = (pseudo_typeS *) hash_find (po_hash, s + 1); + if (pop && !pop->poc_handler) + pop = NULL; + + /* In MRI mode, we may need to insert an + automatic alignment directive. What a hack + this is. */ + if (mri_pending_align + && (pop == NULL + || !((pop->poc_handler == cons + && pop->poc_val == 1) + || (pop->poc_handler == s_space + && pop->poc_val == 1) +#ifdef tc_conditional_pseudoop + || tc_conditional_pseudoop (pop) +#endif + || pop->poc_handler == s_if + || pop->poc_handler == s_ifdef + || pop->poc_handler == s_ifc + || pop->poc_handler == s_ifeqs + || pop->poc_handler == s_else + || pop->poc_handler == s_endif + || pop->poc_handler == s_globl + || pop->poc_handler == s_ignore))) + { + do_align (1, (char *) NULL, 0, 0); + mri_pending_align = 0; + + if (line_label != NULL) + { + symbol_set_frag (line_label, frag_now); + S_SET_VALUE (line_label, frag_now_fix ()); + } + } + + /* Print the error msg now, while we still can. */ + if (pop == NULL) + { + char *end = input_line_pointer; + + *input_line_pointer = c; + s_ignore (0); + c = *--input_line_pointer; + *input_line_pointer = '\0'; + if (! macro_defined || ! try_macro (c, s)) + { + *end = '\0'; + as_bad (_("unknown pseudo-op: `%s'"), s); + *input_line_pointer++ = c; + } + continue; + } + + /* Put it back for error messages etc. */ + *input_line_pointer = c; + /* The following skip of whitespace is compulsory. + A well shaped space is sometimes all that separates + keyword from operands. */ + if (c == ' ' || c == '\t') + input_line_pointer++; + + /* Input_line is restored. + Input_line_pointer->1st non-blank char + after pseudo-operation. */ + (*pop->poc_handler) (pop->poc_val); + + /* If that was .end, just get out now. */ + if (pop->poc_handler == s_end) + goto quit; + } + else + { + /* WARNING: c has char, which may be end-of-line. */ + /* Also: input_line_pointer->`\0` where c was. */ + *input_line_pointer = c; + input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1, 0); + c = *input_line_pointer; + *input_line_pointer = '\0'; + + generate_lineno_debug (); + + if (macro_defined && try_macro (c, s)) + continue; + + if (mri_pending_align) + { + do_align (1, (char *) NULL, 0, 0); + mri_pending_align = 0; + if (line_label != NULL) + { + symbol_set_frag (line_label, frag_now); + S_SET_VALUE (line_label, frag_now_fix ()); + } + } + + assemble_one (s); /* Assemble 1 instruction. */ + + *input_line_pointer++ = c; + + /* We resume loop AFTER the end-of-line from + this instruction. */ + } + } + continue; + } + + /* Empty statement? */ + if (is_end_of_line[(unsigned char) c]) + continue; + + if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (c)) + { + /* local label ("4:") */ + char *backup = input_line_pointer; + + HANDLE_CONDITIONAL_ASSEMBLY (); + + temp = c - '0'; + + /* Read the whole number. */ + while (ISDIGIT (*input_line_pointer)) + { + temp = (temp * 10) + *input_line_pointer - '0'; + ++input_line_pointer; + } + + if (LOCAL_LABELS_DOLLAR + && *input_line_pointer == '$' + && *(input_line_pointer + 1) == ':') + { + input_line_pointer += 2; + + if (dollar_label_defined (temp)) + { + as_fatal (_("label \"%d$\" redefined"), temp); + } + + define_dollar_label (temp); + colon (dollar_label_name (temp, 0)); + continue; + } + + if (LOCAL_LABELS_FB + && *input_line_pointer++ == ':') + { + fb_label_instance_inc (temp); + colon (fb_label_name (temp, 0)); + continue; + } + + input_line_pointer = backup; + } /* local label ("4:") */ + + if (c && strchr (line_comment_chars, c)) + { /* Its a comment. Better say APP or NO_APP. */ + sb sbuf; + char *ends; + char *new_buf; + char *new_tmp; + unsigned int new_length; + char *tmp_buf = 0; + + s = input_line_pointer; + if (strncmp (s, "APP\n", 4)) + { + /* We ignore it. */ + ignore_rest_of_line (); + continue; + } + bump_line_counters (); + s += 4; + + ends = strstr (s, "#NO_APP\n"); + + if (!ends) + { + unsigned int tmp_len; + unsigned int num; + + /* The end of the #APP wasn't in this buffer. We + keep reading in buffers until we find the #NO_APP + that goes with this #APP There is one. The specs + guarantee it... */ + tmp_len = buffer_limit - s; + tmp_buf = (char *) xmalloc (tmp_len + 1); + memcpy (tmp_buf, s, tmp_len); + do + { + new_tmp = input_scrub_next_buffer (&buffer); + if (!new_tmp) + break; + else + buffer_limit = new_tmp; + input_line_pointer = buffer; + ends = strstr (buffer, "#NO_APP\n"); + if (ends) + num = ends - buffer; + else + num = buffer_limit - buffer; + + tmp_buf = (char *) xrealloc (tmp_buf, tmp_len + num); + memcpy (tmp_buf + tmp_len, buffer, num); + tmp_len += num; + } + while (!ends); + + input_line_pointer = ends ? ends + 8 : NULL; + + s = tmp_buf; + ends = s + tmp_len; + + } + else + { + input_line_pointer = ends + 8; + } + + scrub_string = s; + scrub_string_end = ends; + + new_length = ends - s; + new_buf = (char *) xmalloc (new_length); + new_tmp = new_buf; + for (;;) + { + size_t space; + size_t size; + + space = (new_buf + new_length) - new_tmp; + size = do_scrub_chars (scrub_from_string, new_tmp, space); + + if (size < space) + { + new_tmp[size] = 0; + break; + } + + new_buf = (char *) xrealloc (new_buf, new_length + 100); + new_tmp = new_buf + new_length; + new_length += 100; + } + + if (tmp_buf) + free (tmp_buf); + + /* We've "scrubbed" input to the preferred format. In the + process we may have consumed the whole of the remaining + file (and included files). We handle this formatted + input similar to that of macro expansion, letting + actual macro expansion (possibly nested) and other + input expansion work. Beware that in messages, line + numbers and possibly file names will be incorrect. */ + new_length = strlen (new_buf); + sb_build (&sbuf, new_length); + sb_add_buffer (&sbuf, new_buf, new_length); + input_scrub_include_sb (&sbuf, input_line_pointer, 0); + sb_kill (&sbuf); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); + free (new_buf); + continue; + } + + HANDLE_CONDITIONAL_ASSEMBLY (); + +#ifdef tc_unrecognized_line + if (tc_unrecognized_line (c)) + continue; +#endif + input_line_pointer--; + /* Report unknown char as error. */ + demand_empty_rest_of_line (); + } + } + + quit: + symbol_set_value_now (&dot_symbol); + +#ifdef HANDLE_BUNDLE + if (bundle_lock_frag != NULL) + { + as_bad_where (bundle_lock_frag->fr_file, bundle_lock_frag->fr_line, + _(".bundle_lock with no matching .bundle_unlock")); + bundle_lock_frag = NULL; + bundle_lock_frchain = NULL; + bundle_lock_depth = 0; + } +#endif + +#ifdef md_cleanup + md_cleanup (); +#endif + /* Close the input file. */ + input_scrub_close (); +#ifdef WARN_COMMENTS + { + if (warn_comment && found_comment) + as_warn_where (found_comment_file, found_comment, + "first comment found here"); + } +#endif +} + +/* Convert O_constant expression EXP into the equivalent O_big representation. + Take the sign of the number from SIGN rather than X_add_number. */ + +static void +convert_to_bignum (expressionS *exp, int sign) +{ + valueT value; + unsigned int i; + + value = exp->X_add_number; + for (i = 0; i < sizeof (exp->X_add_number) / CHARS_PER_LITTLENUM; i++) + { + generic_bignum[i] = value & LITTLENUM_MASK; + value >>= LITTLENUM_NUMBER_OF_BITS; + } + /* Add a sequence of sign bits if the top bit of X_add_number is not + the sign of the original value. */ + if ((exp->X_add_number < 0) == !sign) + generic_bignum[i++] = sign ? LITTLENUM_MASK : 0; + exp->X_op = O_big; + exp->X_add_number = i; +} + +/* For most MRI pseudo-ops, the line actually ends at the first + nonquoted space. This function looks for that point, stuffs a null + in, and sets *STOPCP to the character that used to be there, and + returns the location. + + Until I hear otherwise, I am going to assume that this is only true + for the m68k MRI assembler. */ + +char * +mri_comment_field (char *stopcp) +{ + char *s; +#ifdef TC_M68K + int inquote = 0; + + know (flag_m68k_mri); + + for (s = input_line_pointer; + ((!is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t') + || inquote); + s++) + { + if (*s == '\'') + inquote = !inquote; + } +#else + for (s = input_line_pointer; + !is_end_of_line[(unsigned char) *s]; + s++) + ; +#endif + *stopcp = *s; + *s = '\0'; + + return s; +} + +/* Skip to the end of an MRI comment field. */ + +void +mri_comment_end (char *stop, int stopc) +{ + know (flag_mri); + + input_line_pointer = stop; + *stop = stopc; + while (!is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; +} + +void +s_abort (int ignore ATTRIBUTE_UNUSED) +{ + as_fatal (_(".abort detected. Abandoning ship.")); +} + +/* Guts of .align directive. N is the power of two to which to align. + FILL may be NULL, or it may point to the bytes of the fill pattern. + LEN is the length of whatever FILL points to, if anything. MAX is + the maximum number of characters to skip when doing the alignment, + or 0 if there is no maximum. */ + +static void +do_align (int n, char *fill, int len, int max) +{ + if (now_seg == absolute_section) + { + if (fill != NULL) + while (len-- > 0) + if (*fill++ != '\0') + { + as_warn (_("ignoring fill value in absolute section")); + break; + } + fill = NULL; + len = 0; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif +#ifdef md_do_align + md_do_align (n, fill, len, max, just_record_alignment); +#endif + + /* Only make a frag if we HAVE to... */ + if (n != 0 && !need_pass_2) + { + if (fill == NULL) + { + if (subseg_text_p (now_seg)) + frag_align_code (n, max); + else + frag_align (n, 0, max); + } + else if (len <= 1) + frag_align (n, *fill, max); + else + frag_align_pattern (n, fill, len, max); + } + +#ifdef md_do_align + just_record_alignment: ATTRIBUTE_UNUSED_LABEL +#endif + + record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); +} + +/* Handle the .align pseudo-op. A positive ARG is a default alignment + (in bytes). A negative ARG is the negative of the length of the + fill pattern. BYTES_P is non-zero if the alignment value should be + interpreted as the byte boundary, rather than the power of 2. */ +#ifndef TC_ALIGN_LIMIT +#define TC_ALIGN_LIMIT (stdoutput->arch_info->bits_per_address - 1) +#endif + +static void +s_align (int arg, int bytes_p) +{ + unsigned int align_limit = TC_ALIGN_LIMIT; + unsigned int align; + char *stop = NULL; + char stopc = 0; + offsetT fill = 0; + int max; + int fill_p; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + if (is_end_of_line[(unsigned char) *input_line_pointer]) + { + if (arg < 0) + align = 0; + else + align = arg; /* Default value from pseudo-op table. */ + } + else + { + align = get_absolute_expression (); + SKIP_WHITESPACE (); + } + + if (bytes_p) + { + /* Convert to a power of 2. */ + if (align != 0) + { + unsigned int i; + + for (i = 0; (align & 1) == 0; align >>= 1, ++i) + ; + if (align != 1) + as_bad (_("alignment not a power of 2")); + + align = i; + } + } + + if (align > align_limit) + { + align = align_limit; + as_warn (_("alignment too large: %u assumed"), align); + } + + if (*input_line_pointer != ',') + { + fill_p = 0; + max = 0; + } + else + { + ++input_line_pointer; + if (*input_line_pointer == ',') + fill_p = 0; + else + { + fill = get_absolute_expression (); + SKIP_WHITESPACE (); + fill_p = 1; + } + + if (*input_line_pointer != ',') + max = 0; + else + { + ++input_line_pointer; + max = get_absolute_expression (); + } + } + + if (!fill_p) + { + if (arg < 0) + as_warn (_("expected fill pattern missing")); + do_align (align, (char *) NULL, 0, max); + } + else + { + int fill_len; + + if (arg >= 0) + fill_len = 1; + else + fill_len = -arg; + if (fill_len <= 1) + { + char fill_char; + + fill_char = fill; + do_align (align, &fill_char, fill_len, max); + } + else + { + char ab[16]; + + if ((size_t) fill_len > sizeof ab) + abort (); + md_number_to_chars (ab, fill, fill_len); + do_align (align, ab, fill_len, max); + } + } + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +/* Handle the .align pseudo-op on machines where ".align 4" means + align to a 4 byte boundary. */ + +void +s_align_bytes (int arg) +{ + s_align (arg, 1); +} + +/* Handle the .align pseudo-op on machines where ".align 4" means align + to a 2**4 boundary. */ + +void +s_align_ptwo (int arg) +{ + s_align (arg, 0); +} + +/* Switch in and out of alternate macro mode. */ + +void +s_altmacro (int on) +{ + demand_empty_rest_of_line (); + macro_set_alternate (on); +} + +/* Read a symbol name from input_line_pointer. + + Stores the symbol name in a buffer and returns a pointer to this buffer. + The buffer is xalloc'ed. It is the caller's responsibility to free + this buffer. + + The name is not left in the i_l_p buffer as it may need processing + to handle escape characters. + + Advances i_l_p to the next non-whitespace character. + + If a symbol name could not be read, the routine issues an error + messages, skips to the end of the line and returns NULL. */ + +static char * +read_symbol_name (void) +{ + char * name; + char * start; + char c; + + c = *input_line_pointer++; + + if (c == '"') + { +#define SYM_NAME_CHUNK_LEN 128 + ptrdiff_t len = SYM_NAME_CHUNK_LEN; + char * name_end; + unsigned int C; + + start = name = xmalloc (len + 1); + + name_end = name + SYM_NAME_CHUNK_LEN; + + while (is_a_char (C = next_char_of_string ())) + { + if (name >= name_end) + { + ptrdiff_t sofar; + + sofar = name - start; + len += SYM_NAME_CHUNK_LEN; + start = xrealloc (start, len + 1); + name_end = start + len; + name = start + sofar; + } + + *name++ = (char) C; + } + *name = 0; + + /* Since quoted symbol names can contain non-ASCII characters, + check the string and warn if it cannot be recognised by the + current character set. */ + if (mbstowcs (NULL, name, len) == (size_t) -1) + as_warn (_("symbol name not recognised in the current locale")); + } + else if (is_name_beginner (c) || c == '\001') + { + ptrdiff_t len; + + name = input_line_pointer - 1; + + /* We accept \001 in a name in case this is + being called with a constructed string. */ + while (is_part_of_name (c = *input_line_pointer++) + || c == '\001') + ; + + len = (input_line_pointer - name) - 1; + start = xmalloc (len + 1); + + memcpy (start, name, len); + start[len] = 0; + + /* Skip a name ender char if one is present. */ + if (! is_name_ender (c)) + --input_line_pointer; + } + else + name = start = NULL; + + if (name == start) + { + as_bad (_("expected symbol name")); + ignore_rest_of_line (); + return NULL; + } + + SKIP_WHITESPACE (); + + return start; +} + + +symbolS * +s_comm_internal (int param, + symbolS *(*comm_parse_extra) (int, symbolS *, addressT)) +{ + char *name; + offsetT temp, size; + symbolS *symbolP = NULL; + char *stop = NULL; + char stopc = 0; + expressionS exp; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + if ((name = read_symbol_name ()) == NULL) + goto out; + + /* Accept an optional comma after the name. The comma used to be + required, but Irix 5 cc does not generate it for .lcomm. */ + if (*input_line_pointer == ',') + input_line_pointer++; + + temp = get_absolute_expr (&exp); + size = temp; + size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1; + if (exp.X_op == O_absent) + { + as_bad (_("missing size expression")); + ignore_rest_of_line (); + goto out; + } + else if (temp != size || !exp.X_unsigned) + { + as_warn (_("size (%ld) out of range, ignored"), (long) temp); + ignore_rest_of_line (); + goto out; + } + + symbolP = symbol_find_or_make (name); + if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + && !S_IS_COMMON (symbolP)) + { + if (!S_IS_VOLATILE (symbolP)) + { + symbolP = NULL; + as_bad (_("symbol `%s' is already defined"), name); + ignore_rest_of_line (); + goto out; + } + symbolP = symbol_clone (symbolP, 1); + S_SET_SEGMENT (symbolP, undefined_section); + S_SET_VALUE (symbolP, 0); + symbol_set_frag (symbolP, &zero_address_frag); + S_CLEAR_VOLATILE (symbolP); + } + + size = S_GET_VALUE (symbolP); + if (size == 0) + size = temp; + else if (size != temp) + as_warn (_("size of \"%s\" is already %ld; not changing to %ld"), + name, (long) size, (long) temp); + + if (comm_parse_extra != NULL) + symbolP = (*comm_parse_extra) (param, symbolP, size); + else + { + S_SET_VALUE (symbolP, (valueT) size); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, bfd_com_section_ptr); + } + + demand_empty_rest_of_line (); + out: + if (flag_mri) + mri_comment_end (stop, stopc); + if (name != NULL) + free (name); + return symbolP; +} + +void +s_comm (int ignore) +{ + s_comm_internal (ignore, NULL); +} + +/* The MRI COMMON pseudo-op. We handle this by creating a common + symbol with the appropriate name. We make s_space do the right + thing by increasing the size. */ + +void +s_mri_common (int small ATTRIBUTE_UNUSED) +{ + char *name; + char c; + char *alc = NULL; + symbolS *sym; + offsetT align; + char *stop = NULL; + char stopc = 0; + + if (!flag_mri) + { + s_comm (0); + return; + } + + stop = mri_comment_field (&stopc); + + SKIP_WHITESPACE (); + + name = input_line_pointer; + if (!ISDIGIT (*name)) + c = get_symbol_end (); + else + { + do + { + ++input_line_pointer; + } + while (ISDIGIT (*input_line_pointer)); + + c = *input_line_pointer; + *input_line_pointer = '\0'; + + if (line_label != NULL) + { + alc = (char *) xmalloc (strlen (S_GET_NAME (line_label)) + + (input_line_pointer - name) + + 1); + sprintf (alc, "%s%s", name, S_GET_NAME (line_label)); + name = alc; + } + } + + sym = symbol_find_or_make (name); + *input_line_pointer = c; + if (alc != NULL) + free (alc); + + if (*input_line_pointer != ',') + align = 0; + else + { + ++input_line_pointer; + align = get_absolute_expression (); + } + + if (S_IS_DEFINED (sym) && !S_IS_COMMON (sym)) + { + as_bad (_("symbol `%s' is already defined"), S_GET_NAME (sym)); + ignore_rest_of_line (); + mri_comment_end (stop, stopc); + return; + } + + S_SET_EXTERNAL (sym); + S_SET_SEGMENT (sym, bfd_com_section_ptr); + mri_common_symbol = sym; + +#ifdef S_SET_ALIGN + if (align != 0) + S_SET_ALIGN (sym, align); +#else + (void) align; +#endif + + if (line_label != NULL) + { + expressionS exp; + exp.X_op = O_symbol; + exp.X_add_symbol = sym; + exp.X_add_number = 0; + symbol_set_value_expression (line_label, &exp); + symbol_set_frag (line_label, &zero_address_frag); + S_SET_SEGMENT (line_label, expr_section); + } + + /* FIXME: We just ignore the small argument, which distinguishes + COMMON and COMMON.S. I don't know what we can do about it. */ + + /* Ignore the type and hptype. */ + if (*input_line_pointer == ',') + input_line_pointer += 2; + if (*input_line_pointer == ',') + input_line_pointer += 2; + + demand_empty_rest_of_line (); + + mri_comment_end (stop, stopc); +} + +void +s_data (int ignore ATTRIBUTE_UNUSED) +{ + segT section; + int temp; + + temp = get_absolute_expression (); + if (flag_readonly_data_in_text) + { + section = text_section; + temp += 1000; + } + else + section = data_section; + + subseg_set (section, (subsegT) temp); + + demand_empty_rest_of_line (); +} + +/* Handle the .appfile pseudo-op. This is automatically generated by + do_scrub_chars 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_string (char *file, int appfile ATTRIBUTE_UNUSED) +{ +#ifdef LISTING + if (listing) + listing_source_file (file); +#endif + register_dependency (file); +#ifdef obj_app_file + obj_app_file (file, appfile); +#endif +} + +void +s_app_file (int appfile) +{ + char *s; + int length; + + /* Some assemblers tolerate immediately following '"'. */ + if ((s = demand_copy_string (&length)) != 0) + { + int may_omit + = (!new_logical_line_flags (s, -1, 1) && appfile); + + /* In MRI mode, the preprocessor may have inserted an extraneous + backquote. */ + if (flag_m68k_mri + && *input_line_pointer == '\'' + && is_end_of_line[(unsigned char) input_line_pointer[1]]) + ++input_line_pointer; + + demand_empty_rest_of_line (); + if (!may_omit) + s_app_file_string (s, appfile); + } +} + +static int +get_linefile_number (int *flag) +{ + SKIP_WHITESPACE (); + + if (*input_line_pointer < '0' || *input_line_pointer > '9') + return 0; + + *flag = get_absolute_expression (); + + return 1; +} + +/* Handle the .appline pseudo-op. This is automatically generated by + do_scrub_chars 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 (int appline) +{ + char *file = NULL; + int l; + + /* The given number is that of the next line. */ + if (appline) + l = get_absolute_expression (); + else if (!get_linefile_number (&l)) + { + ignore_rest_of_line (); + return; + } + + l--; + + if (l < -1) + /* Some of the back ends can't deal with non-positive line numbers. + Besides, it's silly. GCC however will generate a line number of + zero when it is pre-processing builtins for assembler-with-cpp files: + + # 0 "" + + We do not want to barf on this, especially since such files are used + in the GCC and GDB testsuites. So we check for negative line numbers + rather than non-positive line numbers. */ + as_warn (_("line numbers must be positive; line number %d rejected"), + l + 1); + else + { + int flags = 0; + int length = 0; + + if (!appline) + { + SKIP_WHITESPACE (); + + if (*input_line_pointer == '"') + file = demand_copy_string (&length); + + if (file) + { + int this_flag; + + while (get_linefile_number (&this_flag)) + switch (this_flag) + { + /* From GCC's cpp documentation: + 1: start of a new file. + 2: returning to a file after having included + another file. + 3: following text comes from a system header file. + 4: following text should be treated as extern "C". + + 4 is nonsensical for the assembler; 3, we don't + care about, so we ignore it just in case a + system header file is included while + preprocessing assembly. So 1 and 2 are all we + care about, and they are mutually incompatible. + new_logical_line_flags() demands this. */ + case 1: + case 2: + if (flags && flags != (1 << this_flag)) + as_warn (_("incompatible flag %i in line directive"), + this_flag); + else + flags |= 1 << this_flag; + break; + + case 3: + case 4: + /* We ignore these. */ + break; + + default: + as_warn (_("unsupported flag %i in line directive"), + this_flag); + break; + } + + if (!is_end_of_line[(unsigned char)*input_line_pointer]) + file = 0; + } + } + + if (appline || file) + { + new_logical_line_flags (file, l, flags); +#ifdef LISTING + if (listing) + listing_source_line (l); +#endif + } + } + if (appline || file) + demand_empty_rest_of_line (); + else + ignore_rest_of_line (); +} + +/* Handle the .end pseudo-op. Actually, the real work is done in + read_a_source_file. */ + +void +s_end (int ignore ATTRIBUTE_UNUSED) +{ + if (flag_mri) + { + /* The MRI assembler permits the start symbol to follow .end, + but we don't support that. */ + SKIP_WHITESPACE (); + if (!is_end_of_line[(unsigned char) *input_line_pointer] + && *input_line_pointer != '*' + && *input_line_pointer != '!') + as_warn (_("start address not supported")); + } +} + +/* Handle the .err pseudo-op. */ + +void +s_err (int ignore ATTRIBUTE_UNUSED) +{ + as_bad (_(".err encountered")); + demand_empty_rest_of_line (); +} + +/* Handle the .error and .warning pseudo-ops. */ + +void +s_errwarn (int err) +{ + int len; + /* The purpose for the conditional assignment is not to + internationalize the directive itself, but that we need a + self-contained message, one that can be passed like the + demand_copy_C_string return value, and with no assumption on the + location of the name of the directive within the message. */ + char *msg + = (err ? _(".error directive invoked in source file") + : _(".warning directive invoked in source file")); + + if (!is_it_end_of_statement ()) + { + if (*input_line_pointer != '\"') + { + as_bad (_("%s argument must be a string"), + err ? ".error" : ".warning"); + ignore_rest_of_line (); + return; + } + + msg = demand_copy_C_string (&len); + if (msg == NULL) + return; + } + + if (err) + as_bad ("%s", msg); + else + as_warn ("%s", msg); + demand_empty_rest_of_line (); +} + +/* Handle the MRI fail pseudo-op. */ + +void +s_fail (int ignore ATTRIBUTE_UNUSED) +{ + offsetT temp; + char *stop = NULL; + char stopc = 0; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + temp = get_absolute_expression (); + if (temp >= 500) + as_warn (_(".fail %ld encountered"), (long) temp); + else + as_bad (_(".fail %ld encountered"), (long) temp); + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +void +s_fill (int ignore ATTRIBUTE_UNUSED) +{ + expressionS rep_exp; + long size = 1; + long fill = 0; + char *p; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_cons_align + md_cons_align (1); +#endif + + get_known_segmented_expression (&rep_exp); + if (*input_line_pointer == ',') + { + input_line_pointer++; + size = get_absolute_expression (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + fill = get_absolute_expression (); + } + } + + /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */ +#define BSD_FILL_SIZE_CROCK_8 (8) + if (size > BSD_FILL_SIZE_CROCK_8) + { + as_warn (_(".fill size clamped to %d"), BSD_FILL_SIZE_CROCK_8); + size = BSD_FILL_SIZE_CROCK_8; + } + if (size < 0) + { + as_warn (_("size negative; .fill ignored")); + size = 0; + } + else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0) + { + if (rep_exp.X_add_number < 0) + as_warn (_("repeat < 0; .fill ignored")); + size = 0; + } + + if (size && !need_pass_2) + { + if (rep_exp.X_op == O_constant) + { + p = frag_var (rs_fill, (int) size, (int) size, + (relax_substateT) 0, (symbolS *) 0, + (offsetT) rep_exp.X_add_number, + (char *) 0); + } + else + { + /* We don't have a constant repeat count, so we can't use + rs_fill. We can get the same results out of rs_space, + but its argument is in bytes, so we must multiply the + repeat count by size. */ + + symbolS *rep_sym; + rep_sym = make_expr_symbol (&rep_exp); + if (size != 1) + { + expressionS size_exp; + size_exp.X_op = O_constant; + size_exp.X_add_number = size; + + rep_exp.X_op = O_multiply; + rep_exp.X_add_symbol = rep_sym; + rep_exp.X_op_symbol = make_expr_symbol (&size_exp); + rep_exp.X_add_number = 0; + rep_sym = make_expr_symbol (&rep_exp); + } + + p = frag_var (rs_space, (int) size, (int) size, + (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0); + } + + memset (p, 0, (unsigned int) size); + + /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX + flavoured AS. The following bizarre behaviour is to be + compatible with above. I guess they tried to take up to 8 + bytes from a 4-byte expression and they forgot to sign + extend. */ +#define BSD_FILL_SIZE_CROCK_4 (4) + md_number_to_chars (p, (valueT) fill, + (size > BSD_FILL_SIZE_CROCK_4 + ? BSD_FILL_SIZE_CROCK_4 + : (int) size)); + /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) + but emits no error message because it seems a legal thing to do. + It is a degenerate case of .fill but could be emitted by a + compiler. */ + } + demand_empty_rest_of_line (); +} + +void +s_globl (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + int c; + symbolS *symbolP; + char *stop = NULL; + char stopc = 0; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + do + { + if ((name = read_symbol_name ()) == NULL) + return; + + symbolP = symbol_find_or_make (name); + S_SET_EXTERNAL (symbolP); + + SKIP_WHITESPACE (); + c = *input_line_pointer; + if (c == ',') + { + input_line_pointer++; + SKIP_WHITESPACE (); + if (is_end_of_line[(unsigned char) *input_line_pointer]) + c = '\n'; + } + + free (name); + } + while (c == ','); + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +/* Handle the MRI IRP and IRPC pseudo-ops. */ + +void +s_irp (int irpc) +{ + char *file, *eol; + unsigned int line; + sb s; + const char *err; + sb out; + + as_where (&file, &line); + + eol = find_end_of_line (input_line_pointer, 0); + sb_build (&s, eol - input_line_pointer); + sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; + + sb_new (&out); + + err = expand_irp (irpc, 0, &s, &out, get_non_macro_line_sb); + if (err != NULL) + as_bad_where (file, line, "%s", err); + + sb_kill (&s); + + input_scrub_include_sb (&out, input_line_pointer, 1); + sb_kill (&out); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Handle the .linkonce pseudo-op. This tells the assembler to mark + the section to only be linked once. However, this is not supported + by most object file formats. This takes an optional argument, + which is what to do about duplicates. */ + +void +s_linkonce (int ignore ATTRIBUTE_UNUSED) +{ + enum linkonce_type type; + + SKIP_WHITESPACE (); + + type = LINKONCE_DISCARD; + + if (!is_end_of_line[(unsigned char) *input_line_pointer]) + { + char *s; + char c; + + s = input_line_pointer; + c = get_symbol_end (); + if (strcasecmp (s, "discard") == 0) + type = LINKONCE_DISCARD; + else if (strcasecmp (s, "one_only") == 0) + type = LINKONCE_ONE_ONLY; + else if (strcasecmp (s, "same_size") == 0) + type = LINKONCE_SAME_SIZE; + else if (strcasecmp (s, "same_contents") == 0) + type = LINKONCE_SAME_CONTENTS; + else + as_warn (_("unrecognized .linkonce type `%s'"), s); + + *input_line_pointer = c; + } + +#ifdef obj_handle_link_once + obj_handle_link_once (type); +#else /* ! defined (obj_handle_link_once) */ + { + flagword flags; + + if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) + as_warn (_(".linkonce is not supported for this object file format")); + + flags = bfd_get_section_flags (stdoutput, now_seg); + flags |= SEC_LINK_ONCE; + switch (type) + { + default: + abort (); + case LINKONCE_DISCARD: + flags |= SEC_LINK_DUPLICATES_DISCARD; + break; + case LINKONCE_ONE_ONLY: + flags |= SEC_LINK_DUPLICATES_ONE_ONLY; + break; + case LINKONCE_SAME_SIZE: + flags |= SEC_LINK_DUPLICATES_SAME_SIZE; + break; + case LINKONCE_SAME_CONTENTS: + flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS; + break; + } + if (!bfd_set_section_flags (stdoutput, now_seg, flags)) + as_bad (_("bfd_set_section_flags: %s"), + bfd_errmsg (bfd_get_error ())); + } +#endif /* ! defined (obj_handle_link_once) */ + + demand_empty_rest_of_line (); +} + +void +bss_alloc (symbolS *symbolP, addressT size, int align) +{ + char *pfrag; + segT current_seg = now_seg; + subsegT current_subseg = now_subseg; + segT bss_seg = bss_section; + +#if defined (TC_MIPS) || defined (TC_ALPHA) + if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour + || OUTPUT_FLAVOR == bfd_target_elf_flavour) + { + /* For MIPS and Alpha ECOFF or ELF, small objects are put in .sbss. */ + if (size <= bfd_get_gp_size (stdoutput)) + { + bss_seg = subseg_new (".sbss", 1); + seg_info (bss_seg)->bss = 1; + if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC)) + as_warn (_("error setting flags for \".sbss\": %s"), + bfd_errmsg (bfd_get_error ())); + } + } +#endif + subseg_set (bss_seg, 1); + + if (align) + { + record_alignment (bss_seg, align); + frag_align (align, 0, 0); + } + + /* Detach from old frag. */ + if (S_GET_SEGMENT (symbolP) == bss_seg) + symbol_get_frag (symbolP)->fr_symbol = NULL; + + symbol_set_frag (symbolP, frag_now); + pfrag = frag_var (rs_org, 1, 1, 0, symbolP, size, NULL); + *pfrag = 0; + +#ifdef S_SET_SIZE + S_SET_SIZE (symbolP, size); +#endif + S_SET_SEGMENT (symbolP, bss_seg); + +#ifdef OBJ_COFF + /* The symbol may already have been created with a preceding + ".globl" directive -- be careful not to step on storage class + in that case. Otherwise, set it to static. */ + if (S_GET_STORAGE_CLASS (symbolP) != C_EXT) + S_SET_STORAGE_CLASS (symbolP, C_STAT); +#endif /* OBJ_COFF */ + + subseg_set (current_seg, current_subseg); +} + +offsetT +parse_align (int align_bytes) +{ + expressionS exp; + addressT align; + + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + no_align: + as_bad (_("expected alignment after size")); + ignore_rest_of_line (); + return -1; + } + + input_line_pointer++; + SKIP_WHITESPACE (); + + align = get_absolute_expr (&exp); + if (exp.X_op == O_absent) + goto no_align; + + if (!exp.X_unsigned) + { + as_warn (_("alignment negative; 0 assumed")); + align = 0; + } + + if (align_bytes && align != 0) + { + /* convert to a power of 2 alignment */ + unsigned int alignp2 = 0; + while ((align & 1) == 0) + align >>= 1, ++alignp2; + if (align != 1) + { + as_bad (_("alignment not a power of 2")); + ignore_rest_of_line (); + return -1; + } + align = alignp2; + } + return align; +} + +/* Called from s_comm_internal after symbol name and size have been + parsed. NEEDS_ALIGN is 0 if it was an ".lcomm" (2 args only), + 1 if this was a ".bss" directive which has a 3rd argument + (alignment as a power of 2), or 2 if this was a ".bss" directive + with alignment in bytes. */ + +symbolS * +s_lcomm_internal (int needs_align, symbolS *symbolP, addressT size) +{ + addressT align = 0; + + if (needs_align) + { + align = parse_align (needs_align - 1); + if (align == (addressT) -1) + return NULL; + } + else + /* Assume some objects may require alignment on some systems. */ + TC_IMPLICIT_LCOMM_ALIGNMENT (size, align); + + bss_alloc (symbolP, size, align); + return symbolP; +} + +void +s_lcomm (int needs_align) +{ + s_comm_internal (needs_align, s_lcomm_internal); +} + +void +s_lcomm_bytes (int needs_align) +{ + s_comm_internal (needs_align * 2, s_lcomm_internal); +} + +void +s_lsym (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + expressionS exp; + symbolS *symbolP; + + /* We permit ANY defined expression: BSD4.2 demands constants. */ + if ((name = read_symbol_name ()) == NULL) + return; + + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after \"%s\""), name); + goto err_out; + } + + input_line_pointer++; + expression_and_evaluate (&exp); + + if (exp.X_op != O_constant + && exp.X_op != O_register) + { + as_bad (_("bad expression")); + goto err_out; + } + + symbolP = symbol_find_or_make (name); + + if (S_GET_SEGMENT (symbolP) == undefined_section) + { + /* The name might be an undefined .global symbol; be sure to + keep the "external" bit. */ + S_SET_SEGMENT (symbolP, + (exp.X_op == O_constant + ? absolute_section + : reg_section)); + S_SET_VALUE (symbolP, (valueT) exp.X_add_number); + } + else + { + as_bad (_("symbol `%s' is already defined"), name); + } + + demand_empty_rest_of_line (); + free (name); + return; + + err_out: + ignore_rest_of_line (); + free (name); + return; +} + +/* Read a line into an sb. Returns the character that ended the line + or zero if there are no more lines. */ + +static int +get_line_sb (sb *line, int in_macro) +{ + char *eol; + + if (input_line_pointer[-1] == '\n') + bump_line_counters (); + + if (input_line_pointer >= buffer_limit) + { + buffer_limit = input_scrub_next_buffer (&input_line_pointer); + if (buffer_limit == 0) + return 0; + } + + eol = _find_end_of_line (input_line_pointer, flag_m68k_mri, 0, in_macro); + sb_add_buffer (line, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; + + /* Don't skip multiple end-of-line characters, because that breaks support + for the IA-64 stop bit (;;) which looks like two consecutive end-of-line + characters but isn't. Instead just skip one end of line character and + return the character skipped so that the caller can re-insert it if + necessary. */ + return *input_line_pointer++; +} + +static size_t +get_non_macro_line_sb (sb *line) +{ + return get_line_sb (line, 0); +} + +static size_t +get_macro_line_sb (sb *line) +{ + return get_line_sb (line, 1); +} + +/* Define a macro. This is an interface to macro.c. */ + +void +s_macro (int ignore ATTRIBUTE_UNUSED) +{ + char *file, *eol; + unsigned int line; + sb s; + const char *err; + const char *name; + + as_where (&file, &line); + + eol = find_end_of_line (input_line_pointer, 0); + sb_build (&s, eol - input_line_pointer); + sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; + + if (line_label != NULL) + { + sb label; + size_t len; + + name = S_GET_NAME (line_label); + len = strlen (name); + sb_build (&label, len); + sb_add_buffer (&label, name, len); + err = define_macro (0, &s, &label, get_macro_line_sb, file, line, &name); + sb_kill (&label); + } + else + err = define_macro (0, &s, NULL, get_macro_line_sb, file, line, &name); + if (err != NULL) + as_bad_where (file, line, err, name); + else + { + if (line_label != NULL) + { + S_SET_SEGMENT (line_label, absolute_section); + S_SET_VALUE (line_label, 0); + symbol_set_frag (line_label, &zero_address_frag); + } + + if (((NO_PSEUDO_DOT || flag_m68k_mri) + && hash_find (po_hash, name) != NULL) + || (!flag_m68k_mri + && *name == '.' + && hash_find (po_hash, name + 1) != NULL)) + as_warn_where (file, + line, + _("attempt to redefine pseudo-op `%s' ignored"), + name); + } + + sb_kill (&s); +} + +/* Handle the .mexit pseudo-op, which immediately exits a macro + expansion. */ + +void +s_mexit (int ignore ATTRIBUTE_UNUSED) +{ + if (macro_nest) + { + cond_exit_macro (macro_nest); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); + } + else + as_warn (_("ignoring macro exit outside a macro definition.")); +} + +/* Switch in and out of MRI mode. */ + +void +s_mri (int ignore ATTRIBUTE_UNUSED) +{ + int on; +#ifdef MRI_MODE_CHANGE + int old_flag; +#endif + + on = get_absolute_expression (); +#ifdef MRI_MODE_CHANGE + old_flag = flag_mri; +#endif + if (on != 0) + { + flag_mri = 1; +#ifdef TC_M68K + flag_m68k_mri = 1; +#endif + macro_mri_mode (1); + } + else + { + flag_mri = 0; +#ifdef TC_M68K + flag_m68k_mri = 0; +#endif + macro_mri_mode (0); + } + + /* Operator precedence changes in m68k MRI mode, so we need to + update the operator rankings. */ + expr_set_precedence (); + +#ifdef MRI_MODE_CHANGE + if (on != old_flag) + MRI_MODE_CHANGE (on); +#endif + + demand_empty_rest_of_line (); +} + +/* Handle changing the location counter. */ + +static void +do_org (segT segment, expressionS *exp, int fill) +{ + if (segment != now_seg + && segment != absolute_section + && segment != expr_section) + as_bad (_("invalid segment \"%s\""), segment_name (segment)); + + if (now_seg == absolute_section) + { + if (fill != 0) + as_warn (_("ignoring fill value in absolute section")); + if (exp->X_op != O_constant) + { + as_bad (_("only constant offsets supported in absolute section")); + exp->X_add_number = 0; + } + abs_section_offset = exp->X_add_number; + } + else + { + char *p; + symbolS *sym = exp->X_add_symbol; + offsetT off = exp->X_add_number * OCTETS_PER_BYTE; + + if (exp->X_op != O_constant && exp->X_op != O_symbol) + { + /* Handle complex expressions. */ + sym = make_expr_symbol (exp); + off = 0; + } + + p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0); + *p = fill; + } +} + +void +s_org (int ignore ATTRIBUTE_UNUSED) +{ + segT segment; + expressionS exp; + long temp_fill; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + /* The m68k MRI assembler has a different meaning for .org. It + means to create an absolute section at a given address. We can't + support that--use a linker script instead. */ + if (flag_m68k_mri) + { + as_bad (_("MRI style ORG pseudo-op not supported")); + ignore_rest_of_line (); + return; + } + + /* Don't believe the documentation of BSD 4.2 AS. There is no such + thing as a sub-segment-relative origin. Any absolute origin is + given a warning, then assumed to be segment-relative. Any + segmented origin expression ("foo+42") had better be in the right + segment or the .org is ignored. + + BSD 4.2 AS warns if you try to .org backwards. We cannot because + we never know sub-segment sizes when we are reading code. BSD + will crash trying to emit negative numbers of filler bytes in + certain .orgs. We don't crash, but see as-write for that code. + + Don't make frag if need_pass_2==1. */ + segment = get_known_segmented_expression (&exp); + if (*input_line_pointer == ',') + { + input_line_pointer++; + temp_fill = get_absolute_expression (); + } + else + temp_fill = 0; + + if (!need_pass_2) + do_org (segment, &exp, temp_fill); + + demand_empty_rest_of_line (); +} + +/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be + called by the obj-format routine which handles section changing + when in MRI mode. It will create a new section, and return it. It + will set *TYPE to the section type: one of 'C' (code), 'D' (data), + 'M' (mixed), or 'R' (romable). The flags will be set in the section. */ + +void +s_mri_sect (char *type ATTRIBUTE_UNUSED) +{ +#ifdef TC_M68K + + char *name; + char c; + segT seg; + + SKIP_WHITESPACE (); + + name = input_line_pointer; + if (!ISDIGIT (*name)) + c = get_symbol_end (); + else + { + do + { + ++input_line_pointer; + } + while (ISDIGIT (*input_line_pointer)); + + c = *input_line_pointer; + *input_line_pointer = '\0'; + } + + name = xstrdup (name); + + *input_line_pointer = c; + + seg = subseg_new (name, 0); + + if (*input_line_pointer == ',') + { + int align; + + ++input_line_pointer; + align = get_absolute_expression (); + record_alignment (seg, align); + } + + *type = 'C'; + if (*input_line_pointer == ',') + { + c = *++input_line_pointer; + c = TOUPPER (c); + if (c == 'C' || c == 'D' || c == 'M' || c == 'R') + *type = c; + else + as_bad (_("unrecognized section type")); + ++input_line_pointer; + + { + flagword flags; + + flags = SEC_NO_FLAGS; + if (*type == 'C') + flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE; + else if (*type == 'D' || *type == 'M') + flags = SEC_ALLOC | SEC_LOAD | SEC_DATA; + else if (*type == 'R') + flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM; + if (flags != SEC_NO_FLAGS) + { + if (!bfd_set_section_flags (stdoutput, seg, flags)) + as_warn (_("error setting flags for \"%s\": %s"), + bfd_section_name (stdoutput, seg), + bfd_errmsg (bfd_get_error ())); + } + } + } + + /* Ignore the HP type. */ + if (*input_line_pointer == ',') + input_line_pointer += 2; + + demand_empty_rest_of_line (); + +#else /* ! TC_M68K */ +#ifdef TC_I960 + + char *name; + char c; + segT seg; + + SKIP_WHITESPACE (); + + name = input_line_pointer; + c = get_symbol_end (); + + name = xstrdup (name); + + *input_line_pointer = c; + + seg = subseg_new (name, 0); + + if (*input_line_pointer != ',') + *type = 'C'; + else + { + char *sectype; + + ++input_line_pointer; + SKIP_WHITESPACE (); + sectype = input_line_pointer; + c = get_symbol_end (); + if (*sectype == '\0') + *type = 'C'; + else if (strcasecmp (sectype, "text") == 0) + *type = 'C'; + else if (strcasecmp (sectype, "data") == 0) + *type = 'D'; + else if (strcasecmp (sectype, "romdata") == 0) + *type = 'R'; + else + as_warn (_("unrecognized section type `%s'"), sectype); + *input_line_pointer = c; + } + + if (*input_line_pointer == ',') + { + char *seccmd; + + ++input_line_pointer; + SKIP_WHITESPACE (); + seccmd = input_line_pointer; + c = get_symbol_end (); + if (strcasecmp (seccmd, "absolute") == 0) + { + as_bad (_("absolute sections are not supported")); + *input_line_pointer = c; + ignore_rest_of_line (); + return; + } + else if (strcasecmp (seccmd, "align") == 0) + { + int align; + + *input_line_pointer = c; + align = get_absolute_expression (); + record_alignment (seg, align); + } + else + { + as_warn (_("unrecognized section command `%s'"), seccmd); + *input_line_pointer = c; + } + } + + demand_empty_rest_of_line (); + +#else /* ! TC_I960 */ + /* The MRI assembler seems to use different forms of .sect for + different targets. */ + as_bad ("MRI mode not supported for this target"); + ignore_rest_of_line (); +#endif /* ! TC_I960 */ +#endif /* ! TC_M68K */ +} + +/* Handle the .print pseudo-op. */ + +void +s_print (int ignore ATTRIBUTE_UNUSED) +{ + char *s; + int len; + + s = demand_copy_C_string (&len); + if (s != NULL) + printf ("%s\n", s); + demand_empty_rest_of_line (); +} + +/* Handle the .purgem pseudo-op. */ + +void +s_purgem (int ignore ATTRIBUTE_UNUSED) +{ + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + return; + } + + do + { + char *name; + char c; + + SKIP_WHITESPACE (); + name = input_line_pointer; + c = get_symbol_end (); + delete_macro (name); + *input_line_pointer = c; + SKIP_WHITESPACE (); + } + while (*input_line_pointer++ == ','); + + --input_line_pointer; + demand_empty_rest_of_line (); +} + +/* Handle the .endm/.endr pseudo-ops. */ + +static void +s_bad_end (int endr) +{ + as_warn (_(".end%c encountered without preceding %s"), + endr ? 'r' : 'm', + endr ? ".rept, .irp, or .irpc" : ".macro"); + demand_empty_rest_of_line (); +} + +/* Handle the .rept pseudo-op. */ + +void +s_rept (int ignore ATTRIBUTE_UNUSED) +{ + int count; + + count = get_absolute_expression (); + + do_repeat (count, "REPT", "ENDR"); +} + +/* This function provides a generic repeat block implementation. It allows + different directives to be used as the start/end keys. */ + +void +do_repeat (int count, const char *start, const char *end) +{ + sb one; + sb many; + + sb_new (&one); + if (!buffer_and_nest (start, end, &one, get_non_macro_line_sb)) + { + as_bad (_("%s without %s"), start, end); + return; + } + + sb_build (&many, count * one.len); + while (count-- > 0) + sb_add_sb (&many, &one); + + sb_kill (&one); + + input_scrub_include_sb (&many, input_line_pointer, 1); + sb_kill (&many); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Like do_repeat except that any text matching EXPANDER in the + block is replaced by the itteration count. */ + +void +do_repeat_with_expander (int count, + const char * start, + const char * end, + const char * expander) +{ + sb one; + sb many; + + sb_new (&one); + if (!buffer_and_nest (start, end, &one, get_non_macro_line_sb)) + { + as_bad (_("%s without %s"), start, end); + return; + } + + sb_new (&many); + + if (expander != NULL && strstr (one.ptr, expander) != NULL) + { + while (count -- > 0) + { + int len; + char * sub; + sb processed; + + sb_build (& processed, one.len); + sb_add_sb (& processed, & one); + sub = strstr (processed.ptr, expander); + len = sprintf (sub, "%d", count); + gas_assert (len < 8); + strcpy (sub + len, sub + 8); + processed.len -= (8 - len); + sb_add_sb (& many, & processed); + sb_kill (& processed); + } + } + else + while (count-- > 0) + sb_add_sb (&many, &one); + + sb_kill (&one); + + input_scrub_include_sb (&many, input_line_pointer, 1); + sb_kill (&many); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Skip to end of current repeat loop; EXTRA indicates how many additional + input buffers to skip. Assumes that conditionals preceding the loop end + are properly nested. + + This function makes it easier to implement a premature "break" out of the + loop. The EXTRA arg accounts for other buffers we might have inserted, + such as line substitutions. */ + +void +end_repeat (int extra) +{ + cond_exit_macro (macro_nest); + while (extra-- >= 0) + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +static void +assign_symbol (char *name, int mode) +{ + symbolS *symbolP; + + if (name[0] == '.' && name[1] == '\0') + { + /* Turn '. = mumble' into a .org mumble. */ + segT segment; + expressionS exp; + + segment = get_known_segmented_expression (&exp); + + if (!need_pass_2) + do_org (segment, &exp, 0); + + return; + } + + if ((symbolP = symbol_find (name)) == NULL + && (symbolP = md_undefined_symbol (name)) == NULL) + { + symbolP = symbol_find_or_make (name); +#ifndef NO_LISTING + /* When doing symbol listings, play games with dummy fragments living + outside the normal fragment chain to record the file and line info + for this symbol. */ + if (listing & LISTING_SYMBOLS) + { + extern struct list_info_struct *listing_tail; + fragS *dummy_frag = (fragS *) xcalloc (1, sizeof (fragS)); + dummy_frag->line = listing_tail; + dummy_frag->fr_symbol = symbolP; + symbol_set_frag (symbolP, dummy_frag); + } +#endif +#ifdef OBJ_COFF + /* "set" symbols are local unless otherwise specified. */ + SF_SET_LOCAL (symbolP); +#endif + } + + if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + { + if ((mode != 0 || !S_IS_VOLATILE (symbolP)) + && !S_CAN_BE_REDEFINED (symbolP)) + { + as_bad (_("symbol `%s' is already defined"), name); + symbolP = symbol_clone (symbolP, 0); + } + /* If the symbol is volatile, copy the symbol and replace the + original with the copy, so that previous uses of the symbol will + retain the value of the symbol at the point of use. */ + else if (S_IS_VOLATILE (symbolP)) + symbolP = symbol_clone (symbolP, 1); + } + + if (mode == 0) + S_SET_VOLATILE (symbolP); + else if (mode < 0) + S_SET_FORWARD_REF (symbolP); + + pseudo_set (symbolP); +} + +/* Handle the .equ, .equiv, .eqv, and .set directives. If EQUIV is 1, + then this is .equiv, and it is an error if the symbol is already + defined. If EQUIV is -1, the symbol additionally is a forward + reference. */ + +void +s_set (int equiv) +{ + char *name; + + /* Especial apologies for the random logic: + this just grew, and could be parsed much more simply! + Dean in haste. */ + if ((name = read_symbol_name ()) == NULL) + return; + + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after \"%s\""), name); + ignore_rest_of_line (); + free (name); + return; + } + + input_line_pointer++; + assign_symbol (name, equiv); + demand_empty_rest_of_line (); + free (name); +} + +void +s_space (int mult) +{ + expressionS exp; + expressionS val; + char *p = 0; + char *stop = NULL; + char stopc = 0; + int bytes; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_cons_align + md_cons_align (1); +#endif + + if (flag_mri) + stop = mri_comment_field (&stopc); + + /* In m68k MRI mode, we need to align to a word boundary, unless + this is ds.b. */ + if (flag_m68k_mri && mult > 1) + { + if (now_seg == absolute_section) + { + abs_section_offset += abs_section_offset & 1; + if (line_label != NULL) + S_SET_VALUE (line_label, abs_section_offset); + } + else if (mri_common_symbol != NULL) + { + valueT mri_val; + + mri_val = S_GET_VALUE (mri_common_symbol); + if ((mri_val & 1) != 0) + { + S_SET_VALUE (mri_common_symbol, mri_val + 1); + if (line_label != NULL) + { + expressionS *symexp; + + symexp = symbol_get_value_expression (line_label); + know (symexp->X_op == O_symbol); + know (symexp->X_add_symbol == mri_common_symbol); + symexp->X_add_number += 1; + } + } + } + else + { + do_align (1, (char *) NULL, 0, 0); + if (line_label != NULL) + { + symbol_set_frag (line_label, frag_now); + S_SET_VALUE (line_label, frag_now_fix ()); + } + } + } + + bytes = mult; + + expression (&exp); + + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + ++input_line_pointer; + expression (&val); + } + else + { + val.X_op = O_constant; + val.X_add_number = 0; + } + + if (val.X_op != O_constant + || val.X_add_number < - 0x80 + || val.X_add_number > 0xff + || (mult != 0 && mult != 1 && val.X_add_number != 0)) + { + resolve_expression (&exp); + if (exp.X_op != O_constant) + as_bad (_("unsupported variable size or fill value")); + else + { + offsetT i; + + if (mult == 0) + mult = 1; + bytes = mult * exp.X_add_number; + for (i = 0; i < exp.X_add_number; i++) + emit_expr (&val, mult); + } + } + else + { + if (now_seg == absolute_section || mri_common_symbol != NULL) + resolve_expression (&exp); + + if (exp.X_op == O_constant) + { + offsetT repeat; + + repeat = exp.X_add_number; + if (mult) + repeat *= mult; + bytes = repeat; + if (repeat <= 0) + { + if (!flag_mri) + as_warn (_(".space repeat count is zero, ignored")); + else if (repeat < 0) + as_warn (_(".space repeat count is negative, ignored")); + goto getout; + } + + /* If we are in the absolute section, just bump the offset. */ + if (now_seg == absolute_section) + { + abs_section_offset += repeat; + goto getout; + } + + /* If we are secretly in an MRI common section, then + creating space just increases the size of the common + symbol. */ + if (mri_common_symbol != NULL) + { + S_SET_VALUE (mri_common_symbol, + S_GET_VALUE (mri_common_symbol) + repeat); + goto getout; + } + + if (!need_pass_2) + p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0, + (offsetT) repeat, (char *) 0); + } + else + { + if (now_seg == absolute_section) + { + as_bad (_("space allocation too complex in absolute section")); + subseg_set (text_section, 0); + } + + if (mri_common_symbol != NULL) + { + as_bad (_("space allocation too complex in common section")); + mri_common_symbol = NULL; + } + + if (!need_pass_2) + p = frag_var (rs_space, 1, 1, (relax_substateT) 0, + make_expr_symbol (&exp), (offsetT) 0, (char *) 0); + } + + if (p) + *p = val.X_add_number; + } + + getout: + + /* In MRI mode, after an odd number of bytes, we must align to an + even word boundary, unless the next instruction is a dc.b, ds.b + or dcb.b. */ + if (flag_mri && (bytes & 1) != 0) + mri_pending_align = 1; + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +/* This is like s_space, but the value is a floating point number with + the given precision. This is for the MRI dcb.s pseudo-op and + friends. */ + +void +s_float_space (int float_type) +{ + offsetT count; + int flen; + char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; + char *stop = NULL; + char stopc = 0; + +#ifdef md_cons_align + md_cons_align (1); +#endif + + if (flag_mri) + stop = mri_comment_field (&stopc); + + count = get_absolute_expression (); + + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_("missing value")); + ignore_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); + return; + } + + ++input_line_pointer; + + SKIP_WHITESPACE (); + + /* Skip any 0{letter} that may be present. Don't even check if the + * letter is legal. */ + if (input_line_pointer[0] == '0' + && ISALPHA (input_line_pointer[1])) + input_line_pointer += 2; + + /* Accept :xxxx, where the x's are hex digits, for a floating point + with the exact digits specified. */ + if (input_line_pointer[0] == ':') + { + flen = hex_float (float_type, temp); + if (flen < 0) + { + ignore_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); + return; + } + } + else + { + char *err; + + err = md_atof (float_type, temp, &flen); + know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); + know (err != NULL || flen > 0); + if (err) + { + as_bad (_("bad floating literal: %s"), err); + ignore_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); + return; + } + } + + while (--count >= 0) + { + char *p; + + p = frag_more (flen); + memcpy (p, temp, (unsigned int) flen); + } + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +/* Handle the .struct pseudo-op, as found in MIPS assemblers. */ + +void +s_struct (int ignore ATTRIBUTE_UNUSED) +{ + char *stop = NULL; + char stopc = 0; + + if (flag_mri) + stop = mri_comment_field (&stopc); + abs_section_offset = get_absolute_expression (); +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + /* The ELF backend needs to know that we are changing sections, so + that .previous works correctly. */ + if (IS_ELF) + obj_elf_section_change_hook (); +#endif + subseg_set (absolute_section, 0); + demand_empty_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); +} + +void +s_text (int ignore ATTRIBUTE_UNUSED) +{ + int temp; + + temp = get_absolute_expression (); + subseg_set (text_section, (subsegT) temp); + demand_empty_rest_of_line (); +} + +/* .weakref x, y sets x as an alias to y that, as long as y is not + referenced directly, will cause y to become a weak symbol. */ +void +s_weakref (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + symbolS *symbolP; + symbolS *symbolP2; + expressionS exp; + + if ((name = read_symbol_name ()) == NULL) + return; + + symbolP = symbol_find_or_make (name); + + if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + { + if (!S_IS_VOLATILE (symbolP)) + { + as_bad (_("symbol `%s' is already defined"), name); + goto err_out; + } + symbolP = symbol_clone (symbolP, 1); + S_CLEAR_VOLATILE (symbolP); + } + + SKIP_WHITESPACE (); + + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after \"%s\""), name); + goto err_out; + } + + input_line_pointer++; + + SKIP_WHITESPACE (); + free (name); + + if ((name = read_symbol_name ()) == NULL) + return; + + if ((symbolP2 = symbol_find_noref (name, 1)) == NULL + && (symbolP2 = md_undefined_symbol (name)) == NULL) + { + symbolP2 = symbol_find_or_make (name); + S_SET_WEAKREFD (symbolP2); + } + else + { + symbolS *symp = symbolP2; + + while (S_IS_WEAKREFR (symp) && symp != symbolP) + { + expressionS *expP = symbol_get_value_expression (symp); + + gas_assert (expP->X_op == O_symbol + && expP->X_add_number == 0); + symp = expP->X_add_symbol; + } + if (symp == symbolP) + { + char *loop; + + loop = concat (S_GET_NAME (symbolP), + " => ", S_GET_NAME (symbolP2), (const char *) NULL); + + symp = symbolP2; + while (symp != symbolP) + { + char *old_loop = loop; + + symp = symbol_get_value_expression (symp)->X_add_symbol; + loop = concat (loop, " => ", S_GET_NAME (symp), + (const char *) NULL); + free (old_loop); + } + + as_bad (_("%s: would close weakref loop: %s"), + S_GET_NAME (symbolP), loop); + + free (loop); + free (name); + ignore_rest_of_line (); + return; + } + + /* Short-circuiting instead of just checking here might speed + things up a tiny little bit, but loop error messages would + miss intermediate links. */ + /* symbolP2 = symp; */ + } + + memset (&exp, 0, sizeof (exp)); + exp.X_op = O_symbol; + exp.X_add_symbol = symbolP2; + + S_SET_SEGMENT (symbolP, undefined_section); + symbol_set_value_expression (symbolP, &exp); + symbol_set_frag (symbolP, &zero_address_frag); + S_SET_WEAKREFR (symbolP); + + demand_empty_rest_of_line (); + free (name); + return; + + err_out: + ignore_rest_of_line (); + free (name); + return; +} + + +/* Verify that we are at the end of a line. If not, issue an error and + skip to EOL. */ + +void +demand_empty_rest_of_line (void) +{ + SKIP_WHITESPACE (); + if (is_end_of_line[(unsigned char) *input_line_pointer]) + input_line_pointer++; + else + { + if (ISPRINT (*input_line_pointer)) + as_bad (_("junk at end of line, first unrecognized character is `%c'"), + *input_line_pointer); + else + as_bad (_("junk at end of line, first unrecognized character valued 0x%x"), + *input_line_pointer); + ignore_rest_of_line (); + } + + /* Return pointing just after end-of-line. */ + know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); +} + +/* Silently advance to the end of line. Use this after already having + issued an error about something bad. */ + +void +ignore_rest_of_line (void) +{ + while (input_line_pointer < buffer_limit + && !is_end_of_line[(unsigned char) *input_line_pointer]) + input_line_pointer++; + + input_line_pointer++; + + /* Return pointing just after end-of-line. */ + know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); +} + +/* Sets frag for given symbol to zero_address_frag, except when the + symbol frag is already set to a dummy listing frag. */ + +static void +set_zero_frag (symbolS *symbolP) +{ + if (symbol_get_frag (symbolP)->fr_type != rs_dummy) + symbol_set_frag (symbolP, &zero_address_frag); +} + +/* In: Pointer to a symbol. + Input_line_pointer->expression. + + Out: Input_line_pointer->just after any whitespace after expression. + Tried to set symbol to value of expression. + Will change symbols type, value, and frag; */ + +void +pseudo_set (symbolS *symbolP) +{ + expressionS exp; + segT seg; + + know (symbolP); /* NULL pointer is logic error. */ + + if (!S_IS_FORWARD_REF (symbolP)) + (void) expression (&exp); + else + (void) deferred_expression (&exp); + + if (exp.X_op == O_illegal) + as_bad (_("illegal expression")); + else if (exp.X_op == O_absent) + as_bad (_("missing expression")); + else if (exp.X_op == O_big) + { + if (exp.X_add_number > 0) + as_bad (_("bignum invalid")); + else + as_bad (_("floating point number invalid")); + } + else if (exp.X_op == O_subtract + && !S_IS_FORWARD_REF (symbolP) + && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol)) + && (symbol_get_frag (exp.X_add_symbol) + == symbol_get_frag (exp.X_op_symbol))) + { + exp.X_op = O_constant; + exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol) + - S_GET_VALUE (exp.X_op_symbol)); + } + + if (symbol_section_p (symbolP)) + { + as_bad ("attempt to set value of section symbol"); + return; + } + + switch (exp.X_op) + { + case O_illegal: + case O_absent: + case O_big: + exp.X_add_number = 0; + /* Fall through. */ + case O_constant: + S_SET_SEGMENT (symbolP, absolute_section); + S_SET_VALUE (symbolP, (valueT) exp.X_add_number); + set_zero_frag (symbolP); + break; + + case O_register: +#ifndef TC_GLOBAL_REGISTER_SYMBOL_OK + if (S_IS_EXTERNAL (symbolP)) + { + as_bad ("can't equate global symbol `%s' with register name", + S_GET_NAME (symbolP)); + return; + } +#endif + S_SET_SEGMENT (symbolP, reg_section); + S_SET_VALUE (symbolP, (valueT) exp.X_add_number); + set_zero_frag (symbolP); + symbol_get_value_expression (symbolP)->X_op = O_register; + break; + + case O_symbol: + seg = S_GET_SEGMENT (exp.X_add_symbol); + /* For x=undef+const, create an expression symbol. + For x=x+const, just update x except when x is an undefined symbol + For x=defined+const, evaluate x. */ + if (symbolP == exp.X_add_symbol + && (seg != undefined_section + || !symbol_constant_p (symbolP))) + { + *symbol_X_add_number (symbolP) += exp.X_add_number; + break; + } + else if (!S_IS_FORWARD_REF (symbolP) && seg != undefined_section) + { + symbolS *s = exp.X_add_symbol; + + if (S_IS_COMMON (s)) + as_bad (_("`%s' can't be equated to common symbol '%s'"), + S_GET_NAME (symbolP), S_GET_NAME (s)); + + S_SET_SEGMENT (symbolP, seg); + S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s)); + symbol_set_frag (symbolP, symbol_get_frag (s)); + copy_symbol_attributes (symbolP, s); + break; + } + S_SET_SEGMENT (symbolP, undefined_section); + symbol_set_value_expression (symbolP, &exp); + copy_symbol_attributes (symbolP, exp.X_add_symbol); + set_zero_frag (symbolP); + break; + + default: + /* The value is some complex expression. */ + S_SET_SEGMENT (symbolP, expr_section); + symbol_set_value_expression (symbolP, &exp); + set_zero_frag (symbolP); + break; + } +} + +/* cons() + + CONStruct more frag of .bytes, or .words etc. + Should need_pass_2 be 1 then emit no frag(s). + This understands EXPRESSIONS. + + Bug (?) + + This has a split personality. We use expression() to read the + value. We can detect if the value won't fit in a byte or word. + But we can't detect if expression() discarded significant digits + in the case of a long. Not worth the crocks required to fix it. */ + +/* Select a parser for cons expressions. */ + +/* Some targets need to parse the expression in various fancy ways. + You can define TC_PARSE_CONS_EXPRESSION to do whatever you like + (for example, the HPPA does this). Otherwise, you can define + BITFIELD_CONS_EXPRESSIONS to permit bitfields to be specified, or + REPEAT_CONS_EXPRESSIONS to permit repeat counts. If none of these + are defined, which is the normal case, then only simple expressions + are permitted. */ + +#ifdef TC_M68K +static void +parse_mri_cons (expressionS *exp, unsigned int nbytes); +#endif + +#ifndef TC_PARSE_CONS_EXPRESSION +#ifdef BITFIELD_CONS_EXPRESSIONS +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES) +static void +parse_bitfield_cons (expressionS *exp, unsigned int nbytes); +#endif +#ifdef REPEAT_CONS_EXPRESSIONS +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES) +static void +parse_repeat_cons (expressionS *exp, unsigned int nbytes); +#endif + +/* If we haven't gotten one yet, just call expression. */ +#ifndef TC_PARSE_CONS_EXPRESSION +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP) +#endif +#endif + +void +do_parse_cons_expression (expressionS *exp, + int nbytes ATTRIBUTE_UNUSED) +{ + TC_PARSE_CONS_EXPRESSION (exp, nbytes); +} + + +/* Worker to do .byte etc statements. + Clobbers input_line_pointer and checks end-of-line. */ + +static void +cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */ + int rva) +{ + int c; + expressionS exp; + char *stop = NULL; + char stopc = 0; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + if (flag_mri) + stop = mri_comment_field (&stopc); + + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); + return; + } + +#ifdef TC_ADDRESS_BYTES + if (nbytes == 0) + nbytes = TC_ADDRESS_BYTES (); +#endif + +#ifdef md_cons_align + md_cons_align (nbytes); +#endif + + c = 0; + do + { +#ifdef TC_M68K + if (flag_m68k_mri) + parse_mri_cons (&exp, (unsigned int) nbytes); + else +#endif + { + if (*input_line_pointer == '"') + { + as_bad (_("unexpected `\"' in expression")); + ignore_rest_of_line (); + return; + } + TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); + } + + if (rva) + { + if (exp.X_op == O_symbol) + exp.X_op = O_symbol_rva; + else + as_fatal (_("rva without symbol")); + } + emit_expr (&exp, (unsigned int) nbytes); + ++c; + } + while (*input_line_pointer++ == ','); + + /* In MRI mode, after an odd number of bytes, we must align to an + even word boundary, unless the next instruction is a dc.b, ds.b + or dcb.b. */ + if (flag_mri && nbytes == 1 && (c & 1) != 0) + mri_pending_align = 1; + + input_line_pointer--; /* Put terminator back into stream. */ + + demand_empty_rest_of_line (); + + if (flag_mri) + mri_comment_end (stop, stopc); +} + +void +cons (int size) +{ + cons_worker (size, 0); +} + +void +s_rva (int size) +{ + cons_worker (size, 1); +} + +/* .reloc offset, reloc_name, symbol+addend. */ + +void +s_reloc (int ignore ATTRIBUTE_UNUSED) +{ + char *stop = NULL; + char stopc = 0; + expressionS exp; + char *r_name; + int c; + struct reloc_list *reloc; + + reloc = (struct reloc_list *) xmalloc (sizeof (*reloc)); + + if (flag_mri) + stop = mri_comment_field (&stopc); + + expression (&exp); + switch (exp.X_op) + { + case O_illegal: + case O_absent: + case O_big: + case O_register: + as_bad (_("missing or bad offset expression")); + goto err_out; + case O_constant: + exp.X_add_symbol = section_symbol (now_seg); + exp.X_op = O_symbol; + /* Fall thru */ + case O_symbol: + if (exp.X_add_number == 0) + { + reloc->u.a.offset_sym = exp.X_add_symbol; + break; + } + /* Fall thru */ + default: + reloc->u.a.offset_sym = make_expr_symbol (&exp); + break; + } + + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_("missing reloc type")); + goto err_out; + } + + ++input_line_pointer; + SKIP_WHITESPACE (); + r_name = input_line_pointer; + c = get_symbol_end (); + reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name); + *input_line_pointer = c; + if (reloc->u.a.howto == NULL) + { + as_bad (_("unrecognized reloc type")); + goto err_out; + } + + exp.X_op = O_absent; + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + ++input_line_pointer; + expression (&exp); + } + switch (exp.X_op) + { + case O_illegal: + case O_big: + case O_register: + as_bad (_("bad reloc expression")); + err_out: + ignore_rest_of_line (); + free (reloc); + if (flag_mri) + mri_comment_end (stop, stopc); + return; + case O_absent: + reloc->u.a.sym = NULL; + reloc->u.a.addend = 0; + break; + case O_constant: + reloc->u.a.sym = NULL; + reloc->u.a.addend = exp.X_add_number; + break; + case O_symbol: + reloc->u.a.sym = exp.X_add_symbol; + reloc->u.a.addend = exp.X_add_number; + break; + default: + reloc->u.a.sym = make_expr_symbol (&exp); + reloc->u.a.addend = 0; + break; + } + + as_where (&reloc->file, &reloc->line); + reloc->next = reloc_list; + reloc_list = reloc; + + demand_empty_rest_of_line (); + if (flag_mri) + mri_comment_end (stop, stopc); +} + +/* Put the contents of expression EXP into the object file using + NBYTES bytes. If need_pass_2 is 1, this does nothing. */ + +void +emit_expr (expressionS *exp, unsigned int nbytes) +{ + operatorT op; + char *p; + valueT extra_digit = 0; + + /* Don't do anything if we are going to make another pass. */ + if (need_pass_2) + return; + + frag_grow (nbytes); + dot_value = frag_now_fix (); + dot_frag = frag_now; + +#ifndef NO_LISTING +#ifdef OBJ_ELF + /* When gcc emits DWARF 1 debugging pseudo-ops, a line number will + appear as a four byte positive constant in the .line section, + followed by a 2 byte 0xffff. Look for that case here. */ + { + static int dwarf_line = -1; + + if (strcmp (segment_name (now_seg), ".line") != 0) + dwarf_line = -1; + else if (dwarf_line >= 0 + && nbytes == 2 + && exp->X_op == O_constant + && (exp->X_add_number == -1 || exp->X_add_number == 0xffff)) + listing_source_line ((unsigned int) dwarf_line); + else if (nbytes == 4 + && exp->X_op == O_constant + && exp->X_add_number >= 0) + dwarf_line = exp->X_add_number; + else + dwarf_line = -1; + } + + /* When gcc emits DWARF 1 debugging pseudo-ops, a file name will + appear as a 2 byte TAG_compile_unit (0x11) followed by a 2 byte + AT_sibling (0x12) followed by a four byte address of the sibling + followed by a 2 byte AT_name (0x38) followed by the name of the + file. We look for that case here. */ + { + static int dwarf_file = 0; + + if (strcmp (segment_name (now_seg), ".debug") != 0) + dwarf_file = 0; + else if (dwarf_file == 0 + && nbytes == 2 + && exp->X_op == O_constant + && exp->X_add_number == 0x11) + dwarf_file = 1; + else if (dwarf_file == 1 + && nbytes == 2 + && exp->X_op == O_constant + && exp->X_add_number == 0x12) + dwarf_file = 2; + else if (dwarf_file == 2 + && nbytes == 4) + dwarf_file = 3; + else if (dwarf_file == 3 + && nbytes == 2 + && exp->X_op == O_constant + && exp->X_add_number == 0x38) + dwarf_file = 4; + else + dwarf_file = 0; + + /* The variable dwarf_file_string tells stringer that the string + may be the name of the source file. */ + if (dwarf_file == 4) + dwarf_file_string = 1; + else + dwarf_file_string = 0; + } +#endif +#endif + + if (check_eh_frame (exp, &nbytes)) + return; + + op = exp->X_op; + + /* Allow `.word 0' in the absolute section. */ + if (now_seg == absolute_section) + { + if (op != O_constant || exp->X_add_number != 0) + as_bad (_("attempt to store value in absolute section")); + abs_section_offset += nbytes; + return; + } + + /* Handle a negative bignum. */ + if (op == O_uminus + && exp->X_add_number == 0 + && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big + && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0) + { + int i; + unsigned long carry; + + exp = symbol_get_value_expression (exp->X_add_symbol); + + /* Negate the bignum: one's complement each digit and add 1. */ + carry = 1; + for (i = 0; i < exp->X_add_number; i++) + { + unsigned long next; + + next = (((~(generic_bignum[i] & LITTLENUM_MASK)) + & LITTLENUM_MASK) + + carry); + generic_bignum[i] = next & LITTLENUM_MASK; + carry = next >> LITTLENUM_NUMBER_OF_BITS; + } + + /* We can ignore any carry out, because it will be handled by + extra_digit if it is needed. */ + + extra_digit = (valueT) -1; + op = O_big; + } + + if (op == O_absent || op == O_illegal) + { + as_warn (_("zero assumed for missing expression")); + exp->X_add_number = 0; + op = O_constant; + } + else if (op == O_big && exp->X_add_number <= 0) + { + as_bad (_("floating point number invalid")); + exp->X_add_number = 0; + op = O_constant; + } + else if (op == O_register) + { + as_warn (_("register value used as expression")); + op = O_constant; + } + + p = frag_more ((int) nbytes); + +#ifndef WORKING_DOT_WORD + /* If we have the difference of two symbols in a word, save it on + the broken_words list. See the code in write.c. */ + if (op == O_subtract && nbytes == 2) + { + struct broken_word *x; + + x = (struct broken_word *) xmalloc (sizeof (struct broken_word)); + x->next_broken_word = broken_words; + broken_words = x; + x->seg = now_seg; + x->subseg = now_subseg; + x->frag = frag_now; + x->word_goes_here = p; + x->dispfrag = 0; + x->add = exp->X_add_symbol; + x->sub = exp->X_op_symbol; + x->addnum = exp->X_add_number; + x->added = 0; + x->use_jump = 0; + new_broken_words++; + return; + } +#endif + + /* If we have an integer, but the number of bytes is too large to + pass to md_number_to_chars, handle it as a bignum. */ + if (op == O_constant && nbytes > sizeof (valueT)) + { + extra_digit = exp->X_unsigned ? 0 : -1; + convert_to_bignum (exp, !exp->X_unsigned); + op = O_big; + } + + if (op == O_constant) + { + valueT get; + valueT use; + valueT mask; + valueT hibit; + valueT unmask; + + /* JF << of >= number of bits in the object is undefined. In + particular SPARC (Sun 4) has problems. */ + if (nbytes >= sizeof (valueT)) + { + mask = 0; + if (nbytes > sizeof (valueT)) + hibit = 0; + else + hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); + } + else + { + /* Don't store these bits. */ + mask = ~(valueT) 0 << (BITS_PER_CHAR * nbytes); + hibit = (valueT) 1 << (nbytes * BITS_PER_CHAR - 1); + } + + unmask = ~mask; /* Do store these bits. */ + +#ifdef NEVER + "Do this mod if you want every overflow check to assume SIGNED 2's complement data."; + mask = ~(unmask >> 1); /* Includes sign bit now. */ +#endif + + get = exp->X_add_number; + use = get & unmask; + if ((get & mask) != 0 + && ((get & mask) != mask + || (get & hibit) == 0)) + { /* Leading bits contain both 0s & 1s. */ +#if defined (BFD64) && BFD_HOST_64BIT_LONG_LONG +#ifndef __MSVCRT__ + as_warn (_("value 0x%llx truncated to 0x%llx"), + (unsigned long long) get, (unsigned long long) use); +#else + as_warn (_("value 0x%I64x truncated to 0x%I64x"), + (unsigned long long) get, (unsigned long long) use); +#endif +#else + as_warn (_("value 0x%lx truncated to 0x%lx"), + (unsigned long) get, (unsigned long) use); +#endif + } + /* Put bytes in right order. */ + md_number_to_chars (p, use, (int) nbytes); + } + else if (op == O_big) + { + unsigned int size; + LITTLENUM_TYPE *nums; + + size = exp->X_add_number * CHARS_PER_LITTLENUM; + if (nbytes < size) + { + int i = nbytes / CHARS_PER_LITTLENUM; + if (i != 0) + { + LITTLENUM_TYPE sign = 0; + if ((generic_bignum[--i] + & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0) + sign = ~(LITTLENUM_TYPE) 0; + while (++i < exp->X_add_number) + if (generic_bignum[i] != sign) + break; + } + if (i < exp->X_add_number) + as_warn (_("bignum truncated to %d bytes"), nbytes); + size = nbytes; + } + + if (nbytes == 1) + { + md_number_to_chars (p, (valueT) generic_bignum[0], 1); + return; + } + know (nbytes % CHARS_PER_LITTLENUM == 0); + + if (target_big_endian) + { + while (nbytes > size) + { + md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); + nbytes -= CHARS_PER_LITTLENUM; + p += CHARS_PER_LITTLENUM; + } + + nums = generic_bignum + size / CHARS_PER_LITTLENUM; + while (size >= CHARS_PER_LITTLENUM) + { + --nums; + md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); + size -= CHARS_PER_LITTLENUM; + p += CHARS_PER_LITTLENUM; + } + } + else + { + nums = generic_bignum; + while (size >= CHARS_PER_LITTLENUM) + { + md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM); + ++nums; + size -= CHARS_PER_LITTLENUM; + p += CHARS_PER_LITTLENUM; + nbytes -= CHARS_PER_LITTLENUM; + } + + while (nbytes >= CHARS_PER_LITTLENUM) + { + md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM); + nbytes -= CHARS_PER_LITTLENUM; + p += CHARS_PER_LITTLENUM; + } + } + } + else + emit_expr_fix (exp, nbytes, frag_now, p); +} + +void +emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p) +{ + memset (p, 0, nbytes); + + /* Generate a fixS to record the symbol value. */ + +#ifdef TC_CONS_FIX_NEW + TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp); +#else + { + bfd_reloc_code_real_type r; + + switch (nbytes) + { + case 1: + r = BFD_RELOC_8; + break; + case 2: + r = BFD_RELOC_16; + break; + case 3: + r = BFD_RELOC_24; + break; + case 4: + r = BFD_RELOC_32; + break; + case 8: + r = BFD_RELOC_64; + break; + default: + as_bad (_("unsupported BFD relocation size %u"), nbytes); + r = BFD_RELOC_32; + break; + } + fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp, + 0, r); + } +#endif +} + +#ifdef BITFIELD_CONS_EXPRESSIONS + +/* i960 assemblers, (eg, asm960), allow bitfields after ".byte" as + w:x,y:z, where w and y are bitwidths and x and y are values. They + then pack them all together. We do a little better in that we allow + them in words, longs, etc. and we'll pack them in target byte order + for you. + + The rules are: pack least significant bit first, if a field doesn't + entirely fit, put it in the next unit. Overflowing the bitfield is + explicitly *not* even a warning. The bitwidth should be considered + a "mask". + + To use this function the tc-XXX.h file should define + BITFIELD_CONS_EXPRESSIONS. */ + +static void +parse_bitfield_cons (exp, nbytes) + expressionS *exp; + unsigned int nbytes; +{ + unsigned int bits_available = BITS_PER_CHAR * nbytes; + char *hold = input_line_pointer; + + (void) expression (exp); + + if (*input_line_pointer == ':') + { + /* Bitfields. */ + long value = 0; + + for (;;) + { + unsigned long width; + + if (*input_line_pointer != ':') + { + input_line_pointer = hold; + break; + } /* Next piece is not a bitfield. */ + + /* In the general case, we can't allow + full expressions with symbol + differences and such. The relocation + entries for symbols not defined in this + assembly would require arbitrary field + widths, positions, and masks which most + of our current object formats don't + support. + + In the specific case where a symbol + *is* defined in this assembly, we + *could* build fixups and track it, but + this could lead to confusion for the + backends. I'm lazy. I'll take any + SEG_ABSOLUTE. I think that means that + you can use a previous .set or + .equ type symbol. xoxorich. */ + + if (exp->X_op == O_absent) + { + as_warn (_("using a bit field width of zero")); + exp->X_add_number = 0; + exp->X_op = O_constant; + } /* Implied zero width bitfield. */ + + if (exp->X_op != O_constant) + { + *input_line_pointer = '\0'; + as_bad (_("field width \"%s\" too complex for a bitfield"), hold); + *input_line_pointer = ':'; + demand_empty_rest_of_line (); + return; + } /* Too complex. */ + + if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes)) + { + as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), + width, nbytes, (BITS_PER_CHAR * nbytes)); + width = BITS_PER_CHAR * nbytes; + } /* Too big. */ + + if (width > bits_available) + { + /* FIXME-SOMEDAY: backing up and reparsing is wasteful. */ + input_line_pointer = hold; + exp->X_add_number = value; + break; + } /* Won't fit. */ + + /* Skip ':'. */ + hold = ++input_line_pointer; + + (void) expression (exp); + if (exp->X_op != O_constant) + { + char cache = *input_line_pointer; + + *input_line_pointer = '\0'; + as_bad (_("field value \"%s\" too complex for a bitfield"), hold); + *input_line_pointer = cache; + demand_empty_rest_of_line (); + return; + } /* Too complex. */ + + value |= ((~(-1 << width) & exp->X_add_number) + << ((BITS_PER_CHAR * nbytes) - bits_available)); + + if ((bits_available -= width) == 0 + || is_it_end_of_statement () + || *input_line_pointer != ',') + { + break; + } /* All the bitfields we're gonna get. */ + + hold = ++input_line_pointer; + (void) expression (exp); + } + + exp->X_add_number = value; + exp->X_op = O_constant; + exp->X_unsigned = 1; + exp->X_extrabit = 0; + } +} + +#endif /* BITFIELD_CONS_EXPRESSIONS */ + +/* Handle an MRI style string expression. */ + +#ifdef TC_M68K +static void +parse_mri_cons (exp, nbytes) + expressionS *exp; + unsigned int nbytes; +{ + if (*input_line_pointer != '\'' + && (input_line_pointer[1] != '\'' + || (*input_line_pointer != 'A' + && *input_line_pointer != 'E'))) + TC_PARSE_CONS_EXPRESSION (exp, nbytes); + else + { + unsigned int scan; + unsigned int result = 0; + + /* An MRI style string. Cut into as many bytes as will fit into + a nbyte chunk, left justify if necessary, and separate with + commas so we can try again later. */ + if (*input_line_pointer == 'A') + ++input_line_pointer; + else if (*input_line_pointer == 'E') + { + as_bad (_("EBCDIC constants are not supported")); + ++input_line_pointer; + } + + input_line_pointer++; + for (scan = 0; scan < nbytes; scan++) + { + if (*input_line_pointer == '\'') + { + if (input_line_pointer[1] == '\'') + { + input_line_pointer++; + } + else + break; + } + result = (result << 8) | (*input_line_pointer++); + } + + /* Left justify. */ + while (scan < nbytes) + { + result <<= 8; + scan++; + } + + /* Create correct expression. */ + exp->X_op = O_constant; + exp->X_add_number = result; + + /* Fake it so that we can read the next char too. */ + if (input_line_pointer[0] != '\'' || + (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\'')) + { + input_line_pointer -= 2; + input_line_pointer[0] = ','; + input_line_pointer[1] = '\''; + } + else + input_line_pointer++; + } +} +#endif /* TC_M68K */ + +#ifdef REPEAT_CONS_EXPRESSIONS + +/* Parse a repeat expression for cons. This is used by the MIPS + assembler. The format is NUMBER:COUNT; NUMBER appears in the + object file COUNT times. + + To use this for a target, define REPEAT_CONS_EXPRESSIONS. */ + +static void +parse_repeat_cons (exp, nbytes) + expressionS *exp; + unsigned int nbytes; +{ + expressionS count; + int i; + + expression (exp); + + if (*input_line_pointer != ':') + { + /* No repeat count. */ + return; + } + + ++input_line_pointer; + expression (&count); + if (count.X_op != O_constant + || count.X_add_number <= 0) + { + as_warn (_("unresolvable or nonpositive repeat count; using 1")); + return; + } + + /* The cons function is going to output this expression once. So we + output it count - 1 times. */ + for (i = count.X_add_number - 1; i > 0; i--) + emit_expr (exp, nbytes); +} + +#endif /* REPEAT_CONS_EXPRESSIONS */ + +/* Parse a floating point number represented as a hex constant. This + permits users to specify the exact bits they want in the floating + point number. */ + +static int +hex_float (int float_type, char *bytes) +{ + int length; + int i; + + switch (float_type) + { + case 'f': + case 'F': + case 's': + case 'S': + length = 4; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + length = 8; + break; + + case 'x': + case 'X': + length = 12; + break; + + case 'p': + case 'P': + length = 12; + break; + + default: + as_bad (_("unknown floating type type '%c'"), float_type); + return -1; + } + + /* It would be nice if we could go through expression to parse the + hex constant, but if we get a bignum it's a pain to sort it into + the buffer correctly. */ + i = 0; + while (hex_p (*input_line_pointer) || *input_line_pointer == '_') + { + int d; + + /* The MRI assembler accepts arbitrary underscores strewn about + through the hex constant, so we ignore them as well. */ + if (*input_line_pointer == '_') + { + ++input_line_pointer; + continue; + } + + if (i >= length) + { + as_warn (_("floating point constant too large")); + return -1; + } + d = hex_value (*input_line_pointer) << 4; + ++input_line_pointer; + while (*input_line_pointer == '_') + ++input_line_pointer; + if (hex_p (*input_line_pointer)) + { + d += hex_value (*input_line_pointer); + ++input_line_pointer; + } + if (target_big_endian) + bytes[i] = d; + else + bytes[length - i - 1] = d; + ++i; + } + + if (i < length) + { + if (target_big_endian) + memset (bytes + i, 0, length - i); + else + memset (bytes, 0, length - i); + } + + return length; +} + +/* float_cons() + + CONStruct some more frag chars of .floats .ffloats etc. + Makes 0 or more new frags. + If need_pass_2 == 1, no frags are emitted. + This understands only floating literals, not expressions. Sorry. + + A floating constant is defined by atof_generic(), except it is preceded + by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its + reading, I decided to be incompatible. This always tries to give you + rounded bits to the precision of the pseudo-op. Former AS did premature + truncation, restored noisy bits instead of trailing 0s AND gave you + a choice of 2 flavours of noise according to which of 2 floating-point + scanners you directed AS to use. + + In: input_line_pointer->whitespace before, or '0' of flonum. */ + +void +float_cons (/* Clobbers input_line-pointer, checks end-of-line. */ + int float_type /* 'f':.ffloat ... 'F':.float ... */) +{ + char *p; + int length; /* Number of chars in an object. */ + char *err; /* Error from scanning floating literal. */ + char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; + + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + return; + } + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_cons_align + md_cons_align (1); +#endif + + do + { + /* input_line_pointer->1st char of a flonum (we hope!). */ + SKIP_WHITESPACE (); + + /* Skip any 0{letter} that may be present. Don't even check if the + letter is legal. Someone may invent a "z" format and this routine + has no use for such information. Lusers beware: you get + diagnostics if your input is ill-conditioned. */ + if (input_line_pointer[0] == '0' + && ISALPHA (input_line_pointer[1])) + input_line_pointer += 2; + + /* Accept :xxxx, where the x's are hex digits, for a floating + point with the exact digits specified. */ + if (input_line_pointer[0] == ':') + { + ++input_line_pointer; + length = hex_float (float_type, temp); + if (length < 0) + { + ignore_rest_of_line (); + return; + } + } + else + { + err = md_atof (float_type, temp, &length); + know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); + know (err != NULL || length > 0); + if (err) + { + as_bad (_("bad floating literal: %s"), err); + ignore_rest_of_line (); + return; + } + } + + if (!need_pass_2) + { + int count; + + count = 1; + +#ifdef REPEAT_CONS_EXPRESSIONS + if (*input_line_pointer == ':') + { + expressionS count_exp; + + ++input_line_pointer; + expression (&count_exp); + + if (count_exp.X_op != O_constant + || count_exp.X_add_number <= 0) + as_warn (_("unresolvable or nonpositive repeat count; using 1")); + else + count = count_exp.X_add_number; + } +#endif + + while (--count >= 0) + { + p = frag_more (length); + memcpy (p, temp, (unsigned int) length); + } + } + SKIP_WHITESPACE (); + } + while (*input_line_pointer++ == ','); + + /* Put terminator back into stream. */ + --input_line_pointer; + demand_empty_rest_of_line (); +} + +/* Return the size of a LEB128 value. */ + +static inline int +sizeof_sleb128 (offsetT value) +{ + int size = 0; + unsigned byte; + + do + { + byte = (value & 0x7f); + /* Sadly, we cannot rely on typical arithmetic right shift behaviour. + Fortunately, we can structure things so that the extra work reduces + to a noop on systems that do things "properly". */ + value = (value >> 7) | ~(-(offsetT)1 >> 7); + size += 1; + } + while (!(((value == 0) && ((byte & 0x40) == 0)) + || ((value == -1) && ((byte & 0x40) != 0)))); + + return size; +} + +static inline int +sizeof_uleb128 (valueT value) +{ + int size = 0; + + do + { + value >>= 7; + size += 1; + } + while (value != 0); + + return size; +} + +int +sizeof_leb128 (valueT value, int sign) +{ + if (sign) + return sizeof_sleb128 ((offsetT) value); + else + return sizeof_uleb128 (value); +} + +/* Output a LEB128 value. */ + +static inline int +output_sleb128 (char *p, offsetT value) +{ + char *orig = p; + int more; + + do + { + unsigned byte = (value & 0x7f); + + /* Sadly, we cannot rely on typical arithmetic right shift behaviour. + Fortunately, we can structure things so that the extra work reduces + to a noop on systems that do things "properly". */ + value = (value >> 7) | ~(-(offsetT)1 >> 7); + + more = !((((value == 0) && ((byte & 0x40) == 0)) + || ((value == -1) && ((byte & 0x40) != 0)))); + if (more) + byte |= 0x80; + + *p++ = byte; + } + while (more); + + return p - orig; +} + +static inline int +output_uleb128 (char *p, valueT value) +{ + char *orig = p; + + do + { + unsigned byte = (value & 0x7f); + value >>= 7; + if (value != 0) + /* More bytes to follow. */ + byte |= 0x80; + + *p++ = byte; + } + while (value != 0); + + return p - orig; +} + +int +output_leb128 (char *p, valueT value, int sign) +{ + if (sign) + return output_sleb128 (p, (offsetT) value); + else + return output_uleb128 (p, value); +} + +/* Do the same for bignums. We combine sizeof with output here in that + we don't output for NULL values of P. It isn't really as critical as + for "normal" values that this be streamlined. */ + +static inline int +output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size) +{ + char *orig = p; + valueT val = 0; + int loaded = 0; + unsigned byte; + + /* Strip leading sign extensions off the bignum. */ + while (size > 1 + && bignum[size - 1] == LITTLENUM_MASK + && bignum[size - 2] > LITTLENUM_MASK / 2) + size--; + + do + { + /* OR in the next part of the littlenum. */ + val |= (*bignum << loaded); + loaded += LITTLENUM_NUMBER_OF_BITS; + size--; + bignum++; + + /* Add bytes until there are less than 7 bits left in VAL + or until every non-sign bit has been written. */ + do + { + byte = val & 0x7f; + loaded -= 7; + val >>= 7; + if (size > 0 + || val != ((byte & 0x40) == 0 ? 0 : ((valueT) 1 << loaded) - 1)) + byte |= 0x80; + + if (orig) + *p = byte; + p++; + } + while ((byte & 0x80) != 0 && loaded >= 7); + } + while (size > 0); + + /* Mop up any left-over bits (of which there will be less than 7). */ + if ((byte & 0x80) != 0) + { + /* Sign-extend VAL. */ + if (val & (1 << (loaded - 1))) + val |= ~0 << loaded; + if (orig) + *p = val & 0x7f; + p++; + } + + return p - orig; +} + +static inline int +output_big_uleb128 (char *p, LITTLENUM_TYPE *bignum, int size) +{ + char *orig = p; + valueT val = 0; + int loaded = 0; + unsigned byte; + + /* Strip leading zeros off the bignum. */ + /* XXX: Is this needed? */ + while (size > 0 && bignum[size - 1] == 0) + size--; + + do + { + if (loaded < 7 && size > 0) + { + val |= (*bignum << loaded); + loaded += 8 * CHARS_PER_LITTLENUM; + size--; + bignum++; + } + + byte = val & 0x7f; + loaded -= 7; + val >>= 7; + + if (size > 0 || val) + byte |= 0x80; + + if (orig) + *p = byte; + p++; + } + while (byte & 0x80); + + return p - orig; +} + +static int +output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, int size, int sign) +{ + if (sign) + return output_big_sleb128 (p, bignum, size); + else + return output_big_uleb128 (p, bignum, size); +} + +/* Generate the appropriate fragments for a given expression to emit a + leb128 value. */ + +static void +emit_leb128_expr (expressionS *exp, int sign) +{ + operatorT op = exp->X_op; + unsigned int nbytes; + + if (op == O_absent || op == O_illegal) + { + as_warn (_("zero assumed for missing expression")); + exp->X_add_number = 0; + op = O_constant; + } + else if (op == O_big && exp->X_add_number <= 0) + { + as_bad (_("floating point number invalid")); + exp->X_add_number = 0; + op = O_constant; + } + else if (op == O_register) + { + as_warn (_("register value used as expression")); + op = O_constant; + } + else if (op == O_constant + && sign + && (exp->X_add_number < 0) == !exp->X_extrabit) + { + /* We're outputting a signed leb128 and the sign of X_add_number + doesn't reflect the sign of the original value. Convert EXP + to a correctly-extended bignum instead. */ + convert_to_bignum (exp, exp->X_extrabit); + op = O_big; + } + + /* Let check_eh_frame know that data is being emitted. nbytes == -1 is + a signal that this is leb128 data. It shouldn't optimize this away. */ + nbytes = (unsigned int) -1; + if (check_eh_frame (exp, &nbytes)) + abort (); + + /* Let the backend know that subsequent data may be byte aligned. */ +#ifdef md_cons_align + md_cons_align (1); +#endif + + if (op == O_constant) + { + /* If we've got a constant, emit the thing directly right now. */ + + valueT value = exp->X_add_number; + int size; + char *p; + + size = sizeof_leb128 (value, sign); + p = frag_more (size); + output_leb128 (p, value, sign); + } + else if (op == O_big) + { + /* O_big is a different sort of constant. */ + + int size; + char *p; + + size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign); + p = frag_more (size); + output_big_leb128 (p, generic_bignum, exp->X_add_number, sign); + } + else + { + /* Otherwise, we have to create a variable sized fragment and + resolve things later. */ + + frag_var (rs_leb128, sizeof_uleb128 (~(valueT) 0), 0, sign, + make_expr_symbol (exp), 0, (char *) NULL); + } +} + +/* Parse the .sleb128 and .uleb128 pseudos. */ + +void +s_leb128 (int sign) +{ + expressionS exp; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + do + { + expression (&exp); + emit_leb128_expr (&exp, sign); + } + while (*input_line_pointer++ == ','); + + input_line_pointer--; + demand_empty_rest_of_line (); +} + +static void +stringer_append_char (int c, int bitsize) +{ + if (!target_big_endian) + FRAG_APPEND_1_CHAR (c); + + switch (bitsize) + { + case 64: + FRAG_APPEND_1_CHAR (0); + FRAG_APPEND_1_CHAR (0); + FRAG_APPEND_1_CHAR (0); + FRAG_APPEND_1_CHAR (0); + /* Fall through. */ + case 32: + FRAG_APPEND_1_CHAR (0); + FRAG_APPEND_1_CHAR (0); + /* Fall through. */ + case 16: + FRAG_APPEND_1_CHAR (0); + /* Fall through. */ + case 8: + break; + default: + /* Called with invalid bitsize argument. */ + abort (); + break; + } + if (target_big_endian) + FRAG_APPEND_1_CHAR (c); +} + +/* Worker to do .ascii etc statements. + Reads 0 or more ',' separated, double-quoted strings. + Caller should have checked need_pass_2 is FALSE because we don't + check it. + Checks for end-of-line. + BITS_APPENDZERO says how many bits are in a target char. + The bottom bit is set if a NUL char should be appended to the strings. */ + +void +stringer (int bits_appendzero) +{ + const int bitsize = bits_appendzero & ~7; + const int append_zero = bits_appendzero & 1; + unsigned int c; +#if !defined(NO_LISTING) && defined (OBJ_ELF) + char *start; +#endif + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_cons_align + md_cons_align (1); +#endif + + /* The following awkward logic is to parse ZERO or more strings, + comma separated. Recall a string expression includes spaces + before the opening '\"' and spaces after the closing '\"'. + We fake a leading ',' if there is (supposed to be) + a 1st, expression. We keep demanding expressions for each ','. */ + if (is_it_end_of_statement ()) + { + c = 0; /* Skip loop. */ + ++input_line_pointer; /* Compensate for end of loop. */ + } + else + { + c = ','; /* Do loop. */ + } + /* If we have been switched into the abs_section then we + will not have an obstack onto which we can hang strings. */ + if (now_seg == absolute_section) + { + as_bad (_("strings must be placed into a section")); + c = 0; + ignore_rest_of_line (); + } + + while (c == ',' || c == '<' || c == '"') + { + SKIP_WHITESPACE (); + switch (*input_line_pointer) + { + case '\"': + ++input_line_pointer; /*->1st char of string. */ +#if !defined(NO_LISTING) && defined (OBJ_ELF) + start = input_line_pointer; +#endif + + while (is_a_char (c = next_char_of_string ())) + stringer_append_char (c, bitsize); + + if (append_zero) + stringer_append_char (0, bitsize); + + know (input_line_pointer[-1] == '\"'); + +#if !defined(NO_LISTING) && defined (OBJ_ELF) + /* In ELF, when gcc is emitting DWARF 1 debugging output, it + will emit .string with a filename in the .debug section + after a sequence of constants. See the comment in + emit_expr for the sequence. emit_expr will set + dwarf_file_string to non-zero if this string might be a + source file name. */ + if (strcmp (segment_name (now_seg), ".debug") != 0) + dwarf_file_string = 0; + else if (dwarf_file_string) + { + c = input_line_pointer[-1]; + input_line_pointer[-1] = '\0'; + listing_source_file (start); + input_line_pointer[-1] = c; + } +#endif + + break; + case '<': + input_line_pointer++; + c = get_single_number (); + stringer_append_char (c, bitsize); + if (*input_line_pointer != '>') + as_bad (_("expected ")); + + input_line_pointer++; + break; + case ',': + input_line_pointer++; + break; + } + SKIP_WHITESPACE (); + c = *input_line_pointer; + } + + demand_empty_rest_of_line (); +} + +/* FIXME-SOMEDAY: I had trouble here on characters with the + high bits set. We'll probably also have trouble with + multibyte chars, wide chars, etc. Also be careful about + returning values bigger than 1 byte. xoxorich. */ + +unsigned int +next_char_of_string (void) +{ + unsigned int c; + + c = *input_line_pointer++ & CHAR_MASK; + switch (c) + { + case '\"': + c = NOT_A_CHAR; + break; + + case '\n': + as_warn (_("unterminated string; newline inserted")); + bump_line_counters (); + break; + +#ifndef NO_STRING_ESCAPES + case '\\': + switch (c = *input_line_pointer++) + { + case 'b': + c = '\b'; + break; + + case 'f': + c = '\f'; + break; + + case 'n': + c = '\n'; + break; + + case 'r': + c = '\r'; + break; + + case 't': + c = '\t'; + break; + + case 'v': + c = '\013'; + break; + + case '\\': + case '"': + break; /* As itself. */ + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + long number; + int i; + + for (i = 0, number = 0; + ISDIGIT (c) && i < 3; + c = *input_line_pointer++, i++) + { + number = number * 8 + c - '0'; + } + + c = number & 0xff; + } + --input_line_pointer; + break; + + case 'x': + case 'X': + { + long number; + + number = 0; + c = *input_line_pointer++; + while (ISXDIGIT (c)) + { + if (ISDIGIT (c)) + number = number * 16 + c - '0'; + else if (ISUPPER (c)) + number = number * 16 + c - 'A' + 10; + else + number = number * 16 + c - 'a' + 10; + c = *input_line_pointer++; + } + c = number & 0xff; + --input_line_pointer; + } + break; + + case '\n': + /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */ + as_warn (_("unterminated string; newline inserted")); + c = '\n'; + bump_line_counters (); + break; + + default: + +#ifdef ONLY_STANDARD_ESCAPES + as_bad (_("bad escaped character in string")); + c = '?'; +#endif /* ONLY_STANDARD_ESCAPES */ + + break; + } + break; +#endif /* ! defined (NO_STRING_ESCAPES) */ + + default: + break; + } + return (c); +} + +static segT +get_segmented_expression (expressionS *expP) +{ + segT retval; + + retval = expression (expP); + if (expP->X_op == O_illegal + || expP->X_op == O_absent + || expP->X_op == O_big) + { + as_bad (_("expected address expression")); + expP->X_op = O_constant; + expP->X_add_number = 0; + retval = absolute_section; + } + return retval; +} + +static segT +get_known_segmented_expression (expressionS *expP) +{ + segT retval = get_segmented_expression (expP); + + if (retval == undefined_section) + { + /* There is no easy way to extract the undefined symbol from the + expression. */ + if (expP->X_add_symbol != NULL + && S_GET_SEGMENT (expP->X_add_symbol) != expr_section) + as_warn (_("symbol \"%s\" undefined; zero assumed"), + S_GET_NAME (expP->X_add_symbol)); + else + as_warn (_("some symbol undefined; zero assumed")); + retval = absolute_section; + expP->X_op = O_constant; + expP->X_add_number = 0; + } + return retval; +} + +char /* Return terminator. */ +get_absolute_expression_and_terminator (long *val_pointer /* Return value of expression. */) +{ + /* FIXME: val_pointer should probably be offsetT *. */ + *val_pointer = (long) get_absolute_expression (); + return (*input_line_pointer++); +} + +/* Like demand_copy_string, but return NULL if the string contains any '\0's. + Give a warning if that happens. */ + +char * +demand_copy_C_string (int *len_pointer) +{ + char *s; + + if ((s = demand_copy_string (len_pointer)) != 0) + { + int len; + + for (len = *len_pointer; len > 0; len--) + { + if (*s == 0) + { + s = 0; + len = 1; + *len_pointer = 0; + as_bad (_("this string may not contain \'\\0\'")); + } + } + } + + return s; +} + +/* Demand string, but return a safe (=private) copy of the string. + Return NULL if we can't read a string here. */ + +char * +demand_copy_string (int *lenP) +{ + unsigned int c; + int len; + char *retval; + + len = 0; + SKIP_WHITESPACE (); + if (*input_line_pointer == '\"') + { + input_line_pointer++; /* Skip opening quote. */ + + while (is_a_char (c = next_char_of_string ())) + { + obstack_1grow (¬es, c); + len++; + } + /* JF this next line is so demand_copy_C_string will return a + null terminated string. */ + obstack_1grow (¬es, '\0'); + retval = (char *) obstack_finish (¬es); + } + else + { + as_bad (_("missing string")); + retval = NULL; + ignore_rest_of_line (); + } + *lenP = len; + return (retval); +} + +/* In: Input_line_pointer->next character. + + Do: Skip input_line_pointer over all whitespace. + + Out: 1 if input_line_pointer->end-of-line. */ + +int +is_it_end_of_statement (void) +{ + SKIP_WHITESPACE (); + return (is_end_of_line[(unsigned char) *input_line_pointer]); +} + +void +equals (char *sym_name, int reassign) +{ + char *stop = NULL; + char stopc = 0; + + input_line_pointer++; + if (*input_line_pointer == '=') + input_line_pointer++; + if (reassign < 0 && *input_line_pointer == '=') + input_line_pointer++; + + while (*input_line_pointer == ' ' || *input_line_pointer == '\t') + input_line_pointer++; + + if (flag_mri) + stop = mri_comment_field (&stopc); + + assign_symbol (sym_name, reassign >= 0 ? !reassign : reassign); + + if (flag_mri) + { + demand_empty_rest_of_line (); + mri_comment_end (stop, stopc); + } +} + +/* .incbin -- include a file verbatim at the current location. */ + +void +s_incbin (int x ATTRIBUTE_UNUSED) +{ + FILE * binfile; + char * path; + char * filename; + char * binfrag; + long skip = 0; + long count = 0; + long bytes; + int len; + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + +#ifdef md_cons_align + md_cons_align (1); +#endif + + SKIP_WHITESPACE (); + filename = demand_copy_string (& len); + if (filename == NULL) + return; + + SKIP_WHITESPACE (); + + /* Look for optional skip and count. */ + if (* input_line_pointer == ',') + { + ++ input_line_pointer; + skip = get_absolute_expression (); + + SKIP_WHITESPACE (); + + if (* input_line_pointer == ',') + { + ++ input_line_pointer; + + count = get_absolute_expression (); + if (count == 0) + as_warn (_(".incbin count zero, ignoring `%s'"), filename); + + SKIP_WHITESPACE (); + } + } + + demand_empty_rest_of_line (); + + /* Try opening absolute path first, then try include dirs. */ + binfile = fopen (filename, FOPEN_RB); + if (binfile == NULL) + { + int i; + + path = (char *) xmalloc ((unsigned long) len + include_dir_maxlen + 5); + + for (i = 0; i < include_dir_count; i++) + { + sprintf (path, "%s/%s", include_dirs[i], filename); + + binfile = fopen (path, FOPEN_RB); + if (binfile != NULL) + break; + } + + if (binfile == NULL) + as_bad (_("file not found: %s"), filename); + } + else + path = xstrdup (filename); + + if (binfile) + { + long file_len; + + register_dependency (path); + + /* Compute the length of the file. */ + if (fseek (binfile, 0, SEEK_END) != 0) + { + as_bad (_("seek to end of .incbin file failed `%s'"), path); + goto done; + } + file_len = ftell (binfile); + + /* If a count was not specified use the remainder of the file. */ + if (count == 0) + count = file_len - skip; + + if (skip < 0 || count < 0 || file_len < 0 || skip + count > file_len) + { + as_bad (_("skip (%ld) or count (%ld) invalid for file size (%ld)"), + skip, count, file_len); + goto done; + } + + if (fseek (binfile, skip, SEEK_SET) != 0) + { + as_bad (_("could not skip to %ld in file `%s'"), skip, path); + goto done; + } + + /* Allocate frag space and store file contents in it. */ + binfrag = frag_more (count); + + bytes = fread (binfrag, 1, count, binfile); + if (bytes < count) + as_warn (_("truncated file `%s', %ld of %ld bytes read"), + path, bytes, count); + } +done: + if (binfile != NULL) + fclose (binfile); + if (path) + free (path); +} + +/* .include -- include a file at this point. */ + +void +s_include (int arg ATTRIBUTE_UNUSED) +{ + char *filename; + int i; + FILE *try_file; + char *path; + + if (!flag_m68k_mri) + { + filename = demand_copy_string (&i); + if (filename == NULL) + { + /* demand_copy_string has already printed an error and + called ignore_rest_of_line. */ + return; + } + } + else + { + SKIP_WHITESPACE (); + i = 0; + while (!is_end_of_line[(unsigned char) *input_line_pointer] + && *input_line_pointer != ' ' + && *input_line_pointer != '\t') + { + obstack_1grow (¬es, *input_line_pointer); + ++input_line_pointer; + ++i; + } + + obstack_1grow (¬es, '\0'); + filename = (char *) obstack_finish (¬es); + while (!is_end_of_line[(unsigned char) *input_line_pointer]) + ++input_line_pointer; + } + + demand_empty_rest_of_line (); + path = (char *) xmalloc ((unsigned long) i + + include_dir_maxlen + 5 /* slop */ ); + + for (i = 0; i < include_dir_count; i++) + { + strcpy (path, include_dirs[i]); + strcat (path, "/"); + strcat (path, filename); + if (0 != (try_file = fopen (path, FOPEN_RT))) + { + fclose (try_file); + goto gotit; + } + } + + free (path); + path = filename; +gotit: + /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */ + register_dependency (path); + input_scrub_insert_file (path); +} + +void +add_include_dir (char *path) +{ + int i; + + if (include_dir_count == 0) + { + include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs)); + include_dirs[0] = "."; /* Current dir. */ + include_dir_count = 2; + } + else + { + include_dir_count++; + include_dirs = + (char **) realloc (include_dirs, + include_dir_count * sizeof (*include_dirs)); + } + + include_dirs[include_dir_count - 1] = path; /* New one. */ + + i = strlen (path); + if (i > include_dir_maxlen) + include_dir_maxlen = i; +} + +/* Output debugging information to denote the source file. */ + +static void +generate_file_debug (void) +{ + if (debug_type == DEBUG_STABS) + stabs_generate_asm_file (); +} + +/* Output line number debugging information for the current source line. */ + +void +generate_lineno_debug (void) +{ + switch (debug_type) + { + case DEBUG_UNSPECIFIED: + case DEBUG_NONE: + case DEBUG_DWARF: + break; + case DEBUG_STABS: + stabs_generate_asm_lineno (); + break; + case DEBUG_ECOFF: + ecoff_generate_asm_lineno (); + break; + case DEBUG_DWARF2: + /* ??? We could here indicate to dwarf2dbg.c that something + has changed. However, since there is additional backend + support that is required (calling dwarf2_emit_insn), we + let dwarf2dbg.c call as_where on its own. */ + break; + } +} + +/* Output debugging information to mark a function entry point or end point. + END_P is zero for .func, and non-zero for .endfunc. */ + +void +s_func (int end_p) +{ + do_s_func (end_p, NULL); +} + +/* Subroutine of s_func so targets can choose a different default prefix. + If DEFAULT_PREFIX is NULL, use the target's "leading char". */ + +static void +do_s_func (int end_p, const char *default_prefix) +{ + /* Record the current function so that we can issue an error message for + misplaced .func,.endfunc, and also so that .endfunc needs no + arguments. */ + static char *current_name; + static char *current_label; + + if (end_p) + { + if (current_name == NULL) + { + as_bad (_("missing .func")); + ignore_rest_of_line (); + return; + } + + if (debug_type == DEBUG_STABS) + stabs_generate_asm_endfunc (current_name, current_label); + + current_name = current_label = NULL; + } + else /* ! end_p */ + { + char *name, *label; + char delim1, delim2; + + if (current_name != NULL) + { + as_bad (_(".endfunc missing for previous .func")); + ignore_rest_of_line (); + return; + } + + name = input_line_pointer; + delim1 = get_symbol_end (); + name = xstrdup (name); + *input_line_pointer = delim1; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + if (default_prefix) + { + if (asprintf (&label, "%s%s", default_prefix, name) == -1) + as_fatal ("%s", xstrerror (errno)); + } + else + { + char leading_char = bfd_get_symbol_leading_char (stdoutput); + /* Missing entry point, use function's name with the leading + char prepended. */ + if (leading_char) + { + if (asprintf (&label, "%c%s", leading_char, name) == -1) + as_fatal ("%s", xstrerror (errno)); + } + else + label = name; + } + } + else + { + ++input_line_pointer; + SKIP_WHITESPACE (); + label = input_line_pointer; + delim2 = get_symbol_end (); + label = xstrdup (label); + *input_line_pointer = delim2; + } + + if (debug_type == DEBUG_STABS) + stabs_generate_asm_func (name, label); + + current_name = name; + current_label = label; + } + + demand_empty_rest_of_line (); +} + +#ifdef HANDLE_BUNDLE + +void +s_bundle_align_mode (int arg ATTRIBUTE_UNUSED) +{ + unsigned int align = get_absolute_expression (); + SKIP_WHITESPACE (); + demand_empty_rest_of_line (); + + if (align > (unsigned int) TC_ALIGN_LIMIT) + as_fatal (_(".bundle_align_mode alignment too large (maximum %u)"), + (unsigned int) TC_ALIGN_LIMIT); + + if (bundle_lock_frag != NULL) + { + as_bad (_("cannot change .bundle_align_mode inside .bundle_lock")); + return; + } + + bundle_align_p2 = align; +} + +void +s_bundle_lock (int arg ATTRIBUTE_UNUSED) +{ + demand_empty_rest_of_line (); + + if (bundle_align_p2 == 0) + { + as_bad (_(".bundle_lock is meaningless without .bundle_align_mode")); + return; + } + + if (bundle_lock_depth == 0) + { + bundle_lock_frchain = frchain_now; + bundle_lock_frag = start_bundle (); + } + ++bundle_lock_depth; +} + +void +s_bundle_unlock (int arg ATTRIBUTE_UNUSED) +{ + unsigned int size; + + demand_empty_rest_of_line (); + + if (bundle_lock_frag == NULL) + { + as_bad (_(".bundle_unlock without preceding .bundle_lock")); + return; + } + + gas_assert (bundle_align_p2 > 0); + + gas_assert (bundle_lock_depth > 0); + if (--bundle_lock_depth > 0) + return; + + size = pending_bundle_size (bundle_lock_frag); + + if (size > (1U << bundle_align_p2)) + as_bad (_(".bundle_lock sequence is %u bytes, but bundle size only %u"), + size, 1 << bundle_align_p2); + else + finish_bundle (bundle_lock_frag, size); + + bundle_lock_frag = NULL; + bundle_lock_frchain = NULL; +} + +#endif /* HANDLE_BUNDLE */ + +void +s_ignore (int arg ATTRIBUTE_UNUSED) +{ + ignore_rest_of_line (); +} + +void +read_print_statistics (FILE *file) +{ + hash_print_statistics (file, "pseudo-op table", po_hash); +} + +/* Inserts the given line into the input stream. + + This call avoids macro/conditionals nesting checking, since the contents of + the line are assumed to replace the contents of a line already scanned. + + An appropriate use of this function would be substitution of input lines when + called by md_start_line_hook(). The given line is assumed to already be + properly scrubbed. */ + +void +input_scrub_insert_line (const char *line) +{ + sb newline; + size_t len = strlen (line); + sb_build (&newline, len); + sb_add_buffer (&newline, line, len); + input_scrub_include_sb (&newline, input_line_pointer, 0); + sb_kill (&newline); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Insert a file into the input stream; the path must resolve to an actual + file; no include path searching or dependency registering is performed. */ + +void +input_scrub_insert_file (char *path) +{ + input_scrub_include_file (path, input_line_pointer); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Find the end of a line, considering quotation and escaping of quotes. */ + +#if !defined(TC_SINGLE_QUOTE_STRINGS) && defined(SINGLE_QUOTE_STRINGS) +# define TC_SINGLE_QUOTE_STRINGS 1 +#endif + +static char * +_find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED, + int in_macro) +{ + char inquote = '\0'; + int inescape = 0; + + while (!is_end_of_line[(unsigned char) *s] + || (inquote && !ISCNTRL (*s)) + || (inquote == '\'' && flag_mri) +#ifdef TC_EOL_IN_INSN + || (insn && TC_EOL_IN_INSN (s)) +#endif + /* PR 6926: When we are parsing the body of a macro the sequence + \@ is special - it refers to the invocation count. If the @ + character happens to be registered as a line-separator character + by the target, then the is_end_of_line[] test above will have + returned true, but we need to ignore the line separating + semantics in this particular case. */ + || (in_macro && inescape && *s == '@') + ) + { + if (mri_string && *s == '\'') + inquote ^= *s; + else if (inescape) + inescape = 0; + else if (*s == '\\') + inescape = 1; + else if (!inquote + ? *s == '"' +#ifdef TC_SINGLE_QUOTE_STRINGS + || (TC_SINGLE_QUOTE_STRINGS && *s == '\'') +#endif + : *s == inquote) + inquote ^= *s; + ++s; + } + if (inquote) + as_warn (_("missing closing `%c'"), inquote); + if (inescape) + as_warn (_("stray `\\'")); + return s; +} + +char * +find_end_of_line (char *s, int mri_string) +{ + return _find_end_of_line (s, mri_string, 0, 0); +} diff --git a/contrib/toolchain/binutils/gas/read.h b/contrib/toolchain/binutils/gas/read.h new file mode 100644 index 0000000000..81b958ac14 --- /dev/null +++ b/contrib/toolchain/binutils/gas/read.h @@ -0,0 +1,193 @@ +/* read.h - of read.c + Copyright 1986, 1990, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2012 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +extern char *input_line_pointer; /* -> char we are parsing now. */ + +/* Define to make whitespace be allowed in many syntactically + unnecessary places. Normally undefined. For compatibility with + ancient GNU cc. */ +/* #undef PERMIT_WHITESPACE */ +#define PERMIT_WHITESPACE + +#ifdef PERMIT_WHITESPACE +#define SKIP_WHITESPACE() \ + ((*input_line_pointer == ' ') ? ++input_line_pointer : 0) +#else +#define SKIP_WHITESPACE() know(*input_line_pointer != ' ' ) +#endif + +#define LEX_NAME (1) /* may continue a name */ +#define LEX_BEGIN_NAME (2) /* may begin a name */ +#define LEX_END_NAME (4) /* ends a name */ + +#define is_name_beginner(c) \ + ( lex_type[(unsigned char) (c)] & LEX_BEGIN_NAME ) +#define is_part_of_name(c) \ + ( lex_type[(unsigned char) (c)] & LEX_NAME ) +#define is_name_ender(c) \ + ( lex_type[(unsigned char) (c)] & LEX_END_NAME ) + +#ifndef is_a_char +#define CHAR_MASK (0xff) +#define NOT_A_CHAR (CHAR_MASK+1) +#define is_a_char(c) (((unsigned) (c)) <= CHAR_MASK) +#endif /* is_a_char() */ + +extern char lex_type[]; +extern char is_end_of_line[]; + +extern int is_it_end_of_statement (void); +extern char *find_end_of_line (char *, int); + +extern int target_big_endian; + +/* 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[]; + +/* Table of -I directories. */ +extern char **include_dirs; +extern int include_dir_count; +extern int include_dir_maxlen; + +/* The offset in the absolute section. */ +extern addressT abs_section_offset; + +/* The label on a line, used by some of the pseudo-ops. */ +extern symbolS *line_label; + +/* This is used to support MRI common sections. */ +extern symbolS *mri_common_symbol; + +/* True if a stabs line debug statement is currently being emitted. */ +extern int outputting_stabs_line_debug; + +/* Possible arguments to .linkonce. */ +enum linkonce_type { + LINKONCE_UNSET = 0, + LINKONCE_DISCARD, + LINKONCE_ONE_ONLY, + LINKONCE_SAME_SIZE, + LINKONCE_SAME_CONTENTS +}; + +#ifndef TC_CASE_SENSITIVE +extern char original_case_string[]; +#endif + +extern void pop_insert (const pseudo_typeS *); +extern unsigned int get_stab_string_offset + (const char *string, const char *stabstr_secname); +extern void aout_process_stab (int, const char *, int, int, int); +extern char *demand_copy_string (int *lenP); +extern char *demand_copy_C_string (int *len_pointer); +extern char get_absolute_expression_and_terminator (long *val_pointer); +extern offsetT get_absolute_expression (void); +extern unsigned int next_char_of_string (void); +extern void s_mri_sect (char *); +extern char *mri_comment_field (char *); +extern void mri_comment_end (char *, int); +extern void add_include_dir (char *path); +extern void cons (int nbytes); +extern void demand_empty_rest_of_line (void); +extern void emit_expr (expressionS *exp, unsigned int nbytes); +extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *); +extern void equals (char *sym_name, int reassign); +extern void float_cons (int float_type); +extern void ignore_rest_of_line (void); +#define discard_rest_of_line ignore_rest_of_line +extern int output_leb128 (char *, valueT, int sign); +extern void pseudo_set (symbolS * symbolP); +extern void read_a_source_file (char *name); +extern void read_begin (void); +extern void read_print_statistics (FILE *); +extern int sizeof_leb128 (valueT, int sign); +extern void stabs_generate_asm_file (void); +extern void stabs_generate_asm_lineno (void); +extern void stabs_generate_asm_func (const char *, const char *); +extern void stabs_generate_asm_endfunc (const char *, const char *); +extern void do_repeat (int,const char *,const char *); +extern void do_repeat_with_expander (int, const char *, const char *, const char *); +extern void end_repeat (int); +extern void do_parse_cons_expression (expressionS *, int); + +extern void generate_lineno_debug (void); + +extern void s_abort (int) ATTRIBUTE_NORETURN; +extern void s_align_bytes (int arg); +extern void s_align_ptwo (int); +extern void bss_alloc (symbolS *, addressT, int); +extern offsetT parse_align (int); +extern symbolS *s_comm_internal (int, symbolS *(*) (int, symbolS *, addressT)); +extern symbolS *s_lcomm_internal (int, symbolS *, addressT); +extern void s_app_file_string (char *, int); +extern void s_app_file (int); +extern void s_app_line (int); +extern void s_bundle_align_mode (int); +extern void s_bundle_lock (int); +extern void s_bundle_unlock (int); +extern void s_comm (int); +extern void s_data (int); +extern void s_desc (int); +extern void s_else (int arg); +extern void s_elseif (int arg); +extern void s_end (int arg); +extern void s_endif (int arg); +extern void s_err (int); +extern void s_errwarn (int); +extern void s_fail (int); +extern void s_fill (int); +extern void s_float_space (int mult); +extern void s_func (int); +extern void s_globl (int arg); +extern void s_if (int arg); +extern void s_ifb (int arg); +extern void s_ifc (int arg); +extern void s_ifdef (int arg); +extern void s_ifeqs (int arg); +extern void s_ignore (int arg); +extern void s_include (int arg); +extern void s_irp (int arg); +extern void s_lcomm (int needs_align); +extern void s_lcomm_bytes (int needs_align); +extern void s_leb128 (int sign); +extern void s_linkonce (int); +extern void s_lsym (int); +extern void s_macro (int); +extern void s_mexit (int); +extern void s_mri (int); +extern void s_mri_common (int); +extern void s_org (int); +extern void s_print (int); +extern void s_purgem (int); +extern void s_rept (int); +extern void s_set (int); +extern void s_space (int mult); +extern void s_stab (int what); +extern void s_struct (int); +extern void s_text (int); +extern void stringer (int append_zero); +extern void s_xstab (int what); +extern void s_rva (int); +extern void s_incbin (int); +extern void s_weakref (int); diff --git a/contrib/toolchain/binutils/gas/remap.c b/contrib/toolchain/binutils/gas/remap.c new file mode 100644 index 0000000000..ae9b9ddaa9 --- /dev/null +++ b/contrib/toolchain/binutils/gas/remap.c @@ -0,0 +1,91 @@ +/* Remap file names for debug info for GNU assembler. + Copyright 2007 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "filenames.h" + +/* Structure recording the mapping from source file and directory + names at compile time to those to be embedded in debug + information. */ +typedef struct debug_prefix_map +{ + const char *old_prefix; + const char *new_prefix; + size_t old_len; + size_t new_len; + struct debug_prefix_map *next; +} debug_prefix_map; + +/* Linked list of such structures. */ +debug_prefix_map *debug_prefix_maps; + + +/* Record a debug file prefix mapping. ARG is the argument to + -fdebug-prefix-map and must be of the form OLD=NEW. */ + +void +add_debug_prefix_map (const char *arg) +{ + debug_prefix_map *map; + const char *p; + char *o; + + p = strchr (arg, '='); + if (!p) + { + as_fatal (_("invalid argument '%s' to -fdebug-prefix-map"), arg); + return; + } + map = (struct debug_prefix_map *) xmalloc (sizeof (debug_prefix_map)); + o = xstrdup (arg); + map->old_prefix = o; + map->old_len = p - arg; + o[map->old_len] = 0; + p++; + map->new_prefix = xstrdup (p); + map->new_len = strlen (p); + map->next = debug_prefix_maps; + debug_prefix_maps = map; +} + +/* Perform user-specified mapping of debug filename prefixes. Returns + a newly allocated buffer containing the name corresponding to FILENAME. + It is the caller's responsibility to free the buffer. */ + +const char * +remap_debug_filename (const char *filename) +{ + debug_prefix_map *map; + char *s; + const char *name; + size_t name_len; + + for (map = debug_prefix_maps; map; map = map->next) + if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) + break; + if (!map) + return xstrdup (filename); + name = filename + map->old_len; + name_len = strlen (name) + 1; + s = (char *) alloca (name_len + map->new_len); + memcpy (s, map->new_prefix, map->new_len); + memcpy (s + map->new_len, name, name_len); + return xstrdup (s); +} diff --git a/contrib/toolchain/binutils/gas/sb.c b/contrib/toolchain/binutils/gas/sb.c new file mode 100644 index 0000000000..7710cbc0c8 --- /dev/null +++ b/contrib/toolchain/binutils/gas/sb.c @@ -0,0 +1,237 @@ +/* sb.c - string buffer manipulation routines + Copyright 1994, 1995, 2000, 2003, 2005, 2006, 2007, 2009, 2012 + Free Software Foundation, Inc. + + Written by Steve and Judy Chamberlain of Cygnus Support, + sac@cygnus.com + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "sb.h" + +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* These routines are about manipulating strings. + + They are managed in things called `sb's which is an abbreviation + for string buffers. An sb has to be created, things can be glued + on to it, and at the end of it's life it should be freed. The + contents should never be pointed at whilst it is still growing, + since it could be moved at any time + + eg: + sb_new (&foo); + sb_grow... (&foo,...); + use foo->ptr[*]; + sb_kill (&foo); */ + +/* Buffers start at INIT_ALLOC size, and roughly double each time we + go over the current allocation. MALLOC_OVERHEAD is a guess at the + system malloc overhead. We aim to not waste any memory in the + underlying page/chunk allocated by the system malloc. */ +#define MALLOC_OVERHEAD (2 * sizeof (size_t)) +#define INIT_ALLOC (64 - MALLOC_OVERHEAD - 1) + +static void sb_check (sb *, size_t); + +/* Initializes an sb. */ + +void +sb_build (sb *ptr, size_t size) +{ + ptr->ptr = xmalloc (size + 1); + ptr->max = size; + ptr->len = 0; +} + +void +sb_new (sb *ptr) +{ + sb_build (ptr, INIT_ALLOC); +} + +/* Deallocate the sb at ptr. */ + +void +sb_kill (sb *ptr) +{ + free (ptr->ptr); +} + +/* Add the sb at s to the end of the sb at ptr. */ + +void +sb_add_sb (sb *ptr, sb *s) +{ + sb_check (ptr, s->len); + memcpy (ptr->ptr + ptr->len, s->ptr, s->len); + ptr->len += s->len; +} + +/* Helper for sb_scrub_and_add_sb. */ + +static sb *sb_to_scrub; +static char *scrub_position; +static size_t +scrub_from_sb (char *buf, size_t buflen) +{ + size_t copy; + copy = sb_to_scrub->len - (scrub_position - sb_to_scrub->ptr); + if (copy > buflen) + copy = buflen; + memcpy (buf, scrub_position, copy); + scrub_position += copy; + return copy; +} + +/* Run the sb at s through do_scrub_chars and add the result to the sb + at ptr. */ + +void +sb_scrub_and_add_sb (sb *ptr, sb *s) +{ + sb_to_scrub = s; + scrub_position = s->ptr; + + sb_check (ptr, s->len); + ptr->len += do_scrub_chars (scrub_from_sb, ptr->ptr + ptr->len, s->len); + + sb_to_scrub = 0; + scrub_position = 0; +} + +/* Make sure that the sb at ptr has room for another len characters, + and grow it if it doesn't. */ + +static void +sb_check (sb *ptr, size_t len) +{ + size_t want = ptr->len + len; + + if (want > ptr->max) + { + size_t max; + + want += MALLOC_OVERHEAD + 1; + if ((ssize_t) want < 0) + as_fatal ("string buffer overflow"); +#if GCC_VERSION >= 3004 + max = (size_t) 1 << (CHAR_BIT * sizeof (want) + - (sizeof (want) <= sizeof (long) + ? __builtin_clzl ((long) want) + : __builtin_clzll ((long long) want))); +#else + max = 128; + while (want > max) + max <<= 1; +#endif + max -= MALLOC_OVERHEAD + 1; + ptr->max = max; + ptr->ptr = xrealloc (ptr->ptr, max + 1); + } +} + +/* Make the sb at ptr point back to the beginning. */ + +void +sb_reset (sb *ptr) +{ + ptr->len = 0; +} + +/* Add character c to the end of the sb at ptr. */ + +void +sb_add_char (sb *ptr, size_t c) +{ + sb_check (ptr, 1); + ptr->ptr[ptr->len++] = c; +} + +/* Add null terminated string s to the end of sb at ptr. */ + +void +sb_add_string (sb *ptr, const char *s) +{ + size_t len = strlen (s); + sb_check (ptr, len); + memcpy (ptr->ptr + ptr->len, s, len); + ptr->len += len; +} + +/* Add string at s of length len to sb at ptr */ + +void +sb_add_buffer (sb *ptr, const char *s, size_t len) +{ + sb_check (ptr, len); + memcpy (ptr->ptr + ptr->len, s, len); + ptr->len += len; +} + +/* Write terminating NUL and return string. */ + +char * +sb_terminate (sb *in) +{ + in->ptr[in->len] = 0; + return in->ptr; +} + +/* Start at the index idx into the string in sb at ptr and skip + whitespace. return the index of the first non whitespace character. */ + +size_t +sb_skip_white (size_t idx, sb *ptr) +{ + while (idx < ptr->len + && (ptr->ptr[idx] == ' ' + || ptr->ptr[idx] == '\t')) + idx++; + return idx; +} + +/* Start at the index idx into the sb at ptr. skips whitespace, + a comma and any following whitespace. returns the index of the + next character. */ + +size_t +sb_skip_comma (size_t idx, sb *ptr) +{ + while (idx < ptr->len + && (ptr->ptr[idx] == ' ' + || ptr->ptr[idx] == '\t')) + idx++; + + if (idx < ptr->len + && ptr->ptr[idx] == ',') + idx++; + + while (idx < ptr->len + && (ptr->ptr[idx] == ' ' + || ptr->ptr[idx] == '\t')) + idx++; + + return idx; +} diff --git a/contrib/toolchain/binutils/gas/sb.h b/contrib/toolchain/binutils/gas/sb.h new file mode 100644 index 0000000000..ea010ee34e --- /dev/null +++ b/contrib/toolchain/binutils/gas/sb.h @@ -0,0 +1,71 @@ +/* sb.h - header file for string buffer manipulation routines + Copyright 1994, 1995, 2000, 2003, 2005, 2006, 2007, 2012 + Free Software Foundation, Inc. + + Written by Steve and Judy Chamberlain of Cygnus Support, + sac@cygnus.com + + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef SB_H + +#define SB_H + +/* String blocks + + I had a couple of choices when deciding upon this data structure. + gas uses null terminated strings for all its internal work. This + often means that parts of the program that want to examine + substrings have to manipulate the data in the string to do the + right thing (a common operation is to single out a bit of text by + saving away the character after it, nulling it out, operating on + the substring and then replacing the character which was under the + null). This is a pain and I remember a load of problems that I had with + code in gas which almost got this right. Also, it's harder to grow and + allocate null terminated strings efficiently. + + Obstacks provide all the functionality needed, but are too + complicated, hence the sb. + + An sb is allocated by the caller. */ + +typedef struct sb +{ + char *ptr; /* Points to the current block. */ + size_t len; /* How much is used. */ + size_t max; /* The maximum length. */ +} +sb; + +extern void sb_new (sb *); +extern void sb_build (sb *, size_t); +extern void sb_kill (sb *); +extern void sb_add_sb (sb *, sb *); +extern void sb_scrub_and_add_sb (sb *, sb *); +extern void sb_reset (sb *); +extern void sb_add_char (sb *, size_t); +extern void sb_add_string (sb *, const char *); +extern void sb_add_buffer (sb *, const char *, size_t); +extern char *sb_terminate (sb *); +extern size_t sb_skip_white (size_t, sb *); +extern size_t sb_skip_comma (size_t, sb *); + +/* Actually in input-scrub.c. */ +extern void input_scrub_include_sb (sb *, char *, int); + +#endif /* SB_H */ diff --git a/contrib/toolchain/binutils/gas/stabs.c b/contrib/toolchain/binutils/gas/stabs.c new file mode 100644 index 0000000000..e0594fa5d4 --- /dev/null +++ b/contrib/toolchain/binutils/gas/stabs.c @@ -0,0 +1,710 @@ +/* Generic stabs parsing for gas. + Copyright 1989, 1990, 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001 + 2002, 2003, 2004, 2005, 2007, 2009 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 3, + 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "filenames.h" +#include "obstack.h" +#include "subsegs.h" +#include "ecoff.h" + +/* We need this, despite the apparent object format dependency, since + it defines stab types, which all object formats can use now. */ + +#include "aout/stab_gnu.h" + +/* Holds whether the assembler is generating stabs line debugging + information or not. Potentially used by md_cleanup function. */ + +int outputting_stabs_line_debug = 0; + +static void s_stab_generic (int, char *, char *); +static void generate_asm_file (int, char *); + +/* Allow backends to override the names used for the stab sections. */ +#ifndef STAB_SECTION_NAME +#define STAB_SECTION_NAME ".stab" +#endif + +#ifndef STAB_STRING_SECTION_NAME +#define STAB_STRING_SECTION_NAME ".stabstr" +#endif + +/* Non-zero if we're in the middle of a .func function, in which case + stabs_generate_asm_lineno emits function relative line number stabs. + Otherwise it emits line number stabs with absolute addresses. Note that + both cases only apply to assembler code assembled with -gstabs. */ +static int in_dot_func_p; + +/* Label at start of current function if in_dot_func_p != 0. */ +static const char *current_function_label; + +/* + * Handle .stabX directives, which used to be open-coded. + * So much creeping featurism overloaded the semantics that we decided + * to put all .stabX thinking in one place. Here. + * + * We try to make any .stabX directive legal. Other people's AS will often + * do assembly-time consistency checks: eg assigning meaning to n_type bits + * and "protecting" you from setting them to certain values. (They also zero + * certain bits before emitting symbols. Tut tut.) + * + * If an expression is not absolute we either gripe or use the relocation + * information. Other people's assemblers silently forget information they + * don't need and invent information they need that you didn't supply. + */ + +/* + * Build a string dictionary entry for a .stabX symbol. + * The symbol is added to the .str section. + */ + +#ifndef SEPARATE_STAB_SECTIONS +#define SEPARATE_STAB_SECTIONS 0 +#endif + +unsigned int +get_stab_string_offset (const char *string, const char *stabstr_secname) +{ + unsigned int length; + unsigned int retval; + segT save_seg; + subsegT save_subseg; + segT seg; + char *p; + + if (! SEPARATE_STAB_SECTIONS) + abort (); + + length = strlen (string); + + save_seg = now_seg; + save_subseg = now_subseg; + + /* Create the stab string section. */ + seg = subseg_new (stabstr_secname, 0); + + retval = seg_info (seg)->stabu.stab_string_size; + if (retval <= 0) + { + /* Make sure the first string is empty. */ + p = frag_more (1); + *p = 0; + retval = seg_info (seg)->stabu.stab_string_size = 1; + bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING); + if (seg->name == stabstr_secname) + seg->name = xstrdup (stabstr_secname); + } + + if (length > 0) + { /* Ordinary case. */ + p = frag_more (length + 1); + strcpy (p, string); + + seg_info (seg)->stabu.stab_string_size += length + 1; + } + else + retval = 0; + + subseg_set (save_seg, save_subseg); + + return retval; +} + +#ifdef AOUT_STABS +#ifndef OBJ_PROCESS_STAB +#define OBJ_PROCESS_STAB(SEG,W,S,T,O,D) aout_process_stab(W,S,T,O,D) +#endif + +/* Here instead of obj-aout.c because other formats use it too. */ +void +aout_process_stab (what, string, type, other, desc) + int what; + const char *string; + int type, other, desc; +{ + /* Put the stab information in the symbol table. */ + symbolS *symbol; + + /* Create the symbol now, but only insert it into the symbol chain + after any symbols mentioned in the value expression get into the + symbol chain. This is to avoid "continuation symbols" (where one + ends in "\" and the debug info is continued in the next .stabs + directive) from being separated by other random symbols. */ + symbol = symbol_create (string, undefined_section, 0, + &zero_address_frag); + if (what == 's' || what == 'n') + { + /* Pick up the value from the input line. */ + pseudo_set (symbol); + } + else + { + /* .stabd sets the name to NULL. Why? */ + S_SET_NAME (symbol, NULL); + symbol_set_frag (symbol, frag_now); + S_SET_VALUE (symbol, (valueT) frag_now_fix ()); + } + + symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP); + + symbol_get_bfdsym (symbol)->flags |= BSF_DEBUGGING; + + S_SET_TYPE (symbol, type); + S_SET_OTHER (symbol, other); + S_SET_DESC (symbol, desc); +} +#endif + +/* This can handle different kinds of stabs (s,n,d) and different + kinds of stab sections. */ + +static void +s_stab_generic (int what, char *stab_secname, char *stabstr_secname) +{ + long longint; + char *string, *saved_string_obstack_end; + int type; + int other; + int desc; + + /* The general format is: + .stabs "STRING",TYPE,OTHER,DESC,VALUE + .stabn TYPE,OTHER,DESC,VALUE + .stabd TYPE,OTHER,DESC + At this point input_line_pointer points after the pseudo-op and + any trailing whitespace. The argument what is one of 's', 'n' or + 'd' indicating which type of .stab this is. */ + + if (what != 's') + { + string = ""; + saved_string_obstack_end = 0; + } + else + { + int length; + + string = demand_copy_C_string (&length); + /* FIXME: We should probably find some other temporary storage + for string, rather than leaking memory if someone else + happens to use the notes obstack. */ + saved_string_obstack_end = notes.next_free; + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + input_line_pointer++; + else + { + as_warn (_(".stab%c: missing comma"), what); + ignore_rest_of_line (); + return; + } + } + + if (get_absolute_expression_and_terminator (&longint) != ',') + { + as_warn (_(".stab%c: missing comma"), what); + ignore_rest_of_line (); + return; + } + type = longint; + + if (get_absolute_expression_and_terminator (&longint) != ',') + { + as_warn (_(".stab%c: missing comma"), what); + ignore_rest_of_line (); + return; + } + other = longint; + + desc = get_absolute_expression (); + + if ((desc > 0xffff) || (desc < -0x8000)) + /* This could happen for example with a source file with a huge + number of lines. The only cure is to use a different debug + format, probably DWARF. */ + as_warn (_(".stab%c: description field '%x' too big, try a different debug format"), + what, desc); + + if (what == 's' || what == 'n') + { + if (*input_line_pointer != ',') + { + as_warn (_(".stab%c: missing comma"), what); + ignore_rest_of_line (); + return; + } + input_line_pointer++; + SKIP_WHITESPACE (); + } + +#ifdef TC_PPC +#ifdef OBJ_ELF + /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were + given 4 arguments, make it a .stabn */ + else if (what == 'd') + { + char *save_location = input_line_pointer; + + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + { + input_line_pointer++; + what = 'n'; + } + else + input_line_pointer = save_location; + } +#endif /* OBJ_ELF */ +#endif /* TC_PPC */ + +#ifndef NO_LISTING + if (listing) + { + switch (type) + { + case N_SLINE: + listing_source_line ((unsigned int) desc); + break; + case N_SO: + case N_SOL: + listing_source_file (string); + break; + } + } +#endif /* ! NO_LISTING */ + + /* We have now gathered the type, other, and desc information. For + .stabs or .stabn, input_line_pointer is now pointing at the + value. */ + + if (SEPARATE_STAB_SECTIONS) + /* Output the stab information in a separate section. This is used + at least for COFF and ELF. */ + { + segT saved_seg = now_seg; + subsegT saved_subseg = now_subseg; + fragS *saved_frag = frag_now; + valueT dot; + segT seg; + unsigned int stroff; + char *p; + + static segT cached_sec; + static char *cached_secname; + + dot = frag_now_fix (); + +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + + if (cached_secname && !strcmp (cached_secname, stab_secname)) + { + seg = cached_sec; + subseg_set (seg, 0); + } + else + { + seg = subseg_new (stab_secname, 0); + if (cached_secname) + free (cached_secname); + cached_secname = xstrdup (stab_secname); + cached_sec = seg; + } + + if (! seg_info (seg)->hadone) + { + bfd_set_section_flags (stdoutput, seg, + SEC_READONLY | SEC_RELOC | SEC_DEBUGGING); +#ifdef INIT_STAB_SECTION + INIT_STAB_SECTION (seg); +#endif + seg_info (seg)->hadone = 1; + } + + stroff = get_stab_string_offset (string, stabstr_secname); + if (what == 's') + { + /* Release the string, if nobody else has used the obstack. */ + if (saved_string_obstack_end == notes.next_free) + obstack_free (¬es, string); + } + + /* At least for now, stabs in a special stab section are always + output as 12 byte blocks of information. */ + p = frag_more (8); + md_number_to_chars (p, (valueT) stroff, 4); + md_number_to_chars (p + 4, (valueT) type, 1); + md_number_to_chars (p + 5, (valueT) other, 1); + md_number_to_chars (p + 6, (valueT) desc, 2); + + if (what == 's' || what == 'n') + { + /* Pick up the value from the input line. */ + cons (4); + input_line_pointer--; + } + else + { + symbolS *symbol; + expressionS exp; + + /* Arrange for a value representing the current location. */ + symbol = symbol_temp_new (saved_seg, dot, saved_frag); + + exp.X_op = O_symbol; + exp.X_add_symbol = symbol; + exp.X_add_number = 0; + + emit_expr (&exp, 4); + } + +#ifdef OBJ_PROCESS_STAB + OBJ_PROCESS_STAB (seg, what, string, type, other, desc); +#endif + + subseg_set (saved_seg, saved_subseg); + } + else + { +#ifdef OBJ_PROCESS_STAB + OBJ_PROCESS_STAB (0, what, string, type, other, desc); +#else + abort (); +#endif + } + + demand_empty_rest_of_line (); +} + +/* Regular stab directive. */ + +void +s_stab (int what) +{ + s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME); +} + +/* "Extended stabs", used in Solaris only now. */ + +void +s_xstab (int what) +{ + int length; + char *stab_secname, *stabstr_secname; + static char *saved_secname, *saved_strsecname; + + /* @@ MEMORY LEAK: This allocates a copy of the string, but in most + cases it will be the same string, so we could release the storage + back to the obstack it came from. */ + stab_secname = demand_copy_C_string (&length); + SKIP_WHITESPACE (); + if (*input_line_pointer == ',') + input_line_pointer++; + else + { + as_bad (_("comma missing in .xstabs")); + ignore_rest_of_line (); + return; + } + + /* To get the name of the stab string section, simply add "str" to + the stab section name. */ + if (saved_secname == 0 || strcmp (saved_secname, stab_secname)) + { + stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4); + strcpy (stabstr_secname, stab_secname); + strcat (stabstr_secname, "str"); + if (saved_secname) + { + free (saved_secname); + free (saved_strsecname); + } + saved_secname = stab_secname; + saved_strsecname = stabstr_secname; + } + s_stab_generic (what, saved_secname, saved_strsecname); +} + +#ifdef S_SET_DESC + +/* Frob invented at RMS' request. Set the n_desc of a symbol. */ + +void +s_desc (ignore) + int ignore ATTRIBUTE_UNUSED; +{ + char *name; + char c; + char *p; + symbolS *symbolP; + int temp; + + name = input_line_pointer; + c = get_symbol_end (); + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + *p = 0; + as_bad (_("expected comma after \"%s\""), name); + *p = c; + ignore_rest_of_line (); + } + else + { + input_line_pointer++; + temp = get_absolute_expression (); + *p = 0; + symbolP = symbol_find_or_make (name); + *p = c; + S_SET_DESC (symbolP, temp); + } + demand_empty_rest_of_line (); +} /* s_desc() */ + +#endif /* defined (S_SET_DESC) */ + +/* Generate stabs debugging information to denote the main source file. */ + +void +stabs_generate_asm_file (void) +{ + char *file; + unsigned int lineno; + + as_where (&file, &lineno); + if (use_gnu_debug_info_extensions) + { + const char *dir; + char *dir2; + + dir = remap_debug_filename (getpwd ()); + dir2 = (char *) alloca (strlen (dir) + 2); + sprintf (dir2, "%s%s", dir, "/"); + generate_asm_file (N_SO, dir2); + xfree ((char *) dir); + } + generate_asm_file (N_SO, file); +} + +/* Generate stabs debugging information to denote the source file. + TYPE is one of N_SO, N_SOL. */ + +static void +generate_asm_file (int type, char *file) +{ + static char *last_file; + static int label_count; + char *hold; + char sym[30]; + char *buf; + char *tmp = file; + char *file_endp = file + strlen (file); + char *bufp; + + if (last_file != NULL + && filename_cmp (last_file, file) == 0) + return; + + /* Rather than try to do this in some efficient fashion, we just + generate a string and then parse it again. That lets us use the + existing stabs hook, which expect to see a string, rather than + inventing new ones. */ + hold = input_line_pointer; + + sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count); + ++label_count; + + /* Allocate enough space for the file name (possibly extended with + doubled up backslashes), the symbol name, and the other characters + that make up a stabs file directive. */ + bufp = buf = (char *) xmalloc (2 * strlen (file) + strlen (sym) + 12); + + *bufp++ = '"'; + + while (tmp < file_endp) + { + char *bslash = strchr (tmp, '\\'); + size_t len = (bslash) ? (size_t) (bslash - tmp + 1) : strlen (tmp); + + /* Double all backslashes, since demand_copy_C_string (used by + s_stab to extract the part in quotes) will try to replace them as + escape sequences. backslash may appear in a filespec. */ + strncpy (bufp, tmp, len); + + tmp += len; + bufp += len; + + if (bslash != NULL) + *bufp++ = '\\'; + } + + sprintf (bufp, "\",%d,0,0,%s\n", type, sym); + + input_line_pointer = buf; + s_stab ('s'); + colon (sym); + + if (last_file != NULL) + free (last_file); + last_file = xstrdup (file); + + free (buf); + + input_line_pointer = hold; +} + +/* Generate stabs debugging information for the current line. This is + used to produce debugging information for an assembler file. */ + +void +stabs_generate_asm_lineno (void) +{ + static int label_count; + char *hold; + char *file; + unsigned int lineno; + char *buf; + char sym[30]; + /* Remember the last file/line and avoid duplicates. */ + static unsigned int prev_lineno = -1; + static char *prev_file = NULL; + + /* Rather than try to do this in some efficient fashion, we just + generate a string and then parse it again. That lets us use the + existing stabs hook, which expect to see a string, rather than + inventing new ones. */ + + hold = input_line_pointer; + + as_where (&file, &lineno); + + /* Don't emit sequences of stabs for the same line. */ + if (prev_file == NULL) + { + /* First time thru. */ + prev_file = xstrdup (file); + prev_lineno = lineno; + } + else if (lineno == prev_lineno + && filename_cmp (file, prev_file) == 0) + { + /* Same file/line as last time. */ + return; + } + else + { + /* Remember file/line for next time. */ + prev_lineno = lineno; + if (filename_cmp (file, prev_file) != 0) + { + free (prev_file); + prev_file = xstrdup (file); + } + } + + /* Let the world know that we are in the middle of generating a + piece of stabs line debugging information. */ + outputting_stabs_line_debug = 1; + + generate_asm_file (N_SOL, file); + + sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count); + ++label_count; + + if (in_dot_func_p) + { + buf = (char *) alloca (100 + strlen (current_function_label)); + sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno, + sym, current_function_label); + } + else + { + buf = (char *) alloca (100); + sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym); + } + input_line_pointer = buf; + s_stab ('n'); + colon (sym); + + input_line_pointer = hold; + outputting_stabs_line_debug = 0; +} + +/* Emit a function stab. + All assembler functions are assumed to have return type `void'. */ + +void +stabs_generate_asm_func (const char *funcname, const char *startlabname) +{ + static int void_emitted_p; + char *hold = input_line_pointer; + char *buf; + char *file; + unsigned int lineno; + + if (! void_emitted_p) + { + input_line_pointer = "\"void:t1=1\",128,0,0,0"; + s_stab ('s'); + void_emitted_p = 1; + } + + as_where (&file, &lineno); + if (asprintf (&buf, "\"%s:F1\",%d,0,%d,%s", + funcname, N_FUN, lineno + 1, startlabname) == -1) + as_fatal ("%s", xstrerror (errno)); + input_line_pointer = buf; + s_stab ('s'); + free (buf); + + input_line_pointer = hold; + current_function_label = xstrdup (startlabname); + in_dot_func_p = 1; +} + +/* Emit a stab to record the end of a function. */ + +void +stabs_generate_asm_endfunc (const char *funcname ATTRIBUTE_UNUSED, + const char *startlabname) +{ + static int label_count; + char *hold = input_line_pointer; + char *buf; + char sym[30]; + + sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count); + ++label_count; + colon (sym); + + if (asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname) == -1) + as_fatal ("%s", xstrerror (errno)); + input_line_pointer = buf; + s_stab ('s'); + free (buf); + + input_line_pointer = hold; + in_dot_func_p = 0; + current_function_label = NULL; +} diff --git a/contrib/toolchain/binutils/gas/struc-symbol.h b/contrib/toolchain/binutils/gas/struc-symbol.h new file mode 100644 index 0000000000..1dbb9d2c35 --- /dev/null +++ b/contrib/toolchain/binutils/gas/struc-symbol.h @@ -0,0 +1,159 @@ +/* struct_symbol.h - Internal symbol structure + Copyright 1987, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2005, + 2007, 2008, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef __struc_symbol_h__ +#define __struc_symbol_h__ + +struct symbol_flags +{ + /* Wether the symbol is a local_symbol. */ + unsigned int sy_local_symbol : 1; + + /* Wether symbol has been written. */ + unsigned int sy_written : 1; + + /* Whether symbol value has been completely resolved (used during + final pass over symbol table). */ + unsigned int sy_resolved : 1; + + /* Whether the symbol value is currently being resolved (used to + detect loops in symbol dependencies). */ + unsigned int sy_resolving : 1; + + /* Whether the symbol value is used in a reloc. This is used to + ensure that symbols used in relocs are written out, even if they + are local and would otherwise not be. */ + unsigned int sy_used_in_reloc : 1; + + /* Whether the symbol is used as an operand or in an expression. + NOTE: Not all the backends keep this information accurate; + backends which use this bit are responsible for setting it when + a symbol is used in backend routines. */ + unsigned int sy_used : 1; + + /* Whether the symbol can be re-defined. */ + unsigned int sy_volatile : 1; + + /* Whether the symbol is a forward reference. */ + unsigned int sy_forward_ref : 1; + + /* This is set if the symbol is defined in an MRI common section. + We handle such sections as single common symbols, so symbols + defined within them must be treated specially by the relocation + routines. */ + unsigned int sy_mri_common : 1; + + /* This is set if the symbol is set with a .weakref directive. */ + unsigned int sy_weakrefr : 1; + + /* This is set when the symbol is referenced as part of a .weakref + directive, but only if the symbol was not in the symbol table + before. It is cleared as soon as any direct reference to the + symbol is present. */ + unsigned int sy_weakrefd : 1; +}; + +/* The information we keep for a symbol. Note that the symbol table + holds pointers both to this and to local_symbol structures. See + below. */ + +struct symbol +{ + /* Symbol flags. */ + struct symbol_flags sy_flags; + + /* BFD symbol */ + asymbol *bsym; + + /* The value of the symbol. */ + expressionS sy_value; + + /* Forwards and (optionally) backwards chain pointers. */ + struct symbol *sy_next; + struct symbol *sy_previous; + + /* Pointer to the frag this symbol is attached to, if any. + Otherwise, NULL. */ + struct frag *sy_frag; + +#ifdef OBJ_SYMFIELD_TYPE + OBJ_SYMFIELD_TYPE sy_obj; +#endif + +#ifdef TC_SYMFIELD_TYPE + TC_SYMFIELD_TYPE sy_tc; +#endif + +#ifdef TARGET_SYMBOL_FIELDS + TARGET_SYMBOL_FIELDS +#endif +}; + +/* A pointer in the symbol may point to either a complete symbol + (struct symbol above) or to a local symbol (struct local_symbol + defined here). The symbol code can detect the case by examining + the first field. It is always NULL for a local symbol. + + We do this because we ordinarily only need a small amount of + information for a local symbol. The symbol table takes up a lot of + space, and storing less information for a local symbol can make a + big difference in assembler memory usage when assembling a large + file. */ + +struct local_symbol +{ + /* Symbol flags. Only sy_local_symbol and sy_resolved are relevant. */ + struct symbol_flags lsy_flags; + + /* The symbol section. This also serves as a flag. If this is + reg_section, then this symbol has been converted into a regular + symbol, and lsy_sym points to it. */ + segT lsy_section; + + /* The symbol name. */ + const char *lsy_name; + + /* The symbol frag or the real symbol, depending upon the value in + lsy_section. */ + union + { + fragS *lsy_frag; + symbolS *lsy_sym; + } u; + + /* The value of the symbol. */ + valueT lsy_value; + +#ifdef TC_LOCAL_SYMFIELD_TYPE + TC_LOCAL_SYMFIELD_TYPE lsy_tc; +#endif +}; + +#define local_symbol_converted_p(l) ((l)->lsy_section == reg_section) +#define local_symbol_mark_converted(l) ((l)->lsy_section = reg_section) +#define local_symbol_resolved_p(l) ((l)->lsy_flags.sy_resolved) +#define local_symbol_mark_resolved(l) ((l)->lsy_flags.sy_resolved = 1) +#define local_symbol_get_frag(l) ((l)->u.lsy_frag) +#define local_symbol_set_frag(l, f) ((l)->u.lsy_frag = (f)) +#define local_symbol_get_real_symbol(l) ((l)->u.lsy_sym) +#define local_symbol_set_real_symbol(l, s) ((l)->u.lsy_sym = (s)) + +#endif /* __struc_symbol_h__ */ diff --git a/contrib/toolchain/binutils/gas/subsegs.c b/contrib/toolchain/binutils/gas/subsegs.c new file mode 100644 index 0000000000..69f837b2a2 --- /dev/null +++ b/contrib/toolchain/binutils/gas/subsegs.c @@ -0,0 +1,330 @@ +/* subsegs.c - subsegments - + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Segments & sub-segments. */ + +#include "as.h" + +#include "subsegs.h" +#include "obstack.h" + +frchainS *frchain_now; + +static struct obstack frchains; + +static fragS dummy_frag; + + +void +subsegs_begin (void) +{ + obstack_begin (&frchains, chunksize); +#if __GNUC__ >= 2 + obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1; +#endif + + frchain_now = NULL; /* Warn new_subseg() that we are booting. */ + frag_now = &dummy_frag; +} + +/* + * subseg_change() + * + * Change the subsegment we are in, BUT DO NOT MAKE A NEW FRAG for the + * subsegment. If we are already in the correct subsegment, change nothing. + * This is used eg as a worker for subseg_set [which does make a new frag_now] + * and for changing segments after we have read the source. We construct eg + * fixSs even after the source file is read, so we do have to keep the + * segment context correct. + */ +void +subseg_change (register segT seg, register int subseg) +{ + segment_info_type *seginfo = seg_info (seg); + now_seg = seg; + now_subseg = subseg; + + if (! seginfo) + { + seginfo = (segment_info_type *) xcalloc (1, sizeof (*seginfo)); + seginfo->bfd_section = seg; + bfd_set_section_userdata (stdoutput, seg, seginfo); + } +} + +static void +subseg_set_rest (segT seg, subsegT subseg) +{ + frchainS *frcP; /* crawl frchain chain */ + frchainS **lastPP; /* address of last pointer */ + frchainS *newP; /* address of new frchain */ + segment_info_type *seginfo; + + mri_common_symbol = NULL; + + if (frag_now && frchain_now) + frchain_now->frch_frag_now = frag_now; + + gas_assert (frchain_now == 0 + || frchain_now->frch_last == frag_now); + + subseg_change (seg, (int) subseg); + + seginfo = seg_info (seg); + + /* Attempt to find or make a frchain for that subsection. + We keep the list sorted by subsection number. */ + for (frcP = *(lastPP = &seginfo->frchainP); + frcP != NULL; + frcP = *(lastPP = &frcP->frch_next)) + if (frcP->frch_subseg >= subseg) + break; + + if (frcP == NULL || frcP->frch_subseg != subseg) + { + /* This should be the only code that creates a frchainS. */ + + newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); + newP->frch_subseg = subseg; + newP->fix_root = NULL; + newP->fix_tail = NULL; + obstack_begin (&newP->frch_obstack, chunksize); +#if __GNUC__ >= 2 + obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1; +#endif + newP->frch_frag_now = frag_alloc (&newP->frch_obstack); + newP->frch_frag_now->fr_type = rs_fill; + newP->frch_cfi_data = NULL; + + newP->frch_root = newP->frch_last = newP->frch_frag_now; + + *lastPP = newP; + newP->frch_next = frcP; + frcP = newP; + } + + frchain_now = frcP; + frag_now = frcP->frch_frag_now; + + gas_assert (frchain_now->frch_last == frag_now); +} + +/* + * subseg_set(segT, subsegT) + * + * If you attempt to change to the current subsegment, nothing happens. + * + * In: segT, subsegT code for new subsegment. + * frag_now -> incomplete frag for current subsegment. + * If frag_now==NULL, then there is no old, incomplete frag, so + * the old frag is not closed off. + * + * Out: now_subseg, now_seg updated. + * Frchain_now points to the (possibly new) struct frchain for this + * sub-segment. + */ + +segT +subseg_get (const char *segname, int force_new) +{ + segT secptr; + segment_info_type *seginfo; + const char *now_seg_name = (now_seg + ? bfd_get_section_name (stdoutput, now_seg) + : 0); + + if (!force_new + && now_seg_name + && (now_seg_name == segname + || !strcmp (now_seg_name, segname))) + return now_seg; + + if (!force_new) + secptr = bfd_make_section_old_way (stdoutput, segname); + else + secptr = bfd_make_section_anyway (stdoutput, segname); + + seginfo = seg_info (secptr); + if (! seginfo) + { + secptr->output_section = secptr; + seginfo = (segment_info_type *) xcalloc (1, sizeof (*seginfo)); + seginfo->bfd_section = secptr; + bfd_set_section_userdata (stdoutput, secptr, seginfo); + } + return secptr; +} + +segT +subseg_new (const char *segname, subsegT subseg) +{ + segT secptr; + + secptr = subseg_get (segname, 0); + subseg_set_rest (secptr, subseg); + return secptr; +} + +/* Like subseg_new, except a new section is always created, even if + a section with that name already exists. */ +segT +subseg_force_new (const char *segname, subsegT subseg) +{ + segT secptr; + + secptr = subseg_get (segname, 1); + subseg_set_rest (secptr, subseg); + return secptr; +} + +void +subseg_set (segT secptr, subsegT subseg) +{ + if (! (secptr == now_seg && subseg == now_subseg)) + subseg_set_rest (secptr, subseg); + mri_common_symbol = NULL; +} + +#ifndef obj_sec_sym_ok_for_reloc +#define obj_sec_sym_ok_for_reloc(SEC) 0 +#endif + +symbolS * +section_symbol (segT sec) +{ + segment_info_type *seginfo = seg_info (sec); + symbolS *s; + + if (seginfo == 0) + abort (); + if (seginfo->sym) + return seginfo->sym; + +#ifndef EMIT_SECTION_SYMBOLS +#define EMIT_SECTION_SYMBOLS 1 +#endif + + if (! EMIT_SECTION_SYMBOLS || symbol_table_frozen) + { + /* Here we know it won't be going into the symbol table. */ + s = symbol_create (sec->symbol->name, sec, 0, &zero_address_frag); + } + else + { + segT seg; + s = symbol_find (sec->symbol->name); + /* We have to make sure it is the right symbol when we + have multiple sections with the same section name. */ + if (s == NULL + || ((seg = S_GET_SEGMENT (s)) != sec + && seg != undefined_section)) + s = symbol_new (sec->symbol->name, sec, 0, &zero_address_frag); + else if (seg == undefined_section) + { + S_SET_SEGMENT (s, sec); + symbol_set_frag (s, &zero_address_frag); + } + } + + S_CLEAR_EXTERNAL (s); + + /* Use the BFD section symbol, if possible. */ + if (obj_sec_sym_ok_for_reloc (sec)) + symbol_set_bfdsym (s, sec->symbol); + else + symbol_get_bfdsym (s)->flags |= BSF_SECTION_SYM; + + seginfo->sym = s; + return s; +} + +/* Return whether the specified segment is thought to hold text. */ + +int +subseg_text_p (segT sec) +{ + return (bfd_get_section_flags (stdoutput, sec) & SEC_CODE) != 0; +} + +/* Return non zero if SEC has at least one byte of data. It is + possible that we'll return zero even on a non-empty section because + we don't know all the fragment types, and it is possible that an + fr_fix == 0 one still contributes data. Think of this as + seg_definitely_not_empty_p. */ + +int +seg_not_empty_p (segT sec ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + frchainS *chain; + fragS *frag; + + if (!seginfo) + return 0; + + for (chain = seginfo->frchainP; chain; chain = chain->frch_next) + { + for (frag = chain->frch_root; frag; frag = frag->fr_next) + if (frag->fr_fix) + return 1; + if (obstack_next_free (&chain->frch_obstack) + != chain->frch_last->fr_literal) + return 1; + } + return 0; +} + +void +subsegs_print_statistics (FILE *file) +{ + frchainS *frchp; + asection *s; + + fprintf (file, "frag chains:\n"); + for (s = stdoutput->sections; s; s = s->next) + { + segment_info_type *seginfo; + + /* Skip gas-internal sections. */ + if (segment_name (s)[0] == '*') + continue; + + seginfo = seg_info (s); + if (!seginfo) + continue; + + for (frchp = seginfo->frchainP; frchp; frchp = frchp->frch_next) + { + int count = 0; + fragS *fragp; + + for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next) + count++; + + fprintf (file, "\n"); + fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp, + segment_name (s), count); + } + } +} + +/* end of subsegs.c */ diff --git a/contrib/toolchain/binutils/gas/subsegs.h b/contrib/toolchain/binutils/gas/subsegs.h new file mode 100644 index 0000000000..1e5f6199cf --- /dev/null +++ b/contrib/toolchain/binutils/gas/subsegs.h @@ -0,0 +1,117 @@ +/* subsegs.h -> subsegs.c + Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2003, 2005, + 2006, 2007, 2009 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* + * For every sub-segment the user mentions in the ASsembler program, + * we make one struct frchain. Each sub-segment has exactly one struct frchain + * and vice versa. + * + * Struct frchain's are forward chained (in ascending order of sub-segment + * code number). The chain runs through frch_next of each subsegment. + * This makes it hard to find a subsegment's frags + * if programmer uses a lot of them. Most programs only use text0 and + * data0, so they don't suffer. At least this way: + * (1) There are no "arbitrary" restrictions on how many subsegments + * can be programmed; + * (2) Subsegments' frchain-s are (later) chained together in the order in + * which they are emitted for object file viz text then data. + * + * From each struct frchain dangles a chain of struct frags. The frags + * represent code fragments, for that sub-segment, forward chained. + */ + +#include "obstack.h" + +struct frch_cfi_data; + +struct frchain /* control building of a frag chain */ +{ /* FRCH = FRagment CHain control */ + struct frag *frch_root; /* 1st struct frag in chain, or NULL */ + struct frag *frch_last; /* last struct frag in chain, or NULL */ + struct frchain *frch_next; /* next in chain of struct frchain-s */ + subsegT frch_subseg; /* subsegment number of this chain */ + fixS *fix_root; /* Root of fixups for this subsegment. */ + fixS *fix_tail; /* Last fixup for this subsegment. */ + struct obstack frch_obstack; /* for objects in this frag chain */ + fragS *frch_frag_now; /* frag_now for this subsegment */ + struct frch_cfi_data *frch_cfi_data; +}; + +typedef struct frchain frchainS; + +/* Frchain we are assembling into now. That is, the current segment's + frag chain, even if it contains no (complete) frags. */ +extern frchainS *frchain_now; + +typedef struct segment_info_struct { + frchainS *frchainP; + unsigned int hadone : 1; + + /* This field is set if this is a .bss section which does not really + have any contents. Once upon a time a .bss section did not have + any frags, but that is no longer true. This field prevent the + SEC_HAS_CONTENTS flag from being set for the section even if + there are frags. */ + unsigned int bss : 1; + + int user_stuff; + + /* Fixups for this segment. This is only valid after the frchains + are run together. */ + fixS *fix_root; + fixS *fix_tail; + + symbolS *dot; + + struct lineno_list *lineno_list_head; + struct lineno_list *lineno_list_tail; + + /* Which BFD section does this gas segment correspond to? */ + asection *bfd_section; + + /* NULL, or pointer to the gas symbol that is the section symbol for + this section. sym->bsym and bfd_section->symbol should be the same. */ + symbolS *sym; + + union { + /* Current size of section holding stabs strings. */ + unsigned long stab_string_size; + /* Initial frag for ELF. */ + char *p; + } + stabu; + +#ifdef NEED_LITERAL_POOL + unsigned long literal_pool_size; +#endif + +#ifdef TC_SEGMENT_INFO_TYPE + TC_SEGMENT_INFO_TYPE tc_segment_info_data; +#endif +} segment_info_type; + + +#define seg_info(sec) \ + ((segment_info_type *) bfd_get_section_userdata (stdoutput, sec)) + +extern symbolS *section_symbol (segT); + +extern void subsegs_print_statistics (FILE *); diff --git a/contrib/toolchain/binutils/gas/symbols.c b/contrib/toolchain/binutils/gas/symbols.c new file mode 100644 index 0000000000..67fc84bb7e --- /dev/null +++ b/contrib/toolchain/binutils/gas/symbols.c @@ -0,0 +1,3252 @@ +/* symbols.c -symbol table- + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011, 2012 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* #define DEBUG_SYMS / * to debug symbol list maintenance. */ + +#include "as.h" +#include "safe-ctype.h" +#include "obstack.h" /* For "symbols.h" */ +#include "subsegs.h" +#include "struc-symbol.h" + +/* This is non-zero if symbols are case sensitive, which is the + default. */ +int symbols_case_sensitive = 1; + +#ifndef WORKING_DOT_WORD +extern int new_broken_words; +#endif + +/* symbol-name => struct symbol pointer */ +static struct hash_control *sy_hash; + +/* Table of local symbols. */ +static struct hash_control *local_hash; + +/* Below are commented in "symbols.h". */ +symbolS *symbol_rootP; +symbolS *symbol_lastP; +symbolS abs_symbol; +symbolS dot_symbol; + +#ifdef DEBUG_SYMS +#define debug_verify_symchain verify_symbol_chain +#else +#define debug_verify_symchain(root, last) ((void) 0) +#endif + +#define DOLLAR_LABEL_CHAR '\001' +#define LOCAL_LABEL_CHAR '\002' + +#ifndef TC_LABEL_IS_LOCAL +#define TC_LABEL_IS_LOCAL(name) 0 +#endif + +struct obstack notes; +#ifdef TE_PE +/* The name of an external symbol which is + used to make weak PE symbol names unique. */ +const char * an_external_name; +#endif + +static char *save_symbol_name (const char *); +static void fb_label_init (void); +static long dollar_label_instance (long); +static long fb_label_instance (long); + +static void print_binary (FILE *, const char *, expressionS *); + +/* Return a pointer to a new symbol. Die if we can't make a new + symbol. Fill in the symbol's values. Add symbol to end of symbol + chain. + + This function should be called in the general case of creating a + symbol. However, if the output file symbol table has already been + set, and you are certain that this symbol won't be wanted in the + output file, you can call symbol_create. */ + +symbolS * +symbol_new (const char *name, segT segment, valueT valu, fragS *frag) +{ + symbolS *symbolP = symbol_create (name, segment, valu, frag); + + /* Link to end of symbol chain. */ + { + extern int symbol_table_frozen; + if (symbol_table_frozen) + abort (); + } + symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP); + + return symbolP; +} + +/* Save a symbol name on a permanent obstack, and convert it according + to the object file format. */ + +static char * +save_symbol_name (const char *name) +{ + unsigned int name_length; + char *ret; + + name_length = strlen (name) + 1; /* +1 for \0. */ + obstack_grow (¬es, name, name_length); + ret = (char *) obstack_finish (¬es); + +#ifdef tc_canonicalize_symbol_name + ret = tc_canonicalize_symbol_name (ret); +#endif + + if (! symbols_case_sensitive) + { + char *s; + + for (s = ret; *s != '\0'; s++) + *s = TOUPPER (*s); + } + + return ret; +} + +symbolS * +symbol_create (const char *name, /* It is copied, the caller can destroy/modify. */ + segT segment, /* Segment identifier (SEG_). */ + valueT valu, /* Symbol value. */ + fragS *frag /* Associated fragment. */) +{ + char *preserved_copy_of_name; + symbolS *symbolP; + + preserved_copy_of_name = save_symbol_name (name); + + symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS)); + + /* symbol must be born in some fixed state. This seems as good as any. */ + memset (symbolP, 0, sizeof (symbolS)); + + symbolP->bsym = bfd_make_empty_symbol (stdoutput); + if (symbolP->bsym == NULL) + as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ())); + S_SET_NAME (symbolP, preserved_copy_of_name); + + S_SET_SEGMENT (symbolP, segment); + S_SET_VALUE (symbolP, valu); + symbol_clear_list_pointers (symbolP); + + symbolP->sy_frag = frag; + + obj_symbol_new_hook (symbolP); + +#ifdef tc_symbol_new_hook + tc_symbol_new_hook (symbolP); +#endif + + return symbolP; +} + + +/* Local symbol support. If we can get away with it, we keep only a + small amount of information for local symbols. */ + +static symbolS *local_symbol_convert (struct local_symbol *); + +/* Used for statistics. */ + +static unsigned long local_symbol_count; +static unsigned long local_symbol_conversion_count; + +/* This macro is called with a symbol argument passed by reference. + It returns whether this is a local symbol. If necessary, it + changes its argument to the real symbol. */ + +#define LOCAL_SYMBOL_CHECK(s) \ + (s->sy_flags.sy_local_symbol \ + ? (local_symbol_converted_p ((struct local_symbol *) s) \ + ? (s = local_symbol_get_real_symbol ((struct local_symbol *) s), \ + 0) \ + : 1) \ + : 0) + +/* Create a local symbol and insert it into the local hash table. */ + +struct local_symbol * +local_symbol_make (const char *name, segT section, valueT val, fragS *frag) +{ + char *name_copy; + struct local_symbol *ret; + + ++local_symbol_count; + + name_copy = save_symbol_name (name); + + ret = (struct local_symbol *) obstack_alloc (¬es, sizeof *ret); + ret->lsy_flags.sy_local_symbol = 1; + ret->lsy_flags.sy_resolved = 0; + ret->lsy_name = name_copy; + ret->lsy_section = section; + local_symbol_set_frag (ret, frag); + ret->lsy_value = val; + + hash_jam (local_hash, name_copy, (void *) ret); + + return ret; +} + +/* Convert a local symbol into a real symbol. Note that we do not + reclaim the space used by the local symbol. */ + +static symbolS * +local_symbol_convert (struct local_symbol *locsym) +{ + symbolS *ret; + + gas_assert (locsym->lsy_flags.sy_local_symbol); + if (local_symbol_converted_p (locsym)) + return local_symbol_get_real_symbol (locsym); + + ++local_symbol_conversion_count; + + ret = symbol_new (locsym->lsy_name, locsym->lsy_section, locsym->lsy_value, + local_symbol_get_frag (locsym)); + + if (local_symbol_resolved_p (locsym)) + ret->sy_flags.sy_resolved = 1; + + /* Local symbols are always either defined or used. */ + ret->sy_flags.sy_used = 1; + +#ifdef TC_LOCAL_SYMFIELD_CONVERT + TC_LOCAL_SYMFIELD_CONVERT (locsym, ret); +#endif + + symbol_table_insert (ret); + + local_symbol_mark_converted (locsym); + local_symbol_set_real_symbol (locsym, ret); + + hash_jam (local_hash, locsym->lsy_name, NULL); + + return ret; +} + +static void +define_sym_at_dot (symbolS *symbolP) +{ + symbolP->sy_frag = frag_now; + S_SET_VALUE (symbolP, (valueT) frag_now_fix ()); + S_SET_SEGMENT (symbolP, now_seg); +} + +/* We have just seen ":". + Creates a struct symbol unless it already exists. + + Gripes if we are redefining a symbol incompatibly (and ignores it). */ + +symbolS * +colon (/* Just seen "x:" - rattle symbols & frags. */ + const char *sym_name /* Symbol name, as a cannonical string. */ + /* We copy this string: OK to alter later. */) +{ + register symbolS *symbolP; /* Symbol we are working with. */ + + /* Sun local labels go out of scope whenever a non-local symbol is + defined. */ + if (LOCAL_LABELS_DOLLAR + && !bfd_is_local_label_name (stdoutput, sym_name)) + dollar_label_clear (); + +#ifndef WORKING_DOT_WORD + if (new_broken_words) + { + struct broken_word *a; + int possible_bytes; + fragS *frag_tmp; + char *frag_opcode; + + if (now_seg == absolute_section) + { + as_bad (_("cannot define symbol `%s' in absolute section"), sym_name); + return NULL; + } + + possible_bytes = (md_short_jump_size + + new_broken_words * md_long_jump_size); + + frag_tmp = frag_now; + frag_opcode = frag_var (rs_broken_word, + possible_bytes, + possible_bytes, + (relax_substateT) 0, + (symbolS *) broken_words, + (offsetT) 0, + NULL); + + /* We want to store the pointer to where to insert the jump + table in the fr_opcode of the rs_broken_word frag. This + requires a little hackery. */ + while (frag_tmp + && (frag_tmp->fr_type != rs_broken_word + || frag_tmp->fr_opcode)) + frag_tmp = frag_tmp->fr_next; + know (frag_tmp); + frag_tmp->fr_opcode = frag_opcode; + new_broken_words = 0; + + for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word) + a->dispfrag = frag_tmp; + } +#endif /* WORKING_DOT_WORD */ + +#ifdef obj_frob_colon + obj_frob_colon (sym_name); +#endif + + if ((symbolP = symbol_find (sym_name)) != 0) + { + S_CLEAR_WEAKREFR (symbolP); +#ifdef RESOLVE_SYMBOL_REDEFINITION + if (RESOLVE_SYMBOL_REDEFINITION (symbolP)) + return symbolP; +#endif + /* Now check for undefined symbols. */ + if (LOCAL_SYMBOL_CHECK (symbolP)) + { + struct local_symbol *locsym = (struct local_symbol *) symbolP; + + if (locsym->lsy_section != undefined_section + && (local_symbol_get_frag (locsym) != frag_now + || locsym->lsy_section != now_seg + || locsym->lsy_value != frag_now_fix ())) + { + as_bad (_("symbol `%s' is already defined"), sym_name); + return symbolP; + } + + locsym->lsy_section = now_seg; + local_symbol_set_frag (locsym, frag_now); + locsym->lsy_value = frag_now_fix (); + } + else if (!(S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + || S_IS_COMMON (symbolP) + || S_IS_VOLATILE (symbolP)) + { + if (S_IS_VOLATILE (symbolP)) + { + symbolP = symbol_clone (symbolP, 1); + S_SET_VALUE (symbolP, 0); + S_CLEAR_VOLATILE (symbolP); + } + if (S_GET_VALUE (symbolP) == 0) + { + define_sym_at_dot (symbolP); +#ifdef N_UNDF + know (N_UNDF == 0); +#endif /* if we have one, it better be zero. */ + + } + else + { + /* There are still several cases to check: + + A .comm/.lcomm symbol being redefined as initialized + data is OK + + A .comm/.lcomm symbol being redefined with a larger + size is also OK + + This only used to be allowed on VMS gas, but Sun cc + on the sparc also depends on it. */ + + if (((!S_IS_DEBUG (symbolP) + && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)) + && S_IS_EXTERNAL (symbolP)) + || S_GET_SEGMENT (symbolP) == bss_section) + && (now_seg == data_section + || now_seg == bss_section + || now_seg == S_GET_SEGMENT (symbolP))) + { + /* Select which of the 2 cases this is. */ + if (now_seg != data_section) + { + /* New .comm for prev .comm symbol. + + If the new size is larger we just change its + value. If the new size is smaller, we ignore + this symbol. */ + if (S_GET_VALUE (symbolP) + < ((unsigned) frag_now_fix ())) + { + S_SET_VALUE (symbolP, (valueT) frag_now_fix ()); + } + } + else + { + /* It is a .comm/.lcomm being converted to initialized + data. */ + define_sym_at_dot (symbolP); + } + } + else + { +#if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT) \ + && !defined (OBJ_BOUT) && !defined (OBJ_MAYBE_BOUT)) + static const char *od_buf = ""; +#else + char od_buf[100]; + od_buf[0] = '\0'; + if (OUTPUT_FLAVOR == bfd_target_aout_flavour) + sprintf (od_buf, "%d.%d.", + S_GET_OTHER (symbolP), + S_GET_DESC (symbolP)); +#endif + as_bad (_("symbol `%s' is already defined as \"%s\"/%s%ld"), + sym_name, + segment_name (S_GET_SEGMENT (symbolP)), + od_buf, + (long) S_GET_VALUE (symbolP)); + } + } /* if the undefined symbol has no value */ + } + else + { + /* Don't blow up if the definition is the same. */ + if (!(frag_now == symbolP->sy_frag + && S_GET_VALUE (symbolP) == frag_now_fix () + && S_GET_SEGMENT (symbolP) == now_seg)) + { + as_bad (_("symbol `%s' is already defined"), sym_name); + symbolP = symbol_clone (symbolP, 0); + define_sym_at_dot (symbolP); + } + } + + } + else if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, sym_name)) + { + symbolP = (symbolS *) local_symbol_make (sym_name, now_seg, + (valueT) frag_now_fix (), + frag_now); + } + else + { + symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (), + frag_now); + + symbol_table_insert (symbolP); + } + + if (mri_common_symbol != NULL) + { + /* This symbol is actually being defined within an MRI common + section. This requires special handling. */ + if (LOCAL_SYMBOL_CHECK (symbolP)) + symbolP = local_symbol_convert ((struct local_symbol *) symbolP); + symbolP->sy_value.X_op = O_symbol; + symbolP->sy_value.X_add_symbol = mri_common_symbol; + symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol); + symbolP->sy_frag = &zero_address_frag; + S_SET_SEGMENT (symbolP, expr_section); + symbolP->sy_flags.sy_mri_common = 1; + } + +#ifdef tc_frob_label + tc_frob_label (symbolP); +#endif +#ifdef obj_frob_label + obj_frob_label (symbolP); +#endif + + return symbolP; +} + +/* Die if we can't insert the symbol. */ + +void +symbol_table_insert (symbolS *symbolP) +{ + register const char *error_string; + + know (symbolP); + know (S_GET_NAME (symbolP)); + + if (LOCAL_SYMBOL_CHECK (symbolP)) + { + error_string = hash_jam (local_hash, S_GET_NAME (symbolP), + (void *) symbolP); + if (error_string != NULL) + as_fatal (_("inserting \"%s\" into symbol table failed: %s"), + S_GET_NAME (symbolP), error_string); + return; + } + + if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (void *) symbolP))) + { + as_fatal (_("inserting \"%s\" into symbol table failed: %s"), + S_GET_NAME (symbolP), error_string); + } /* on error */ +} + +/* If a symbol name does not exist, create it as undefined, and insert + it into the symbol table. Return a pointer to it. */ + +symbolS * +symbol_find_or_make (const char *name) +{ + register symbolS *symbolP; + + symbolP = symbol_find (name); + + if (symbolP == NULL) + { + if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, name)) + { + symbolP = md_undefined_symbol ((char *) name); + if (symbolP != NULL) + return symbolP; + + symbolP = (symbolS *) local_symbol_make (name, undefined_section, + (valueT) 0, + &zero_address_frag); + return symbolP; + } + + symbolP = symbol_make (name); + + symbol_table_insert (symbolP); + } /* if symbol wasn't found */ + + return (symbolP); +} + +symbolS * +symbol_make (const char *name) +{ + symbolS *symbolP; + + /* Let the machine description default it, e.g. for register names. */ + symbolP = md_undefined_symbol ((char *) name); + + if (!symbolP) + symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag); + + return (symbolP); +} + +symbolS * +symbol_clone (symbolS *orgsymP, int replace) +{ + symbolS *newsymP; + asymbol *bsymorg, *bsymnew; + + /* Make sure we never clone the dot special symbol. */ + gas_assert (orgsymP != &dot_symbol); + + /* Running local_symbol_convert on a clone that's not the one currently + in local_hash would incorrectly replace the hash entry. Thus the + symbol must be converted here. Note that the rest of the function + depends on not encountering an unconverted symbol. */ + if (LOCAL_SYMBOL_CHECK (orgsymP)) + orgsymP = local_symbol_convert ((struct local_symbol *) orgsymP); + bsymorg = orgsymP->bsym; + + newsymP = (symbolS *) obstack_alloc (¬es, sizeof (*newsymP)); + *newsymP = *orgsymP; + bsymnew = bfd_make_empty_symbol (bfd_asymbol_bfd (bsymorg)); + if (bsymnew == NULL) + as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ())); + newsymP->bsym = bsymnew; + bsymnew->name = bsymorg->name; + bsymnew->flags = bsymorg->flags & ~BSF_SECTION_SYM; + bsymnew->section = bsymorg->section; + bfd_copy_private_symbol_data (bfd_asymbol_bfd (bsymorg), bsymorg, + bfd_asymbol_bfd (bsymnew), bsymnew); + +#ifdef obj_symbol_clone_hook + obj_symbol_clone_hook (newsymP, orgsymP); +#endif + +#ifdef tc_symbol_clone_hook + tc_symbol_clone_hook (newsymP, orgsymP); +#endif + + if (replace) + { + if (symbol_rootP == orgsymP) + symbol_rootP = newsymP; + else if (orgsymP->sy_previous) + { + orgsymP->sy_previous->sy_next = newsymP; + orgsymP->sy_previous = NULL; + } + if (symbol_lastP == orgsymP) + symbol_lastP = newsymP; + else if (orgsymP->sy_next) + orgsymP->sy_next->sy_previous = newsymP; + + /* Symbols that won't be output can't be external. */ + S_CLEAR_EXTERNAL (orgsymP); + orgsymP->sy_previous = orgsymP->sy_next = orgsymP; + debug_verify_symchain (symbol_rootP, symbol_lastP); + + symbol_table_insert (newsymP); + } + else + { + /* Symbols that won't be output can't be external. */ + S_CLEAR_EXTERNAL (newsymP); + newsymP->sy_previous = newsymP->sy_next = newsymP; + } + + return newsymP; +} + +/* Referenced symbols, if they are forward references, need to be cloned + (without replacing the original) so that the value of the referenced + symbols at the point of use . */ + +#undef symbol_clone_if_forward_ref +symbolS * +symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward) +{ + if (symbolP && !LOCAL_SYMBOL_CHECK (symbolP)) + { + symbolS *add_symbol = symbolP->sy_value.X_add_symbol; + symbolS *op_symbol = symbolP->sy_value.X_op_symbol; + + if (symbolP->sy_flags.sy_forward_ref) + is_forward = 1; + + if (is_forward) + { + /* assign_symbol() clones volatile symbols; pre-existing expressions + hold references to the original instance, but want the current + value. Just repeat the lookup. */ + if (add_symbol && S_IS_VOLATILE (add_symbol)) + add_symbol = symbol_find_exact (S_GET_NAME (add_symbol)); + if (op_symbol && S_IS_VOLATILE (op_symbol)) + op_symbol = symbol_find_exact (S_GET_NAME (op_symbol)); + } + + /* Re-using sy_resolving here, as this routine cannot get called from + symbol resolution code. */ + if ((symbolP->bsym->section == expr_section + || symbolP->sy_flags.sy_forward_ref) + && !symbolP->sy_flags.sy_resolving) + { + symbolP->sy_flags.sy_resolving = 1; + add_symbol = symbol_clone_if_forward_ref (add_symbol, is_forward); + op_symbol = symbol_clone_if_forward_ref (op_symbol, is_forward); + symbolP->sy_flags.sy_resolving = 0; + } + + if (symbolP->sy_flags.sy_forward_ref + || add_symbol != symbolP->sy_value.X_add_symbol + || op_symbol != symbolP->sy_value.X_op_symbol) + { + if (symbolP != &dot_symbol) + { + symbolP = symbol_clone (symbolP, 0); + symbolP->sy_flags.sy_resolving = 0; + } + else + { + symbolP = symbol_temp_new_now (); +#ifdef tc_new_dot_label + tc_new_dot_label (symbolP); +#endif + } + } + + symbolP->sy_value.X_add_symbol = add_symbol; + symbolP->sy_value.X_op_symbol = op_symbol; + } + + return symbolP; +} + +symbolS * +symbol_temp_new (segT seg, valueT ofs, fragS *frag) +{ + return symbol_new (FAKE_LABEL_NAME, seg, ofs, frag); +} + +symbolS * +symbol_temp_new_now (void) +{ + return symbol_temp_new (now_seg, frag_now_fix (), frag_now); +} + +symbolS * +symbol_temp_make (void) +{ + return symbol_make (FAKE_LABEL_NAME); +} + +/* Implement symbol table lookup. + In: A symbol's name as a string: '\0' can't be part of a symbol name. + Out: NULL if the name was not in the symbol table, else the address + of a struct symbol associated with that name. */ + +symbolS * +symbol_find_exact (const char *name) +{ + return symbol_find_exact_noref (name, 0); +} + +symbolS * +symbol_find_exact_noref (const char *name, int noref) +{ + struct local_symbol *locsym; + symbolS* sym; + + locsym = (struct local_symbol *) hash_find (local_hash, name); + if (locsym != NULL) + return (symbolS *) locsym; + + sym = ((symbolS *) hash_find (sy_hash, name)); + + /* Any references to the symbol, except for the reference in + .weakref, must clear this flag, such that the symbol does not + turn into a weak symbol. Note that we don't have to handle the + local_symbol case, since a weakrefd is always promoted out of the + local_symbol table when it is turned into a weak symbol. */ + if (sym && ! noref) + S_CLEAR_WEAKREFD (sym); + + return sym; +} + +symbolS * +symbol_find (const char *name) +{ + return symbol_find_noref (name, 0); +} + +symbolS * +symbol_find_noref (const char *name, int noref) +{ +#ifdef tc_canonicalize_symbol_name + { + char *copy; + size_t len = strlen (name) + 1; + + copy = (char *) alloca (len); + memcpy (copy, name, len); + name = tc_canonicalize_symbol_name (copy); + } +#endif + + if (! symbols_case_sensitive) + { + char *copy; + const char *orig; + unsigned char c; + + orig = name; + name = copy = (char *) alloca (strlen (name) + 1); + + while ((c = *orig++) != '\0') + { + *copy++ = TOUPPER (c); + } + *copy = '\0'; + } + + return symbol_find_exact_noref (name, noref); +} + +/* Once upon a time, symbols were kept in a singly linked list. At + least coff needs to be able to rearrange them from time to time, for + which a doubly linked list is much more convenient. Loic did these + as macros which seemed dangerous to me so they're now functions. + xoxorich. */ + +/* Link symbol ADDME after symbol TARGET in the chain. */ + +void +symbol_append (symbolS *addme, symbolS *target, + symbolS **rootPP, symbolS **lastPP) +{ + if (LOCAL_SYMBOL_CHECK (addme)) + abort (); + if (target != NULL && LOCAL_SYMBOL_CHECK (target)) + abort (); + + if (target == NULL) + { + know (*rootPP == NULL); + know (*lastPP == NULL); + addme->sy_next = NULL; + addme->sy_previous = NULL; + *rootPP = addme; + *lastPP = addme; + return; + } /* if the list is empty */ + + if (target->sy_next != NULL) + { + target->sy_next->sy_previous = addme; + } + else + { + know (*lastPP == target); + *lastPP = addme; + } /* if we have a next */ + + addme->sy_next = target->sy_next; + target->sy_next = addme; + addme->sy_previous = target; + + debug_verify_symchain (symbol_rootP, symbol_lastP); +} + +/* Set the chain pointers of SYMBOL to null. */ + +void +symbol_clear_list_pointers (symbolS *symbolP) +{ + if (LOCAL_SYMBOL_CHECK (symbolP)) + abort (); + symbolP->sy_next = NULL; + symbolP->sy_previous = NULL; +} + +/* Remove SYMBOLP from the list. */ + +void +symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP) +{ + if (LOCAL_SYMBOL_CHECK (symbolP)) + abort (); + + if (symbolP == *rootPP) + { + *rootPP = symbolP->sy_next; + } /* if it was the root */ + + if (symbolP == *lastPP) + { + *lastPP = symbolP->sy_previous; + } /* if it was the tail */ + + if (symbolP->sy_next != NULL) + { + symbolP->sy_next->sy_previous = symbolP->sy_previous; + } /* if not last */ + + if (symbolP->sy_previous != NULL) + { + symbolP->sy_previous->sy_next = symbolP->sy_next; + } /* if not first */ + + debug_verify_symchain (*rootPP, *lastPP); +} + +/* Link symbol ADDME before symbol TARGET in the chain. */ + +void +symbol_insert (symbolS *addme, symbolS *target, + symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED) +{ + if (LOCAL_SYMBOL_CHECK (addme)) + abort (); + if (LOCAL_SYMBOL_CHECK (target)) + abort (); + + if (target->sy_previous != NULL) + { + target->sy_previous->sy_next = addme; + } + else + { + know (*rootPP == target); + *rootPP = addme; + } /* if not first */ + + addme->sy_previous = target->sy_previous; + target->sy_previous = addme; + addme->sy_next = target; + + debug_verify_symchain (*rootPP, *lastPP); +} + +void +verify_symbol_chain (symbolS *rootP, symbolS *lastP) +{ + symbolS *symbolP = rootP; + + if (symbolP == NULL) + return; + + for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP)) + { + gas_assert (symbolP->bsym != NULL); + gas_assert (symbolP->sy_flags.sy_local_symbol == 0); + gas_assert (symbolP->sy_next->sy_previous == symbolP); + } + + gas_assert (lastP == symbolP); +} + +#ifdef OBJ_COMPLEX_RELC + +static int +use_complex_relocs_for (symbolS * symp) +{ + switch (symp->sy_value.X_op) + { + case O_constant: + return 0; + + case O_symbol: + case O_symbol_rva: + case O_uminus: + case O_bit_not: + case O_logical_not: + if ( (S_IS_COMMON (symp->sy_value.X_add_symbol) + || S_IS_LOCAL (symp->sy_value.X_add_symbol)) + && + (S_IS_DEFINED (symp->sy_value.X_add_symbol) + && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)) + return 0; + break; + + case O_multiply: + case O_divide: + case O_modulus: + case O_left_shift: + case O_right_shift: + case O_bit_inclusive_or: + case O_bit_or_not: + case O_bit_exclusive_or: + case O_bit_and: + case O_add: + case O_subtract: + case O_eq: + case O_ne: + case O_lt: + case O_le: + case O_ge: + case O_gt: + case O_logical_and: + case O_logical_or: + + if ( (S_IS_COMMON (symp->sy_value.X_add_symbol) + || S_IS_LOCAL (symp->sy_value.X_add_symbol)) + && + (S_IS_COMMON (symp->sy_value.X_op_symbol) + || S_IS_LOCAL (symp->sy_value.X_op_symbol)) + + && S_IS_DEFINED (symp->sy_value.X_add_symbol) + && S_IS_DEFINED (symp->sy_value.X_op_symbol) + && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section + && S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section) + return 0; + break; + + default: + break; + } + return 1; +} +#endif + +static void +report_op_error (symbolS *symp, symbolS *left, operatorT op, symbolS *right) +{ + char *file; + unsigned int line; + segT seg_left = left ? S_GET_SEGMENT (left) : 0; + segT seg_right = S_GET_SEGMENT (right); + const char *opname; + + switch (op) + { + default: + abort (); + return; + + case O_uminus: opname = "-"; break; + case O_bit_not: opname = "~"; break; + case O_logical_not: opname = "!"; break; + case O_multiply: opname = "*"; break; + case O_divide: opname = "/"; break; + case O_modulus: opname = "%"; break; + case O_left_shift: opname = "<<"; break; + case O_right_shift: opname = ">>"; break; + case O_bit_inclusive_or: opname = "|"; break; + case O_bit_or_not: opname = "|~"; break; + case O_bit_exclusive_or: opname = "^"; break; + case O_bit_and: opname = "&"; break; + case O_add: opname = "+"; break; + case O_subtract: opname = "-"; break; + case O_eq: opname = "=="; break; + case O_ne: opname = "!="; break; + case O_lt: opname = "<"; break; + case O_le: opname = "<="; break; + case O_ge: opname = ">="; break; + case O_gt: opname = ">"; break; + case O_logical_and: opname = "&&"; break; + case O_logical_or: opname = "||"; break; + } + + if (expr_symbol_where (symp, &file, &line)) + { + if (left) + as_bad_where (file, line, + _("invalid operands (%s and %s sections) for `%s'"), + seg_left->name, seg_right->name, opname); + else + as_bad_where (file, line, + _("invalid operand (%s section) for `%s'"), + seg_right->name, opname); + } + else + { + const char *sname = S_GET_NAME (symp); + + if (left) + as_bad (_("invalid operands (%s and %s sections) for `%s' when setting `%s'"), + seg_left->name, seg_right->name, opname, sname); + else + as_bad (_("invalid operand (%s section) for `%s' when setting `%s'"), + seg_right->name, opname, sname); + } +} + +/* Resolve the value of a symbol. This is called during the final + pass over the symbol table to resolve any symbols with complex + values. */ + +valueT +resolve_symbol_value (symbolS *symp) +{ + int resolved; + valueT final_val = 0; + segT final_seg; + + if (LOCAL_SYMBOL_CHECK (symp)) + { + struct local_symbol *locsym = (struct local_symbol *) symp; + + final_val = locsym->lsy_value; + if (local_symbol_resolved_p (locsym)) + return final_val; + + final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE; + + if (finalize_syms) + { + locsym->lsy_value = final_val; + local_symbol_mark_resolved (locsym); + } + + return final_val; + } + + if (symp->sy_flags.sy_resolved) + { + if (symp->sy_value.X_op == O_constant) + return (valueT) symp->sy_value.X_add_number; + else + return 0; + } + + resolved = 0; + final_seg = S_GET_SEGMENT (symp); + + if (symp->sy_flags.sy_resolving) + { + if (finalize_syms) + as_bad (_("symbol definition loop encountered at `%s'"), + S_GET_NAME (symp)); + final_val = 0; + resolved = 1; + } +#ifdef OBJ_COMPLEX_RELC + else if (final_seg == expr_section + && use_complex_relocs_for (symp)) + { + symbolS * relc_symbol = NULL; + char * relc_symbol_name = NULL; + + relc_symbol_name = symbol_relc_make_expr (& symp->sy_value); + + /* For debugging, print out conversion input & output. */ +#ifdef DEBUG_SYMS + print_expr (& symp->sy_value); + if (relc_symbol_name) + fprintf (stderr, "-> relc symbol: %s\n", relc_symbol_name); +#endif + + if (relc_symbol_name != NULL) + relc_symbol = symbol_new (relc_symbol_name, undefined_section, + 0, & zero_address_frag); + + if (relc_symbol == NULL) + { + as_bad (_("cannot convert expression symbol %s to complex relocation"), + S_GET_NAME (symp)); + resolved = 0; + } + else + { + symbol_table_insert (relc_symbol); + + /* S_CLEAR_EXTERNAL (relc_symbol); */ + if (symp->bsym->flags & BSF_SRELC) + relc_symbol->bsym->flags |= BSF_SRELC; + else + relc_symbol->bsym->flags |= BSF_RELC; + /* symp->bsym->flags |= BSF_RELC; */ + copy_symbol_attributes (symp, relc_symbol); + symp->sy_value.X_op = O_symbol; + symp->sy_value.X_add_symbol = relc_symbol; + symp->sy_value.X_add_number = 0; + resolved = 1; + } + + final_seg = undefined_section; + goto exit_dont_set_value; + } +#endif + else + { + symbolS *add_symbol, *op_symbol; + offsetT left, right; + segT seg_left, seg_right; + operatorT op; + int move_seg_ok; + + symp->sy_flags.sy_resolving = 1; + + /* Help out with CSE. */ + add_symbol = symp->sy_value.X_add_symbol; + op_symbol = symp->sy_value.X_op_symbol; + final_val = symp->sy_value.X_add_number; + op = symp->sy_value.X_op; + + switch (op) + { + default: + BAD_CASE (op); + break; + + case O_absent: + final_val = 0; + /* Fall through. */ + + case O_constant: + final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE; + if (final_seg == expr_section) + final_seg = absolute_section; + /* Fall through. */ + + case O_register: + resolved = 1; + break; + + case O_symbol: + case O_symbol_rva: + left = resolve_symbol_value (add_symbol); + seg_left = S_GET_SEGMENT (add_symbol); + if (finalize_syms) + symp->sy_value.X_op_symbol = NULL; + + do_symbol: + if (S_IS_WEAKREFR (symp)) + { + gas_assert (final_val == 0); + if (S_IS_WEAKREFR (add_symbol)) + { + gas_assert (add_symbol->sy_value.X_op == O_symbol + && add_symbol->sy_value.X_add_number == 0); + add_symbol = add_symbol->sy_value.X_add_symbol; + gas_assert (! S_IS_WEAKREFR (add_symbol)); + symp->sy_value.X_add_symbol = add_symbol; + } + } + + if (symp->sy_flags.sy_mri_common) + { + /* This is a symbol inside an MRI common section. The + relocation routines are going to handle it specially. + Don't change the value. */ + resolved = symbol_resolved_p (add_symbol); + break; + } + + if (finalize_syms && final_val == 0) + { + if (LOCAL_SYMBOL_CHECK (add_symbol)) + add_symbol = local_symbol_convert ((struct local_symbol *) + add_symbol); + copy_symbol_attributes (symp, add_symbol); + } + + /* If we have equated this symbol to an undefined or common + symbol, keep X_op set to O_symbol, and don't change + X_add_number. This permits the routine which writes out + relocation to detect this case, and convert the + relocation to be against the symbol to which this symbol + is equated. */ + if (! S_IS_DEFINED (add_symbol) +#if defined (OBJ_COFF) && defined (TE_PE) + || S_IS_WEAK (add_symbol) +#endif + || S_IS_COMMON (add_symbol)) + { + if (finalize_syms) + { + symp->sy_value.X_op = O_symbol; + symp->sy_value.X_add_symbol = add_symbol; + symp->sy_value.X_add_number = final_val; + /* Use X_op_symbol as a flag. */ + symp->sy_value.X_op_symbol = add_symbol; + } + final_seg = seg_left; + final_val = 0; + resolved = symbol_resolved_p (add_symbol); + symp->sy_flags.sy_resolving = 0; + goto exit_dont_set_value; + } + else if (finalize_syms + && ((final_seg == expr_section && seg_left != expr_section) + || symbol_shadow_p (symp))) + { + /* If the symbol is an expression symbol, do similarly + as for undefined and common syms above. Handles + "sym +/- expr" where "expr" cannot be evaluated + immediately, and we want relocations to be against + "sym", eg. because it is weak. */ + symp->sy_value.X_op = O_symbol; + symp->sy_value.X_add_symbol = add_symbol; + symp->sy_value.X_add_number = final_val; + symp->sy_value.X_op_symbol = add_symbol; + final_seg = seg_left; + final_val += symp->sy_frag->fr_address + left; + resolved = symbol_resolved_p (add_symbol); + symp->sy_flags.sy_resolving = 0; + goto exit_dont_set_value; + } + else + { + final_val += symp->sy_frag->fr_address + left; + if (final_seg == expr_section || final_seg == undefined_section) + final_seg = seg_left; + } + + resolved = symbol_resolved_p (add_symbol); + if (S_IS_WEAKREFR (symp)) + goto exit_dont_set_value; + break; + + case O_uminus: + case O_bit_not: + case O_logical_not: + left = resolve_symbol_value (add_symbol); + seg_left = S_GET_SEGMENT (add_symbol); + + /* By reducing these to the relevant dyadic operator, we get + !S -> S == 0 permitted on anything, + -S -> 0 - S only permitted on absolute + ~S -> S ^ ~0 only permitted on absolute */ + if (op != O_logical_not && seg_left != absolute_section + && finalize_syms) + report_op_error (symp, NULL, op, add_symbol); + + if (final_seg == expr_section || final_seg == undefined_section) + final_seg = absolute_section; + + if (op == O_uminus) + left = -left; + else if (op == O_logical_not) + left = !left; + else + left = ~left; + + final_val += left + symp->sy_frag->fr_address; + + resolved = symbol_resolved_p (add_symbol); + break; + + case O_multiply: + case O_divide: + case O_modulus: + case O_left_shift: + case O_right_shift: + case O_bit_inclusive_or: + case O_bit_or_not: + case O_bit_exclusive_or: + case O_bit_and: + case O_add: + case O_subtract: + case O_eq: + case O_ne: + case O_lt: + case O_le: + case O_ge: + case O_gt: + case O_logical_and: + case O_logical_or: + left = resolve_symbol_value (add_symbol); + right = resolve_symbol_value (op_symbol); + seg_left = S_GET_SEGMENT (add_symbol); + seg_right = S_GET_SEGMENT (op_symbol); + + /* Simplify addition or subtraction of a constant by folding the + constant into X_add_number. */ + if (op == O_add) + { + if (seg_right == absolute_section) + { + final_val += right; + goto do_symbol; + } + else if (seg_left == absolute_section) + { + final_val += left; + add_symbol = op_symbol; + left = right; + seg_left = seg_right; + goto do_symbol; + } + } + else if (op == O_subtract) + { + if (seg_right == absolute_section) + { + final_val -= right; + goto do_symbol; + } + } + + move_seg_ok = 1; + /* Equality and non-equality tests are permitted on anything. + Subtraction, and other comparison operators are permitted if + both operands are in the same section. Otherwise, both + operands must be absolute. We already handled the case of + addition or subtraction of a constant above. This will + probably need to be changed for an object file format which + supports arbitrary expressions, such as IEEE-695. */ + if (!(seg_left == absolute_section + && seg_right == absolute_section) + && !(op == O_eq || op == O_ne) + && !((op == O_subtract + || op == O_lt || op == O_le || op == O_ge || op == O_gt) + && seg_left == seg_right + && (seg_left != undefined_section + || add_symbol == op_symbol))) + { + /* Don't emit messages unless we're finalizing the symbol value, + otherwise we may get the same message multiple times. */ + if (finalize_syms) + report_op_error (symp, add_symbol, op, op_symbol); + /* However do not move the symbol into the absolute section + if it cannot currently be resolved - this would confuse + other parts of the assembler into believing that the + expression had been evaluated to zero. */ + else + move_seg_ok = 0; + } + + if (move_seg_ok + && (final_seg == expr_section || final_seg == undefined_section)) + final_seg = absolute_section; + + /* Check for division by zero. */ + if ((op == O_divide || op == O_modulus) && right == 0) + { + /* If seg_right is not absolute_section, then we've + already issued a warning about using a bad symbol. */ + if (seg_right == absolute_section && finalize_syms) + { + char *file; + unsigned int line; + + if (expr_symbol_where (symp, &file, &line)) + as_bad_where (file, line, _("division by zero")); + else + as_bad (_("division by zero when setting `%s'"), + S_GET_NAME (symp)); + } + + right = 1; + } + + switch (symp->sy_value.X_op) + { + case O_multiply: left *= right; break; + case O_divide: left /= right; break; + case O_modulus: left %= right; break; + case O_left_shift: left <<= right; break; + case O_right_shift: left >>= right; break; + case O_bit_inclusive_or: left |= right; break; + case O_bit_or_not: left |= ~right; break; + case O_bit_exclusive_or: left ^= right; break; + case O_bit_and: left &= right; break; + case O_add: left += right; break; + case O_subtract: left -= right; break; + case O_eq: + case O_ne: + left = (left == right && seg_left == seg_right + && (seg_left != undefined_section + || add_symbol == op_symbol) + ? ~ (offsetT) 0 : 0); + if (symp->sy_value.X_op == O_ne) + left = ~left; + break; + case O_lt: left = left < right ? ~ (offsetT) 0 : 0; break; + case O_le: left = left <= right ? ~ (offsetT) 0 : 0; break; + case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; break; + case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break; + case O_logical_and: left = left && right; break; + case O_logical_or: left = left || right; break; + default: abort (); + } + + final_val += symp->sy_frag->fr_address + left; + if (final_seg == expr_section || final_seg == undefined_section) + { + if (seg_left == undefined_section + || seg_right == undefined_section) + final_seg = undefined_section; + else if (seg_left == absolute_section) + final_seg = seg_right; + else + final_seg = seg_left; + } + resolved = (symbol_resolved_p (add_symbol) + && symbol_resolved_p (op_symbol)); + break; + + case O_big: + case O_illegal: + /* Give an error (below) if not in expr_section. We don't + want to worry about expr_section symbols, because they + are fictional (they are created as part of expression + resolution), and any problems may not actually mean + anything. */ + break; + } + + symp->sy_flags.sy_resolving = 0; + } + + if (finalize_syms) + S_SET_VALUE (symp, final_val); + +exit_dont_set_value: + /* Always set the segment, even if not finalizing the value. + The segment is used to determine whether a symbol is defined. */ + S_SET_SEGMENT (symp, final_seg); + + /* Don't worry if we can't resolve an expr_section symbol. */ + if (finalize_syms) + { + if (resolved) + symp->sy_flags.sy_resolved = 1; + else if (S_GET_SEGMENT (symp) != expr_section) + { + as_bad (_("can't resolve value for symbol `%s'"), + S_GET_NAME (symp)); + symp->sy_flags.sy_resolved = 1; + } + } + + return final_val; +} + +static void resolve_local_symbol (const char *, void *); + +/* A static function passed to hash_traverse. */ + +static void +resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, void *value) +{ + if (value != NULL) + resolve_symbol_value ((symbolS *) value); +} + +/* Resolve all local symbols. */ + +void +resolve_local_symbol_values (void) +{ + hash_traverse (local_hash, resolve_local_symbol); +} + +/* Obtain the current value of a symbol without changing any + sub-expressions used. */ + +int +snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP) +{ + symbolS *symbolP = *symbolPP; + + if (LOCAL_SYMBOL_CHECK (symbolP)) + { + struct local_symbol *locsym = (struct local_symbol *) symbolP; + + *valueP = locsym->lsy_value; + *segP = locsym->lsy_section; + *fragPP = local_symbol_get_frag (locsym); + } + else + { + expressionS exp = symbolP->sy_value; + + if (!symbolP->sy_flags.sy_resolved && exp.X_op != O_illegal) + { + int resolved; + + if (symbolP->sy_flags.sy_resolving) + return 0; + symbolP->sy_flags.sy_resolving = 1; + resolved = resolve_expression (&exp); + symbolP->sy_flags.sy_resolving = 0; + if (!resolved) + return 0; + + switch (exp.X_op) + { + case O_constant: + case O_register: + if (!symbol_equated_p (symbolP)) + break; + /* Fall thru. */ + case O_symbol: + case O_symbol_rva: + symbolP = exp.X_add_symbol; + break; + default: + return 0; + } + } + + *symbolPP = symbolP; + *valueP = exp.X_add_number; + *segP = symbolP->bsym->section; + *fragPP = symbolP->sy_frag; + + if (*segP == expr_section) + switch (exp.X_op) + { + case O_constant: *segP = absolute_section; break; + case O_register: *segP = reg_section; break; + default: break; + } + } + + return 1; +} + +/* Dollar labels look like a number followed by a dollar sign. Eg, "42$". + They are *really* local. That is, they go out of scope whenever we see a + label that isn't local. Also, like fb labels, there can be multiple + instances of a dollar label. Therefor, we name encode each instance with + the instance number, keep a list of defined symbols separate from the real + symbol table, and we treat these buggers as a sparse array. */ + +static long *dollar_labels; +static long *dollar_label_instances; +static char *dollar_label_defines; +static unsigned long dollar_label_count; +static unsigned long dollar_label_max; + +int +dollar_label_defined (long label) +{ + long *i; + + know ((dollar_labels != NULL) || (dollar_label_count == 0)); + + for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) + if (*i == label) + return dollar_label_defines[i - dollar_labels]; + + /* If we get here, label isn't defined. */ + return 0; +} + +static long +dollar_label_instance (long label) +{ + long *i; + + know ((dollar_labels != NULL) || (dollar_label_count == 0)); + + for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) + if (*i == label) + return (dollar_label_instances[i - dollar_labels]); + + /* If we get here, we haven't seen the label before. + Therefore its instance count is zero. */ + return 0; +} + +void +dollar_label_clear (void) +{ + memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count); +} + +#define DOLLAR_LABEL_BUMP_BY 10 + +void +define_dollar_label (long label) +{ + long *i; + + for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i) + if (*i == label) + { + ++dollar_label_instances[i - dollar_labels]; + dollar_label_defines[i - dollar_labels] = 1; + return; + } + + /* If we get to here, we don't have label listed yet. */ + + if (dollar_labels == NULL) + { + dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long)); + dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long)); + dollar_label_defines = (char *) xmalloc (DOLLAR_LABEL_BUMP_BY); + dollar_label_max = DOLLAR_LABEL_BUMP_BY; + dollar_label_count = 0; + } + else if (dollar_label_count == dollar_label_max) + { + dollar_label_max += DOLLAR_LABEL_BUMP_BY; + dollar_labels = (long *) xrealloc ((char *) dollar_labels, + dollar_label_max * sizeof (long)); + dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances, + dollar_label_max * sizeof (long)); + dollar_label_defines = (char *) xrealloc (dollar_label_defines, dollar_label_max); + } /* if we needed to grow */ + + dollar_labels[dollar_label_count] = label; + dollar_label_instances[dollar_label_count] = 1; + dollar_label_defines[dollar_label_count] = 1; + ++dollar_label_count; +} + +/* Caller must copy returned name: we re-use the area for the next name. + + The mth occurence of label n: is turned into the symbol "Ln^Am" + where n is the label number and m is the instance number. "L" makes + it a label discarded unless debugging and "^A"('\1') ensures no + ordinary symbol SHOULD get the same name as a local label + symbol. The first "4:" is "L4^A1" - the m numbers begin at 1. + + fb labels get the same treatment, except that ^B is used in place + of ^A. */ + +char * /* Return local label name. */ +dollar_label_name (register long n, /* we just saw "n$:" : n a number. */ + register int augend /* 0 for current instance, 1 for new instance. */) +{ + long i; + /* Returned to caller, then copied. Used for created names ("4f"). */ + static char symbol_name_build[24]; + register char *p; + register char *q; + char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */ + + know (n >= 0); + know (augend == 0 || augend == 1); + p = symbol_name_build; +#ifdef LOCAL_LABEL_PREFIX + *p++ = LOCAL_LABEL_PREFIX; +#endif + *p++ = 'L'; + + /* Next code just does sprintf( {}, "%d", n); */ + /* Label number. */ + q = symbol_name_temporary; + for (*q++ = 0, i = n; i; ++q) + { + *q = i % 10 + '0'; + i /= 10; + } + while ((*p = *--q) != '\0') + ++p; + + *p++ = DOLLAR_LABEL_CHAR; /* ^A */ + + /* Instance number. */ + q = symbol_name_temporary; + for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q) + { + *q = i % 10 + '0'; + i /= 10; + } + while ((*p++ = *--q) != '\0'); + + /* The label, as a '\0' ended string, starts at symbol_name_build. */ + return symbol_name_build; +} + +/* Somebody else's idea of local labels. They are made by "n:" where n + is any decimal digit. Refer to them with + "nb" for previous (backward) n: + or "nf" for next (forward) n:. + + We do a little better and let n be any number, not just a single digit, but + since the other guy's assembler only does ten, we treat the first ten + specially. + + Like someone else's assembler, we have one set of local label counters for + entire assembly, not one set per (sub)segment like in most assemblers. This + implies that one can refer to a label in another segment, and indeed some + crufty compilers have done just that. + + Since there could be a LOT of these things, treat them as a sparse + array. */ + +#define FB_LABEL_SPECIAL (10) + +static long fb_low_counter[FB_LABEL_SPECIAL]; +static long *fb_labels; +static long *fb_label_instances; +static long fb_label_count; +static long fb_label_max; + +/* This must be more than FB_LABEL_SPECIAL. */ +#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6) + +static void +fb_label_init (void) +{ + memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter)); +} + +/* Add one to the instance number of this fb label. */ + +void +fb_label_instance_inc (long label) +{ + long *i; + + if ((unsigned long) label < FB_LABEL_SPECIAL) + { + ++fb_low_counter[label]; + return; + } + + if (fb_labels != NULL) + { + for (i = fb_labels + FB_LABEL_SPECIAL; + i < fb_labels + fb_label_count; ++i) + { + if (*i == label) + { + ++fb_label_instances[i - fb_labels]; + return; + } /* if we find it */ + } /* for each existing label */ + } + + /* If we get to here, we don't have label listed yet. */ + + if (fb_labels == NULL) + { + fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long)); + fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long)); + fb_label_max = FB_LABEL_BUMP_BY; + fb_label_count = FB_LABEL_SPECIAL; + + } + else if (fb_label_count == fb_label_max) + { + fb_label_max += FB_LABEL_BUMP_BY; + fb_labels = (long *) xrealloc ((char *) fb_labels, + fb_label_max * sizeof (long)); + fb_label_instances = (long *) xrealloc ((char *) fb_label_instances, + fb_label_max * sizeof (long)); + } /* if we needed to grow */ + + fb_labels[fb_label_count] = label; + fb_label_instances[fb_label_count] = 1; + ++fb_label_count; +} + +static long +fb_label_instance (long label) +{ + long *i; + + if ((unsigned long) label < FB_LABEL_SPECIAL) + { + return (fb_low_counter[label]); + } + + if (fb_labels != NULL) + { + for (i = fb_labels + FB_LABEL_SPECIAL; + i < fb_labels + fb_label_count; ++i) + { + if (*i == label) + { + return (fb_label_instances[i - fb_labels]); + } /* if we find it */ + } /* for each existing label */ + } + + /* We didn't find the label, so this must be a reference to the + first instance. */ + return 0; +} + +/* Caller must copy returned name: we re-use the area for the next name. + + The mth occurence of label n: is turned into the symbol "Ln^Bm" + where n is the label number and m is the instance number. "L" makes + it a label discarded unless debugging and "^B"('\2') ensures no + ordinary symbol SHOULD get the same name as a local label + symbol. The first "4:" is "L4^B1" - the m numbers begin at 1. + + dollar labels get the same treatment, except that ^A is used in + place of ^B. */ + +char * /* Return local label name. */ +fb_label_name (long n, /* We just saw "n:", "nf" or "nb" : n a number. */ + long augend /* 0 for nb, 1 for n:, nf. */) +{ + long i; + /* Returned to caller, then copied. Used for created names ("4f"). */ + static char symbol_name_build[24]; + register char *p; + register char *q; + char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */ + + know (n >= 0); +#ifdef TC_MMIX + know ((unsigned long) augend <= 2 /* See mmix_fb_label. */); +#else + know ((unsigned long) augend <= 1); +#endif + p = symbol_name_build; +#ifdef LOCAL_LABEL_PREFIX + *p++ = LOCAL_LABEL_PREFIX; +#endif + *p++ = 'L'; + + /* Next code just does sprintf( {}, "%d", n); */ + /* Label number. */ + q = symbol_name_temporary; + for (*q++ = 0, i = n; i; ++q) + { + *q = i % 10 + '0'; + i /= 10; + } + while ((*p = *--q) != '\0') + ++p; + + *p++ = LOCAL_LABEL_CHAR; /* ^B */ + + /* Instance number. */ + q = symbol_name_temporary; + for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q) + { + *q = i % 10 + '0'; + i /= 10; + } + while ((*p++ = *--q) != '\0'); + + /* The label, as a '\0' ended string, starts at symbol_name_build. */ + return (symbol_name_build); +} + +/* Decode name that may have been generated by foo_label_name() above. + If the name wasn't generated by foo_label_name(), then return it + unaltered. This is used for error messages. */ + +char * +decode_local_label_name (char *s) +{ + char *p; + char *symbol_decode; + int label_number; + int instance_number; + char *type; + const char *message_format; + int lindex = 0; + +#ifdef LOCAL_LABEL_PREFIX + if (s[lindex] == LOCAL_LABEL_PREFIX) + ++lindex; +#endif + + if (s[lindex] != 'L') + return s; + + for (label_number = 0, p = s + lindex + 1; ISDIGIT (*p); ++p) + label_number = (10 * label_number) + *p - '0'; + + if (*p == DOLLAR_LABEL_CHAR) + type = "dollar"; + else if (*p == LOCAL_LABEL_CHAR) + type = "fb"; + else + return s; + + for (instance_number = 0, p++; ISDIGIT (*p); ++p) + instance_number = (10 * instance_number) + *p - '0'; + + message_format = _("\"%d\" (instance number %d of a %s label)"); + symbol_decode = (char *) obstack_alloc (¬es, strlen (message_format) + 30); + sprintf (symbol_decode, message_format, label_number, instance_number, type); + + return symbol_decode; +} + +/* Get the value of a symbol. */ + +valueT +S_GET_VALUE (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return resolve_symbol_value (s); + + if (!s->sy_flags.sy_resolved) + { + valueT val = resolve_symbol_value (s); + if (!finalize_syms) + return val; + } + if (S_IS_WEAKREFR (s)) + return S_GET_VALUE (s->sy_value.X_add_symbol); + + if (s->sy_value.X_op != O_constant) + { + if (! s->sy_flags.sy_resolved + || s->sy_value.X_op != O_symbol + || (S_IS_DEFINED (s) && ! S_IS_COMMON (s))) + as_bad (_("attempt to get value of unresolved symbol `%s'"), + S_GET_NAME (s)); + } + return (valueT) s->sy_value.X_add_number; +} + +/* Set the value of a symbol. */ + +void +S_SET_VALUE (symbolS *s, valueT val) +{ + if (LOCAL_SYMBOL_CHECK (s)) + { + ((struct local_symbol *) s)->lsy_value = val; + return; + } + + s->sy_value.X_op = O_constant; + s->sy_value.X_add_number = (offsetT) val; + s->sy_value.X_unsigned = 0; + S_CLEAR_WEAKREFR (s); +} + +void +copy_symbol_attributes (symbolS *dest, symbolS *src) +{ + if (LOCAL_SYMBOL_CHECK (dest)) + dest = local_symbol_convert ((struct local_symbol *) dest); + if (LOCAL_SYMBOL_CHECK (src)) + src = local_symbol_convert ((struct local_symbol *) src); + + /* In an expression, transfer the settings of these flags. + The user can override later, of course. */ +#define COPIED_SYMFLAGS (BSF_FUNCTION | BSF_OBJECT \ + | BSF_GNU_INDIRECT_FUNCTION) + dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS; + +#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES + OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src); +#endif + +#ifdef TC_COPY_SYMBOL_ATTRIBUTES + TC_COPY_SYMBOL_ATTRIBUTES (dest, src); +#endif +} + +int +S_IS_FUNCTION (symbolS *s) +{ + flagword flags; + + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + + flags = s->bsym->flags; + + return (flags & BSF_FUNCTION) != 0; +} + +int +S_IS_EXTERNAL (symbolS *s) +{ + flagword flags; + + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + + flags = s->bsym->flags; + + /* Sanity check. */ + if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL)) + abort (); + + return (flags & BSF_GLOBAL) != 0; +} + +int +S_IS_WEAK (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + /* Conceptually, a weakrefr is weak if the referenced symbol is. We + could probably handle a WEAKREFR as always weak though. E.g., if + the referenced symbol has lost its weak status, there's no reason + to keep handling the weakrefr as if it was weak. */ + if (S_IS_WEAKREFR (s)) + return S_IS_WEAK (s->sy_value.X_add_symbol); + return (s->bsym->flags & BSF_WEAK) != 0; +} + +int +S_IS_WEAKREFR (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_weakrefr != 0; +} + +int +S_IS_WEAKREFD (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_weakrefd != 0; +} + +int +S_IS_COMMON (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return bfd_is_com_section (s->bsym->section); +} + +int +S_IS_DEFINED (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return ((struct local_symbol *) s)->lsy_section != undefined_section; + return s->bsym->section != undefined_section; +} + + +#ifndef EXTERN_FORCE_RELOC +#define EXTERN_FORCE_RELOC IS_ELF +#endif + +/* Return true for symbols that should not be reduced to section + symbols or eliminated from expressions, because they may be + overridden by the linker. */ +int +S_FORCE_RELOC (symbolS *s, int strict) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return ((struct local_symbol *) s)->lsy_section == undefined_section; + + return ((strict + && ((s->bsym->flags & BSF_WEAK) != 0 + || (EXTERN_FORCE_RELOC + && (s->bsym->flags & BSF_GLOBAL) != 0))) + || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0 + || s->bsym->section == undefined_section + || bfd_is_com_section (s->bsym->section)); +} + +int +S_IS_DEBUG (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + if (s->bsym->flags & BSF_DEBUGGING) + return 1; + return 0; +} + +int +S_IS_LOCAL (symbolS *s) +{ + flagword flags; + const char *name; + + if (LOCAL_SYMBOL_CHECK (s)) + return 1; + + flags = s->bsym->flags; + + /* Sanity check. */ + if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL)) + abort (); + + if (bfd_get_section (s->bsym) == reg_section) + return 1; + + if (flag_strip_local_absolute + /* Keep BSF_FILE symbols in order to allow debuggers to identify + the source file even when the object file is stripped. */ + && (flags & (BSF_GLOBAL | BSF_FILE)) == 0 + && bfd_get_section (s->bsym) == absolute_section) + return 1; + + name = S_GET_NAME (s); + return (name != NULL + && ! S_IS_DEBUG (s) + && (strchr (name, DOLLAR_LABEL_CHAR) + || strchr (name, LOCAL_LABEL_CHAR) + || TC_LABEL_IS_LOCAL (name) + || (! flag_keep_locals + && (bfd_is_local_label (stdoutput, s->bsym) + || (flag_mri + && name[0] == '?' + && name[1] == '?'))))); +} + +int +S_IS_STABD (symbolS *s) +{ + return S_GET_NAME (s) == 0; +} + +int +S_CAN_BE_REDEFINED (const symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return (local_symbol_get_frag ((struct local_symbol *) s) + == &predefined_address_frag); + /* Permit register names to be redefined. */ + return s->bsym->section == reg_section; +} + +int +S_IS_VOLATILE (const symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_volatile; +} + +int +S_IS_FORWARD_REF (const symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_forward_ref; +} + +const char * +S_GET_NAME (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return ((struct local_symbol *) s)->lsy_name; + return s->bsym->name; +} + +segT +S_GET_SEGMENT (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return ((struct local_symbol *) s)->lsy_section; + return s->bsym->section; +} + +void +S_SET_SEGMENT (symbolS *s, segT seg) +{ + /* Don't reassign section symbols. The direct reason is to prevent seg + faults assigning back to const global symbols such as *ABS*, but it + shouldn't happen anyway. */ + + if (LOCAL_SYMBOL_CHECK (s)) + { + if (seg == reg_section) + s = local_symbol_convert ((struct local_symbol *) s); + else + { + ((struct local_symbol *) s)->lsy_section = seg; + return; + } + } + + if (s->bsym->flags & BSF_SECTION_SYM) + { + if (s->bsym->section != seg) + abort (); + } + else + s->bsym->section = seg; +} + +void +S_SET_EXTERNAL (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + if ((s->bsym->flags & BSF_WEAK) != 0) + { + /* Let .weak override .global. */ + return; + } + if (s->bsym->flags & BSF_SECTION_SYM) + { + char * file; + unsigned int line; + + /* Do not reassign section symbols. */ + as_where (& file, & line); + as_warn_where (file, line, + _("section symbols are already global")); + return; + } +#ifndef TC_GLOBAL_REGISTER_SYMBOL_OK + if (S_GET_SEGMENT (s) == reg_section) + { + as_bad ("can't make register symbol `%s' global", + S_GET_NAME (s)); + return; + } +#endif + s->bsym->flags |= BSF_GLOBAL; + s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK); + +#ifdef TE_PE + if (! an_external_name && S_GET_NAME(s)[0] != '.') + an_external_name = S_GET_NAME (s); +#endif +} + +void +S_CLEAR_EXTERNAL (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + if ((s->bsym->flags & BSF_WEAK) != 0) + { + /* Let .weak override. */ + return; + } + s->bsym->flags |= BSF_LOCAL; + s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK); +} + +void +S_SET_WEAK (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); +#ifdef obj_set_weak_hook + obj_set_weak_hook (s); +#endif + s->bsym->flags |= BSF_WEAK; + s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL); +} + +void +S_SET_WEAKREFR (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_weakrefr = 1; + /* If the alias was already used, make sure we mark the target as + used as well, otherwise it might be dropped from the symbol + table. This may have unintended side effects if the alias is + later redirected to another symbol, such as keeping the unused + previous target in the symbol table. Since it will be weak, it's + not a big deal. */ + if (s->sy_flags.sy_used) + symbol_mark_used (s->sy_value.X_add_symbol); +} + +void +S_CLEAR_WEAKREFR (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_weakrefr = 0; +} + +void +S_SET_WEAKREFD (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_weakrefd = 1; + S_SET_WEAK (s); +} + +void +S_CLEAR_WEAKREFD (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + if (s->sy_flags.sy_weakrefd) + { + s->sy_flags.sy_weakrefd = 0; + /* If a weakref target symbol is weak, then it was never + referenced directly before, not even in a .global directive, + so decay it to local. If it remains undefined, it will be + later turned into a global, like any other undefined + symbol. */ + if (s->bsym->flags & BSF_WEAK) + { +#ifdef obj_clear_weak_hook + obj_clear_weak_hook (s); +#endif + s->bsym->flags &= ~BSF_WEAK; + s->bsym->flags |= BSF_LOCAL; + } + } +} + +void +S_SET_THREAD_LOCAL (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + if (bfd_is_com_section (s->bsym->section) + && (s->bsym->flags & BSF_THREAD_LOCAL) != 0) + return; + s->bsym->flags |= BSF_THREAD_LOCAL; + if ((s->bsym->flags & BSF_FUNCTION) != 0) + as_bad (_("Accessing function `%s' as thread-local object"), + S_GET_NAME (s)); + else if (! bfd_is_und_section (s->bsym->section) + && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0) + as_bad (_("Accessing `%s' as thread-local object"), + S_GET_NAME (s)); +} + +void +S_SET_NAME (symbolS *s, const char *name) +{ + if (LOCAL_SYMBOL_CHECK (s)) + { + ((struct local_symbol *) s)->lsy_name = name; + return; + } + s->bsym->name = name; +} + +void +S_SET_VOLATILE (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_volatile = 1; +} + +void +S_CLEAR_VOLATILE (symbolS *s) +{ + if (!LOCAL_SYMBOL_CHECK (s)) + s->sy_flags.sy_volatile = 0; +} + +void +S_SET_FORWARD_REF (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_forward_ref = 1; +} + +/* Return the previous symbol in a chain. */ + +symbolS * +symbol_previous (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + abort (); + return s->sy_previous; +} + +/* Return the next symbol in a chain. */ + +symbolS * +symbol_next (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + abort (); + return s->sy_next; +} + +/* Return a pointer to the value of a symbol as an expression. */ + +expressionS * +symbol_get_value_expression (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + return &s->sy_value; +} + +/* Set the value of a symbol to an expression. */ + +void +symbol_set_value_expression (symbolS *s, const expressionS *exp) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_value = *exp; + S_CLEAR_WEAKREFR (s); +} + +/* Return whether 2 symbols are the same. */ + +int +symbol_same_p (symbolS *s1, symbolS *s2) +{ + if (s1->sy_flags.sy_local_symbol + && local_symbol_converted_p ((struct local_symbol *) s1)) + s1 = local_symbol_get_real_symbol ((struct local_symbol *) s1); + if (s2->sy_flags.sy_local_symbol + && local_symbol_converted_p ((struct local_symbol *) s2)) + s2 = local_symbol_get_real_symbol ((struct local_symbol *) s2); + return s1 == s2; +} + +/* Return a pointer to the X_add_number component of a symbol. */ + +offsetT * +symbol_X_add_number (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return (offsetT *) &((struct local_symbol *) s)->lsy_value; + + return &s->sy_value.X_add_number; +} + +/* Set the value of SYM to the current position in the current segment. */ + +void +symbol_set_value_now (symbolS *sym) +{ + S_SET_SEGMENT (sym, now_seg); + S_SET_VALUE (sym, frag_now_fix ()); + symbol_set_frag (sym, frag_now); +} + +/* Set the frag of a symbol. */ + +void +symbol_set_frag (symbolS *s, fragS *f) +{ + if (LOCAL_SYMBOL_CHECK (s)) + { + local_symbol_set_frag ((struct local_symbol *) s, f); + return; + } + s->sy_frag = f; + S_CLEAR_WEAKREFR (s); +} + +/* Return the frag of a symbol. */ + +fragS * +symbol_get_frag (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return local_symbol_get_frag ((struct local_symbol *) s); + return s->sy_frag; +} + +/* Mark a symbol as having been used. */ + +void +symbol_mark_used (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_used = 1; + if (S_IS_WEAKREFR (s)) + symbol_mark_used (s->sy_value.X_add_symbol); +} + +/* Clear the mark of whether a symbol has been used. */ + +void +symbol_clear_used (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_used = 0; +} + +/* Return whether a symbol has been used. */ + +int +symbol_used_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 1; + return s->sy_flags.sy_used; +} + +/* Mark a symbol as having been used in a reloc. */ + +void +symbol_mark_used_in_reloc (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_used_in_reloc = 1; +} + +/* Clear the mark of whether a symbol has been used in a reloc. */ + +void +symbol_clear_used_in_reloc (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_used_in_reloc = 0; +} + +/* Return whether a symbol has been used in a reloc. */ + +int +symbol_used_in_reloc_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_used_in_reloc; +} + +/* Mark a symbol as an MRI common symbol. */ + +void +symbol_mark_mri_common (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_flags.sy_mri_common = 1; +} + +/* Clear the mark of whether a symbol is an MRI common symbol. */ + +void +symbol_clear_mri_common (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_mri_common = 0; +} + +/* Return whether a symbol is an MRI common symbol. */ + +int +symbol_mri_common_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_mri_common; +} + +/* Mark a symbol as having been written. */ + +void +symbol_mark_written (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_written = 1; +} + +/* Clear the mark of whether a symbol has been written. */ + +void +symbol_clear_written (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return; + s->sy_flags.sy_written = 0; +} + +/* Return whether a symbol has been written. */ + +int +symbol_written_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_flags.sy_written; +} + +/* Mark a symbol has having been resolved. */ + +void +symbol_mark_resolved (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + { + local_symbol_mark_resolved ((struct local_symbol *) s); + return; + } + s->sy_flags.sy_resolved = 1; +} + +/* Return whether a symbol has been resolved. */ + +int +symbol_resolved_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return local_symbol_resolved_p ((struct local_symbol *) s); + return s->sy_flags.sy_resolved; +} + +/* Return whether a symbol is a section symbol. */ + +int +symbol_section_p (symbolS *s ATTRIBUTE_UNUSED) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return (s->bsym->flags & BSF_SECTION_SYM) != 0; +} + +/* Return whether a symbol is equated to another symbol. */ + +int +symbol_equated_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_value.X_op == O_symbol; +} + +/* Return whether a symbol is equated to another symbol, and should be + treated specially when writing out relocs. */ + +int +symbol_equated_reloc_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + /* X_op_symbol, normally not used for O_symbol, is set by + resolve_symbol_value to flag expression syms that have been + equated. */ + return (s->sy_value.X_op == O_symbol +#if defined (OBJ_COFF) && defined (TE_PE) + && ! S_IS_WEAK (s) +#endif + && ((s->sy_flags.sy_resolved && s->sy_value.X_op_symbol != NULL) + || ! S_IS_DEFINED (s) + || S_IS_COMMON (s))); +} + +/* Return whether a symbol has a constant value. */ + +int +symbol_constant_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 1; + return s->sy_value.X_op == O_constant; +} + +/* Return whether a symbol was cloned and thus removed from the global + symbol list. */ + +int +symbol_shadow_p (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + return 0; + return s->sy_next == s; +} + +/* Return the BFD symbol for a symbol. */ + +asymbol * +symbol_get_bfdsym (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + return s->bsym; +} + +/* Set the BFD symbol for a symbol. */ + +void +symbol_set_bfdsym (symbolS *s, asymbol *bsym) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + /* Usually, it is harmless to reset a symbol to a BFD section + symbol. For example, obj_elf_change_section sets the BFD symbol + of an old symbol with the newly created section symbol. But when + we have multiple sections with the same name, the newly created + section may have the same name as an old section. We check if the + old symbol has been already marked as a section symbol before + resetting it. */ + if ((s->bsym->flags & BSF_SECTION_SYM) == 0) + s->bsym = bsym; + /* else XXX - What do we do now ? */ +} + +#ifdef OBJ_SYMFIELD_TYPE + +/* Get a pointer to the object format information for a symbol. */ + +OBJ_SYMFIELD_TYPE * +symbol_get_obj (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + return &s->sy_obj; +} + +/* Set the object format information for a symbol. */ + +void +symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_obj = *o; +} + +#endif /* OBJ_SYMFIELD_TYPE */ + +#ifdef TC_SYMFIELD_TYPE + +/* Get a pointer to the processor information for a symbol. */ + +TC_SYMFIELD_TYPE * +symbol_get_tc (symbolS *s) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + return &s->sy_tc; +} + +/* Set the processor information for a symbol. */ + +void +symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o) +{ + if (LOCAL_SYMBOL_CHECK (s)) + s = local_symbol_convert ((struct local_symbol *) s); + s->sy_tc = *o; +} + +#endif /* TC_SYMFIELD_TYPE */ + +void +symbol_begin (void) +{ + symbol_lastP = NULL; + symbol_rootP = NULL; /* In case we have 0 symbols (!!) */ + sy_hash = hash_new (); + local_hash = hash_new (); + + memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol)); +#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL) + abs_symbol.bsym = bfd_abs_section_ptr->symbol; +#endif + abs_symbol.sy_value.X_op = O_constant; + abs_symbol.sy_frag = &zero_address_frag; + + if (LOCAL_LABELS_FB) + fb_label_init (); +} + +void +dot_symbol_init (void) +{ + dot_symbol.bsym = bfd_make_empty_symbol (stdoutput); + if (dot_symbol.bsym == NULL) + as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ())); + dot_symbol.bsym->name = "."; + dot_symbol.sy_flags.sy_forward_ref = 1; + dot_symbol.sy_value.X_op = O_constant; +} + +int indent_level; + +/* Maximum indent level. + Available for modification inside a gdb session. */ +static int max_indent_level = 8; + +void +print_symbol_value_1 (FILE *file, symbolS *sym) +{ + const char *name = S_GET_NAME (sym); + if (!name || !name[0]) + name = "(unnamed)"; + fprintf (file, "sym "); + fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym)); + fprintf (file, " %s", name); + + if (LOCAL_SYMBOL_CHECK (sym)) + { + struct local_symbol *locsym = (struct local_symbol *) sym; + + if (local_symbol_get_frag (locsym) != & zero_address_frag + && local_symbol_get_frag (locsym) != NULL) + { + fprintf (file, " frag "); + fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) local_symbol_get_frag (locsym))); + } + if (local_symbol_resolved_p (locsym)) + fprintf (file, " resolved"); + fprintf (file, " local"); + } + else + { + if (sym->sy_frag != &zero_address_frag) + { + fprintf (file, " frag "); + fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym->sy_frag)); + } + if (sym->sy_flags.sy_written) + fprintf (file, " written"); + if (sym->sy_flags.sy_resolved) + fprintf (file, " resolved"); + else if (sym->sy_flags.sy_resolving) + fprintf (file, " resolving"); + if (sym->sy_flags.sy_used_in_reloc) + fprintf (file, " used-in-reloc"); + if (sym->sy_flags.sy_used) + fprintf (file, " used"); + if (S_IS_LOCAL (sym)) + fprintf (file, " local"); + if (S_IS_EXTERNAL (sym)) + fprintf (file, " extern"); + if (S_IS_WEAK (sym)) + fprintf (file, " weak"); + if (S_IS_DEBUG (sym)) + fprintf (file, " debug"); + if (S_IS_DEFINED (sym)) + fprintf (file, " defined"); + } + if (S_IS_WEAKREFR (sym)) + fprintf (file, " weakrefr"); + if (S_IS_WEAKREFD (sym)) + fprintf (file, " weakrefd"); + fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym))); + if (symbol_resolved_p (sym)) + { + segT s = S_GET_SEGMENT (sym); + + if (s != undefined_section + && s != expr_section) + fprintf (file, " %lx", (unsigned long) S_GET_VALUE (sym)); + } + else if (indent_level < max_indent_level + && S_GET_SEGMENT (sym) != undefined_section) + { + indent_level++; + fprintf (file, "\n%*s<", indent_level * 4, ""); + if (LOCAL_SYMBOL_CHECK (sym)) + fprintf (file, "constant %lx", + (unsigned long) ((struct local_symbol *) sym)->lsy_value); + else + print_expr_1 (file, &sym->sy_value); + fprintf (file, ">"); + indent_level--; + } + fflush (file); +} + +void +print_symbol_value (symbolS *sym) +{ + indent_level = 0; + print_symbol_value_1 (stderr, sym); + fprintf (stderr, "\n"); +} + +static void +print_binary (FILE *file, const char *name, expressionS *exp) +{ + indent_level++; + fprintf (file, "%s\n%*s<", name, indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_add_symbol); + fprintf (file, ">\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_op_symbol); + fprintf (file, ">"); + indent_level--; +} + +void +print_expr_1 (FILE *file, expressionS *exp) +{ + fprintf (file, "expr "); + fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) exp)); + fprintf (file, " "); + switch (exp->X_op) + { + case O_illegal: + fprintf (file, "illegal"); + break; + case O_absent: + fprintf (file, "absent"); + break; + case O_constant: + fprintf (file, "constant %lx", (unsigned long) exp->X_add_number); + break; + case O_symbol: + indent_level++; + fprintf (file, "symbol\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_add_symbol); + fprintf (file, ">"); + maybe_print_addnum: + if (exp->X_add_number) + fprintf (file, "\n%*s%lx", indent_level * 4, "", + (unsigned long) exp->X_add_number); + indent_level--; + break; + case O_register: + fprintf (file, "register #%d", (int) exp->X_add_number); + break; + case O_big: + fprintf (file, "big"); + break; + case O_uminus: + fprintf (file, "uminus -<"); + indent_level++; + print_symbol_value_1 (file, exp->X_add_symbol); + fprintf (file, ">"); + goto maybe_print_addnum; + case O_bit_not: + fprintf (file, "bit_not"); + break; + case O_multiply: + print_binary (file, "multiply", exp); + break; + case O_divide: + print_binary (file, "divide", exp); + break; + case O_modulus: + print_binary (file, "modulus", exp); + break; + case O_left_shift: + print_binary (file, "lshift", exp); + break; + case O_right_shift: + print_binary (file, "rshift", exp); + break; + case O_bit_inclusive_or: + print_binary (file, "bit_ior", exp); + break; + case O_bit_exclusive_or: + print_binary (file, "bit_xor", exp); + break; + case O_bit_and: + print_binary (file, "bit_and", exp); + break; + case O_eq: + print_binary (file, "eq", exp); + break; + case O_ne: + print_binary (file, "ne", exp); + break; + case O_lt: + print_binary (file, "lt", exp); + break; + case O_le: + print_binary (file, "le", exp); + break; + case O_ge: + print_binary (file, "ge", exp); + break; + case O_gt: + print_binary (file, "gt", exp); + break; + case O_logical_and: + print_binary (file, "logical_and", exp); + break; + case O_logical_or: + print_binary (file, "logical_or", exp); + break; + case O_add: + indent_level++; + fprintf (file, "add\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_add_symbol); + fprintf (file, ">\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_op_symbol); + fprintf (file, ">"); + goto maybe_print_addnum; + case O_subtract: + indent_level++; + fprintf (file, "subtract\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_add_symbol); + fprintf (file, ">\n%*s<", indent_level * 4, ""); + print_symbol_value_1 (file, exp->X_op_symbol); + fprintf (file, ">"); + goto maybe_print_addnum; + default: + fprintf (file, "{unknown opcode %d}", (int) exp->X_op); + break; + } + fflush (stdout); +} + +void +print_expr (expressionS *exp) +{ + print_expr_1 (stderr, exp); + fprintf (stderr, "\n"); +} + +void +symbol_print_statistics (FILE *file) +{ + hash_print_statistics (file, "symbol table", sy_hash); + hash_print_statistics (file, "mini local symbol table", local_hash); + fprintf (file, "%lu mini local symbols created, %lu converted\n", + local_symbol_count, local_symbol_conversion_count); +} + +#ifdef OBJ_COMPLEX_RELC + +/* Convert given symbol to a new complex-relocation symbol name. This + may be a recursive function, since it might be called for non-leaf + nodes (plain symbols) in the expression tree. The caller owns the + returning string, so should free it eventually. Errors are + indicated via as_bad and a NULL return value. The given symbol + is marked with sy_used_in_reloc. */ + +char * +symbol_relc_make_sym (symbolS * sym) +{ + char * terminal = NULL; + const char * sname; + char typetag; + int sname_len; + + gas_assert (sym != NULL); + + /* Recurse to symbol_relc_make_expr if this symbol + is defined as an expression or a plain value. */ + if ( S_GET_SEGMENT (sym) == expr_section + || S_GET_SEGMENT (sym) == absolute_section) + return symbol_relc_make_expr (& sym->sy_value); + + /* This may be a "fake symbol" L0\001, referring to ".". + Write out a special null symbol to refer to this position. */ + if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME)) + return xstrdup ("."); + + /* We hope this is a plain leaf symbol. Construct the encoding + as {S,s}II...:CCCCCCC.... + where 'S'/'s' means section symbol / plain symbol + III is decimal for the symbol name length + CCC is the symbol name itself. */ + symbol_mark_used_in_reloc (sym); + + sname = S_GET_NAME (sym); + sname_len = strlen (sname); + typetag = symbol_section_p (sym) ? 'S' : 's'; + + terminal = xmalloc (1 /* S or s */ + + 8 /* sname_len in decimal */ + + 1 /* _ spacer */ + + sname_len /* name itself */ + + 1 /* \0 */ ); + + sprintf (terminal, "%c%d:%s", typetag, sname_len, sname); + return terminal; +} + +/* Convert given value to a new complex-relocation symbol name. This + is a non-recursive function, since it is be called for leaf nodes + (plain values) in the expression tree. The caller owns the + returning string, so should free() it eventually. No errors. */ + +char * +symbol_relc_make_value (offsetT val) +{ + char * terminal = xmalloc (28); /* Enough for long long. */ + + terminal[0] = '#'; + bfd_sprintf_vma (stdoutput, terminal + 1, val); + return terminal; +} + +/* Convert given expression to a new complex-relocation symbol name. + This is a recursive function, since it traverses the entire given + expression tree. The caller owns the returning string, so should + free() it eventually. Errors are indicated via as_bad() and a NULL + return value. */ + +char * +symbol_relc_make_expr (expressionS * exp) +{ + char * opstr = NULL; /* Operator prefix string. */ + int arity = 0; /* Arity of this operator. */ + char * operands[3]; /* Up to three operands. */ + char * concat_string = NULL; + + operands[0] = operands[1] = operands[2] = NULL; + + gas_assert (exp != NULL); + + /* Match known operators -> fill in opstr, arity, operands[] and fall + through to construct subexpression fragments; may instead return + string directly for leaf nodes. */ + + /* See expr.h for the meaning of all these enums. Many operators + have an unnatural arity (X_add_number implicitly added). The + conversion logic expands them to explicit "+" subexpressions. */ + + switch (exp->X_op) + { + default: + as_bad ("Unknown expression operator (enum %d)", exp->X_op); + break; + + /* Leaf nodes. */ + case O_constant: + return symbol_relc_make_value (exp->X_add_number); + + case O_symbol: + if (exp->X_add_number) + { + arity = 2; + opstr = "+"; + operands[0] = symbol_relc_make_sym (exp->X_add_symbol); + operands[1] = symbol_relc_make_value (exp->X_add_number); + break; + } + else + return symbol_relc_make_sym (exp->X_add_symbol); + + /* Helper macros for nesting nodes. */ + +#define HANDLE_XADD_OPT1(str_) \ + if (exp->X_add_number) \ + { \ + arity = 2; \ + opstr = "+:" str_; \ + operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \ + operands[1] = symbol_relc_make_value (exp->X_add_number); \ + break; \ + } \ + else \ + { \ + arity = 1; \ + opstr = str_; \ + operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \ + } \ + break + +#define HANDLE_XADD_OPT2(str_) \ + if (exp->X_add_number) \ + { \ + arity = 3; \ + opstr = "+:" str_; \ + operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \ + operands[1] = symbol_relc_make_sym (exp->X_op_symbol); \ + operands[2] = symbol_relc_make_value (exp->X_add_number); \ + } \ + else \ + { \ + arity = 2; \ + opstr = str_; \ + operands[0] = symbol_relc_make_sym (exp->X_add_symbol); \ + operands[1] = symbol_relc_make_sym (exp->X_op_symbol); \ + } \ + break + + /* Nesting nodes. */ + + case O_uminus: HANDLE_XADD_OPT1 ("0-"); + case O_bit_not: HANDLE_XADD_OPT1 ("~"); + case O_logical_not: HANDLE_XADD_OPT1 ("!"); + case O_multiply: HANDLE_XADD_OPT2 ("*"); + case O_divide: HANDLE_XADD_OPT2 ("/"); + case O_modulus: HANDLE_XADD_OPT2 ("%"); + case O_left_shift: HANDLE_XADD_OPT2 ("<<"); + case O_right_shift: HANDLE_XADD_OPT2 (">>"); + case O_bit_inclusive_or: HANDLE_XADD_OPT2 ("|"); + case O_bit_exclusive_or: HANDLE_XADD_OPT2 ("^"); + case O_bit_and: HANDLE_XADD_OPT2 ("&"); + case O_add: HANDLE_XADD_OPT2 ("+"); + case O_subtract: HANDLE_XADD_OPT2 ("-"); + case O_eq: HANDLE_XADD_OPT2 ("=="); + case O_ne: HANDLE_XADD_OPT2 ("!="); + case O_lt: HANDLE_XADD_OPT2 ("<"); + case O_le: HANDLE_XADD_OPT2 ("<="); + case O_ge: HANDLE_XADD_OPT2 (">="); + case O_gt: HANDLE_XADD_OPT2 (">"); + case O_logical_and: HANDLE_XADD_OPT2 ("&&"); + case O_logical_or: HANDLE_XADD_OPT2 ("||"); + } + + /* Validate & reject early. */ + if (arity >= 1 && ((operands[0] == NULL) || (strlen (operands[0]) == 0))) + opstr = NULL; + if (arity >= 2 && ((operands[1] == NULL) || (strlen (operands[1]) == 0))) + opstr = NULL; + if (arity >= 3 && ((operands[2] == NULL) || (strlen (operands[2]) == 0))) + opstr = NULL; + + if (opstr == NULL) + concat_string = NULL; + else + { + /* Allocate new string; include inter-operand padding gaps etc. */ + concat_string = xmalloc (strlen (opstr) + + 1 + + (arity >= 1 ? (strlen (operands[0]) + 1 ) : 0) + + (arity >= 2 ? (strlen (operands[1]) + 1 ) : 0) + + (arity >= 3 ? (strlen (operands[2]) + 0 ) : 0) + + 1); + gas_assert (concat_string != NULL); + + /* Format the thing. */ + sprintf (concat_string, + (arity == 0 ? "%s" : + arity == 1 ? "%s:%s" : + arity == 2 ? "%s:%s:%s" : + /* arity == 3 */ "%s:%s:%s:%s"), + opstr, operands[0], operands[1], operands[2]); + } + + /* Free operand strings (not opstr). */ + if (arity >= 1) xfree (operands[0]); + if (arity >= 2) xfree (operands[1]); + if (arity >= 3) xfree (operands[2]); + + return concat_string; +} + +#endif diff --git a/contrib/toolchain/binutils/gas/symbols.h b/contrib/toolchain/binutils/gas/symbols.h new file mode 100644 index 0000000000..a3a31f765b --- /dev/null +++ b/contrib/toolchain/binutils/gas/symbols.h @@ -0,0 +1,216 @@ +/* symbols.h - + Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +extern struct obstack notes; /* eg FixS live here. */ + +extern struct obstack cond_obstack; /* this is where we track .ifdef/.endif + (if we do that at all). */ + +extern symbolS *symbol_rootP; /* all the symbol nodes */ +extern symbolS *symbol_lastP; /* last struct symbol we made, or NULL */ + +extern symbolS abs_symbol; +extern symbolS dot_symbol; + +extern int symbol_table_frozen; + +/* This is non-zero if symbols are case sensitive, which is the + default. */ +extern int symbols_case_sensitive; + +char * symbol_relc_make_expr (expressionS *); +char * symbol_relc_make_sym (symbolS *); +char * symbol_relc_make_value (offsetT); +char *decode_local_label_name (char *s); +symbolS *symbol_find (const char *name); +symbolS *symbol_find_noref (const char *name, int noref); +symbolS *symbol_find_exact (const char *name); +symbolS *symbol_find_exact_noref (const char *name, int noref); +symbolS *symbol_find_or_make (const char *name); +symbolS *symbol_make (const char *name); +symbolS *symbol_new (const char *name, segT segment, valueT value, + fragS * frag); +symbolS *symbol_create (const char *name, segT segment, valueT value, + fragS * frag); +struct local_symbol *local_symbol_make (const char *name, segT section, + valueT val, fragS *frag); +symbolS *symbol_clone (symbolS *, int); +#undef symbol_clone_if_forward_ref +symbolS *symbol_clone_if_forward_ref (symbolS *, int); +#define symbol_clone_if_forward_ref(s) symbol_clone_if_forward_ref (s, 0) +symbolS *symbol_temp_new (segT, valueT, fragS *); +symbolS *symbol_temp_new_now (void); +symbolS *symbol_temp_make (void); + +symbolS *colon (const char *sym_name); +void local_colon (int n); +void symbol_begin (void); +void dot_symbol_init (void); +void symbol_print_statistics (FILE *); +void symbol_table_insert (symbolS * symbolP); +valueT resolve_symbol_value (symbolS *); +void resolve_local_symbol_values (void); +int snapshot_symbol (symbolS **, valueT *, segT *, fragS **); + +void print_symbol_value (symbolS *); +void print_expr (expressionS *); +void print_expr_1 (FILE *, expressionS *); +void print_symbol_value_1 (FILE *, symbolS *); + +int dollar_label_defined (long l); +void dollar_label_clear (void); +void define_dollar_label (long l); +char *dollar_label_name (long l, int augend); + +void fb_label_instance_inc (long label); +char *fb_label_name (long n, long augend); + +extern void copy_symbol_attributes (symbolS *, symbolS *); + +/* Get and set the values of symbols. These used to be macros. */ +extern valueT S_GET_VALUE (symbolS *); +extern void S_SET_VALUE (symbolS *, valueT); + +extern int S_IS_FUNCTION (symbolS *); +extern int S_IS_EXTERNAL (symbolS *); +extern int S_IS_WEAK (symbolS *); +extern int S_IS_WEAKREFR (symbolS *); +extern int S_IS_WEAKREFD (symbolS *); +extern int S_IS_COMMON (symbolS *); +extern int S_IS_DEFINED (symbolS *); +extern int S_FORCE_RELOC (symbolS *, int); +extern int S_IS_DEBUG (symbolS *); +extern int S_IS_LOCAL (symbolS *); +extern int S_IS_STABD (symbolS *); +extern int S_CAN_BE_REDEFINED (const symbolS *); +extern int S_IS_VOLATILE (const symbolS *); +extern int S_IS_FORWARD_REF (const symbolS *); +extern const char *S_GET_NAME (symbolS *); +extern segT S_GET_SEGMENT (symbolS *); +extern void S_SET_SEGMENT (symbolS *, segT); +extern void S_SET_EXTERNAL (symbolS *); +extern void S_SET_NAME (symbolS *, const char *); +extern void S_CLEAR_EXTERNAL (symbolS *); +extern void S_SET_WEAK (symbolS *); +extern void S_SET_WEAKREFR (symbolS *); +extern void S_CLEAR_WEAKREFR (symbolS *); +extern void S_SET_WEAKREFD (symbolS *); +extern void S_CLEAR_WEAKREFD (symbolS *); +extern void S_SET_THREAD_LOCAL (symbolS *); +extern void S_SET_VOLATILE (symbolS *); +extern void S_CLEAR_VOLATILE (symbolS *); +extern void S_SET_FORWARD_REF (symbolS *); + +#ifndef WORKING_DOT_WORD +struct broken_word + { + /* Linked list -- one of these structures per ".word x-y+C" + expression. */ + struct broken_word *next_broken_word; + /* Segment and subsegment for broken word. */ + segT seg; + subsegT subseg; + /* Which frag is this broken word in? */ + fragS *frag; + /* Where in the frag is it? */ + char *word_goes_here; + /* Where to add the break. */ + fragS *dispfrag; /* where to add the break */ + /* Operands of expression. */ + symbolS *add; + symbolS *sub; + offsetT addnum; + + int added; /* nasty thing happened yet? */ + /* 1: added and has a long-jump */ + /* 2: added but uses someone elses long-jump */ + + /* Pointer to broken_word with a similar long-jump. */ + struct broken_word *use_jump; + }; +extern struct broken_word *broken_words; +#endif /* ndef WORKING_DOT_WORD */ + +/* + * Current means for getting from symbols to segments and vice verse. + * This will change for infinite-segments support (e.g. COFF). + */ +extern const segT N_TYPE_seg[]; /* subseg.c */ + +#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 */ + +void symbol_clear_list_pointers (symbolS * symbolP); + +void symbol_insert (symbolS * addme, symbolS * target, + symbolS ** rootP, symbolS ** lastP); +void symbol_remove (symbolS * symbolP, symbolS ** rootP, + symbolS ** lastP); + +extern symbolS *symbol_previous (symbolS *); + +void verify_symbol_chain (symbolS * rootP, symbolS * lastP); + +void symbol_append (symbolS * addme, symbolS * target, + symbolS ** rootP, symbolS ** lastP); + +extern symbolS *symbol_next (symbolS *); + +extern expressionS *symbol_get_value_expression (symbolS *); +extern void symbol_set_value_expression (symbolS *, const expressionS *); +extern offsetT *symbol_X_add_number (symbolS *); +extern void symbol_set_value_now (symbolS *); +extern void symbol_set_frag (symbolS *, fragS *); +extern fragS *symbol_get_frag (symbolS *); +extern void symbol_mark_used (symbolS *); +extern void symbol_clear_used (symbolS *); +extern int symbol_used_p (symbolS *); +extern void symbol_mark_used_in_reloc (symbolS *); +extern void symbol_clear_used_in_reloc (symbolS *); +extern int symbol_used_in_reloc_p (symbolS *); +extern void symbol_mark_mri_common (symbolS *); +extern void symbol_clear_mri_common (symbolS *); +extern int symbol_mri_common_p (symbolS *); +extern void symbol_mark_written (symbolS *); +extern void symbol_clear_written (symbolS *); +extern int symbol_written_p (symbolS *); +extern void symbol_mark_resolved (symbolS *); +extern int symbol_resolved_p (symbolS *); +extern int symbol_section_p (symbolS *); +extern int symbol_equated_p (symbolS *); +extern int symbol_equated_reloc_p (symbolS *); +extern int symbol_constant_p (symbolS *); +extern int symbol_shadow_p (symbolS *); +extern asymbol *symbol_get_bfdsym (symbolS *); +extern void symbol_set_bfdsym (symbolS *, asymbol *); +extern int symbol_same_p (symbolS *, symbolS *); + +#ifdef OBJ_SYMFIELD_TYPE +OBJ_SYMFIELD_TYPE *symbol_get_obj (symbolS *); +void symbol_set_obj (symbolS *, OBJ_SYMFIELD_TYPE *); +#endif + +#ifdef TC_SYMFIELD_TYPE +TC_SYMFIELD_TYPE *symbol_get_tc (symbolS *); +void symbol_set_tc (symbolS *, TC_SYMFIELD_TYPE *); +#endif diff --git a/contrib/toolchain/binutils/gas/targ-cpu.h b/contrib/toolchain/binutils/gas/targ-cpu.h new file mode 100644 index 0000000000..f4be0e50bd --- /dev/null +++ b/contrib/toolchain/binutils/gas/targ-cpu.h @@ -0,0 +1 @@ +#include "tc-i386.h" diff --git a/contrib/toolchain/binutils/gas/targ-env.h b/contrib/toolchain/binutils/gas/targ-env.h new file mode 100644 index 0000000000..372c77016f --- /dev/null +++ b/contrib/toolchain/binutils/gas/targ-env.h @@ -0,0 +1 @@ +#include "te-pe.h" diff --git a/contrib/toolchain/binutils/gas/tc.h b/contrib/toolchain/binutils/gas/tc.h new file mode 100644 index 0000000000..ff1cf3618a --- /dev/null +++ b/contrib/toolchain/binutils/gas/tc.h @@ -0,0 +1,79 @@ +/* tc.h - target cpu dependent + + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 2001, 2003, + 2004, 2005, 2006, 2007, 2008, 2009 + 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 3, 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, 51 Franklin Street - Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* In theory (mine, at least!) the machine dependent part of the assembler + should only have to include one file. This one. -- JF */ + +extern const pseudo_typeS md_pseudo_table[]; + +char * md_atof (int, char *, int *); +int md_parse_option (int, char *); +void md_show_usage (FILE *); +void md_assemble (char *); +void md_begin (void); +#ifndef md_number_to_chars +void md_number_to_chars (char *, valueT, int); +#endif +void md_apply_fix (fixS *, valueT *, segT); + +#ifndef WORKING_DOT_WORD +extern int md_short_jump_size; +extern int md_long_jump_size; +#endif + +#ifdef TE_PE +/* The name of an external symbol which is + used to make weak PE symbol names unique. */ +extern const char * an_external_name; +#endif + +#ifndef md_create_long_jump +void md_create_long_jump (char *, addressT, addressT, fragS *, symbolS *); +#endif +#ifndef md_create_short_jump +void md_create_short_jump (char *, addressT, addressT, fragS *, symbolS *); +#endif +#ifndef md_pcrel_from +long md_pcrel_from (fixS *); +#endif +#ifndef md_operand +void md_operand (expressionS *); +#endif +#ifndef md_estimate_size_before_relax +int md_estimate_size_before_relax (fragS * fragP, segT); +#endif +#ifndef md_section_align +valueT md_section_align (segT, valueT); +#endif +#ifndef md_undefined_symbol +symbolS *md_undefined_symbol (char *); +#endif + +#ifndef md_convert_frag +void md_convert_frag (bfd *, segT, fragS *); +#endif +#ifndef RELOC_EXPANSION_POSSIBLE +extern arelent *tc_gen_reloc (asection *, fixS *); +#else +extern arelent **tc_gen_reloc (asection *, fixS *); +#endif diff --git a/contrib/toolchain/binutils/gas/write.c b/contrib/toolchain/binutils/gas/write.c new file mode 100644 index 0000000000..745abe66d8 --- /dev/null +++ b/contrib/toolchain/binutils/gas/write.c @@ -0,0 +1,2868 @@ +/* write.c - emit .o file + Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, + 2010, 2011, 2012 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* This thing should be set up to do byteordering correctly. But... */ + +#include "as.h" +#include "subsegs.h" +#include "obstack.h" +#include "output-file.h" +#include "dwarf2dbg.h" +#include "libbfd.h" +#include "compress-debug.h" + +#ifndef TC_FORCE_RELOCATION +#define TC_FORCE_RELOCATION(FIX) \ + (generic_force_reloc (FIX)) +#endif + +#ifndef TC_FORCE_RELOCATION_ABS +#define TC_FORCE_RELOCATION_ABS(FIX) \ + (TC_FORCE_RELOCATION (FIX)) +#endif + +#ifndef TC_FORCE_RELOCATION_LOCAL +#define TC_FORCE_RELOCATION_LOCAL(FIX) \ + (!(FIX)->fx_pcrel \ + || TC_FORCE_RELOCATION (FIX)) +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_SAME +#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ + (! SEG_NORMAL (SEG)) +#endif + +#ifndef md_register_arithmetic +# define md_register_arithmetic 1 +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_ABS +#define TC_FORCE_RELOCATION_SUB_ABS(FIX, SEG) \ + (!md_register_arithmetic && (SEG) == reg_section) +#endif + +#ifndef TC_FORCE_RELOCATION_SUB_LOCAL +#ifdef DIFF_EXPR_OK +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \ + (!md_register_arithmetic && (SEG) == reg_section) +#else +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 +#endif +#endif + +#ifndef TC_VALIDATE_FIX_SUB +#ifdef UNDEFINED_DIFFERENCE_OK +/* The PA needs this for PIC code generation. */ +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + (md_register_arithmetic || (SEG) != reg_section) +#else +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + ((md_register_arithmetic || (SEG) != reg_section) \ + && ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \ + || (FIX)->fx_r_type == BFD_RELOC_GPREL16)) +#endif +#endif + +#ifndef TC_LINKRELAX_FIXUP +#define TC_LINKRELAX_FIXUP(SEG) 1 +#endif + +#ifndef MD_APPLY_SYM_VALUE +#define MD_APPLY_SYM_VALUE(FIX) 1 +#endif + +#ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG +#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 1 +#endif + +#ifndef MD_PCREL_FROM_SECTION +#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX) +#endif + +#ifndef TC_FAKE_LABEL +#define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0) +#endif + +/* Positive values of TC_FX_SIZE_SLACK allow a target to define + fixups that far past the end of a frag. Having such fixups + is of course most most likely a bug in setting fx_size correctly. + A negative value disables the fixup check entirely, which is + appropriate for something like the Renesas / SuperH SH_COUNT + reloc. */ +#ifndef TC_FX_SIZE_SLACK +#define TC_FX_SIZE_SLACK(FIX) 0 +#endif + +/* Used to control final evaluation of expressions. */ +int finalize_syms = 0; + +int symbol_table_frozen; + +symbolS *abs_section_sym; + +/* Remember the value of dot when parsing expressions. */ +addressT dot_value; + +/* The frag that dot_value is based from. */ +fragS *dot_frag; + +/* Relocs generated by ".reloc" pseudo. */ +struct reloc_list* reloc_list; + +void print_fixup (fixS *); + +/* We generally attach relocs to frag chains. However, after we have + chained these all together into a segment, any relocs we add after + that must be attached to a segment. This will include relocs added + in md_estimate_size_for_relax, for example. */ +static int frags_chained = 0; + +static int n_fixups; + +#define RELOC_ENUM enum bfd_reloc_code_real + +/* Create a fixS in obstack 'notes'. */ + +static fixS * +fix_new_internal (fragS *frag, /* Which frag? */ + int where, /* Where in that frag? */ + int size, /* 1, 2, or 4 usually. */ + symbolS *add_symbol, /* X_add_symbol. */ + symbolS *sub_symbol, /* X_op_symbol. */ + offsetT offset, /* X_add_number. */ + int pcrel, /* TRUE if PC-relative relocation. */ + RELOC_ENUM r_type /* Relocation type. */, + int at_beginning) /* Add to the start of the list? */ +{ + fixS *fixP; + + n_fixups++; + + fixP = (fixS *) obstack_alloc (¬es, sizeof (fixS)); + + fixP->fx_frag = frag; + fixP->fx_where = where; + fixP->fx_size = size; + /* We've made fx_size a narrow field; check that it's wide enough. */ + if (fixP->fx_size != size) + { + as_bad (_("field fx_size too small to hold %d"), size); + abort (); + } + fixP->fx_addsy = add_symbol; + fixP->fx_subsy = sub_symbol; + fixP->fx_offset = offset; + fixP->fx_dot_value = dot_value; + fixP->fx_dot_frag = dot_frag; + fixP->fx_pcrel = pcrel; + fixP->fx_r_type = r_type; + fixP->fx_im_disp = 0; + fixP->fx_pcrel_adjust = 0; + fixP->fx_bit_fixP = 0; + fixP->fx_addnumber = 0; + fixP->fx_tcbit = 0; + fixP->fx_tcbit2 = 0; + fixP->fx_done = 0; + fixP->fx_no_overflow = 0; + fixP->fx_signed = 0; + +#ifdef USING_CGEN + fixP->fx_cgen.insn = NULL; + fixP->fx_cgen.opinfo = 0; +#endif + +#ifdef TC_FIX_TYPE + TC_INIT_FIX_DATA (fixP); +#endif + + as_where (&fixP->fx_file, &fixP->fx_line); + + { + + fixS **seg_fix_rootP = (frags_chained + ? &seg_info (now_seg)->fix_root + : &frchain_now->fix_root); + fixS **seg_fix_tailP = (frags_chained + ? &seg_info (now_seg)->fix_tail + : &frchain_now->fix_tail); + + if (at_beginning) + { + fixP->fx_next = *seg_fix_rootP; + *seg_fix_rootP = fixP; + if (fixP->fx_next == NULL) + *seg_fix_tailP = fixP; + } + else + { + fixP->fx_next = NULL; + if (*seg_fix_tailP) + (*seg_fix_tailP)->fx_next = fixP; + else + *seg_fix_rootP = fixP; + *seg_fix_tailP = fixP; + } + } + + return fixP; +} + +/* Create a fixup relative to a symbol (plus a constant). */ + +fixS * +fix_new (fragS *frag, /* Which frag? */ + int where, /* Where in that frag? */ + int size, /* 1, 2, or 4 usually. */ + symbolS *add_symbol, /* X_add_symbol. */ + offsetT offset, /* X_add_number. */ + int pcrel, /* TRUE if PC-relative relocation. */ + RELOC_ENUM r_type /* Relocation type. */) +{ + return fix_new_internal (frag, where, size, add_symbol, + (symbolS *) NULL, offset, pcrel, r_type, FALSE); +} + +/* Create a fixup for an expression. Currently we only support fixups + for difference expressions. That is itself more than most object + file formats support anyhow. */ + +fixS * +fix_new_exp (fragS *frag, /* Which frag? */ + int where, /* Where in that frag? */ + int size, /* 1, 2, or 4 usually. */ + expressionS *exp, /* Expression. */ + int pcrel, /* TRUE if PC-relative relocation. */ + RELOC_ENUM r_type /* Relocation type. */) +{ + symbolS *add = NULL; + symbolS *sub = NULL; + offsetT off = 0; + + switch (exp->X_op) + { + case O_absent: + break; + + case O_register: + as_bad (_("register value used as expression")); + break; + + case O_add: + /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if + the difference expression cannot immediately be reduced. */ + { + symbolS *stmp = make_expr_symbol (exp); + + exp->X_op = O_symbol; + exp->X_op_symbol = 0; + exp->X_add_symbol = stmp; + exp->X_add_number = 0; + + return fix_new_exp (frag, where, size, exp, pcrel, r_type); + } + + case O_symbol_rva: + add = exp->X_add_symbol; + off = exp->X_add_number; + r_type = BFD_RELOC_RVA; + break; + + case O_uminus: + sub = exp->X_add_symbol; + off = exp->X_add_number; + break; + + case O_subtract: + sub = exp->X_op_symbol; + /* Fall through. */ + case O_symbol: + add = exp->X_add_symbol; + /* Fall through. */ + case O_constant: + off = exp->X_add_number; + break; + + default: + add = make_expr_symbol (exp); + break; + } + + return fix_new_internal (frag, where, size, add, sub, off, pcrel, + r_type, FALSE); +} + +/* Create a fixup at the beginning of FRAG. The arguments are the same + as for fix_new, except that WHERE is implicitly 0. */ + +fixS * +fix_at_start (fragS *frag, int size, symbolS *add_symbol, + offsetT offset, int pcrel, RELOC_ENUM r_type) +{ + return fix_new_internal (frag, 0, size, add_symbol, + (symbolS *) NULL, offset, pcrel, r_type, TRUE); +} + +/* Generic function to determine whether a fixup requires a relocation. */ +int +generic_force_reloc (fixS *fix) +{ + if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 1; + + if (fix->fx_addsy == NULL) + return 0; + + return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL); +} + +/* Append a string onto another string, bumping the pointer along. */ +void +append (char **charPP, char *fromP, unsigned long length) +{ + /* Don't trust memcpy() of 0 chars. */ + if (length == 0) + return; + + memcpy (*charPP, fromP, length); + *charPP += length; +} + +/* This routine records the largest alignment seen for each segment. + If the beginning of the segment is aligned on the worst-case + boundary, all of the other alignments within it will work. At + least one object format really uses this info. */ + +void +record_alignment (/* Segment to which alignment pertains. */ + segT seg, + /* Alignment, as a power of 2 (e.g., 1 => 2-byte + boundary, 2 => 4-byte boundary, etc.) */ + int align) +{ + if (seg == absolute_section) + return; + + if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg)) + bfd_set_section_alignment (stdoutput, seg, align); +} + +int +get_recorded_alignment (segT seg) +{ + if (seg == absolute_section) + return 0; + + return bfd_get_section_alignment (stdoutput, seg); +} + +/* Reset the section indices after removing the gas created sections. */ + +static void +renumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *countparg) +{ + int *countp = (int *) countparg; + + sec->index = *countp; + ++*countp; +} + +static fragS * +chain_frchains_together_1 (segT section, struct frchain *frchp) +{ + fragS dummy, *prev_frag = &dummy; + fixS fix_dummy, *prev_fix = &fix_dummy; + + for (; frchp; frchp = frchp->frch_next) + { + prev_frag->fr_next = frchp->frch_root; + prev_frag = frchp->frch_last; + gas_assert (prev_frag->fr_type != 0); + if (frchp->fix_root != (fixS *) NULL) + { + if (seg_info (section)->fix_root == (fixS *) NULL) + seg_info (section)->fix_root = frchp->fix_root; + prev_fix->fx_next = frchp->fix_root; + seg_info (section)->fix_tail = frchp->fix_tail; + prev_fix = frchp->fix_tail; + } + } + gas_assert (prev_frag != &dummy + && prev_frag->fr_type != 0); + prev_frag->fr_next = 0; + return prev_frag; +} + +static void +chain_frchains_together (bfd *abfd ATTRIBUTE_UNUSED, + segT section, + void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *info; + + /* BFD may have introduced its own sections without using + subseg_new, so it is possible that seg_info is NULL. */ + info = seg_info (section); + if (info != (segment_info_type *) NULL) + info->frchainP->frch_last + = chain_frchains_together_1 (section, info->frchainP); + + /* Now that we've chained the frags together, we must add new fixups + to the segment, not to the frag chain. */ + frags_chained = 1; +} + +static void +cvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP) +{ + switch (fragP->fr_type) + { + case rs_align: + case rs_align_code: + case rs_align_test: + case rs_org: + case rs_space: +#ifdef HANDLE_ALIGN + HANDLE_ALIGN (fragP); +#endif + know (fragP->fr_next != NULL); + fragP->fr_offset = (fragP->fr_next->fr_address + - fragP->fr_address + - fragP->fr_fix) / fragP->fr_var; + if (fragP->fr_offset < 0) + { + as_bad_where (fragP->fr_file, fragP->fr_line, + _("attempt to .org/.space backwards? (%ld)"), + (long) fragP->fr_offset); + fragP->fr_offset = 0; + } + fragP->fr_type = rs_fill; + break; + + case rs_fill: + break; + + case rs_leb128: + { + valueT value = S_GET_VALUE (fragP->fr_symbol); + int size; + + size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value, + fragP->fr_subtype); + + fragP->fr_fix += size; + fragP->fr_type = rs_fill; + fragP->fr_var = 0; + fragP->fr_offset = 0; + fragP->fr_symbol = NULL; + } + break; + + case rs_cfa: + eh_frame_convert_frag (fragP); + break; + + case rs_dwarf2dbg: + dwarf2dbg_convert_frag (fragP); + break; + + case rs_machine_dependent: + md_convert_frag (stdoutput, sec, fragP); + + gas_assert (fragP->fr_next == NULL + || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address) + == fragP->fr_fix)); + + /* After md_convert_frag, we make the frag into a ".space 0". + md_convert_frag() should set up any fixSs and constants + required. */ + frag_wane (fragP); + break; + +#ifndef WORKING_DOT_WORD + case rs_broken_word: + { + struct broken_word *lie; + + if (fragP->fr_subtype) + { + fragP->fr_fix += md_short_jump_size; + for (lie = (struct broken_word *) (fragP->fr_symbol); + lie && lie->dispfrag == fragP; + lie = lie->next_broken_word) + if (lie->added == 1) + fragP->fr_fix += md_long_jump_size; + } + frag_wane (fragP); + } + break; +#endif + + default: + BAD_CASE (fragP->fr_type); + break; + } +#ifdef md_frag_check + md_frag_check (fragP); +#endif +} + +struct relax_seg_info +{ + int pass; + int changed; +}; + +static void +relax_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *xxx) +{ + segment_info_type *seginfo = seg_info (sec); + struct relax_seg_info *info = (struct relax_seg_info *) xxx; + + if (seginfo && seginfo->frchainP + && relax_segment (seginfo->frchainP->frch_root, sec, info->pass)) + info->changed = 1; +} + +static void +size_seg (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) +{ + flagword flags; + fragS *fragp; + segment_info_type *seginfo; + int x; + valueT size, newsize; + + subseg_change (sec, 0); + + seginfo = seg_info (sec); + if (seginfo && seginfo->frchainP) + { + for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next) + cvt_frag_to_fill (sec, fragp); + for (fragp = seginfo->frchainP->frch_root; + fragp->fr_next; + fragp = fragp->fr_next) + /* Walk to last elt. */ + ; + size = fragp->fr_address + fragp->fr_fix; + } + else + size = 0; + + flags = bfd_get_section_flags (abfd, sec); + if (size == 0 && bfd_get_section_size (sec) != 0 && + (flags & SEC_HAS_CONTENTS) != 0) + return; + + if (size > 0 && ! seginfo->bss) + flags |= SEC_HAS_CONTENTS; + + flags &= ~SEC_RELOC; + x = bfd_set_section_flags (abfd, sec, flags); + gas_assert (x); + + newsize = md_section_align (sec, size); + x = bfd_set_section_size (abfd, sec, newsize); + gas_assert (x); + + /* If the size had to be rounded up, add some padding in the last + non-empty frag. */ + gas_assert (newsize >= size); + if (size != newsize) + { + fragS *last = seginfo->frchainP->frch_last; + fragp = seginfo->frchainP->frch_root; + while (fragp->fr_next != last) + fragp = fragp->fr_next; + last->fr_address = size; + if ((newsize - size) % fragp->fr_var == 0) + fragp->fr_offset += (newsize - size) / fragp->fr_var; + else + /* If we hit this abort, it's likely due to subsegs_finish not + providing sufficient alignment on the last frag, and the + machine dependent code using alignment frags with fr_var + greater than 1. */ + abort (); + } + +#ifdef tc_frob_section + tc_frob_section (sec); +#endif +#ifdef obj_frob_section + obj_frob_section (sec); +#endif +} + +#ifdef DEBUG2 +static void +dump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream) +{ + segment_info_type *seginfo = seg_info (sec); + fixS *fixp = seginfo->fix_root; + + if (!fixp) + return; + + fprintf (stream, "sec %s relocs:\n", sec->name); + while (fixp) + { + symbolS *s = fixp->fx_addsy; + + fprintf (stream, " %08lx: type %d ", (unsigned long) fixp, + (int) fixp->fx_r_type); + if (s == NULL) + fprintf (stream, "no sym\n"); + else + { + print_symbol_value_1 (stream, s); + fprintf (stream, "\n"); + } + fixp = fixp->fx_next; + } +} +#else +#define dump_section_relocs(ABFD,SEC,STREAM) ((void) 0) +#endif + +#ifndef EMIT_SECTION_SYMBOLS +#define EMIT_SECTION_SYMBOLS 1 +#endif + +/* Resolve U.A.OFFSET_SYM and U.A.SYM fields of RELOC_LIST entries, + and check for validity. Convert RELOC_LIST from using U.A fields + to U.B fields. */ +static void +resolve_reloc_expr_symbols (void) +{ + bfd_vma addr_mask = 1; + struct reloc_list *r; + + /* Avoid a shift by the width of type. */ + addr_mask <<= bfd_arch_bits_per_address (stdoutput) - 1; + addr_mask <<= 1; + addr_mask -= 1; + + for (r = reloc_list; r; r = r->next) + { + reloc_howto_type *howto = r->u.a.howto; + expressionS *symval; + symbolS *sym; + bfd_vma offset, addend; + asection *sec; + + resolve_symbol_value (r->u.a.offset_sym); + symval = symbol_get_value_expression (r->u.a.offset_sym); + + offset = 0; + sym = NULL; + if (symval->X_op == O_constant) + sym = r->u.a.offset_sym; + else if (symval->X_op == O_symbol) + { + sym = symval->X_add_symbol; + offset = symval->X_add_number; + symval = symbol_get_value_expression (symval->X_add_symbol); + } + if (sym == NULL + || symval->X_op != O_constant + || (sec = S_GET_SEGMENT (sym)) == NULL + || !SEG_NORMAL (sec)) + { + as_bad_where (r->file, r->line, _("invalid offset expression")); + sec = NULL; + } + else + offset += S_GET_VALUE (sym); + + sym = NULL; + addend = r->u.a.addend; + if (r->u.a.sym != NULL) + { + resolve_symbol_value (r->u.a.sym); + symval = symbol_get_value_expression (r->u.a.sym); + if (symval->X_op == O_constant) + sym = r->u.a.sym; + else if (symval->X_op == O_symbol) + { + sym = symval->X_add_symbol; + addend += symval->X_add_number; + symval = symbol_get_value_expression (symval->X_add_symbol); + } + if (symval->X_op != O_constant) + { + as_bad_where (r->file, r->line, _("invalid reloc expression")); + sec = NULL; + } + else if (sym != NULL) + { + /* Convert relocs against local symbols to refer to the + corresponding section symbol plus offset instead. Keep + PC-relative relocs of the REL variety intact though to + prevent the offset from overflowing the relocated field, + unless it has enough bits to cover the whole address + space. */ + if (S_IS_LOCAL (sym) && !symbol_section_p (sym) + && (sec->use_rela_p + || (howto->partial_inplace + && (!howto->pc_relative + || howto->src_mask == addr_mask)))) + { + asection *symsec = S_GET_SEGMENT (sym); + if (!(((symsec->flags & SEC_MERGE) != 0 + && addend != 0) + || (symsec->flags & SEC_THREAD_LOCAL) != 0)) + { + addend += S_GET_VALUE (sym); + sym = section_symbol (symsec); + } + } + symbol_mark_used_in_reloc (sym); + } + } + if (sym == NULL) + { + if (abs_section_sym == NULL) + abs_section_sym = section_symbol (absolute_section); + sym = abs_section_sym; + } + + r->u.b.sec = sec; + r->u.b.s = symbol_get_bfdsym (sym); + r->u.b.r.sym_ptr_ptr = &r->u.b.s; + r->u.b.r.address = offset; + r->u.b.r.addend = addend; + r->u.b.r.howto = howto; + } +} + +/* This pass over fixups decides whether symbols can be replaced with + section symbols. */ + +static void +adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + fixS *fixp; + + if (seginfo == NULL) + return; + + dump_section_relocs (abfd, sec, stderr); + + for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) + if (fixp->fx_done) + /* Ignore it. */ + ; + else if (fixp->fx_addsy) + { + symbolS *sym; + asection *symsec; + +#ifdef DEBUG5 + fprintf (stderr, "\n\nadjusting fixup:\n"); + print_fixup (fixp); +#endif + + sym = fixp->fx_addsy; + + /* All symbols should have already been resolved at this + point. It is possible to see unresolved expression + symbols, though, since they are not in the regular symbol + table. */ + resolve_symbol_value (sym); + + if (fixp->fx_subsy != NULL) + resolve_symbol_value (fixp->fx_subsy); + + /* If this symbol is equated to an undefined or common symbol, + convert the fixup to being against that symbol. */ + while (symbol_equated_reloc_p (sym) + || S_IS_WEAKREFR (sym)) + { + symbolS *newsym = symbol_get_value_expression (sym)->X_add_symbol; + if (sym == newsym) + break; + fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number; + fixp->fx_addsy = newsym; + sym = newsym; + } + + if (symbol_mri_common_p (sym)) + { + fixp->fx_offset += S_GET_VALUE (sym); + fixp->fx_addsy = symbol_get_value_expression (sym)->X_add_symbol; + continue; + } + + /* If the symbol is undefined, common, weak, or global (ELF + shared libs), we can't replace it with the section symbol. */ + if (S_FORCE_RELOC (fixp->fx_addsy, 1)) + continue; + + /* Is there some other (target cpu dependent) reason we can't adjust + this one? (E.g. relocations involving function addresses on + the PA. */ +#ifdef tc_fix_adjustable + if (! tc_fix_adjustable (fixp)) + continue; +#endif + + /* Since we're reducing to section symbols, don't attempt to reduce + anything that's already using one. */ + if (symbol_section_p (sym)) + continue; + + symsec = S_GET_SEGMENT (sym); + if (symsec == NULL) + abort (); + + if (bfd_is_abs_section (symsec)) + { + /* The fixup_segment routine normally will not use this + symbol in a relocation. */ + continue; + } + + /* Don't try to reduce relocs which refer to non-local symbols + in .linkonce sections. It can lead to confusion when a + debugging section refers to a .linkonce section. I hope + this will always be correct. */ + if (symsec != sec && ! S_IS_LOCAL (sym)) + { + if ((symsec->flags & SEC_LINK_ONCE) != 0 + || (IS_ELF + /* The GNU toolchain uses an extension for ELF: a + section beginning with the magic string + .gnu.linkonce is a linkonce section. */ + && strncmp (segment_name (symsec), ".gnu.linkonce", + sizeof ".gnu.linkonce" - 1) == 0)) + continue; + } + + /* Never adjust a reloc against local symbol in a merge section + with non-zero addend. */ + if ((symsec->flags & SEC_MERGE) != 0 + && (fixp->fx_offset != 0 || fixp->fx_subsy != NULL)) + continue; + + /* Never adjust a reloc against TLS local symbol. */ + if ((symsec->flags & SEC_THREAD_LOCAL) != 0) + continue; + + /* We refetch the segment when calling section_symbol, rather + than using symsec, because S_GET_VALUE may wind up changing + the section when it calls resolve_symbol_value. */ + fixp->fx_offset += S_GET_VALUE (sym); + fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym)); +#ifdef DEBUG5 + fprintf (stderr, "\nadjusted fixup:\n"); + print_fixup (fixp); +#endif + } + + dump_section_relocs (abfd, sec, stderr); +} + +/* fixup_segment() + + Go through all the fixS's in a segment and see which ones can be + handled now. (These consist of fixS where we have since discovered + the value of a symbol, or the address of the frag involved.) + For each one, call md_apply_fix to put the fix into the frag data. + Ones that we couldn't completely handle here will be output later + by emit_relocations. */ + +static void +fixup_segment (fixS *fixP, segT this_segment) +{ + valueT add_number; + fragS *fragP; + segT add_symbol_segment = absolute_section; + + if (fixP != NULL && abs_section_sym == NULL) + abs_section_sym = section_symbol (absolute_section); + + /* If the linker is doing the relaxing, we must not do any fixups. + + Well, strictly speaking that's not true -- we could do any that + are PC-relative and don't cross regions that could change size. + And for the i960 we might be able to turn callx/callj into bal + anyways in cases where we know the maximum displacement. */ + if (linkrelax && TC_LINKRELAX_FIXUP (this_segment)) + { + for (; fixP; fixP = fixP->fx_next) + if (!fixP->fx_done) + { + if (fixP->fx_addsy == NULL) + { + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; + } + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + } + return; + } + + for (; fixP; fixP = fixP->fx_next) + { +#ifdef DEBUG5 + fprintf (stderr, "\nprocessing fixup:\n"); + print_fixup (fixP); +#endif + + fragP = fixP->fx_frag; + know (fragP); +#ifdef TC_VALIDATE_FIX + TC_VALIDATE_FIX (fixP, this_segment, skip); +#endif + add_number = fixP->fx_offset; + + if (fixP->fx_addsy != NULL) + add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy); + + if (fixP->fx_subsy != NULL) + { + segT sub_symbol_segment; + resolve_symbol_value (fixP->fx_subsy); + sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy); + if (fixP->fx_addsy != NULL + && sub_symbol_segment == add_symbol_segment + && !S_FORCE_RELOC (fixP->fx_addsy, 0) + && !S_FORCE_RELOC (fixP->fx_subsy, 0) + && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment)) + { + add_number += S_GET_VALUE (fixP->fx_addsy); + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + fixP->fx_addsy = NULL; + fixP->fx_subsy = NULL; +#ifdef TC_M68K + /* See the comment below about 68k weirdness. */ + fixP->fx_pcrel = 0; +#endif + } + else if (sub_symbol_segment == absolute_section + && !S_FORCE_RELOC (fixP->fx_subsy, 0) + && !TC_FORCE_RELOCATION_SUB_ABS (fixP, add_symbol_segment)) + { + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + fixP->fx_subsy = NULL; + } + else if (sub_symbol_segment == this_segment + && !S_FORCE_RELOC (fixP->fx_subsy, 0) + && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP, add_symbol_segment)) + { + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = (add_number + fixP->fx_dot_value + + fixP->fx_dot_frag->fr_address); + + /* Make it pc-relative. If the back-end code has not + selected a pc-relative reloc, cancel the adjustment + we do later on all pc-relative relocs. */ + if (0 +#ifdef TC_M68K + /* Do this for m68k even if it's already described + as pc-relative. On the m68k, an operand of + "pc@(foo-.-2)" should address "foo" in a + pc-relative mode. */ + || 1 +#endif + || !fixP->fx_pcrel) + add_number += MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_subsy = NULL; + fixP->fx_pcrel = 1; + } + else if (!TC_VALIDATE_FIX_SUB (fixP, add_symbol_segment)) + { + if (!md_register_arithmetic + && (add_symbol_segment == reg_section + || sub_symbol_segment == reg_section)) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("register value used as expression")); + else + as_bad_where (fixP->fx_file, fixP->fx_line, + _("can't resolve `%s' {%s section} - `%s' {%s section}"), + fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0", + segment_name (add_symbol_segment), + S_GET_NAME (fixP->fx_subsy), + segment_name (sub_symbol_segment)); + } + else if (sub_symbol_segment != undefined_section + && ! bfd_is_com_section (sub_symbol_segment) + && MD_APPLY_SYM_VALUE (fixP)) + add_number -= S_GET_VALUE (fixP->fx_subsy); + } + + if (fixP->fx_addsy) + { + if (add_symbol_segment == this_segment + && !S_FORCE_RELOC (fixP->fx_addsy, 0) + && !TC_FORCE_RELOCATION_LOCAL (fixP)) + { + /* This fixup was made when the symbol's segment was + SEG_UNKNOWN, but it is now in the local segment. + So we know how to do the address without relocation. */ + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + if (fixP->fx_pcrel) + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_addsy = NULL; + fixP->fx_pcrel = 0; + } + else if (add_symbol_segment == absolute_section + && !S_FORCE_RELOC (fixP->fx_addsy, 0) + && !TC_FORCE_RELOCATION_ABS (fixP)) + { + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + fixP->fx_addsy = NULL; + } + else if (add_symbol_segment != undefined_section + && ! bfd_is_com_section (add_symbol_segment) + && MD_APPLY_SYM_VALUE (fixP)) + add_number += S_GET_VALUE (fixP->fx_addsy); + } + + if (fixP->fx_pcrel) + { + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + if (!fixP->fx_done && fixP->fx_addsy == NULL) + { + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; + } + } + + if (!fixP->fx_done) + md_apply_fix (fixP, &add_number, this_segment); + + if (!fixP->fx_done) + { + if (fixP->fx_addsy == NULL) + fixP->fx_addsy = abs_section_sym; + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + } + + if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0) + { + if (fixP->fx_size < sizeof (valueT)) + { + valueT mask; + + mask = 0; + mask--; /* Set all bits to one. */ + mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0); + if ((add_number & mask) != 0 && (add_number & mask) != mask) + { + char buf[50], buf2[50]; + sprint_value (buf, fragP->fr_address + fixP->fx_where); + if (add_number > 1000) + sprint_value (buf2, add_number); + else + sprintf (buf2, "%ld", (long) add_number); + as_bad_where (fixP->fx_file, fixP->fx_line, + _("value of %s too large for field of %d bytes at %s"), + buf2, fixP->fx_size, buf); + } /* Generic error checking. */ + } +#ifdef WARN_SIGNED_OVERFLOW_WORD + /* Warn if a .word value is too large when treated as a signed + number. We already know it is not too negative. This is to + catch over-large switches generated by gcc on the 68k. */ + if (!flag_signed_overflow_ok + && fixP->fx_size == 2 + && add_number > 0x7fff) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("signed .word overflow; switch may be too large; %ld at 0x%lx"), + (long) add_number, + (long) (fragP->fr_address + fixP->fx_where)); +#endif + } /* Not a bit fix. */ + +#ifdef TC_VALIDATE_FIX + skip: ATTRIBUTE_UNUSED_LABEL + ; +#endif +#ifdef DEBUG5 + fprintf (stderr, "result:\n"); + print_fixup (fixP); +#endif + } /* For each fixS in this segment. */ +} + +static void +fix_segment (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + + fixup_segment (seginfo->fix_root, sec); +} + +static void +install_reloc (asection *sec, arelent *reloc, fragS *fragp, + char *file, unsigned int line) +{ + char *err; + bfd_reloc_status_type s; + asymbol *sym; + + if (reloc->sym_ptr_ptr != NULL + && (sym = *reloc->sym_ptr_ptr) != NULL + && (sym->flags & BSF_KEEP) == 0 + && ((sym->flags & BSF_SECTION_SYM) == 0 + || (EMIT_SECTION_SYMBOLS + && !bfd_is_abs_section (sym->section)))) + as_bad_where (file, line, _("redefined symbol cannot be used on reloc")); + + s = bfd_install_relocation (stdoutput, reloc, + fragp->fr_literal, fragp->fr_address, + sec, &err); + switch (s) + { + case bfd_reloc_ok: + break; + case bfd_reloc_overflow: + as_bad_where (file, line, _("relocation overflow")); + break; + case bfd_reloc_outofrange: + as_bad_where (file, line, _("relocation out of range")); + break; + default: + as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"), + file, line, s); + } +} + +static fragS * +get_frag_for_reloc (fragS *last_frag, + const segment_info_type *seginfo, + const struct reloc_list *r) +{ + fragS *f; + + for (f = last_frag; f != NULL; f = f->fr_next) + if (f->fr_address <= r->u.b.r.address + && r->u.b.r.address < f->fr_address + f->fr_fix) + return f; + + for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next) + if (f->fr_address <= r->u.b.r.address + && r->u.b.r.address < f->fr_address + f->fr_fix) + return f; + + as_bad_where (r->file, r->line, + _("reloc not within (fixed part of) section")); + return NULL; +} + +static void +write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + unsigned int n; + struct reloc_list *my_reloc_list, **rp, *r; + arelent **relocs; + fixS *fixp; + fragS *last_frag; + + /* If seginfo is NULL, we did not create this section; don't do + anything with it. */ + if (seginfo == NULL) + return; + + n = 0; + for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) + if (!fixp->fx_done) + n++; + +#ifdef RELOC_EXPANSION_POSSIBLE + n *= MAX_RELOC_EXPANSION; +#endif + + /* Extract relocs for this section from reloc_list. */ + rp = &reloc_list; + my_reloc_list = NULL; + while ((r = *rp) != NULL) + { + if (r->u.b.sec == sec) + { + *rp = r->next; + r->next = my_reloc_list; + my_reloc_list = r; + n++; + } + else + rp = &r->next; + } + + relocs = (arelent **) xcalloc (n, sizeof (arelent *)); + + n = 0; + r = my_reloc_list; + last_frag = NULL; + for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next) + { + int fx_size, slack; + offsetT loc; + arelent **reloc; +#ifndef RELOC_EXPANSION_POSSIBLE + arelent *rel; + + reloc = &rel; +#endif + + if (fixp->fx_done) + continue; + + fx_size = fixp->fx_size; + slack = TC_FX_SIZE_SLACK (fixp); + if (slack > 0) + fx_size = fx_size > slack ? fx_size - slack : 0; + loc = fixp->fx_where + fx_size; + if (slack >= 0 && loc > fixp->fx_frag->fr_fix) + as_bad_where (fixp->fx_file, fixp->fx_line, + _("internal error: fixup not contained within frag")); + +#ifndef RELOC_EXPANSION_POSSIBLE + *reloc = tc_gen_reloc (sec, fixp); +#else + reloc = tc_gen_reloc (sec, fixp); +#endif + + while (*reloc) + { + while (r != NULL && r->u.b.r.address < (*reloc)->address) + { + fragS *f = get_frag_for_reloc (last_frag, seginfo, r); + if (f != NULL) + { + last_frag = f; + relocs[n++] = &r->u.b.r; + install_reloc (sec, &r->u.b.r, f, r->file, r->line); + } + r = r->next; + } + relocs[n++] = *reloc; + install_reloc (sec, *reloc, fixp->fx_frag, + fixp->fx_file, fixp->fx_line); +#ifndef RELOC_EXPANSION_POSSIBLE + break; +#else + reloc++; +#endif + } + } + + while (r != NULL) + { + fragS *f = get_frag_for_reloc (last_frag, seginfo, r); + if (f != NULL) + { + last_frag = f; + relocs[n++] = &r->u.b.r; + install_reloc (sec, &r->u.b.r, f, r->file, r->line); + } + r = r->next; + } + +#ifdef DEBUG4 + { + unsigned int k, j, nsyms; + asymbol **sympp; + sympp = bfd_get_outsymbols (stdoutput); + nsyms = bfd_get_symcount (stdoutput); + for (k = 0; k < n; k++) + if (((*relocs[k]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) + { + for (j = 0; j < nsyms; j++) + if (sympp[j] == *relocs[k]->sym_ptr_ptr) + break; + if (j == nsyms) + abort (); + } + } +#endif + + if (n) + { + flagword flags = bfd_get_section_flags (abfd, sec); + flags |= SEC_RELOC; + bfd_set_section_flags (abfd, sec, flags); + bfd_set_reloc (stdoutput, sec, relocs, n); + } + +#ifdef SET_SECTION_RELOCS + SET_SECTION_RELOCS (sec, relocs, n); +#endif + +#ifdef DEBUG3 + { + unsigned int k; + + fprintf (stderr, "relocs for sec %s\n", sec->name); + for (k = 0; k < n; k++) + { + arelent *rel = relocs[k]; + asymbol *s = *rel->sym_ptr_ptr; + fprintf (stderr, " reloc %2d @%p off %4lx : sym %-10s addend %lx\n", + k, rel, (unsigned long)rel->address, s->name, + (unsigned long)rel->addend); + } + } +#endif +} + +static int +compress_frag (struct z_stream_s *strm, const char *contents, int in_size, + fragS **last_newf, struct obstack *ob) +{ + int out_size; + int total_out_size = 0; + fragS *f = *last_newf; + char *next_out; + int avail_out; + + /* Call the compression routine repeatedly until it has finished + processing the frag. */ + while (in_size > 0) + { + /* Reserve all the space available in the current chunk. + If none is available, start a new frag. */ + avail_out = obstack_room (ob); + if (avail_out <= 0) + { + obstack_finish (ob); + f = frag_alloc (ob); + f->fr_type = rs_fill; + (*last_newf)->fr_next = f; + *last_newf = f; + avail_out = obstack_room (ob); + } + if (avail_out <= 0) + as_fatal (_("can't extend frag")); + next_out = obstack_next_free (ob); + obstack_blank_fast (ob, avail_out); + out_size = compress_data (strm, &contents, &in_size, + &next_out, &avail_out); + if (out_size < 0) + return -1; + + f->fr_fix += out_size; + total_out_size += out_size; + + /* Return unused space. */ + if (avail_out > 0) + obstack_blank_fast (ob, -avail_out); + } + + return total_out_size; +} + +static void +compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + fragS *f; + fragS *first_newf; + fragS *last_newf; + struct obstack *ob = &seginfo->frchainP->frch_obstack; + bfd_size_type uncompressed_size = (bfd_size_type) sec->size; + bfd_size_type compressed_size; + const char *section_name; + char *compressed_name; + char *header; + struct z_stream_s *strm; + int x; + flagword flags = bfd_get_section_flags (abfd, sec); + + if (seginfo == NULL + || sec->size < 32 + || (flags & (SEC_ALLOC | SEC_HAS_CONTENTS)) == SEC_ALLOC) + return; + + section_name = bfd_get_section_name (stdoutput, sec); + if (strncmp (section_name, ".debug_", 7) != 0) + return; + + strm = compress_init (); + if (strm == NULL) + return; + + /* Create a new frag to contain the "ZLIB" header. */ + first_newf = frag_alloc (ob); + if (obstack_room (ob) < 12) + first_newf = frag_alloc (ob); + if (obstack_room (ob) < 12) + as_fatal (_("can't extend frag %u chars"), 12); + last_newf = first_newf; + obstack_blank_fast (ob, 12); + last_newf->fr_type = rs_fill; + last_newf->fr_fix = 12; + header = last_newf->fr_literal; + memcpy (header, "ZLIB", 4); + header[11] = uncompressed_size; uncompressed_size >>= 8; + header[10] = uncompressed_size; uncompressed_size >>= 8; + header[9] = uncompressed_size; uncompressed_size >>= 8; + header[8] = uncompressed_size; uncompressed_size >>= 8; + header[7] = uncompressed_size; uncompressed_size >>= 8; + header[6] = uncompressed_size; uncompressed_size >>= 8; + header[5] = uncompressed_size; uncompressed_size >>= 8; + header[4] = uncompressed_size; + compressed_size = 12; + + /* Stream the frags through the compression engine, adding new frags + as necessary to accomodate the compressed output. */ + for (f = seginfo->frchainP->frch_root; + f; + f = f->fr_next) + { + offsetT fill_size; + char *fill_literal; + offsetT count; + int out_size; + + gas_assert (f->fr_type == rs_fill); + if (f->fr_fix) + { + out_size = compress_frag (strm, f->fr_literal, f->fr_fix, + &last_newf, ob); + if (out_size < 0) + return; + compressed_size += out_size; + } + fill_literal = f->fr_literal + f->fr_fix; + fill_size = f->fr_var; + count = f->fr_offset; + gas_assert (count >= 0); + if (fill_size && count) + { + while (count--) + { + out_size = compress_frag (strm, fill_literal, (int) fill_size, + &last_newf, ob); + if (out_size < 0) + return; + compressed_size += out_size; + } + } + } + + /* Flush the compression state. */ + for (;;) + { + int avail_out; + char *next_out; + int out_size; + + /* Reserve all the space available in the current chunk. + If none is available, start a new frag. */ + avail_out = obstack_room (ob); + if (avail_out <= 0) + { + fragS *newf; + + obstack_finish (ob); + newf = frag_alloc (ob); + newf->fr_type = rs_fill; + last_newf->fr_next = newf; + last_newf = newf; + avail_out = obstack_room (ob); + } + if (avail_out <= 0) + as_fatal (_("can't extend frag")); + next_out = obstack_next_free (ob); + obstack_blank_fast (ob, avail_out); + x = compress_finish (strm, &next_out, &avail_out, &out_size); + if (x < 0) + return; + + last_newf->fr_fix += out_size; + compressed_size += out_size; + + /* Return unused space. */ + if (avail_out > 0) + obstack_blank_fast (ob, -avail_out); + + if (x == 0) + break; + } + + /* Replace the uncompressed frag list with the compressed frag list. */ + seginfo->frchainP->frch_root = first_newf; + seginfo->frchainP->frch_last = last_newf; + + /* Update the section size and its name. */ + x = bfd_set_section_size (abfd, sec, compressed_size); + gas_assert (x); + compressed_name = (char *) xmalloc (strlen (section_name) + 2); + compressed_name[0] = '.'; + compressed_name[1] = 'z'; + strcpy (compressed_name + 2, section_name + 1); + bfd_section_name (stdoutput, sec) = compressed_name; +} + +static void +write_contents (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *xxx ATTRIBUTE_UNUSED) +{ + segment_info_type *seginfo = seg_info (sec); + addressT offset = 0; + fragS *f; + + /* Write out the frags. */ + if (seginfo == NULL + || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)) + return; + + for (f = seginfo->frchainP->frch_root; + f; + f = f->fr_next) + { + int x; + addressT fill_size; + char *fill_literal; + offsetT count; + + gas_assert (f->fr_type == rs_fill); + if (f->fr_fix) + { + x = bfd_set_section_contents (stdoutput, sec, + f->fr_literal, (file_ptr) offset, + (bfd_size_type) f->fr_fix); + if (!x) + as_fatal (_("can't write %s: %s"), stdoutput->filename, + bfd_errmsg (bfd_get_error ())); + offset += f->fr_fix; + } + fill_literal = f->fr_literal + f->fr_fix; + fill_size = f->fr_var; + count = f->fr_offset; + gas_assert (count >= 0); + if (fill_size && count) + { + char buf[256]; + if (fill_size > sizeof (buf)) + { + /* Do it the old way. Can this ever happen? */ + while (count--) + { + x = bfd_set_section_contents (stdoutput, sec, + fill_literal, + (file_ptr) offset, + (bfd_size_type) fill_size); + if (!x) + as_fatal (_("can't write %s: %s"), stdoutput->filename, + bfd_errmsg (bfd_get_error ())); + offset += fill_size; + } + } + else + { + /* Build a buffer full of fill objects and output it as + often as necessary. This saves on the overhead of + potentially lots of bfd_set_section_contents calls. */ + int n_per_buf, i; + if (fill_size == 1) + { + n_per_buf = sizeof (buf); + memset (buf, *fill_literal, n_per_buf); + } + else + { + char *bufp; + n_per_buf = sizeof (buf) / fill_size; + for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size) + memcpy (bufp, fill_literal, fill_size); + } + for (; count > 0; count -= n_per_buf) + { + n_per_buf = n_per_buf > count ? count : n_per_buf; + x = bfd_set_section_contents + (stdoutput, sec, buf, (file_ptr) offset, + (bfd_size_type) n_per_buf * fill_size); + if (!x) + as_fatal (_("cannot write to output file '%s': %s"), + stdoutput->filename, + bfd_errmsg (bfd_get_error ())); + offset += n_per_buf * fill_size; + } + } + } + } +} + +static void +merge_data_into_text (void) +{ + seg_info (text_section)->frchainP->frch_last->fr_next = + seg_info (data_section)->frchainP->frch_root; + seg_info (text_section)->frchainP->frch_last = + seg_info (data_section)->frchainP->frch_last; + seg_info (data_section)->frchainP = 0; +} + +static void +set_symtab (void) +{ + int nsyms; + asymbol **asympp; + symbolS *symp; + bfd_boolean result; + + /* Count symbols. We can't rely on a count made by the loop in + write_object_file, because *_frob_file may add a new symbol or + two. */ + nsyms = 0; + for (symp = symbol_rootP; symp; symp = symbol_next (symp)) + nsyms++; + + if (nsyms) + { + int i; + bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *); + + asympp = (asymbol **) bfd_alloc (stdoutput, amt); + symp = symbol_rootP; + for (i = 0; i < nsyms; i++, symp = symbol_next (symp)) + { + asympp[i] = symbol_get_bfdsym (symp); + if (asympp[i]->flags != BSF_SECTION_SYM + || !(bfd_is_const_section (asympp[i]->section) + && asympp[i]->section->symbol == asympp[i])) + asympp[i]->flags |= BSF_KEEP; + symbol_mark_written (symp); + } + } + else + asympp = 0; + result = bfd_set_symtab (stdoutput, asympp, nsyms); + gas_assert (result); + symbol_table_frozen = 1; +} + +/* Finish the subsegments. After every sub-segment, we fake an + ".align ...". This conforms to BSD4.2 brane-damage. We then fake + ".fill 0" because that is the kind of frag that requires least + thought. ".align" frags like to have a following frag since that + makes calculating their intended length trivial. */ + +#ifndef SUB_SEGMENT_ALIGN +#ifdef HANDLE_ALIGN +/* The last subsegment gets an alignment corresponding to the alignment + of the section. This allows proper nop-filling at the end of + code-bearing sections. */ +#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \ + (!(FRCHAIN)->frch_next ? get_recorded_alignment (SEG) : 0) +#else +#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0 +#endif +#endif + +void +subsegs_finish (void) +{ + struct frchain *frchainP; + asection *s; + + for (s = stdoutput->sections; s; s = s->next) + { + segment_info_type *seginfo = seg_info (s); + if (!seginfo) + continue; + + for (frchainP = seginfo->frchainP; + frchainP != NULL; + frchainP = frchainP->frch_next) + { + int alignment = 0; + + subseg_set (s, frchainP->frch_subseg); + + /* This now gets called even if we had errors. In that case, + any alignment is meaningless, and, moreover, will look weird + if we are generating a listing. */ + if (!had_errors ()) + { + alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP); + if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) + && now_seg->entsize) + { + unsigned int entsize = now_seg->entsize; + int entalign = 0; + + while ((entsize & 1) == 0) + { + ++entalign; + entsize >>= 1; + } + if (entalign > alignment) + alignment = entalign; + } + } + + if (subseg_text_p (now_seg)) + frag_align_code (alignment, 0); + else + frag_align (alignment, 0, 0); + + /* frag_align will have left a new frag. + Use this last frag for an empty ".fill". + + For this segment ... + Create a last frag. Do not leave a "being filled in frag". */ + frag_wane (frag_now); + frag_now->fr_fix = 0; + know (frag_now->fr_next == NULL); + } + } +} + +/* Write the object file. */ + +void +write_object_file (void) +{ + struct relax_seg_info rsi; +#ifndef WORKING_DOT_WORD + fragS *fragP; /* Track along all frags. */ +#endif + +#ifdef md_pre_output_hook + md_pre_output_hook; +#endif + + /* Do we really want to write it? */ + { + int n_warns, n_errs; + n_warns = had_warnings (); + n_errs = had_errors (); + /* The -Z flag indicates that an object file should be generated, + regardless of warnings and errors. */ + if (flag_always_generate_output) + { + if (n_warns || n_errs) + as_warn (_("%d error%s, %d warning%s, generating bad object file"), + n_errs, n_errs == 1 ? "" : "s", + n_warns, n_warns == 1 ? "" : "s"); + } + else + { + if (n_errs) + as_fatal (_("%d error%s, %d warning%s, no object file generated"), + n_errs, n_errs == 1 ? "" : "s", + n_warns, n_warns == 1 ? "" : "s"); + } + } + +#ifdef md_pre_relax_hook + md_pre_relax_hook; +#endif + + /* From now on, we don't care about sub-segments. Build one frag chain + for each segment. Linked thru fr_next. */ + + /* Remove the sections created by gas for its own purposes. */ + { + int i; + + bfd_section_list_remove (stdoutput, reg_section); + bfd_section_list_remove (stdoutput, expr_section); + stdoutput->section_count -= 2; + i = 0; + bfd_map_over_sections (stdoutput, renumber_sections, &i); + } + + bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0); + + /* We have two segments. If user gave -R flag, then we must put the + data frags into the text segment. Do this before relaxing so + we know to take advantage of -R and make shorter addresses. */ + if (flag_readonly_data_in_text) + { + merge_data_into_text (); + } + + rsi.pass = 0; + while (1) + { +#ifndef WORKING_DOT_WORD + /* We need to reset the markers in the broken word list and + associated frags between calls to relax_segment (via + relax_seg). Since the broken word list is global, we do it + once per round, rather than locally in relax_segment for each + segment. */ + struct broken_word *brokp; + + for (brokp = broken_words; + brokp != (struct broken_word *) NULL; + brokp = brokp->next_broken_word) + { + brokp->added = 0; + + if (brokp->dispfrag != (fragS *) NULL + && brokp->dispfrag->fr_type == rs_broken_word) + brokp->dispfrag->fr_subtype = 0; + } +#endif + + rsi.changed = 0; + bfd_map_over_sections (stdoutput, relax_seg, &rsi); + rsi.pass++; + if (!rsi.changed) + break; + } + + /* Note - Most ports will use the default value of + TC_FINALIZE_SYMS_BEFORE_SIZE_SEG, which 1. This will force + local symbols to be resolved, removing their frag information. + Some ports however, will not have finished relaxing all of + their frags and will still need the local symbol frag + information. These ports can set + TC_FINALIZE_SYMS_BEFORE_SIZE_SEG to 0. */ + finalize_syms = TC_FINALIZE_SYMS_BEFORE_SIZE_SEG; + + bfd_map_over_sections (stdoutput, size_seg, (char *) 0); + + /* Relaxation has completed. Freeze all syms. */ + finalize_syms = 1; + +#ifdef md_post_relax_hook + md_post_relax_hook; +#endif + +#ifndef WORKING_DOT_WORD + { + struct broken_word *lie; + struct broken_word **prevP; + + prevP = &broken_words; + for (lie = broken_words; lie; lie = lie->next_broken_word) + if (!lie->added) + { + expressionS exp; + + subseg_change (lie->seg, lie->subseg); + exp.X_op = O_subtract; + exp.X_add_symbol = lie->add; + exp.X_op_symbol = lie->sub; + exp.X_add_number = lie->addnum; +#ifdef TC_CONS_FIX_NEW + TC_CONS_FIX_NEW (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp); +#else + fix_new_exp (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp, 0, BFD_RELOC_16); +#endif + *prevP = lie->next_broken_word; + } + else + prevP = &(lie->next_broken_word); + + for (lie = broken_words; lie;) + { + struct broken_word *untruth; + char *table_ptr; + addressT table_addr; + addressT from_addr, to_addr; + int n, m; + + subseg_change (lie->seg, lie->subseg); + fragP = lie->dispfrag; + + /* Find out how many broken_words go here. */ + n = 0; + for (untruth = lie; + untruth && untruth->dispfrag == fragP; + untruth = untruth->next_broken_word) + if (untruth->added == 1) + n++; + + table_ptr = lie->dispfrag->fr_opcode; + table_addr = (lie->dispfrag->fr_address + + (table_ptr - lie->dispfrag->fr_literal)); + /* Create the jump around the long jumps. This is a short + jump from table_ptr+0 to table_ptr+n*long_jump_size. */ + from_addr = table_addr; + to_addr = table_addr + md_short_jump_size + n * md_long_jump_size; + md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag, + lie->add); + table_ptr += md_short_jump_size; + table_addr += md_short_jump_size; + + for (m = 0; + lie && lie->dispfrag == fragP; + m++, lie = lie->next_broken_word) + { + if (lie->added == 2) + continue; + /* Patch the jump table. */ + for (untruth = (struct broken_word *) (fragP->fr_symbol); + untruth && untruth->dispfrag == fragP; + untruth = untruth->next_broken_word) + { + if (untruth->use_jump == lie) + { + /* This is the offset from ??? to table_ptr+0. + The target is the same for all users of this + md_long_jump, but the "sub" bases (and hence the + offsets) may be different. */ + addressT to_word = table_addr - S_GET_VALUE (untruth->sub); +#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD + TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_word, untruth); +#endif + md_number_to_chars (untruth->word_goes_here, to_word, 2); + } + } + + /* Install the long jump. */ + /* This is a long jump from table_ptr+0 to the final target. */ + from_addr = table_addr; + to_addr = S_GET_VALUE (lie->add) + lie->addnum; + md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, + lie->add); + table_ptr += md_long_jump_size; + table_addr += md_long_jump_size; + } + } + } +#endif /* not WORKING_DOT_WORD */ + + /* Resolve symbol values. This needs to be done before processing + the relocations. */ + if (symbol_rootP) + { + symbolS *symp; + + for (symp = symbol_rootP; symp; symp = symbol_next (symp)) + resolve_symbol_value (symp); + } + resolve_local_symbol_values (); + resolve_reloc_expr_symbols (); + + PROGRESS (1); + +#ifdef tc_frob_file_before_adjust + tc_frob_file_before_adjust (); +#endif +#ifdef obj_frob_file_before_adjust + obj_frob_file_before_adjust (); +#endif + + bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0); + +#ifdef tc_frob_file_before_fix + tc_frob_file_before_fix (); +#endif +#ifdef obj_frob_file_before_fix + obj_frob_file_before_fix (); +#endif + + bfd_map_over_sections (stdoutput, fix_segment, (char *) 0); + + /* Set up symbol table, and write it out. */ + if (symbol_rootP) + { + symbolS *symp; + bfd_boolean skip_next_symbol = FALSE; + + for (symp = symbol_rootP; symp; symp = symbol_next (symp)) + { + int punt = 0; + const char *name; + + if (skip_next_symbol) + { + /* Don't do anything besides moving the value of the + symbol from the GAS value-field to the BFD value-field. */ + symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp); + skip_next_symbol = FALSE; + continue; + } + + if (symbol_mri_common_p (symp)) + { + if (S_IS_EXTERNAL (symp)) + as_bad (_("%s: global symbols not supported in common sections"), + S_GET_NAME (symp)); + symbol_remove (symp, &symbol_rootP, &symbol_lastP); + continue; + } + + name = S_GET_NAME (symp); + if (name) + { + const char *name2 = + decode_local_label_name ((char *) S_GET_NAME (symp)); + /* They only differ if `name' is a fb or dollar local + label name. */ + if (name2 != name && ! S_IS_DEFINED (symp)) + as_bad (_("local label `%s' is not defined"), name2); + } + + /* Do it again, because adjust_reloc_syms might introduce + more symbols. They'll probably only be section symbols, + but they'll still need to have the values computed. */ + resolve_symbol_value (symp); + + /* Skip symbols which were equated to undefined or common + symbols. */ + if (symbol_equated_reloc_p (symp) + || S_IS_WEAKREFR (symp)) + { + const char *sname = S_GET_NAME (symp); + + if (S_IS_COMMON (symp) + && !TC_FAKE_LABEL (sname) + && !S_IS_WEAKREFR (symp) + && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp))) + { + expressionS *e = symbol_get_value_expression (symp); + + as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"), + sname, S_GET_NAME (e->X_add_symbol)); + } + if (S_GET_SEGMENT (symp) == reg_section) + { + /* Report error only if we know the symbol name. */ + if (S_GET_NAME (symp) != reg_section->name) + as_bad (_("can't make global register symbol `%s'"), + sname); + } + symbol_remove (symp, &symbol_rootP, &symbol_lastP); + continue; + } + +#ifdef obj_frob_symbol + obj_frob_symbol (symp, punt); +#endif +#ifdef tc_frob_symbol + if (! punt || symbol_used_in_reloc_p (symp)) + tc_frob_symbol (symp, punt); +#endif + + /* If we don't want to keep this symbol, splice it out of + the chain now. If EMIT_SECTION_SYMBOLS is 0, we never + want section symbols. Otherwise, we skip local symbols + and symbols that the frob_symbol macros told us to punt, + but we keep such symbols if they are used in relocs. */ + if (symp == abs_section_sym + || (! EMIT_SECTION_SYMBOLS + && symbol_section_p (symp)) + /* Note that S_IS_EXTERNAL and S_IS_LOCAL are not always + opposites. Sometimes the former checks flags and the + latter examines the name... */ + || (!S_IS_EXTERNAL (symp) + && (punt || S_IS_LOCAL (symp) || + (S_IS_WEAKREFD (symp) && ! symbol_used_p (symp))) + && ! symbol_used_in_reloc_p (symp))) + { + symbol_remove (symp, &symbol_rootP, &symbol_lastP); + + /* After symbol_remove, symbol_next(symp) still returns + the one that came after it in the chain. So we don't + need to do any extra cleanup work here. */ + continue; + } + + /* Make sure we really got a value for the symbol. */ + if (! symbol_resolved_p (symp)) + { + as_bad (_("can't resolve value for symbol `%s'"), + S_GET_NAME (symp)); + symbol_mark_resolved (symp); + } + + /* Set the value into the BFD symbol. Up til now the value + has only been kept in the gas symbolS struct. */ + symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp); + + /* A warning construct is a warning symbol followed by the + symbol warned about. Don't let anything object-format or + target-specific muck with it; it's ready for output. */ + if (symbol_get_bfdsym (symp)->flags & BSF_WARNING) + skip_next_symbol = TRUE; + } + } + + PROGRESS (1); + + /* Now do any format-specific adjustments to the symbol table, such + as adding file symbols. */ +#ifdef tc_adjust_symtab + tc_adjust_symtab (); +#endif +#ifdef obj_adjust_symtab + obj_adjust_symtab (); +#endif + + /* Stop if there is an error. */ + if (had_errors ()) + return; + + /* Now that all the sizes are known, and contents correct, we can + start writing to the file. */ + set_symtab (); + + /* If *_frob_file changes the symbol value at this point, it is + responsible for moving the changed value into symp->bsym->value + as well. Hopefully all symbol value changing can be done in + *_frob_symbol. */ +#ifdef tc_frob_file + tc_frob_file (); +#endif +#ifdef obj_frob_file + obj_frob_file (); +#endif +#ifdef obj_coff_generate_pdata + obj_coff_generate_pdata (); +#endif + bfd_map_over_sections (stdoutput, write_relocs, (char *) 0); + +#ifdef tc_frob_file_after_relocs + tc_frob_file_after_relocs (); +#endif +#ifdef obj_frob_file_after_relocs + obj_frob_file_after_relocs (); +#endif + + /* Once all relocations have been written, we can compress the + contents of the debug sections. This needs to be done before + we start writing any sections, because it will affect the file + layout, which is fixed once we start writing contents. */ + if (flag_compress_debug) + bfd_map_over_sections (stdoutput, compress_debug, (char *) 0); + + bfd_map_over_sections (stdoutput, write_contents, (char *) 0); +} + +#ifdef TC_GENERIC_RELAX_TABLE +/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */ + +long +relax_frag (segT segment, fragS *fragP, long stretch) +{ + const relax_typeS *this_type; + const relax_typeS *start_type; + relax_substateT next_state; + relax_substateT this_state; + offsetT growth; + offsetT aim; + addressT target; + addressT address; + symbolS *symbolP; + const relax_typeS *table; + + target = fragP->fr_offset; + address = fragP->fr_address; + table = TC_GENERIC_RELAX_TABLE; + this_state = fragP->fr_subtype; + start_type = this_type = table + this_state; + symbolP = fragP->fr_symbol; + + if (symbolP) + { + fragS *sym_frag; + + sym_frag = symbol_get_frag (symbolP); + +#ifndef DIFF_EXPR_OK + know (sym_frag != NULL); +#endif + know (S_GET_SEGMENT (symbolP) != absolute_section + || sym_frag == &zero_address_frag); + target += S_GET_VALUE (symbolP); + + /* If SYM_FRAG has yet to be reached on this pass, assume it + will move by STRETCH just as we did, unless there is an + alignment frag between here and SYM_FRAG. An alignment may + well absorb any STRETCH, and we don't want to choose a larger + branch insn by overestimating the needed reach of this + branch. It isn't critical to calculate TARGET exactly; We + know we'll be doing another pass if STRETCH is non-zero. */ + + if (stretch != 0 + && sym_frag->relax_marker != fragP->relax_marker + && S_GET_SEGMENT (symbolP) == segment) + { + if (stretch < 0 + || sym_frag->region == fragP->region) + target += stretch; + /* If we get here we know we have a forward branch. This + relax pass may have stretched previous instructions so + far that omitting STRETCH would make the branch + negative. Don't allow this in case the negative reach is + large enough to require a larger branch instruction. */ + else if (target < address) + target = fragP->fr_next->fr_address + stretch; + } + } + + aim = target - address - fragP->fr_fix; +#ifdef TC_PCREL_ADJUST + /* Currently only the ns32k family needs this. */ + aim += TC_PCREL_ADJUST (fragP); +#endif + +#ifdef md_prepare_relax_scan + /* Formerly called M68K_AIM_KLUDGE. */ + md_prepare_relax_scan (fragP, address, aim, this_state, this_type); +#endif + + if (aim < 0) + { + /* Look backwards. */ + for (next_state = this_type->rlx_more; next_state;) + if (aim >= this_type->rlx_backward) + next_state = 0; + else + { + /* Grow to next state. */ + this_state = next_state; + this_type = table + this_state; + next_state = this_type->rlx_more; + } + } + else + { + /* Look forwards. */ + for (next_state = this_type->rlx_more; next_state;) + if (aim <= this_type->rlx_forward) + next_state = 0; + else + { + /* Grow to next state. */ + this_state = next_state; + this_type = table + this_state; + next_state = this_type->rlx_more; + } + } + + growth = this_type->rlx_length - start_type->rlx_length; + if (growth != 0) + fragP->fr_subtype = this_state; + return growth; +} + +#endif /* defined (TC_GENERIC_RELAX_TABLE) */ + +/* Relax_align. Advance location counter to next address that has 'alignment' + lowest order bits all 0s, return size of adjustment made. */ +static relax_addressT +relax_align (register relax_addressT address, /* Address now. */ + register int alignment /* Alignment (binary). */) +{ + relax_addressT mask; + relax_addressT new_address; + + mask = ~((~0) << alignment); + new_address = (address + mask) & (~mask); +#ifdef LINKER_RELAXING_SHRINKS_ONLY + if (linkrelax) + /* We must provide lots of padding, so the linker can discard it + when needed. The linker will not add extra space, ever. */ + new_address += (1 << alignment); +#endif + return (new_address - address); +} + +/* Now we have a segment, not a crowd of sub-segments, we can make + fr_address values. + + Relax the frags. + + After this, all frags in this segment have addresses that are correct + within the segment. Since segments live in different file addresses, + these frag addresses may not be the same as final object-file + addresses. */ + +int +relax_segment (struct frag *segment_frag_root, segT segment, int pass) +{ + unsigned long frag_count; + struct frag *fragP; + relax_addressT address; + int region; + int ret; + + /* In case md_estimate_size_before_relax() wants to make fixSs. */ + subseg_change (segment, 0); + + /* For each frag in segment: count and store (a 1st guess of) + fr_address. */ + address = 0; + region = 0; + for (frag_count = 0, fragP = segment_frag_root; + fragP; + fragP = fragP->fr_next, frag_count ++) + { + fragP->region = region; + fragP->relax_marker = 0; + fragP->fr_address = address; + address += fragP->fr_fix; + + switch (fragP->fr_type) + { + case rs_fill: + address += fragP->fr_offset * fragP->fr_var; + break; + + case rs_align: + case rs_align_code: + case rs_align_test: + { + addressT offset = relax_align (address, (int) fragP->fr_offset); + + if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype) + offset = 0; + + if (offset % fragP->fr_var != 0) + { + as_bad_where (fragP->fr_file, fragP->fr_line, + _("alignment padding (%lu bytes) not a multiple of %ld"), + (unsigned long) offset, (long) fragP->fr_var); + offset -= (offset % fragP->fr_var); + } + + address += offset; + region += 1; + } + break; + + case rs_org: + /* Assume .org is nugatory. It will grow with 1st relax. */ + region += 1; + break; + + case rs_space: + break; + + case rs_machine_dependent: + /* If fr_symbol is an expression, this call to + resolve_symbol_value sets up the correct segment, which will + likely be needed in md_estimate_size_before_relax. */ + if (fragP->fr_symbol) + resolve_symbol_value (fragP->fr_symbol); + + address += md_estimate_size_before_relax (fragP, segment); + break; + +#ifndef WORKING_DOT_WORD + /* Broken words don't concern us yet. */ + case rs_broken_word: + break; +#endif + + case rs_leb128: + /* Initial guess is always 1; doing otherwise can result in + stable solutions that are larger than the minimum. */ + address += fragP->fr_offset = 1; + break; + + case rs_cfa: + address += eh_frame_estimate_size_before_relax (fragP); + break; + + case rs_dwarf2dbg: + address += dwarf2dbg_estimate_size_before_relax (fragP); + break; + + default: + BAD_CASE (fragP->fr_type); + break; + } + } + + /* Do relax(). */ + { + unsigned long max_iterations; + + /* Cumulative address adjustment. */ + offsetT stretch; + + /* Have we made any adjustment this pass? We can't just test + stretch because one piece of code may have grown and another + shrank. */ + int stretched; + + /* Most horrible, but gcc may give us some exception data that + is impossible to assemble, of the form + + .align 4 + .byte 0, 0 + .uleb128 end - start + start: + .space 128*128 - 1 + .align 4 + end: + + If the leb128 is two bytes in size, then end-start is 128*128, + which requires a three byte leb128. If the leb128 is three + bytes in size, then end-start is 128*128-1, which requires a + two byte leb128. We work around this dilemma by inserting + an extra 4 bytes of alignment just after the .align. This + works because the data after the align is accessed relative to + the end label. + + This counter is used in a tiny state machine to detect + whether a leb128 followed by an align is impossible to + relax. */ + int rs_leb128_fudge = 0; + + /* We want to prevent going into an infinite loop where one frag grows + depending upon the location of a symbol which is in turn moved by + the growing frag. eg: + + foo = . + .org foo+16 + foo = . + + So we dictate that this algorithm can be at most O2. */ + max_iterations = frag_count * frag_count; + /* Check for overflow. */ + if (max_iterations < frag_count) + max_iterations = frag_count; + + ret = 0; + do + { + stretch = 0; + stretched = 0; + + for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) + { + offsetT growth = 0; + addressT was_address; + offsetT offset; + symbolS *symbolP; + + fragP->relax_marker ^= 1; + was_address = fragP->fr_address; + address = fragP->fr_address += stretch; + symbolP = fragP->fr_symbol; + offset = fragP->fr_offset; + + switch (fragP->fr_type) + { + case rs_fill: /* .fill never relaxes. */ + growth = 0; + break; + +#ifndef WORKING_DOT_WORD + /* JF: This is RMS's idea. I do *NOT* want to be blamed + for it I do not want to write it. I do not want to have + anything to do with it. This is not the proper way to + implement this misfeature. */ + case rs_broken_word: + { + struct broken_word *lie; + struct broken_word *untruth; + + /* Yes this is ugly (storing the broken_word pointer + in the symbol slot). Still, this whole chunk of + code is ugly, and I don't feel like doing anything + about it. Think of it as stubbornness in action. */ + growth = 0; + for (lie = (struct broken_word *) (fragP->fr_symbol); + lie && lie->dispfrag == fragP; + lie = lie->next_broken_word) + { + + if (lie->added) + continue; + + offset = (S_GET_VALUE (lie->add) + + lie->addnum + - S_GET_VALUE (lie->sub)); + if (offset <= -32768 || offset >= 32767) + { + if (flag_warn_displacement) + { + char buf[50]; + sprint_value (buf, (addressT) lie->addnum); + as_warn_where (fragP->fr_file, fragP->fr_line, + _(".word %s-%s+%s didn't fit"), + S_GET_NAME (lie->add), + S_GET_NAME (lie->sub), + buf); + } + if (fragP->fr_subtype == 0) + { + fragP->fr_subtype++; + growth += md_short_jump_size; + } + + /* Redirect *all* words of this table with the same + target, lest we have to handle the case where the + same target but with a offset that fits on this + round overflows at the next relaxation round. */ + for (untruth = (struct broken_word *) (fragP->fr_symbol); + untruth && untruth->dispfrag == lie->dispfrag; + untruth = untruth->next_broken_word) + if ((symbol_get_frag (untruth->add) + == symbol_get_frag (lie->add)) + && (S_GET_VALUE (untruth->add) + == S_GET_VALUE (lie->add))) + { + untruth->added = 2; + untruth->use_jump = lie; + } + + lie->added = 1; + growth += md_long_jump_size; + } + } + + break; + } /* case rs_broken_word */ +#endif + case rs_align: + case rs_align_code: + case rs_align_test: + { + addressT oldoff, newoff; + + oldoff = relax_align (was_address + fragP->fr_fix, + (int) offset); + newoff = relax_align (address + fragP->fr_fix, + (int) offset); + + if (fragP->fr_subtype != 0) + { + if (oldoff > fragP->fr_subtype) + oldoff = 0; + if (newoff > fragP->fr_subtype) + newoff = 0; + } + + growth = newoff - oldoff; + + /* If this align happens to follow a leb128 and + we have determined that the leb128 is bouncing + in size, then break the cycle by inserting an + extra alignment. */ + if (growth < 0 + && (rs_leb128_fudge & 16) != 0 + && (rs_leb128_fudge & 15) >= 2) + { + segment_info_type *seginfo = seg_info (segment); + struct obstack *ob = &seginfo->frchainP->frch_obstack; + struct frag *newf; + + newf = frag_alloc (ob); + obstack_blank_fast (ob, fragP->fr_var); + obstack_finish (ob); + memcpy (newf, fragP, SIZEOF_STRUCT_FRAG); + memcpy (newf->fr_literal, + fragP->fr_literal + fragP->fr_fix, + fragP->fr_var); + newf->fr_type = rs_fill; + newf->fr_address = address + fragP->fr_fix + newoff; + newf->fr_fix = 0; + newf->fr_offset = (((offsetT) 1 << fragP->fr_offset) + / fragP->fr_var); + if (newf->fr_offset * newf->fr_var + != (offsetT) 1 << fragP->fr_offset) + { + newf->fr_offset = (offsetT) 1 << fragP->fr_offset; + newf->fr_var = 1; + } + /* Include size of new frag in GROWTH. */ + growth += newf->fr_offset * newf->fr_var; + /* Adjust the new frag address for the amount + we'll add when we process the new frag. */ + newf->fr_address -= stretch + growth; + newf->relax_marker ^= 1; + fragP->fr_next = newf; +#ifdef DEBUG + as_warn (_("padding added")); +#endif + } + } + break; + + case rs_org: + { + addressT target = offset; + addressT after; + + if (symbolP) + { + /* Convert from an actual address to an octet offset + into the section. Here it is assumed that the + section's VMA is zero, and can omit subtracting it + from the symbol's value to get the address offset. */ + know (S_GET_SEGMENT (symbolP)->vma == 0); + target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE; + } + + know (fragP->fr_next); + after = fragP->fr_next->fr_address + stretch; + growth = target - after; + if (growth < 0) + { + growth = 0; + + /* Don't error on first few frag relax passes. + The symbol might be an expression involving + symbol values from other sections. If those + sections have not yet been processed their + frags will all have zero addresses, so we + will calculate incorrect values for them. The + number of passes we allow before giving an + error is somewhat arbitrary. It should be at + least one, with larger values requiring + increasingly contrived dependencies between + frags to trigger a false error. */ + if (pass < 2) + { + /* Force another pass. */ + ret = 1; + break; + } + + /* Growth may be negative, but variable part of frag + cannot have fewer than 0 chars. That is, we can't + .org backwards. */ + as_bad_where (fragP->fr_file, fragP->fr_line, + _("attempt to move .org backwards")); + + /* We've issued an error message. Change the + frag to avoid cascading errors. */ + fragP->fr_type = rs_align; + fragP->fr_subtype = 0; + fragP->fr_offset = 0; + fragP->fr_fix = after - address; + } + } + break; + + case rs_space: + growth = 0; + if (symbolP) + { + offsetT amount; + + amount = S_GET_VALUE (symbolP); + if (S_GET_SEGMENT (symbolP) != absolute_section + || S_IS_COMMON (symbolP) + || ! S_IS_DEFINED (symbolP)) + { + as_bad_where (fragP->fr_file, fragP->fr_line, + _(".space specifies non-absolute value")); + /* Prevent repeat of this error message. */ + fragP->fr_symbol = 0; + } + else if (amount < 0) + { + /* Don't error on first few frag relax passes. + See rs_org comment for a longer explanation. */ + if (pass < 2) + { + ret = 1; + break; + } + + as_warn_where (fragP->fr_file, fragP->fr_line, + _(".space or .fill with negative value, ignored")); + fragP->fr_symbol = 0; + } + else + growth = (was_address + fragP->fr_fix + amount + - fragP->fr_next->fr_address); + } + break; + + case rs_machine_dependent: +#ifdef md_relax_frag + growth = md_relax_frag (segment, fragP, stretch); +#else +#ifdef TC_GENERIC_RELAX_TABLE + /* The default way to relax a frag is to look through + TC_GENERIC_RELAX_TABLE. */ + growth = relax_frag (segment, fragP, stretch); +#endif /* TC_GENERIC_RELAX_TABLE */ +#endif + break; + + case rs_leb128: + { + valueT value; + offsetT size; + + value = resolve_symbol_value (fragP->fr_symbol); + size = sizeof_leb128 (value, fragP->fr_subtype); + growth = size - fragP->fr_offset; + fragP->fr_offset = size; + } + break; + + case rs_cfa: + growth = eh_frame_relax_frag (fragP); + break; + + case rs_dwarf2dbg: + growth = dwarf2dbg_relax_frag (fragP); + break; + + default: + BAD_CASE (fragP->fr_type); + break; + } + if (growth) + { + stretch += growth; + stretched = 1; + if (fragP->fr_type == rs_leb128) + rs_leb128_fudge += 16; + else if (fragP->fr_type == rs_align + && (rs_leb128_fudge & 16) != 0 + && stretch == 0) + rs_leb128_fudge += 16; + else + rs_leb128_fudge = 0; + } + } + + if (stretch == 0 + && (rs_leb128_fudge & 16) == 0 + && (rs_leb128_fudge & -16) != 0) + rs_leb128_fudge += 1; + else + rs_leb128_fudge = 0; + } + /* Until nothing further to relax. */ + while (stretched && -- max_iterations); + + if (stretched) + as_fatal (_("Infinite loop encountered whilst attempting to compute the addresses of symbols in section %s"), + segment_name (segment)); + } + + for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) + if (fragP->last_fr_address != fragP->fr_address) + { + fragP->last_fr_address = fragP->fr_address; + ret = 1; + } + return ret; +} + +void +number_to_chars_bigendian (char *buf, valueT val, int n) +{ + if (n <= 0) + abort (); + while (n--) + { + buf[n] = val & 0xff; + val >>= 8; + } +} + +void +number_to_chars_littleendian (char *buf, valueT val, int n) +{ + if (n <= 0) + abort (); + while (n--) + { + *buf++ = val & 0xff; + val >>= 8; + } +} + +void +write_print_statistics (FILE *file) +{ + fprintf (file, "fixups: %d\n", n_fixups); +} + +/* For debugging. */ +extern int indent_level; + +void +print_fixup (fixS *fixp) +{ + indent_level = 1; + fprintf (stderr, "fix "); + fprintf_vma (stderr, (bfd_vma)((bfd_hostptr_t) fixp)); + fprintf (stderr, " %s:%d",fixp->fx_file, fixp->fx_line); + if (fixp->fx_pcrel) + fprintf (stderr, " pcrel"); + if (fixp->fx_pcrel_adjust) + fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust); + if (fixp->fx_im_disp) + { +#ifdef TC_NS32K + fprintf (stderr, " im_disp=%d", fixp->fx_im_disp); +#else + fprintf (stderr, " im_disp"); +#endif + } + if (fixp->fx_tcbit) + fprintf (stderr, " tcbit"); + if (fixp->fx_done) + fprintf (stderr, " done"); + fprintf (stderr, "\n size=%d frag=", fixp->fx_size); + fprintf_vma (stderr, (bfd_vma) ((bfd_hostptr_t) fixp->fx_frag)); + fprintf (stderr, " where=%ld offset=%lx addnumber=%lx", + (long) fixp->fx_where, + (unsigned long) fixp->fx_offset, + (unsigned long) fixp->fx_addnumber); + fprintf (stderr, "\n %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type), + fixp->fx_r_type); + if (fixp->fx_addsy) + { + fprintf (stderr, "\n +<"); + print_symbol_value_1 (stderr, fixp->fx_addsy); + fprintf (stderr, ">"); + } + if (fixp->fx_subsy) + { + fprintf (stderr, "\n -<"); + print_symbol_value_1 (stderr, fixp->fx_subsy); + fprintf (stderr, ">"); + } + fprintf (stderr, "\n"); +#ifdef TC_FIX_DATA_PRINT + TC_FIX_DATA_PRINT (stderr, fixp); +#endif +} diff --git a/contrib/toolchain/binutils/gas/write.h b/contrib/toolchain/binutils/gas/write.h new file mode 100644 index 0000000000..36de533b32 --- /dev/null +++ b/contrib/toolchain/binutils/gas/write.h @@ -0,0 +1,191 @@ +/* write.h + Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, + 2002, 2003, 2005, 2006, 2007 + 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef __write_h__ +#define __write_h__ + +/* This is the name of a fake symbol which will never appear in the + assembler output. S_IS_LOCAL detects it because of the \001. */ +#ifndef FAKE_LABEL_NAME +#define FAKE_LABEL_NAME "L0\001" +#endif + +#include "bit_fix.h" + +/* + * FixSs may be built up in any order. + */ + +struct fix +{ + /* These small fields are grouped together for compactness of + this structure, and efficiency of access on some architectures. */ + + /* Is this a pc-relative relocation? */ + unsigned fx_pcrel : 1; + + /* Is this value an immediate displacement? */ + /* Only used on ns32k; merge it into TC_FIX_TYPE sometime. */ + unsigned fx_im_disp : 2; + + /* Some bits for the CPU specific code. */ + unsigned fx_tcbit : 1; + unsigned fx_tcbit2 : 1; + + /* Has this relocation already been applied? */ + unsigned fx_done : 1; + + /* Suppress overflow complaints on large addends. This is used + in the PowerPC ELF config to allow large addends on the + BFD_RELOC_{LO16,HI16,HI16_S} relocations. + + @@ Can this be determined from BFD? */ + unsigned fx_no_overflow : 1; + + /* The value is signed when checking for overflow. */ + unsigned fx_signed : 1; + + /* pc-relative offset adjust (only used by some CPU specific code) */ + signed char fx_pcrel_adjust; + + /* How many bytes are involved? */ + unsigned char fx_size; + + /* Which frag does this fix apply to? */ + fragS *fx_frag; + + /* Where is the first byte to fix up? */ + long fx_where; + + /* NULL or Symbol whose value we add in. */ + symbolS *fx_addsy; + + /* NULL or Symbol whose value we subtract. */ + symbolS *fx_subsy; + + /* Absolute number we add in. */ + valueT fx_offset; + + /* The value of dot when the fixup expression was parsed. */ + addressT fx_dot_value; + + /* The frag fx_dot_value is based on. */ + fragS *fx_dot_frag; + + /* Next fixS in linked list, or NULL. */ + struct fix *fx_next; + + /* If NULL, no bitfix's to do. */ + /* Only i960-coff and ns32k use this, and i960-coff stores an + integer. This can probably be folded into tc_fix_data, below. + @@ Alpha also uses it, but only to disable certain relocation + processing. */ + bit_fixS *fx_bit_fixP; + + bfd_reloc_code_real_type fx_r_type; + + /* This field is sort of misnamed. It appears to be a sort of random + scratch field, for use by the back ends. The main gas code doesn't + do anything but initialize it to zero. The use of it does need to + be coordinated between the cpu and format files, though. E.g., some + coff targets pass the `addend' field from the cpu file via this + field. I don't know why the `fx_offset' field above can't be used + for that; investigate later and document. KR */ + valueT fx_addnumber; + + /* The location of the instruction which created the reloc, used + in error messages. */ + char *fx_file; + unsigned fx_line; + +#ifdef USING_CGEN + struct { + /* CGEN_INSN entry for this instruction. */ + const struct cgen_insn *insn; + /* Target specific data, usually reloc number. */ + int opinfo; + /* Which ifield this fixup applies to. */ + struct cgen_maybe_multi_ifield * field; + /* is this field is the MSB field in a set? */ + int msb_field_p; + } fx_cgen; +#endif + +#ifdef TC_FIX_TYPE + /* Location where a backend can attach additional data + needed to perform fixups. */ + TC_FIX_TYPE tc_fix_data; +#endif +}; + +typedef struct fix fixS; + +struct reloc_list +{ + struct reloc_list *next; + union + { + struct + { + symbolS *offset_sym; + reloc_howto_type *howto; + symbolS *sym; + bfd_vma addend; + } a; + struct + { + asection *sec; + asymbol *s; + arelent r; + } b; + } u; + char *file; + unsigned int line; +}; + +extern int finalize_syms; +extern symbolS *abs_section_sym; +extern addressT dot_value; +extern fragS *dot_frag; +extern struct reloc_list* reloc_list; + +extern void append (char **charPP, char *fromP, unsigned long length); +extern void record_alignment (segT seg, int align); +extern int get_recorded_alignment (segT seg); +extern void subsegs_finish (void); +extern void write_object_file (void); +extern long relax_frag (segT, fragS *, long); +extern int relax_segment (struct frag *, segT, int); +extern void number_to_chars_littleendian (char *, valueT, int); +extern void number_to_chars_bigendian (char *, valueT, int); +extern fixS *fix_new + (fragS * frag, int where, int size, symbolS * add_symbol, + offsetT offset, int pcrel, bfd_reloc_code_real_type r_type); +extern fixS *fix_at_start + (fragS * frag, int size, symbolS * add_symbol, + offsetT offset, int pcrel, bfd_reloc_code_real_type r_type); +extern fixS *fix_new_exp + (fragS * frag, int where, int size, expressionS *exp, int pcrel, + bfd_reloc_code_real_type r_type); +extern void write_print_statistics (FILE *); + +#endif /* __write_h__ */