Index: gnu/gdb/gdb/ChangeLog.linux diff -u gnu/gdb/gdb/ChangeLog.linux:1.14 gnu/gdb/gdb/ChangeLog.linux:1.17 --- gnu/gdb/gdb/ChangeLog.linux:1.14 Tue Feb 16 15:51:07 1999 +++ gnu/gdb/gdb/ChangeLog.linux Sun May 9 07:41:21 1999 @@ -1,3 +1,22 @@ +Wed May 5 16:36:36 1999 H.J. Lu + + * Makefile.in (VERSION): Updated to "4.17.0.12 with Linux + support". + + * config/i386/linux.mh (NATDEPFILES): Add lnx-thread.o and + lnx-nat.o. + + * config/powerpc/nm-linux.h: Include "nm-linux.h". + + * config/powerpc/tm-linux.h: Include "tm-linux.h". + +Wed Mar 17 19:49:22 1999 Sam Lantinga (slouken@devolution.com) + + * solib.h, solib.c, infrun.c: Added function check_solib_consistency() + to reload list of shared objects when they are added or deleted. + This fixed crashing when the program being debugged unloaded a + dynamic library and added a new library afterwards. + Sat Feb 13 05:42:33 1999 H.J. Lu * Makefile.in (VERSION): Updated to "4.17.0.11 with Linux @@ -29,11 +48,11 @@ * config/nm-linux.h: New. * config/i386/nm-linux.h: Include "nm-linux.h". - * config/alpha/tm-alphalinux.h: Likewise. + * config/alpha/nm-alphalinux.h: Likewise. * config/tm-linux.h: New. * config/i386/tm-linux.h: Include "tm-linux.h". - * config/alpha/nm-linux.h: Likewise. + * config/alpha/tm-linux.h: Likewise. Wed Feb 10 02:39:07 1999 Hannes Reinecke @@ -191,7 +210,7 @@ * config/i386/linux.mt (MT_CFLAGS): Set to -D_GNU_SOURCE. - From RedHat 5.2: + From Eric Paire : * lnx-thread.c: New. Index: gnu/gdb/gdb/Makefile.in diff -u gnu/gdb/gdb/Makefile.in:1.13 gnu/gdb/gdb/Makefile.in:1.14 --- gnu/gdb/gdb/Makefile.in:1.13 Tue Feb 16 15:51:07 1999 +++ gnu/gdb/gdb/Makefile.in Wed May 5 16:32:59 1999 @@ -187,7 +187,7 @@ ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) -VERSION=4.17.0.11 with Linux support +VERSION=4.17.0.12 with Linux support DIST=gdb LINT=/usr/5bin/lint Index: gnu/gdb/gdb/i386lnx-nat.c diff -u gnu/gdb/gdb/i386lnx-nat.c:1.8 gnu/gdb/gdb/i386lnx-nat.c:1.9 --- gnu/gdb/gdb/i386lnx-nat.c:1.8 Tue Feb 16 15:51:07 1999 +++ gnu/gdb/gdb/i386lnx-nat.c Wed May 5 16:32:59 1999 @@ -1,5 +1,5 @@ /* Intel 386 native support for Linux - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1999 Free Software Foundation, Inc. This file is part of GDB. Index: gnu/gdb/gdb/infrun.c diff -u gnu/gdb/gdb/infrun.c:1.2 gnu/gdb/gdb/infrun.c:1.3 --- gnu/gdb/gdb/infrun.c:1.2 Tue Dec 1 21:52:01 1998 +++ gnu/gdb/gdb/infrun.c Sun May 9 07:41:21 1999 @@ -1188,6 +1188,9 @@ /* Switch terminal for any messages produced by breakpoint_re_set. */ target_terminal_ours_for_output (); +#ifdef CHECK_SOLIB_CONSISTENCY + CHECK_SOLIB_CONSISTENCY(); +#endif SOLIB_ADD (NULL, 0, NULL); target_terminal_inferior (); } Index: gnu/gdb/gdb/solib.c diff -u gnu/gdb/gdb/solib.c:1.2 gnu/gdb/gdb/solib.c:1.3 --- gnu/gdb/gdb/solib.c:1.2 Sun Dec 20 11:25:27 1998 +++ gnu/gdb/gdb/solib.c Sun May 9 07:41:21 1999 @@ -884,6 +884,40 @@ /* +GLOBAL FUNCTION + + check_solib_consistency -- check solib list consistency + +SYNOPSIS + + void check_solib_consistency (void) + +DESCRIPTION + + This module is called whenever we hit a dynamic linker breakpoint + and allows us to check the consistency of our shared object list. + Without this, dynamic unlinking of objects could crash us. + */ + +void +check_solib_consistency (void) +{ + +#ifdef SVR4_SHARED_LIBS + + if ( debug_base ) { + read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug)); + /* If the shared object state is consistent, we can reload our list */ + if ( debug_copy.r_state == RT_CONSISTENT ) + clear_solib(); + } + +#endif /* SVR4_SHARED_LIBS */ + +} + +/* + LOCAL FUNCTION find_solib -- step through list of shared objects Index: gnu/gdb/gdb/solib.h diff -u gnu/gdb/gdb/solib.h:1.1.1.1 gnu/gdb/gdb/solib.h:1.2 --- gnu/gdb/gdb/solib.h:1.1.1.1 Fri May 29 06:57:38 1998 +++ gnu/gdb/gdb/solib.h Sun May 9 07:41:21 1999 @@ -55,6 +55,10 @@ extern char * solib_address PARAMS ((CORE_ADDR)); /* solib.c */ +/* Check shared library consistency */ + +#define CHECK_SOLIB_CONSISTENCY() check_solib_consistency() + /* If ADDR lies in a shared library, return its name. */ #define PC_SOLIB(addr) solib_address (addr) Index: gnu/gdb/gdb/config/powerpc/linux.mh diff -u gnu/gdb/gdb/config/powerpc/linux.mh:1.3 gnu/gdb/gdb/config/powerpc/linux.mh:1.4 --- gnu/gdb/gdb/config/powerpc/linux.mh:1.3 Sun Dec 20 11:25:28 1998 +++ gnu/gdb/gdb/config/powerpc/linux.mh Wed May 5 16:32:59 1999 @@ -10,7 +10,7 @@ NAT_FILE= nm-linux.h NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o \ - core-aout.o core-regset.o ppclnx-nat.o + core-aout.o core-regset.o ppclnx-nat.o lnx-thread.o lnx-nat.o GDBSERVER_DEPFILES= low-linux.o Index: gnu/gdb/gdb/config/powerpc/nm-linux.h diff -u gnu/gdb/gdb/config/powerpc/nm-linux.h:1.1 gnu/gdb/gdb/config/powerpc/nm-linux.h:1.2 --- gnu/gdb/gdb/config/powerpc/nm-linux.h:1.1 Tue Dec 1 21:52:02 1998 +++ gnu/gdb/gdb/config/powerpc/nm-linux.h Wed May 5 16:32:59 1999 @@ -20,6 +20,8 @@ #ifndef NM_LINUX_H #define NM_LINUX_H +#include "nm-linux.h" + /* Return sizeof user struct to callers in less machine dependent routines */ #define KERNEL_U_SIZE kernel_u_size() Index: gnu/gdb/gdb/config/powerpc/tm-linux.h diff -u gnu/gdb/gdb/config/powerpc/tm-linux.h:1.1 gnu/gdb/gdb/config/powerpc/tm-linux.h:1.2 --- gnu/gdb/gdb/config/powerpc/tm-linux.h:1.1 Tue Dec 1 21:52:02 1998 +++ gnu/gdb/gdb/config/powerpc/tm-linux.h Wed May 5 16:32:59 1999 @@ -21,6 +21,7 @@ #define TM_LINUX_H #include "powerpc/tm-ppc-eabi.h" +#include "tm-linux.h" /* We can single step on linux */ #undef NO_SINGLE_STEP Index: gnu/gdb/opcodes/ChangeLog.linux diff -u gnu/gdb/opcodes/ChangeLog.linux:1.1 gnu/gdb/opcodes/ChangeLog.linux:1.2 --- gnu/gdb/opcodes/ChangeLog.linux:1.1 Tue Dec 1 21:52:03 1998 +++ gnu/gdb/opcodes/ChangeLog.linux Wed May 5 16:32:59 1999 @@ -1,3 +1,8 @@ +Mon Apr 26 17:25:49 1999 H.J. Lu (hjl@gnu.org) + + * i386-dis.c (print_insn_x86): Update from binutils 2.9.1.0.24 + for Pentium/III and AMD 3DNow!. + Tue Dec 1 19:24:37 1998 H.J. Lu (hjl@gnu.org) From Jack Howarth : Index: gnu/gdb/opcodes/i386-dis.c diff -u gnu/gdb/opcodes/i386-dis.c:1.1.1.1 gnu/gdb/opcodes/i386-dis.c:1.2 --- gnu/gdb/opcodes/i386-dis.c:1.1.1.1 Fri May 29 06:58:29 1998 +++ gnu/gdb/opcodes/i386-dis.c Wed May 5 16:32:59 1999 @@ -1,5 +1,5 @@ /* Print i386 instructions for GDB, the GNU debugger. - Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 1997 + Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. This file is part of GDB. @@ -39,6 +39,7 @@ #define MAXLEN 20 #include +#include static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *)); @@ -51,6 +52,22 @@ jmp_buf bailout; }; +#define PREFIX_REPZ 1 +#define PREFIX_REPNZ 2 +#define PREFIX_LOCK 4 +#define PREFIX_CS 8 +#define PREFIX_SS 0x10 +#define PREFIX_DS 0x20 +#define PREFIX_ES 0x40 +#define PREFIX_FS 0x80 +#define PREFIX_GS 0x100 +#define PREFIX_DATA 0x200 +#define PREFIX_ADR 0x400 +#define PREFIX_FWAIT 0x800 +#define INSN_FWAIT 0x1000 + +static int prefixes; + /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) to ADDR (exclusive) are valid. Returns 1 for success, longjmps on error. */ @@ -73,8 +90,17 @@ info); if (status != 0) { - (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + if ((prefixes & PREFIX_FWAIT) == PREFIX_FWAIT && status == EIO) + { + /* It is possible that fwait is the last instruction. We make + it an instruction. */ + prefixes = INSN_FWAIT; + return 0; + } + else { + (*info->memory_error_func) (status, start, info); + longjmp (priv->bailout, 1); + } } else priv->max_fetched = addr; @@ -129,7 +155,9 @@ #define Sw OP_SEG, w_mode #define Ap OP_DIR, lptr +#if 0 #define Av OP_DIR, v_mode +#endif #define Ob OP_OFF, b_mode #define Ov OP_OFF, v_mode #define Xb OP_DSSI, b_mode @@ -145,8 +173,14 @@ #define gs OP_REG, gs_reg #define MX OP_MMX, 0 +#define XM OP_XMM, 0 #define EM OP_EM, v_mode +#define EX OP_EX, v_mode #define MS OP_MS, b_mode +#define None OP_None, 0 +#define TD OP_3DNow, 0 +#define SUF OP_3DNowSuffix, 0 +#define PF OP_PREFETCH, b_mode typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag)); @@ -172,8 +206,14 @@ static int OP_ONE PARAMS ((int, int, int)); #endif static int OP_MMX PARAMS ((int, int, int)); +static int OP_XMM PARAMS ((int, int, int)); static int OP_EM PARAMS ((int, int, int)); +static int OP_EX PARAMS ((int, int, int)); static int OP_MS PARAMS ((int, int, int)); +static int OP_None PARAMS ((int, int, int)); +static int OP_3DNow PARAMS ((int, int, int)); +static int OP_3DNowSuffix PARAMS ((int, int, int)); +static int OP_PREFETCH PARAMS ((int, int, int)); static void append_prefix PARAMS ((void)); static void set_op PARAMS ((int op)); @@ -225,27 +265,48 @@ #define indir_dx_reg 150 -#define GRP1b NULL, NULL, 0 -#define GRP1S NULL, NULL, 1 -#define GRP1Ss NULL, NULL, 2 -#define GRP2b NULL, NULL, 3 -#define GRP2S NULL, NULL, 4 -#define GRP2b_one NULL, NULL, 5 -#define GRP2S_one NULL, NULL, 6 -#define GRP2b_cl NULL, NULL, 7 -#define GRP2S_cl NULL, NULL, 8 -#define GRP3b NULL, NULL, 9 -#define GRP3S NULL, NULL, 10 -#define GRP4 NULL, NULL, 11 -#define GRP5 NULL, NULL, 12 -#define GRP6 NULL, NULL, 13 -#define GRP7 NULL, NULL, 14 -#define GRP8 NULL, NULL, 15 -#define GRP9 NULL, NULL, 16 -#define GRP10 NULL, NULL, 17 -#define GRP11 NULL, NULL, 18 -#define GRP12 NULL, NULL, 19 +#define USE_GROUPS 1 +#define USE_PREFIX_USER_TABLE 2 +#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS +#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS +#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS +#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS +#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS +#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS +#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS +#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS +#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS +#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS +#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS +#define GRP4 NULL, NULL, 11, NULL, USE_GROUPS +#define GRP5 NULL, NULL, 12, NULL, USE_GROUPS +#define GRP6 NULL, NULL, 13, NULL, USE_GROUPS +#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS +#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS +#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS +#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS +#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS +#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS +#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS +#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS + +#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE +#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE +#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE +#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE +#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE +#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE +#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE +#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE +#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE +#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE +#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE +#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE +#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE +#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE +#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE + #define FLOATCODE 50 #define FLOAT NULL, NULL, FLOATCODE @@ -369,8 +430,8 @@ { "popS", eSI }, { "popS", eDI }, /* 60 */ - { "pusha" }, - { "popa" }, + { "pushaS" }, + { "popaS" }, { "boundS", Gv, Ma }, { "arpl", Ew, Gw }, { "(bad)" }, /* seg fs */ @@ -418,9 +479,9 @@ { "movS", Ev, Gv }, { "movb", Gb, Eb }, { "movS", Gv, Ev }, - { "movw", Ew, Sw }, + { "movS", Ev, Sw }, { "leaS", Gv, M }, - { "movw", Sw, Ew }, + { "movS", Sw, Ev }, { "popS", Ev }, /* 90 */ { "nop" }, @@ -522,7 +583,7 @@ { "outb", Ib, AL }, { "outS", Ib, eAX }, /* e8 */ - { "call", Av }, + { "call", Jv }, { "jmp", Jv }, { "ljmp", Ap }, { "jmp", Jb }, @@ -564,12 +625,19 @@ { "invd" }, { "wbinvd" }, { "(bad)" }, { "ud2a" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "(bad)" }, { "prefetch", PF }, { "femms" }, { "3dnow", TD, EM, SUF }, /* 10 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP8 }, + { PREGRP9 }, + { "movlps", XM, Ev }, + { "movlps", Ev, XM }, + { "unpcklps", XM, EX }, + { "unpckhps", XM, EX }, + { "movhps", XM, Ev }, + { "movhps", Ev, XM }, /* 18 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { GRP14 }, + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, /* 20 */ /* these are all backward in appendix A of the intel book */ @@ -582,11 +650,17 @@ { "movl", Td, Rd }, { "(bad)" }, /* 28 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movaps", XM, EX }, + { "movaps", EX, XM }, + { PREGRP2 }, + { "movntps", Ev, XM }, + { PREGRP4 }, + { PREGRP3 }, + { "ucomiss", XM, EX }, + { "comiss", XM, EX }, /* 30 */ { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" }, /* 38 */ { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, @@ -597,11 +671,23 @@ { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev }, { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev }, /* 50 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { "movmskps", Ev, XM }, + { PREGRP13 }, + { PREGRP12 }, + { PREGRP11 }, + { "andps", XM, EX }, + { "andnps", XM, EX }, + { "orps", XM, EX }, + { "xorps", XM, EX }, /* 58 */ - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, + { PREGRP0 }, + { PREGRP10 }, + { "(bad)" }, + { "(bad)" }, + { PREGRP14 }, + { PREGRP7 }, + { PREGRP5 }, + { PREGRP6 }, /* 60 */ { "punpcklbw", MX, EM }, { "punpcklwd", MX, EM }, @@ -620,7 +706,7 @@ { "movd", MX, Ev }, { "movq", MX, EM }, /* 70 */ - { "(bad)" }, + { "pshufw", MX, EM, Ib }, { GRP10 }, { GRP11 }, { GRP12 }, @@ -685,7 +771,7 @@ { "btsS", Ev, Gv }, { "shrdS", Ev, Gv, Ib }, { "shrdS", Ev, Gv, CL }, - { "(bad)" }, + { GRP13 }, { "imulS", Gv, Ev }, /* b0 */ { "cmpxchgb", Eb, Gb }, @@ -708,11 +794,11 @@ /* c0 */ { "xaddb", Eb, Gb }, { "xaddS", Ev, Gv }, - { "(bad)" }, + { PREGRP1 }, { "(bad)" }, - { "(bad)" }, - { "(bad)" }, - { "(bad)" }, + { "pinsrw", MX, Ev, Ib }, + { "pextrw", Ev, MX, Ib }, + { "shufps", XM, EX, Ib }, { GRP9 }, /* c8 */ { "bswap", eAX }, @@ -730,32 +816,34 @@ { "psrlq", MX, EM }, { "(bad)" }, { "pmullw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "pmovmskb", Ev, MX }, /* d8 */ { "psubusb", MX, EM }, { "psubusw", MX, EM }, - { "(bad)" }, + { "pminub", MX, EM }, { "pand", MX, EM }, { "paddusb", MX, EM }, { "paddusw", MX, EM }, - { "(bad)" }, + { "pmaxub", MX, EM }, { "pandn", MX, EM }, /* e0 */ - { "(bad)" }, + { "pavgb", MX, EM }, { "psraw", MX, EM }, { "psrad", MX, EM }, - { "(bad)" }, - { "(bad)" }, + { "pavgw", MX, EM }, + { "pmulhuw", MX, EM }, { "pmulhw", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "(bad)" }, + { "movntq", Ev, MX }, /* e8 */ { "psubsb", MX, EM }, { "psubsw", MX, EM }, - { "(bad)" }, + { "pminsw", MX, EM }, { "por", MX, EM }, { "paddsb", MX, EM }, { "paddsw", MX, EM }, - { "(bad)" }, + { "pmaxsw", MX, EM }, { "pxor", MX, EM }, /* f0 */ { "(bad)" }, @@ -764,7 +852,8 @@ { "psllq", MX, EM }, { "(bad)" }, { "pmaddwd", MX, EM }, - { "(bad)" }, { "(bad)" }, + { "psadbw", MX, EM }, + { "maskmovq", MX, EM }, /* f8 */ { "psubb", MX, EM }, { "psubw", MX, EM }, @@ -796,22 +885,49 @@ }; static const unsigned char twobyte_has_modrm[256] = { - /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ - /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */ - /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ + /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ - /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */ + /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */ - /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */ + /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ - /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */ - /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */ - /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */ + /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */ + /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */ + /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +}; + +static const unsigned char twobyte_uses_f3_prefix[256] = { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ + /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */ + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ + /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */ + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */ + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */ + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ + /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */ + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */ + /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */ + /* ------------------------------- */ + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ }; static char obuf[100]; @@ -1061,29 +1177,125 @@ { "(bad)" }, { "psllq", MS, Ib }, { "(bad)" }, + }, + /* GRP13 */ + { + { "fxsave", Ev }, + { "fxrstor", Ev }, + { "ldmxcsr", Ev }, + { "stmxcsr", Ev }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "sfence", None }, + }, + /* GRP14 */ + { + { "prefetchnta", Ev }, + { "prefetcht0", Ev }, + { "prefetcht1", Ev }, + { "prefetcht2", Ev }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, + { "(bad)" }, } }; -#define PREFIX_REPZ 1 -#define PREFIX_REPNZ 2 -#define PREFIX_LOCK 4 -#define PREFIX_CS 8 -#define PREFIX_SS 0x10 -#define PREFIX_DS 0x20 -#define PREFIX_ES 0x40 -#define PREFIX_FS 0x80 -#define PREFIX_GS 0x100 -#define PREFIX_DATA 0x200 -#define PREFIX_ADR 0x400 -#define PREFIX_FWAIT 0x800 +static const char *simd_cmp_op [] = { + "eq", + "lt", + "le", + "unord", + "neq", + "nlt", + "nle", + "ord" +}; -static int prefixes; +static struct dis386 prefix_user_table[][2] = { + /* PREGRP0 */ + { + { "addps", XM, EX }, + { "addss", XM, EX }, + }, + /* PREGRP1 */ + { + { "cmp%sps", XM, EX, Ib }, + { "cmp%sss", XM, EX, Ib }, + }, + /* PREGRP2 */ + { + { "cvtpi2ps", XM, EM }, + { "cvtsi2ss", XM, Ev }, + }, + /* PREGRP3 */ + { + { "cvtps2pi", MX, EX }, + { "cvtss2si", Gv, EX }, + }, + /* PREGRP4 */ + { + { "cvttps2pi", MX, EX }, + { "cvttss2si", Gv, EX }, + }, + /* PREGRP5 */ + { + { "divps", XM, EX }, + { "divss", XM, EX }, + }, + /* PREGRP6 */ + { + { "maxps", XM, EX }, + { "maxss", XM, EX }, + }, + /* PREGRP7 */ + { + { "minps", XM, EX }, + { "minss", XM, EX }, + }, + /* PREGRP8 */ + { + { "movups", XM, EX }, + { "movss", XM, EX }, + }, + /* PREGRP9 */ + { + { "movups", EX, XM }, + { "movss", EX, XM }, + }, + /* PREGRP10 */ + { + { "mulps", XM, EX }, + { "mulss", XM, EX }, + }, + /* PREGRP11 */ + { + { "rcpps", XM, EX }, + { "rcpss", XM, EX }, + }, + /* PREGRP12 */ + { + { "rsqrtps", XM, EX }, + { "rsqrtss", XM, EX }, + }, + /* PREGRP13 */ + { + { "sqrtps", XM, EX }, + { "sqrtss", XM, EX }, + }, + /* PREGRP14 */ + { + { "subps", XM, EX }, + { "subss", XM, EX }, + } +}; static void ckprefix () { prefixes = 0; - while (1) + while (prefixes != INSN_FWAIT) { FETCH_DATA (the_info, codep + 1); switch (*codep) @@ -1164,6 +1376,8 @@ print_insn_x86 (pc, info, aflag, dflag) bfd_vma pc; disassemble_info *info; + int aflag; + int dflag; { struct dis386 *dp; int i; @@ -1171,13 +1385,16 @@ char *first, *second, *third; int needcomma; unsigned char need_modrm; + unsigned char uses_f3_prefix; + unsigned char opcode; + int simd_cmp = 0; struct dis_private priv; bfd_byte *inbuf = priv.the_buffer; - /* The output looks better if we put 5 bytes on a line, since that + /* The output looks better if we put 7 bytes on a line, since that puts long word instructions on a single line. */ - info->bytes_per_line = 5; + info->bytes_per_line = 7; info->private_data = (PTR) &priv; priv.max_fetched = priv.the_buffer; @@ -1200,6 +1417,13 @@ ckprefix (); + if (prefixes == INSN_FWAIT) + { + /* fwait not followed by any instructions */ + (*info->fprintf_func) (info->stream, "fwait"); + return (1); + } + FETCH_DATA (info, codep + 1); if (*codep == 0xc8) enter_instruction = 1; @@ -1207,9 +1431,7 @@ enter_instruction = 0; obufp = obuf; - - if (prefixes & PREFIX_REPZ) - oappend ("repz "); + if (prefixes & PREFIX_REPNZ) oappend ("repnz "); if (prefixes & PREFIX_LOCK) @@ -1240,13 +1462,19 @@ FETCH_DATA (info, codep + 2); dp = &dis386_twobyte[*++codep]; need_modrm = twobyte_has_modrm[*codep]; + uses_f3_prefix = twobyte_uses_f3_prefix[*codep]; } else { dp = &dis386[*codep]; need_modrm = onebyte_has_modrm[*codep]; + uses_f3_prefix = 0; } + opcode = *codep; codep++; + + if (!uses_f3_prefix && (prefixes & PREFIX_REPZ)) + oappend ("repz "); if (need_modrm) { @@ -1263,7 +1491,20 @@ else { if (dp->name == NULL) - dp = &grps[dp->bytemode1][reg]; + { + switch(dp->bytemode2) + { + case USE_GROUPS: + dp = &grps[dp->bytemode1][reg]; + break; + case USE_PREFIX_USER_TABLE: + simd_cmp = dp->bytemode1 == 1; + dp = &prefix_user_table[dp->bytemode1][prefixes & 0x01]; + break; + default: + return(1); + } + } putop (dp->name, aflag, dflag); @@ -1277,10 +1518,19 @@ if (dp->op2) (*dp->op2)(dp->bytemode2, aflag, dflag); - obufp = op3out; - op_ad = 0; - if (dp->op3) - (*dp->op3)(dp->bytemode3, aflag, dflag); + if (simd_cmp) + { + FETCH_DATA (the_info, codep + 1); + sprintf (scratchbuf, obuf, simd_cmp_op [*codep++ & 0xff]); + strcpy (obuf, scratchbuf); + } + else + { + obufp = op3out; + op_ad = 0; + if (dp->op3) + (*dp->op3)(dp->bytemode3, aflag, dflag); + } } obufp = obuf + strlen (obuf); @@ -1641,6 +1891,14 @@ { char *p; + if ((prefixes & PREFIX_FWAIT) && !strchr (template, 'N')) + { + /* We print out fwait if it is not the part of the instuctions. */ +#define FWAIT_STRING "fwait; " + strcat (obufp, FWAIT_STRING); + obufp += sizeof (FWAIT_STRING) - 1; + } + for (p = template; *p; p++) { switch (*p) @@ -1711,6 +1969,20 @@ return OP_E (bytemode, aflag, dflag); } +static int OP_PREFETCH(bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + switch(reg) { + case 1: + obufp=obuf; oappend("prefetchw "); + break; + default: + } + return OP_E (bytemode, aflag, dflag); +} + static int OP_E (bytemode, aflag, dflag) int bytemode; @@ -1753,8 +2025,8 @@ int havesib; int havebase; int base; - int index; - int scale; + int index = 0; + int scale = 0; havesib = 0; havebase = 1; @@ -2095,7 +2367,7 @@ switch (size) { case lptr: - if (aflag) + if (dflag) { offset = get32 (); seg = get16 (); @@ -2108,8 +2380,9 @@ sprintf (scratchbuf, "0x%x,0x%x", seg, offset); oappend (scratchbuf); break; +#if 0 case v_mode: - if (aflag) + if (dflag) offset = get32 (); else { @@ -2123,6 +2396,7 @@ sprintf (scratchbuf, "0x%x", offset); oappend (scratchbuf); break; +#endif default: oappend (""); break; @@ -2171,7 +2445,16 @@ int aflag; int dflag; { - oappend ("%ds:("); + if ((prefixes + & (PREFIX_CS + | PREFIX_DS + | PREFIX_SS + | PREFIX_ES + | PREFIX_FS + | PREFIX_GS)) == 0) + prefixes |= PREFIX_DS; + append_prefix (); + oappend ("("); oappend (aflag ? "%esi" : "%si"); oappend (")"); return (0); @@ -2262,6 +2545,17 @@ } static int +OP_XMM (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + sprintf (scratchbuf, "%%xmm%d", reg); + oappend (scratchbuf); + return 0; +} + +static int OP_EM (bytemode, aflag, dflag) int bytemode; int aflag; @@ -2277,6 +2571,21 @@ } static int +OP_EX (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + if (mod != 3) + return OP_E (bytemode, aflag, dflag); + + codep++; + sprintf (scratchbuf, "%%xmm%d", rm); + oappend (scratchbuf); + return 0; +} + +static int OP_MS (bytemode, aflag, dflag) int bytemode; int aflag; @@ -2285,5 +2594,112 @@ ++codep; sprintf (scratchbuf, "%%mm%d", rm); oappend (scratchbuf); + return 0; +} + +static int +OP_None (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + ++codep; + return 0; +} + +static int +OP_3DNow (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + sprintf (scratchbuf, "%%mm%d", reg); + oappend (scratchbuf); + return 0; +} + +static char *_3DNowSuffixes[]= { +/* 00 */ NULL, NULL, NULL, NULL, +/* 04 */ NULL, NULL, NULL, NULL, +/* 08 */ NULL, NULL, NULL, NULL, +/* 0C */ NULL, "pi2fd", NULL, NULL, +/* 10 */ NULL, NULL, NULL, NULL, +/* 14 */ NULL, NULL, NULL, NULL, +/* 18 */ NULL, NULL, NULL, NULL, +/* 1C */ NULL, "pf2id", NULL, NULL, +/* 20 */ NULL, NULL, NULL, NULL, +/* 24 */ NULL, NULL, NULL, NULL, +/* 28 */ NULL, NULL, NULL, NULL, +/* 2C */ NULL, NULL, NULL, NULL, +/* 30 */ NULL, NULL, NULL, NULL, +/* 34 */ NULL, NULL, NULL, NULL, +/* 38 */ NULL, NULL, NULL, NULL, +/* 3C */ NULL, NULL, NULL, NULL, +/* 40 */ NULL, NULL, NULL, NULL, +/* 44 */ NULL, NULL, NULL, NULL, +/* 48 */ NULL, NULL, NULL, NULL, +/* 4C */ NULL, NULL, NULL, NULL, +/* 50 */ NULL, NULL, NULL, NULL, +/* 54 */ NULL, NULL, NULL, NULL, +/* 58 */ NULL, NULL, NULL, NULL, +/* 5C */ NULL, NULL, NULL, NULL, +/* 60 */ NULL, NULL, NULL, NULL, +/* 64 */ NULL, NULL, NULL, NULL, +/* 68 */ NULL, NULL, NULL, NULL, +/* 6C */ NULL, NULL, NULL, NULL, +/* 70 */ NULL, NULL, NULL, NULL, +/* 74 */ NULL, NULL, NULL, NULL, +/* 78 */ NULL, NULL, NULL, NULL, +/* 7C */ NULL, NULL, NULL, NULL, +/* 80 */ NULL, NULL, NULL, NULL, +/* 84 */ NULL, NULL, NULL, NULL, +/* 88 */ NULL, NULL, NULL, NULL, +/* 8C */ NULL, NULL, NULL, NULL, +/* 90 */ "pfcmpge", NULL, NULL, NULL, +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", +/* 98 */ NULL, NULL, "pfsub", NULL, +/* 9C */ NULL, NULL, "pfadd", NULL, +/* A0 */ "pfcmpgt", NULL, NULL, NULL, +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", +/* A8 */ NULL, NULL, "pfsubr", NULL, +/* AC */ NULL, NULL, "pfacc", NULL, +/* B0 */ "pfcmpeq", NULL, NULL, NULL, +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", +/* B8 */ NULL, NULL, NULL, NULL, +/* BC */ NULL, NULL, NULL, "pavgusb", +/* C0 */ NULL, NULL, NULL, NULL, +/* C4 */ NULL, NULL, NULL, NULL, +/* C8 */ NULL, NULL, NULL, NULL, +/* CC */ NULL, NULL, NULL, NULL, +/* D0 */ NULL, NULL, NULL, NULL, +/* D4 */ NULL, NULL, NULL, NULL, +/* D8 */ NULL, NULL, NULL, NULL, +/* DC */ NULL, NULL, NULL, NULL, +/* E0 */ NULL, NULL, NULL, NULL, +/* E4 */ NULL, NULL, NULL, NULL, +/* E8 */ NULL, NULL, NULL, NULL, +/* EC */ NULL, NULL, NULL, NULL, +/* F0 */ NULL, NULL, NULL, NULL, +/* F4 */ NULL, NULL, NULL, NULL, +/* F8 */ NULL, NULL, NULL, NULL, +/* FC */ NULL, NULL, NULL, NULL, +}; + +static int +OP_3DNowSuffix (bytemode, aflag, dflag) + int bytemode; + int aflag; + int dflag; +{ + FETCH_DATA (the_info, codep + 1); + if (_3DNowSuffixes[*codep]) { + /* HACK */ + obufp=obuf; + oappend(_3DNowSuffixes[*codep++]); + oappend(" "); + } else { + sprintf (scratchbuf, "0x%x", *codep++); + oappend (scratchbuf); + } return 0; }