diff --git a/.gitignore b/.gitignore index 9d1c432..caca985 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,9 @@ *.vdm *.exe mpclient +mpclient_x64 avscript eicar.com .gradle/ .idea/ +mpcache-* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..246d1f4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "intercept/zydis"] + path = intercept/zydis + url = https://github.com/zyantific/zydis.git +[submodule "intercept/subhook"] + path = intercept/subhook + url = https://github.com/cube0x8/subhook.git diff --git a/Makefile b/Makefile index 7fb37df..315ce97 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,57 @@ -CFLAGS = -O3 -march=native -ggdb3 -m32 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -mstackrealign -CPPFLAGS=-DNDEBUG -D_GNU_SOURCE -I. -Iintercept -Ipeloader -LDFLAGS = $(CFLAGS) -m32 -lm -Wl,--dynamic-list=exports.lst -LDLIBS = intercept/libdisasm.a -Wl,--whole-archive,peloader/libpeloader.a,--no-whole-archive +CFLAGS = -march=native -ggdb3 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -Iintercept/include -Ilog -Ipeloader -mstackrealign -maccumulate-outgoing-args +CPPFLAGS= -D_GNU_SOURCE -I. +LDFLAGS = $(CFLAGS) -lm -Wl,--dynamic-list=exports.lst -ldl +LDLIBS = -Wl,--whole-archive peloader/libpeloader.a -Wl,intercept/libhook.a -Wl,intercept/libZydis.a -Wl,intercept/libsubhook.a -Wl,--no-whole-archive .PHONY: clean peloader intercept -TARGETS=mpclient | peloader +RELEASE_CFLAGS = -O3 +RELEASE_CPPFLAGS = -DNDEBUG +DEBUG_CFLAGS = -O0 -g +TARGETS=mpclient mpclient_x64 | peloader + +all: CFLAGS += $(RELEASE_CFLAGS) +all: CPPFLAGS += $(RELEASE_CPPFLAGS) +all: BUILD_TARGET = "all" all: $(TARGETS) -mkdir -p faketemp +debug: CFLAGS += $(DEBUG_CFLAGS) +debug: BUILD_TARGET = "debug" +debug: CMAKE_FLAGS = -DCMAKE_BUILD_TYPE=Debug +debug: $(TARGETS) + -mkdir -p faketemp + intercept: - make -C intercept all + cd intercept; mkdir build; cd build; cmake $(CMAKE_FLAGS) ..; make + cp intercept/build/libhook.a intercept/libhook.a + cp intercept/build/zydis/libZydis.a intercept/libZydis.a + cp intercept/build/subhook/libsubhook.a intercept/libsubhook.a peloader: - make -C peloader all + make -C peloader ARCH=x86 + +peloader_x64: + make -C peloader debug ARCH=x64 -intercept/hook.o: intercept +mpclient: CFLAGS += -m32 +mpclient: LDFLAGS += -m32 +mpclient: CMAKE_FLAGS += -DARCH:STRING=x86 +mpclient: mpclient.o log/log.o | peloader intercept + $(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) $(LDFLAGS) + +mpclient_x64: CFLAGS += -g -O0 -fPIC +mpclient_x64: CMAKE_FLAGS = -DARCH:STRING=x64 -DCMAKE_BUILD_TYPE=Debug +mpclient_x64: mpclient_x64.o log/log.o | peloader_x64 intercept + $(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) $(LDFLAGS) -mpclient: mpclient.o intercept/hook.o | peloader +test_seh: CFLAGS += -g -O0 -fPIC +test_seh: CMAKE_FLAGS = -DARCH:STRING=x64 -DCMAKE_BUILD_TYPE=Debug +test_seh: test_seh.o log/log.o | peloader_x64 intercept $(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) $(LDFLAGS) clean: - rm -f a.out core *.o core.* vgcore.* gmon.out mpclient - make -C intercept clean + rm -rf a.out core *.o core.* vgcore.* gmon.out mpclient intercept/build intercept/*.a tests/build log/log.o make -C peloader clean rm -rf faketemp diff --git a/include/engineboot.h b/include/engineboot.h index f28eb72..0a33cbf 100644 --- a/include/engineboot.h +++ b/include/engineboot.h @@ -41,7 +41,7 @@ typedef struct _ENGINE_INFO { } ENGINE_INFO, *PENGINE_INFO; typedef struct _ENGINE_CONFIG { - DWORD EngineFlags; + ulong EngineFlags; PWCHAR Inclusions; // Example, "*.zip" PVOID Exceptions; PWCHAR UnknownString2; @@ -52,9 +52,9 @@ typedef struct _ENGINE_CONFIG { DWORD field_20; DWORD field_24; DWORD field_28; - DWORD field_2C; // Setting this seems to cause packer to be reported. - DWORD field_30; - DWORD field_34; + ulong field_2C; // Setting this seems to cause packer to be reported. + ulong field_30; + ulong field_34; PCHAR UnknownAnsiString1; PCHAR UnknownAnsiString2; } ENGINE_CONFIG, *PENGINE_CONFIG; @@ -64,7 +64,7 @@ typedef struct _ENGINE_CONTEXT { } ENGINE_CONTEXT, *PENGINE_CONTEXT; typedef struct _BOOTENGINE_PARAMS { - DWORD ClientVersion; + ulong ClientVersion; PWCHAR SignatureLocation; PVOID SpynetSource; PENGINE_CONFIG EngineConfig; @@ -74,16 +74,16 @@ typedef struct _BOOTENGINE_PARAMS { PWCHAR LocalCopyDirectory; PWCHAR OfflineTargetOS; CHAR ProductString[16]; - DWORD field_34; + ulong field_34; PVOID GlobalCallback; PENGINE_CONTEXT EngineContext; - DWORD AvgCpuLoadFactor; + ulong AvgCpuLoadFactor; CHAR field_44[16]; PWCHAR SpynetReportingGUID; PWCHAR SpynetVersion; PWCHAR NISEngineVersion; PWCHAR NISSignatureVersion; - DWORD FlightingEnabled; + ulong FlightingEnabled; DWORD FlightingLevel; PVOID DynamicConfig; DWORD AutoSampleSubmission; diff --git a/include/mpclient.h b/include/mpclient.h new file mode 100644 index 0000000..c44c1e2 --- /dev/null +++ b/include/mpclient.h @@ -0,0 +1,6 @@ +#ifndef LOADLIBRARY_MPCLIENT_H +#define LOADLIBRARY_MPCLIENT_H + +extern struct pe_image image; + +#endif //LOADLIBRARY_MPCLIENT_H diff --git a/include/scanreply.h b/include/scanreply.h index be100db..e842d64 100644 --- a/include/scanreply.h +++ b/include/scanreply.h @@ -23,7 +23,6 @@ typedef struct _SCANSTRUCT { DWORD Flags; PCHAR FileName; CHAR VirusName[28]; - DWORD field_28; DWORD field_2C; DWORD field_30; DWORD field_34; @@ -33,22 +32,22 @@ typedef struct _SCANSTRUCT { DWORD field_44; DWORD field_48; DWORD field_4C; - DWORD FileSize; - DWORD field_54; - DWORD UserPtr; - DWORD field_5C; + ULONG64 FileSize; + ULONG64 UserPtr; + DWORD field_60; + DWORD field_64; PCHAR MaybeFileName2; PWCHAR StreamName1; PWCHAR StreamName2; DWORD field_6C; - DWORD ThreatId; // Can be passed back to GetThreatInfo + DWORD ThreatId; // Can be passed back to GetThreatInfo } SCANSTRUCT, *PSCANSTRUCT; typedef struct _SCAN_REPLY { - DWORD (*EngineScanCallback)(PSCANSTRUCT this); - DWORD field_4; - DWORD UserPtr; - DWORD field_C; + DWORD (*EngineScanCallback)(PSCANSTRUCT this); + DWORD field_4; + ULONG64 UserPtr; + DWORD field_C; } SCAN_REPLY, *PSCAN_REPLY; #pragma pack(pop) diff --git a/include/streambuffer.h b/include/streambuffer.h index 0368d67..d0017c3 100644 --- a/include/streambuffer.h +++ b/include/streambuffer.h @@ -92,21 +92,21 @@ enum { }; typedef struct _STREAMBUFFER_DESCRIPTOR { - PVOID UserPtr; - DWORD (* Read)(PVOID this, uint64_t Offset, PVOID Buffer, DWORD Size, PDWORD SizeRead); - DWORD (* Write)(PVOID this, uint64_t Offset, PVOID Buffer, DWORD Size, PDWORD TotalWritten); - DWORD (* GetSize)(PVOID this, uint64_t *FileSize); - DWORD (* SetSize)(PVOID this, uint64_t *FileSize); - PWCHAR (* GetName)(PVOID this); - DWORD (* SetAttributes)(PVOID this, DWORD Attribute, PVOID Data, DWORD DataSize); - DWORD (* GetAttributes)(PVOID this, DWORD Attribute, PVOID Data, DWORD DataSize, PDWORD DataSizeWritten); + FILE *UserPtr; + DWORD (* Read)(FILE *fp, uint64_t Offset, PVOID Buffer, DWORD Size, PDWORD SizeRead); + DWORD (* Write)(FILE *fp, uint64_t Offset, PVOID Buffer, DWORD Size, PDWORD TotalWritten); + DWORD (* GetSize)(FILE *fp, uint64_t *FileSize); + DWORD (* SetSize)(FILE *fp, uint64_t *FileSize); + PWCHAR (* GetName)(FILE *fp); + DWORD (* SetAttributes)(FILE *fp, DWORD Attribute, PVOID Data, DWORD DataSize); + DWORD (* GetAttributes)(FILE *fp, DWORD Attribute, PVOID Data, DWORD DataSize, PDWORD DataSizeWritten); } STREAMBUFFER_DESCRIPTOR, *PSTREAMBUFFER_DESCRIPTOR; typedef struct _SCANSTREAM_PARAMS { - PSTREAMBUFFER_DESCRIPTOR Descriptor; - PSCAN_REPLY ScanReply; - DWORD UnknownB; - DWORD UnknownC; + PSTREAMBUFFER_DESCRIPTOR Descriptor; + PSCAN_REPLY ScanReply; + ULONG64 UnknownB; + ULONG64 UnknownC; } SCANSTREAM_PARAMS, *PSCANSTREAM_PARAMS; #pragma pack(pop) diff --git a/intercept/.gitignore b/intercept/.gitignore new file mode 100644 index 0000000..bae2c2a --- /dev/null +++ b/intercept/.gitignore @@ -0,0 +1,4 @@ +build*/ +cmake-build* +Makefile +Testing diff --git a/intercept/CMakeLists.txt b/intercept/CMakeLists.txt new file mode 100644 index 0000000..3392ecc --- /dev/null +++ b/intercept/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION "3.13") +project(hook C) + +# set arch variables (default x86) +# to change the ARCH value to x64, pass -DARCH:STRING=x64 as argument to cmake command +set(ARCH "x86" CACHE STRING "user-specified architecture") +set(HOOK_SRC "./src/hook.c") + +if(${ARCH} STREQUAL "x64") + set(HOOK_SRC "./src/hook_x86_64.c") +elseif(NOT ${ARCH} STREQUAL "x86") + message(FATAL_ERROR "Allowed ARCH values: x86, x64") +endif() + +include_directories("./include") +include_directories("../log") + +# Disable build of tools and examples. +option(ZYDIS_BUILD_TOOLS "" OFF) +option(ZYDIS_BUILD_EXAMPLES "" OFF) +# build subhook as static library and disable tests +option(SUBHOOK_STATIC "" ON) +option(SUBHOOK_TESTS "" OFF) +# force subhook to compile a 32bit library if ARCH == x86 +if(${ARCH} STREQUAL "x86") + option(SUBHOOK_FORCE_32BIT "" ON) +endif() + +# Register Zydis and subhook dependencies. +add_subdirectory("zydis") +add_subdirectory("subhook") + +# Create our libhook static library +add_library("hook" ${HOOK_SRC}) + +# change build and linker options based on user-supplied ARCH value +if(${ARCH} STREQUAL "x86") + target_compile_options ( Zydis PUBLIC -m32 ) + set_target_properties( hook PROPERTIES LINK_FLAGS -m32 ) +endif() + +# Have CMake link our project executable against Zydis and subhook. +target_link_libraries(hook PRIVATE "Zydis") +target_link_libraries(hook PRIVATE "subhook") +target_link_libraries(hook PRIVATE "x64_dispatcher") \ No newline at end of file diff --git a/intercept/Makefile b/intercept/Makefile deleted file mode 100644 index 2607b58..0000000 --- a/intercept/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -CFLAGS = -O0 -ggdb3 -m32 -std=gnu99 -fshort-wchar -Wno-multichar -w -CPPFLAGS= -DNDEBUG -LDFLAGS = $(CFLAGS) -m32 - -all: hook.o - make -C libdisasm all - cp libdisasm/libdisasm.a . - -clean: - rm -f *.o *.a - make -C libdisasm clean diff --git a/intercept/hook.h b/intercept/include/hook.h similarity index 50% rename from intercept/hook.h rename to intercept/include/hook.h index 0313ea8..4d9d58e 100644 --- a/intercept/hook.h +++ b/intercept/include/hook.h @@ -1,22 +1,31 @@ #ifndef __HOOK_H #define __HOOK_H -bool insert_function_redirect(void *function, void *redirect, uint32_t flags); -bool remove_function_redirect(void *function); -bool redirect_call_within_function(void *function, void *target, void *redirect); +#include "../subhook/subhook.h" // Flags recognised by insert_function_redirect. -enum { - HOOK_DEFAULT = 0, - HOOK_REPLACE_FUNCTION = (1 << 0), // Replace call, don't hook. - HOOK_FASTCALL = (1 << 1), // Try to minimize damage to registers. +enum ENUM_REDIRECT_FLAGS{ + HOOK_DEFAULT = 0, + HOOK_REPLACE_FUNCTION = (1 << 0), // Replace call, don't hook. + HOOK_FASTCALL = (1 << 1), // Try to minimize damage to registers. }; +#ifdef __x86_64__ +subhook_t insert_function_redirect(void *function, void *target, uint32_t flags); +bool remove_function_redirect(subhook_t hook); +bool redirect_call_within_function(void *function, void *target, void *redirect); +#else +bool insert_function_redirect(void *function, void *target, uint32_t flags); +bool remove_function_redirect(void *function); +bool redirect_call_within_function(void *function, void *target, void *redirect); +#endif + // Convenient representation of an x86 near call. The immediate operand is the // relative, displaced branch target, thus actual address is something like: // // target = (uintptr_t)(&call) + sizeof(struct call) + call->operand.i; // + struct __attribute__((packed)) branch { uint8_t opcode; union { @@ -26,15 +35,41 @@ struct __attribute__((packed)) branch { uint8_t data[0]; // Used to chain instructions together. }; -#define X86_OPCODE_CALL_NEAR 0xE8 -#define X86_OPCODE_JMP_NEAR 0xE9 +#ifdef __x86_64__ +struct __attribute__((packed)) branch64 { + uint16_t opcode; + uint8_t reg; + uint8_t data[0]; // Used to chain instructions together. +}; +// Convenient representation of an x64 MOVABS r64, imm64 instruction. +struct __attribute__((packed)) mov_r64_abs_insn { + uint8_t opcode; + uint8_t reg; + union { + uintptr_t i; + void *p; + } imm; + uint8_t data[0]; // Used to chain instructions together. +}; + +typedef struct mov_r64_abs_insn mov_r64_abs_insn; +#endif + +#define X86_64_OPCODE_MOV_ABS_R32 0x48 +#define X86_64_OPCODE_MOV_ABS_R64 0x49 + +#define X86_OPCODE_CALL_NEAR 0xE8 +#define X86_64_OPCODE_CALL_REG 0xFF41 +#define X86_OPCODE_JMP_NEAR 0xE9 +#define X86_64_OPCODE_JMP_NEAR 0xE9 -#define X86_OPCODE_NOP 0x90 -#define X86_OPCODE_RET 0xC3 -#define X86_OPCODE_MOV_EAX_IMM 0xB8 -#define X86_OPCODE_PUSH_EBP 0x55 +#define X86_OPCODE_NOP 0x90 +#define X86_OPCODE_RET 0xC3 +#define X86_OPCODE_MOV_EAX_IMM 0xB8 +#define X86_OPCODE_PUSH_EBP 0x55 +#define X86_64_OPCODE_PUSH_RBP 0x55 -#define X86_PREFIX_DATA16 0x66 +#define X86_PREFIX_DATA16 0x66 // This is used to save an arbitrary 2 byte integer in the instuction stream // without disrupting disassemblers. diff --git a/intercept/libdis.h b/intercept/libdis.h deleted file mode 120000 index 372b2d9..0000000 --- a/intercept/libdis.h +++ /dev/null @@ -1 +0,0 @@ -libdisasm/libdis.h \ No newline at end of file diff --git a/intercept/libdisasm/AUTHORS b/intercept/libdisasm/AUTHORS deleted file mode 100644 index 894f99c..0000000 --- a/intercept/libdisasm/AUTHORS +++ /dev/null @@ -1,7 +0,0 @@ -mammon_, mere coder -ReZiDeNt, Militant Dairy Activist (MIA) -The Grugq, Chief Makefile Architect -MO_K, MIA Libi386 Enthusiast (MIA) -a_p, Invisible Tester -fbj, Visible Tester (MIA) -drb, n0ps 'r us diff --git a/intercept/libdisasm/INSTALL b/intercept/libdisasm/INSTALL deleted file mode 100644 index 5458714..0000000 --- a/intercept/libdisasm/INSTALL +++ /dev/null @@ -1,234 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/intercept/libdisasm/LICENSE b/intercept/libdisasm/LICENSE deleted file mode 100644 index c563828..0000000 --- a/intercept/libdisasm/LICENSE +++ /dev/null @@ -1,137 +0,0 @@ - - - - - The "Clarified Artistic License" - - Preamble - -The intent of this document is to state the conditions under which a -Package may be copied, such that the Copyright Holder maintains some -semblance of artistic control over the development of the package, -while giving the users of the package the right to use and distribute -the Package in a more-or-less customary fashion, plus the right to make -reasonable modifications. - -Definitions: - - "Package" refers to the collection of files distributed by the - Copyright Holder, and derivatives of that collection of files - created through textual modification. - - "Standard Version" refers to such a Package if it has not been - modified, or has been modified in accordance with the wishes - of the Copyright Holder as specified below. - - "Copyright Holder" is whoever is named in the copyright or - copyrights for the package. - - "You" is you, if you're thinking about copying or distributing - this Package. - - "Distribution fee" is a fee you charge for providing a copy of this - Package to another party. - - "Freely Available" means that no fee is charged for the right to use - the item, though there may be fees involved in handling the item. - -1. You may make and give away verbatim copies of the source form of the -Standard Version of this Package without restriction, provided that you -duplicate all of the original copyright notices and associated disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications -derived from the Public Domain, or those made Freely Available, or from -the Copyright Holder. A Package modified in such a way shall still be -considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided -that you insert a prominent notice in each changed file stating how and -when you changed that file, and provided that you do at least ONE of the -following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or - an equivalent medium, or placing the modifications on a major archive - site allowing unrestricted access to them, or by allowing the Copyright - Holder to include your modifications in the Standard Version of the - Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided, and provide - a separate manual page for each non-standard executable that clearly - documents how it differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - - e) permit and encourge anyone who receives a copy of the modified Package - permission to make your modifications Freely Available in some specific - way. - -4. You may distribute the programs of this Package in object code or -executable form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where - to get the Standard Version. - - b) accompany the distribution with the machine-readable source of - the Package with your modifications. - - c) give non-standard executables non-standard names, and clearly - document the differences in manual pages (or equivalent), together - with instructions on where to get the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - - e) offer the machine-readable source of the Package, with your - modifications, by mail order. - -5. You may charge a distribution fee for any distribution of this Package. -If you offer support for this Package, you may charge any fee you choose -for that support. You may not charge a license fee for the right to use -this Package itself. You may distribute this Package in aggregate with -other (possibly commercial and possibly nonfree) programs as part of a -larger (possibly commercial and possibly nonfree) software distribution, -and charge license fees for other parts of that software distribution, -provided that you do not advertise this Package as a product of your own. -If the Package includes an interpreter, You may embed this Package's -interpreter within an executable of yours (by linking); this shall be -construed as a mere form of aggregation, provided that the complete -Standard Version of the interpreter is so embedded. - -6. The scripts and library files supplied as input to or produced as -output from the programs of this Package do not automatically fall -under the copyright of this Package, but belong to whoever generated -them, and may be sold commercially, and may be aggregated with this -Package. If such scripts or library files are aggregated with this -Package via the so-called "undump" or "unexec" methods of producing a -binary executable image, then distribution of such an image shall -neither be construed as a distribution of this Package nor shall it -fall under the restrictions of Paragraphs 3 and 4, provided that you do -not represent such an executable image as a Standard Version of this -Package. - -7. C subroutines (or comparably compiled subroutines in other -languages) supplied by you and linked into this Package in order to -emulate subroutines and variables of the language defined by this -Package shall not be considered part of this Package, but are the -equivalent of input as in Paragraph 6, provided these subroutines do -not change the language in any way that would cause it to fail the -regression tests for the language. - -8. Aggregation of the Standard Version of the Package with a commercial -distribution is always permitted provided that the use of this Package is -embedded; that is, when no overt attempt is made to make this Package's -interfaces visible to the end user of the commercial distribution. -Such use shall not be construed as a distribution of this Package. - -9. The name of the Copyright Holder may not be used to endorse or promote -products derived from this software without specific prior written permission. - -10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - The End diff --git a/intercept/libdisasm/Makefile b/intercept/libdisasm/Makefile deleted file mode 100644 index 8da419c..0000000 --- a/intercept/libdisasm/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -CFLAGS=-O2 -ggdb3 -m32 -std=gnu99 -fshort-wchar -Wno-multichar -w -DHAVE_CONFIG_H -I. -LDFLAGS= $(CFLAGS) -m32 - -all: libdisasm.a - -libdisasm.a: ia32_implicit.o \ - ia32_modrm.o \ - ia32_reg.o \ - x86_format.o \ - x86_misc.o \ - ia32_insn.o \ - ia32_opcode_tables.o \ - ia32_settings.o \ - x86_imm.o \ - x86_operand_list.o \ - ia32_invariant.o \ - ia32_operand.o \ - x86_disasm.o \ - x86_insn.o - $(AR) $(ARFLAGS) $@ $^ - -clean: - rm -f *.o *.a diff --git a/intercept/libdisasm/config.h b/intercept/libdisasm/config.h deleted file mode 100644 index 5ca95ca..0000000 --- a/intercept/libdisasm/config.h +++ /dev/null @@ -1,56 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 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 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_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "libdisasm" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "bastard-libdisasm@lists.sourceforge.net" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "libdisasm" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libdisasm 0.23" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "libdisasm" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "0.23" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "0.23" diff --git a/intercept/libdisasm/ia32_implicit.c b/intercept/libdisasm/ia32_implicit.c deleted file mode 100644 index 8b075d2..0000000 --- a/intercept/libdisasm/ia32_implicit.c +++ /dev/null @@ -1,422 +0,0 @@ -#include - -#include "ia32_implicit.h" -#include "ia32_insn.h" -#include "ia32_reg.h" -#include "x86_operand_list.h" - -/* Conventions: Register operands which are aliases of another register - * operand (e.g. AX in one operand and AL in another) assume that the - * operands are different registers and that alias tracking will resolve - * data flow. This means that something like - * mov ax, al - * would have 'write only' access for AX and 'read only' access for AL, - * even though both AL and AX are read and written */ -typedef struct { - uint32_t type; - uint32_t operand; -} op_implicit_list_t; - -static op_implicit_list_t list_aaa[] = - /* 37 : AAA : rw AL */ - /* 3F : AAS : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* aaa */ - -static op_implicit_list_t list_aad[] = - /* D5 0A, D5 (ib) : AAD : rw AX */ - /* D4 0A, D4 (ib) : AAM : rw AX */ - {{ OP_R | OP_W, REG_WORD_OFFSET }, {0}}; /* aad */ - -static op_implicit_list_t list_call[] = - /* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */ - /* C2, C3, CA, CB : RET : rw ESP, rw EIP */ - {{ OP_R | OP_W, REG_EIP_INDEX }, - { OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* call, ret */ - -static op_implicit_list_t list_cbw[] = - /* 98 : CBW : r AL, rw AX */ - {{ OP_R | OP_W, REG_WORD_OFFSET }, - { OP_R, REG_BYTE_OFFSET}, {0}}; /* cbw */ - -static op_implicit_list_t list_cwde[] = - /* 98 : CWDE : r AX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_R, REG_WORD_OFFSET }, {0}}; /* cwde */ - -static op_implicit_list_t list_clts[] = - /* 0F 06 : CLTS : rw CR0 */ - {{ OP_R | OP_W, REG_CTRL_OFFSET}, {0}}; /* clts */ - -static op_implicit_list_t list_cmpxchg[] = - /* 0F B0 : CMPXCHG : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* cmpxchg */ - -static op_implicit_list_t list_cmpxchgb[] = - /* 0F B1 : CMPXCHG : rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* cmpxchg */ - -static op_implicit_list_t list_cmpxchg8b[] = - /* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R, REG_DWORD_OFFSET + 1 }, - { OP_R, REG_DWORD_OFFSET + 3 }, {0}}; /* cmpxchg8b */ - -static op_implicit_list_t list_cpuid[] = - /* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET + 3 }, {0}}; /* cpuid */ - -static op_implicit_list_t list_cwd[] = - /* 99 : CWD/CWQ : rw EAX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* cwd */ - -static op_implicit_list_t list_daa[] = - /* 27 : DAA : rw AL */ - /* 2F : DAS : rw AL */ - {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* daa */ - -static op_implicit_list_t list_idiv[] = - /* F6 : DIV, IDIV : r AX, w AL, w AH */ - /* FIXED: first op was EAX, not Aw. TODO: verify! */ - {{ OP_R, REG_WORD_OFFSET }, - { OP_W, REG_BYTE_OFFSET }, - { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* div */ - -static op_implicit_list_t list_div[] = - /* F7 : DIV, IDIV : rw EDX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* div */ - -static op_implicit_list_t list_enter[] = - /* C8 : ENTER : rw ESP w EBP */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 4 }, - { OP_R, REG_DWORD_OFFSET + 5 }, {0}}; /* enter */ - -static op_implicit_list_t list_f2xm1[] = - /* D9 F0 : F2XM1 : rw ST(0) */ - /* D9 E1 : FABS : rw ST(0) */ - /* D9 E0 : FCHS : rw ST(0) */ - /* D9 FF : FCOS : rw ST(0)*/ - /* D8, DA : FDIV : rw ST(0) */ - /* D8, DA : FDIVR : rw ST(0) */ - /* D9 F2 : FPTAN : rw ST(0) */ - /* D9 FC : FRNDINT : rw ST(0) */ - /* D9 FB : FSINCOS : rw ST(0) */ - /* D9 FE : FSIN : rw ST(0) */ - /* D9 FA : FSQRT : rw ST(0) */ - /* D9 F4 : FXTRACT : rw ST(0) */ - {{ OP_R | OP_W, REG_FPU_OFFSET }, {0}}; /* f2xm1 */ - -static op_implicit_list_t list_fcom[] = - /* D8, DC, DE D9 : FCOM : r ST(0) */ - /* DE, DA : FICOM : r ST(0) */ - /* DF, D8 : FIST : r ST(0) */ - /* D9 E4 : FTST : r ST(0) */ - /* D9 E5 : FXAM : r ST(0) */ - {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fcom */ - -static op_implicit_list_t list_fpatan[] = - /* D9 F3 : FPATAN : r ST(0), rw ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, {0}}; /* fpatan */ - -static op_implicit_list_t list_fprem[] = - /* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */ - /* D9 FD : FSCALE : rw ST(0), r ST(1) */ - {{ OP_R | OP_W, REG_FPU_OFFSET }, - { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fprem */ - -static op_implicit_list_t list_faddp[] = - /* DE C1 : FADDP : r ST(0), rw ST(1) */ - /* DE E9 : FSUBP : r ST(0), rw ST(1) */ - /* D9 F1 : FYL2X : r ST(0), rw ST(1) */ - /* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, - { OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0}}; /* faddp */ - -static op_implicit_list_t list_fucompp[] = - /* DA E9 : FUCOMPP : r ST(0), r ST(1) */ - {{ OP_R, REG_FPU_OFFSET }, - { OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fucompp */ - -static op_implicit_list_t list_imul[] = - /* F6 : IMUL : r AL, w AX */ - /* F6 : MUL : r AL, w AX */ - {{ OP_R, REG_BYTE_OFFSET }, - { OP_W, REG_WORD_OFFSET }, {0}}; /* imul */ - -static op_implicit_list_t list_mul[] = - /* F7 : IMUL : rw EAX, w EDX */ - /* F7 : MUL : rw EAX, w EDX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET }, - { OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* imul */ - -static op_implicit_list_t list_lahf[] = - /* 9F : LAHF : r EFLAGS, w AH */ - {{ OP_R, REG_FLAGS_INDEX }, - { OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* lahf */ - -static op_implicit_list_t list_ldmxcsr[] = - /* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */ - {{ OP_W, REG_MXCSG_INDEX }, {0}}; /* ldmxcsr */ - -static op_implicit_list_t list_leave[] = - /* C9 : LEAVE : rw ESP, w EBP */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_DWORD_OFFSET + 5 }, {0}}; /* leave */ - -static op_implicit_list_t list_lgdt[] = - /* 0F 01 : LGDT : w GDTR */ - {{ OP_W, REG_GDTR_INDEX }, {0}}; /* lgdt */ - -static op_implicit_list_t list_lidt[] = - /* 0F 01 : LIDT : w IDTR */ - {{ OP_W, REG_IDTR_INDEX }, {0}}; /* lidt */ - -static op_implicit_list_t list_lldt[] = - /* 0F 00 : LLDT : w LDTR */ - {{ OP_W, REG_LDTR_INDEX }, {0}}; /* lldt */ - -static op_implicit_list_t list_lmsw[] = - /* 0F 01 : LMSW : w CR0 */ - {{ OP_W, REG_CTRL_OFFSET }, {0}}; /* lmsw */ - -static op_implicit_list_t list_loop[] = - /* E0, E1, E2 : LOOP : rw ECX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* loop */ - -static op_implicit_list_t list_ltr[] = - /* 0F 00 : LTR : w Task Register */ - {{ OP_W, REG_TR_INDEX }, {0}}; /* ltr */ - -static op_implicit_list_t list_pop[] = - /* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */ - /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ - {{ OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* pop, push */ - -static op_implicit_list_t list_popad[] = - /* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_DWORD_OFFSET + 7 }, - { OP_W, REG_DWORD_OFFSET + 6 }, - { OP_W, REG_DWORD_OFFSET + 5 }, - { OP_W, REG_DWORD_OFFSET + 3 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* popad */ - -static op_implicit_list_t list_popfd[] = - /* 9D : POPFD : rw esp, w eflags */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_W, REG_FLAGS_INDEX }, {0}}; /* popfd */ - -static op_implicit_list_t list_pushad[] = - /* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ - /* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_R, REG_DWORD_OFFSET }, - { OP_R, REG_DWORD_OFFSET + 1 }, - { OP_R, REG_DWORD_OFFSET + 2 }, - { OP_R, REG_DWORD_OFFSET + 3 }, - { OP_R, REG_DWORD_OFFSET + 5 }, - { OP_R, REG_DWORD_OFFSET + 6 }, - { OP_R, REG_DWORD_OFFSET + 7 }, {0}}; /* pushad */ - -static op_implicit_list_t list_pushfd[] = - /* 9C : PUSHFD : rw esp, r eflags */ - {{ OP_R | OP_W, REG_ESP_INDEX }, - { OP_R, REG_FLAGS_INDEX }, {0}}; /* pushfd */ - -static op_implicit_list_t list_rdmsr[] = - /* 0F 32 : RDMSR : r ECX, w EDX, w EAX */ - {{ OP_R, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdmsr */ - -static op_implicit_list_t list_rdpmc[] = - /* 0F 33 : RDPMC : r ECX, w EDX, w EAX */ - {{ OP_R, REG_DWORD_OFFSET + 1 }, - { OP_W, REG_DWORD_OFFSET + 2 }, - { OP_W, REG_DWORD_OFFSET }, {0}}; /* rdpmc */ - -static op_implicit_list_t list_rdtsc[] = - /* 0F 31 : RDTSC : rw EDX, rw EAX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, - { OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* rdtsc */ - -static op_implicit_list_t list_rep[] = - /* F3, F2 ... : REP : rw ECX */ - {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* rep */ - -static op_implicit_list_t list_rsm[] = - /* 0F AA : RSM : r CR4, r CR0 */ - {{ OP_R, REG_CTRL_OFFSET + 4 }, - { OP_R, REG_CTRL_OFFSET }, {0}}; /* rsm */ - -static op_implicit_list_t list_sahf[] = - /* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sahf */ - -static op_implicit_list_t list_sgdt[] = - /* 0F : SGDT : r gdtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sgdt */ - -static op_implicit_list_t list_sidt[] = - /* 0F : SIDT : r idtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sidt */ - -static op_implicit_list_t list_sldt[] = - /* 0F : SLDT : r ldtr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sldt */ - -static op_implicit_list_t list_smsw[] = - /* 0F : SMSW : r CR0 */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* smsw */ - -static op_implicit_list_t list_stmxcsr[] = - /* 0F AE : STMXCSR : r MXCSR */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* stmxcsr */ - -static op_implicit_list_t list_str[] = - /* 0F 00 : STR : r TR (task register) */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* str */ - -static op_implicit_list_t list_sysenter[] = - /* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags - * r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysenter */ - -static op_implicit_list_t list_sysexit[] = - /* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp - * r sysenter_cs_msr */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysexit */ - -static op_implicit_list_t list_wrmsr[] = - /* 0F 30 : WRMST : r edx, r eax, r ecx */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* wrmsr */ - -static op_implicit_list_t list_xlat[] = - /* D7 : XLAT : rw al r ebx (ptr) */ - /* TODO: finish this! */ - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* xlat */ -/* TODO: - * monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R - * mwait 0f 01 c9 eax OP_R ecx OP_R - */ -static op_implicit_list_t list_monitor[] = - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* monitor */ -static op_implicit_list_t list_mwait[] = - {{ OP_R, REG_DWORD_OFFSET }, {0}}; /* mwait */ - -op_implicit_list_t *op_implicit_list[] = { - /* This is a list of implicit operands which are read/written by - * various x86 instructions. Note that modifications to the stack - * register are mentioned here, but that additional information on - * the effect an instruction has on the stack is contained in the - * x86_insn_t 'stack_mod' and 'stack_mod_val' fields. Use of the - * eflags register, i.e. setting, clearing, and testing flags, is - * not recorded here but rather in the flags_set and flags_tested - * fields of the x86_insn_t.*/ - NULL, - list_aaa, list_aad, list_call, list_cbw, /* 1 - 4 */ - list_cwde, list_clts, list_cmpxchg, list_cmpxchgb, /* 5 - 8 */ - list_cmpxchg8b, list_cpuid, list_cwd, list_daa, /* 9 - 12 */ - list_idiv, list_div, list_enter, list_f2xm1, /* 13 - 16 */ - list_fcom, list_fpatan, list_fprem, list_faddp, /* 17 - 20 */ - list_fucompp, list_imul, list_mul, list_lahf, /* 21 - 24 */ - list_ldmxcsr, list_leave, list_lgdt, list_lidt, /* 25 - 28 */ - list_lldt, list_lmsw, list_loop, list_ltr, /* 29 - 32 */ - list_pop, list_popad, list_popfd, list_pushad, /* 33 - 36 */ - list_pushfd, list_rdmsr, list_rdpmc, list_rdtsc, /* 37 - 40 */ - /* NOTE: 'REP' is a hack since it is a prefix: if its position - * in the table changes, then change IDX_IMPLICIT_REP in the .h */ - list_rep, list_rsm, list_sahf, list_sgdt, /* 41 - 44 */ - list_sidt, list_sldt, list_smsw, list_stmxcsr, /* 45 - 48 */ - list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */ - list_xlat, list_monitor, list_mwait, /* 53 - 55*/ - NULL /* end of list */ - }; - -#define LAST_IMPL_IDX 55 - -static void handle_impl_reg( x86_op_t *op, uint32_t val ) { - x86_reg_t *reg = &op->data.reg; - op->type = op_register; - ia32_handle_register( reg, (unsigned int) val ); - switch (reg->size) { - case 1: - op->datatype = op_byte; break; - case 2: - op->datatype = op_word; break; - case 4: - op->datatype = op_dword; break; - case 8: - op->datatype = op_qword; break; - case 10: - op->datatype = op_extreal; break; - case 16: - op->datatype = op_dqword; break; - } - return; -} - -/* 'impl_idx' is the value from the opcode table: between 1 and LAST_IMPL_IDX */ -/* returns number of operands added */ -unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx ) { - op_implicit_list_t *list; - x86_op_t *op; - unsigned int num = 0; - - if (! impl_idx || impl_idx > LAST_IMPL_IDX ) { - return 0; - } - - for ( list = op_implicit_list[impl_idx]; list->type; list++, num++ ) { - enum x86_op_access access = (enum x86_op_access) OP_PERM(list->type); - enum x86_op_flags flags = (enum x86_op_flags) (OP_FLAGS(list->type) >> 12); - - op = NULL; - /* In some cases (MUL), EAX is an implicit operand hardcoded in - * the instruction without being explicitly listed in assembly. - * For this situation, find the hardcoded operand and add the - * implied flag rather than adding a new implicit operand. */ - x86_oplist_t * existing; - if (ia32_true_register_id(list->operand) == REG_DWORD_OFFSET) { - for ( existing = insn->operands; existing; existing = existing->next ) { - if (existing->op.type == op_register && - existing->op.data.reg.id == list->operand) { - op = &existing->op; - break; - } - } - } - if (!op) { - op = x86_operand_new( insn ); - /* all implicit operands are registers */ - handle_impl_reg( op, list->operand ); - /* decrement the 'explicit count' incremented by default in - * x86_operand_new */ - insn->explicit_count = insn->explicit_count -1; - } - if (!op) { - return num; /* gah! return early */ - } - op->access |= access; - op->flags |= flags; - op->flags |= op_implied; - } - - return num; -} diff --git a/intercept/libdisasm/ia32_implicit.h b/intercept/libdisasm/ia32_implicit.h deleted file mode 100644 index 0002b28..0000000 --- a/intercept/libdisasm/ia32_implicit.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef IA32_IMPLICIT_H -#define IA32_IMPLICIT_H - -#include "libdis.h" - -/* OK, this is a hack to deal with prefixes having implicit operands... - * thought I had removed all the old hackishness ;( */ - -#define IDX_IMPLICIT_REP 41 /* change this if the table changes! */ - -unsigned int ia32_insn_implicit_ops( x86_insn_t *insn, unsigned int impl_idx ); - -#endif diff --git a/intercept/libdisasm/ia32_insn.c b/intercept/libdisasm/ia32_insn.c deleted file mode 100644 index e4f4210..0000000 --- a/intercept/libdisasm/ia32_insn.c +++ /dev/null @@ -1,625 +0,0 @@ -#include -#include -#include -#include "qword.h" - -#include "ia32_insn.h" -#include "ia32_opcode_tables.h" - -#include "ia32_reg.h" -#include "ia32_operand.h" -#include "ia32_implicit.h" -#include "ia32_settings.h" - -#include "libdis.h" - -extern ia32_table_desc_t ia32_tables[]; -extern ia32_settings_t ia32_settings; - -#define IS_SP( op ) (op->type == op_register && \ - (op->data.reg.id == REG_ESP_INDEX || \ - op->data.reg.alias == REG_ESP_INDEX) ) -#define IS_IMM( op ) (op->type == op_immediate ) - -#ifdef WIN32 -# define INLINE -#else -# define INLINE inline -#endif - -/* for calculating stack modification based on an operand */ -static INLINE int32_t long_from_operand( x86_op_t *op ) { - - if (! IS_IMM(op) ) { - return 0L; - } - - switch ( op->datatype ) { - case op_byte: - return (int32_t) op->data.sbyte; - case op_word: - return (int32_t) op->data.sword; - case op_qword: - return (int32_t) op->data.sqword; - case op_dword: - return op->data.sdword; - default: - /* these are not used in stack insn */ - break; - } - - return 0L; -} - - -/* determine what this insn does to the stack */ -static void ia32_stack_mod(x86_insn_t *insn) { - x86_op_t *dest, *src = NULL; - - if (! insn || ! insn->operands ) { - return; - } - - dest = &insn->operands->op; - if ( dest ) { - src = &insn->operands->next->op; - } - - insn->stack_mod = 0; - insn->stack_mod_val = 0; - - switch ( insn->type ) { - case insn_call: - case insn_callcc: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size * -1; - break; - case insn_push: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size * -1; - break; - case insn_return: - insn->stack_mod = 1; - insn->stack_mod_val = insn->addr_size; - case insn_int: case insn_intcc: - case insn_iret: - break; - case insn_pop: - insn->stack_mod = 1; - if (! IS_SP( dest ) ) { - insn->stack_mod_val = insn->op_size; - } /* else we don't know the stack change in a pop esp */ - break; - case insn_enter: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_leave: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_pushregs: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_popregs: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_pushflags: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_popflags: - insn->stack_mod = 1; - insn->stack_mod_val = 0; /* TODO : FIX */ - break; - case insn_add: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = long_from_operand( src ); - } - break; - case insn_sub: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = long_from_operand( src ); - insn->stack_mod_val *= -1; - } - break; - case insn_inc: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = 1; - } - break; - case insn_dec: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - insn->stack_mod_val = 1; - } - break; - case insn_mov: case insn_movcc: - case insn_xchg: case insn_xchgcc: - case insn_mul: case insn_div: - case insn_shl: case insn_shr: - case insn_rol: case insn_ror: - case insn_and: case insn_or: - case insn_not: case insn_neg: - case insn_xor: - if ( IS_SP( dest ) ) { - insn->stack_mod = 1; - } - break; - default: - break; - } - if (! strcmp("enter", insn->mnemonic) ) { - insn->stack_mod = 1; - } else if (! strcmp("leave", insn->mnemonic) ) { - insn->stack_mod = 1; - } - - /* for mov, etc we return 0 -- unknown stack mod */ - - return; -} - -/* get the cpu details for this insn from cpu flags int */ -static void ia32_handle_cpu( x86_insn_t *insn, unsigned int cpu ) { - insn->cpu = (enum x86_insn_cpu) CPU_MODEL(cpu); - insn->isa = (enum x86_insn_isa) (ISA_SUBSET(cpu)) >> 16; - return; -} - -/* handle mnemonic type and group */ -static void ia32_handle_mnemtype(x86_insn_t *insn, unsigned int mnemtype) { - unsigned int type = mnemtype & ~INS_FLAG_MASK; - insn->group = (enum x86_insn_group) (INS_GROUP(type)) >> 12; - insn->type = (enum x86_insn_type) INS_TYPE(type); - - return; -} - -static void ia32_handle_notes(x86_insn_t *insn, unsigned int notes) { - insn->note = (enum x86_insn_note) notes; - return; -} - -static void ia32_handle_eflags( x86_insn_t *insn, unsigned int eflags) { - unsigned int flags; - - /* handle flags effected */ - flags = INS_FLAGS_TEST(eflags); - /* handle weird OR cases */ - /* these are either JLE (ZF | SF<>OF) or JBE (CF | ZF) */ - if (flags & INS_TEST_OR) { - flags &= ~INS_TEST_OR; - if ( flags & INS_TEST_ZERO ) { - flags &= ~INS_TEST_ZERO; - if ( flags & INS_TEST_CARRY ) { - flags &= ~INS_TEST_CARRY ; - flags |= (int)insn_carry_or_zero_set; - } else if ( flags & INS_TEST_SFNEOF ) { - flags &= ~INS_TEST_SFNEOF; - flags |= (int)insn_zero_set_or_sign_ne_oflow; - } - } - } - insn->flags_tested = (enum x86_flag_status) flags; - - insn->flags_set = (enum x86_flag_status) INS_FLAGS_SET(eflags) >> 16; - - return; -} - -static void ia32_handle_prefix( x86_insn_t *insn, unsigned int prefixes ) { - - insn->prefix = (enum x86_insn_prefix) prefixes & PREFIX_MASK; // >> 20; - if (! (insn->prefix & PREFIX_PRINT_MASK) ) { - /* no printable prefixes */ - insn->prefix = insn_no_prefix; - } - - /* concat all prefix strings */ - if ( (unsigned int)insn->prefix & PREFIX_LOCK ) { - strncat(insn->prefix_string, "lock ", 32 - - strlen(insn->prefix_string)); - } - - if ( (unsigned int)insn->prefix & PREFIX_REPNZ ) { - strncat(insn->prefix_string, "repnz ", 32 - - strlen(insn->prefix_string)); - } else if ( (unsigned int)insn->prefix & PREFIX_REPZ ) { - strncat(insn->prefix_string, "repz ", 32 - - strlen(insn->prefix_string)); - } - - return; -} - - -static void reg_32_to_16( x86_op_t *op, x86_insn_t *insn, void *arg ) { - - /* if this is a 32-bit register and it is a general register ... */ - if ( op->type == op_register && op->data.reg.size == 4 && - (op->data.reg.type & reg_gen) ) { - /* WORD registers are 8 indices off from DWORD registers */ - ia32_handle_register( &(op->data.reg), - op->data.reg.id + 8 ); - } -} - -static void handle_insn_metadata( x86_insn_t *insn, ia32_insn_t *raw_insn ) { - ia32_handle_mnemtype( insn, raw_insn->mnem_flag ); - ia32_handle_notes( insn, raw_insn->notes ); - ia32_handle_eflags( insn, raw_insn->flags_effected ); - ia32_handle_cpu( insn, raw_insn->cpu ); - ia32_stack_mod( insn ); -} - -static size_t ia32_decode_insn( unsigned char *buf, size_t buf_len, - ia32_insn_t *raw_insn, x86_insn_t *insn, - unsigned int prefixes ) { - size_t size, op_size; - unsigned char modrm; - - /* this should never happen, but just in case... */ - if ( raw_insn->mnem_flag == INS_INVALID ) { - return 0; - } - - if (ia32_settings.options & opt_16_bit) { - insn->op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2; - insn->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2; - } else { - insn->op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4; - insn->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4; - } - - - /* ++++ 1. Copy mnemonic and mnemonic-flags to CODE struct */ - if ((ia32_settings.options & opt_att_mnemonics) && raw_insn->mnemonic_att[0]) { - strncpy( insn->mnemonic, raw_insn->mnemonic_att, 16 ); - } - else { - strncpy( insn->mnemonic, raw_insn->mnemonic, 16 ); - } - ia32_handle_prefix( insn, prefixes ); - - handle_insn_metadata( insn, raw_insn ); - - /* prefetch the next byte in case it is a modr/m byte -- saves - * worrying about whether the 'mod/rm' operand or the 'reg' operand - * occurs first */ - modrm = GET_BYTE( buf, buf_len ); - - /* ++++ 2. Decode Explicit Operands */ - /* Intel uses up to 3 explicit operands in its instructions; - * the first is 'dest', the second is 'src', and the third - * is an additional source value (usually an immediate value, - * e.g. in the MUL instructions). These three explicit operands - * are encoded in the opcode tables, even if they are not used - * by the instruction. Additional implicit operands are stored - * in a supplemental table and are handled later. */ - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->dest, - raw_insn->dest_flag, prefixes, modrm ); - /* advance buffer, increase size if necessary */ - buf += op_size; - buf_len -= op_size; - size = op_size; - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->src, - raw_insn->src_flag, prefixes, modrm ); - buf += op_size; - buf_len -= op_size; - size += op_size; - - op_size = ia32_decode_operand( buf, buf_len, insn, raw_insn->aux, - raw_insn->aux_flag, prefixes, modrm ); - size += op_size; - - - /* ++++ 3. Decode Implicit Operands */ - /* apply implicit operands */ - ia32_insn_implicit_ops( insn, raw_insn->implicit_ops ); - /* we have one small inelegant hack here, to deal with - * the two prefixes that have implicit operands. If Intel - * adds more, we'll change the algorithm to suit :) */ - if ( (prefixes & PREFIX_REPZ) || (prefixes & PREFIX_REPNZ) ) { - ia32_insn_implicit_ops( insn, IDX_IMPLICIT_REP ); - } - - - /* 16-bit hack: foreach operand, if 32-bit reg, make 16-bit reg */ - if ( insn->op_size == 2 ) { - x86_operand_foreach( insn, reg_32_to_16, NULL, op_any ); - } - - return size; -} - - -/* convenience routine */ -#define USES_MOD_RM(flag) \ - (flag == ADDRMETH_E || flag == ADDRMETH_M || flag == ADDRMETH_Q || \ - flag == ADDRMETH_W || flag == ADDRMETH_R) - -static int uses_modrm_flag( unsigned int flag ) { - unsigned int meth; - if ( flag == ARG_NONE ) { - return 0; - } - meth = (flag & ADDRMETH_MASK); - if ( USES_MOD_RM(meth) ) { - return 1; - } - - return 0; -} - -/* This routine performs the actual byte-by-byte opcode table lookup. - * Originally it was pretty simple: get a byte, adjust it to a proper - * index into the table, then check the table row at that index to - * determine what to do next. But is anything that simple with Intel? - * This is now a huge, convoluted mess, mostly of bitter comments. */ -/* buf: pointer to next byte to read from stream - * buf_len: length of buf - * table: index of table to use for lookups - * raw_insn: output pointer that receives opcode definition - * prefixes: output integer that is encoded with prefixes in insn - * returns : number of bytes consumed from stream during lookup */ -size_t ia32_table_lookup( unsigned char *buf, size_t buf_len, - unsigned int table, ia32_insn_t **raw_insn, - unsigned int *prefixes ) { - unsigned char *next, op = buf[0]; /* byte value -- 'opcode' */ - size_t size = 1, sub_size = 0, next_len; - ia32_table_desc_t *table_desc; - unsigned int subtable, prefix = 0, recurse_table = 0; - - table_desc = &ia32_tables[table]; - - op = GET_BYTE( buf, buf_len ); - - if ( table_desc->type == tbl_fpu && op > table_desc->maxlim) { - /* one of the fucking FPU tables out of the 00-BH range */ - /* OK,. this is a bit of a hack -- the proper way would - * have been to use subtables in the 00-BF FPU opcode tables, - * but that is rather wasteful of space... */ - table_desc = &ia32_tables[table +1]; - } - - /* PERFORM TABLE LOOKUP */ - - /* ModR/M trick: shift extension bits into lowest bits of byte */ - /* Note: non-ModR/M tables have a shift value of 0 */ - op >>= table_desc->shift; - - /* ModR/M trick: mask out high bits to turn extension into an index */ - /* Note: non-ModR/M tables have a mask value of 0xFF */ - op &= table_desc->mask; - - - /* Sparse table trick: check that byte is <= max value */ - /* Note: full (256-entry) tables have a maxlim of 155 */ - if ( op > table_desc->maxlim ) { - /* this is a partial table, truncated at the tail, - and op is out of range! */ - return INVALID_INSN; - } - - /* Sparse table trick: check that byte is >= min value */ - /* Note: full (256-entry) tables have a minlim of 0 */ - if ( table_desc->minlim > op ) { - /* this is a partial table, truncated at the head, - and op is out of range! */ - return INVALID_INSN; - } - /* adjust op to be an offset from table index 0 */ - op -= table_desc->minlim; - - /* Yay! 'op' is now fully adjusted to be an index into 'table' */ - *raw_insn = &(table_desc->table[op]); - //printf("BYTE %X TABLE %d OP %X\n", buf[0], table, op ); - - if ( (*raw_insn)->mnem_flag & INS_FLAG_PREFIX ) { - prefix = (*raw_insn)->mnem_flag & PREFIX_MASK; - } - - - /* handle escape to a multibyte/coproc/extension/etc table */ - /* NOTE: if insn is a prefix and has a subtable, then we - * only recurse if this is the first prefix byte -- - * that is, if *prefixes is 0. - * NOTE also that suffix tables are handled later */ - subtable = (*raw_insn)->table; - - if ( subtable && ia32_tables[subtable].type != tbl_suffix && - (! prefix || ! *prefixes) ) { - - if ( ia32_tables[subtable].type == tbl_ext_ext || - ia32_tables[subtable].type == tbl_fpu_ext ) { - /* opcode extension: reuse current byte in buffer */ - next = buf; - next_len = buf_len; - } else { - /* "normal" opcode: advance to next byte in buffer */ - if ( buf_len > 1 ) { - next = &buf[1]; - next_len = buf_len - 1; - } - else { - // buffer is truncated - return INVALID_INSN; - } - } - /* we encountered a multibyte opcode: recurse using the - * table specified in the opcode definition */ - sub_size = ia32_table_lookup( next, next_len, subtable, - raw_insn, prefixes ); - - /* SSE/prefix hack: if the original opcode def was a - * prefix that specified a subtable, and the subtable - * lookup returned a valid insn, then we have encountered - * an SSE opcode definition; otherwise, we pretend we - * never did the subtable lookup, and deal with the - * prefix normally later */ - if ( prefix && ( sub_size == INVALID_INSN || - INS_TYPE((*raw_insn)->mnem_flag) == INS_INVALID ) ) { - /* this is a prefix, not an SSE insn : - * lookup next byte in main table, - * subsize will be reset during the - * main table lookup */ - recurse_table = 1; - } else { - /* this is either a subtable (two-byte) insn - * or an invalid insn: either way, set prefix - * to NULL and end the opcode lookup */ - prefix = 0; - // short-circuit lookup on invalid insn - if (sub_size == INVALID_INSN) return INVALID_INSN; - } - } else if ( prefix ) { - recurse_table = 1; - } - - /* by default, we assume that we have the opcode definition, - * and there is no need to recurse on the same table, but - * if we do then a prefix was encountered... */ - if ( recurse_table ) { - /* this must have been a prefix: use the same table for - * lookup of the next byte */ - sub_size = ia32_table_lookup( &buf[1], buf_len - 1, table, - raw_insn, prefixes ); - - // short-circuit lookup on invalid insn - if (sub_size == INVALID_INSN) return INVALID_INSN; - - /* a bit of a hack for branch hints */ - if ( prefix & BRANCH_HINT_MASK ) { - if ( INS_GROUP((*raw_insn)->mnem_flag) == INS_EXEC ) { - /* segment override prefixes are invalid for - * all branch instructions, so delete them */ - prefix &= ~PREFIX_REG_MASK; - } else { - prefix &= ~BRANCH_HINT_MASK; - } - } - - /* apply prefix to instruction */ - - /* TODO: implement something enforcing prefix groups */ - (*prefixes) |= prefix; - } - - /* if this lookup was in a ModR/M table, then an opcode byte is - * NOT consumed: subtract accordingly. NOTE that if none of the - * operands used the ModR/M, then we need to consume the byte - * here, but ONLY in the 'top-level' opcode extension table */ - - if ( table_desc->type == tbl_ext_ext ) { - /* extensions-to-extensions never consume a byte */ - --size; - } else if ( (table_desc->type == tbl_extension || - table_desc->type == tbl_fpu || - table_desc->type == tbl_fpu_ext ) && - /* extensions that have an operand encoded in ModR/M - * never consume a byte */ - (uses_modrm_flag((*raw_insn)->dest_flag) || - uses_modrm_flag((*raw_insn)->src_flag) ) ) { - --size; - } - - size += sub_size; - - return size; -} - -static size_t handle_insn_suffix( unsigned char *buf, size_t buf_len, - ia32_insn_t *raw_insn, x86_insn_t * insn ) { - ia32_table_desc_t *table_desc; - ia32_insn_t *sfx_insn; - size_t size; - unsigned int prefixes = 0; - - table_desc = &ia32_tables[raw_insn->table]; - size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn, - &prefixes ); - if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) { - return 0; - } - - strncpy( insn->mnemonic, sfx_insn->mnemonic, 16 ); - handle_insn_metadata( insn, sfx_insn ); - - return 1; -} - -/* invalid instructions are handled by returning 0 [error] from the - * function, setting the size of the insn to 1 byte, and copying - * the byte at the start of the invalid insn into the x86_insn_t. - * if the caller is saving the x86_insn_t for invalid instructions, - * instead of discarding them, this will maintain a consistent - * address space in the x86_insn_ts */ - -/* this function is called by the controlling disassembler, so its name and - * calling convention cannot be changed */ -/* buf points to the loc of the current opcode (start of the - * instruction) in the instruction stream. The instruction - * stream is assumed to be a buffer of bytes read directly - * from the file for the purpose of disassembly; a mem-mapped - * file is ideal for * this. - * insn points to a code structure to be filled by instr_decode - * returns the size of the decoded instruction in bytes */ -size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len, - x86_insn_t *insn ) { - ia32_insn_t *raw_insn = NULL; - unsigned int prefixes = 0; - size_t size, sfx_size; - - if ( (ia32_settings.options & opt_ignore_nulls) && buf_len > 3 && - !buf[0] && !buf[1] && !buf[2] && !buf[3]) { - /* IF IGNORE_NULLS is set AND - * first 4 bytes in the intruction stream are NULL - * THEN return 0 (END_OF_DISASSEMBLY) */ - /* TODO: set errno */ - MAKE_INVALID( insn, buf ); - return 0; /* 4 00 bytes in a row? This isn't code! */ - } - - /* Perform recursive table lookup starting with main table (0) */ - size = ia32_table_lookup(buf, buf_len, idx_Main, &raw_insn, &prefixes); - if ( size == INVALID_INSN || size > buf_len || raw_insn->mnem_flag == INS_INVALID ) { - MAKE_INVALID( insn, buf ); - /* TODO: set errno */ - return 0; - } - - /* We now have the opcode itself figured out: we can decode - * the rest of the instruction. */ - size += ia32_decode_insn( &buf[size], buf_len - size, raw_insn, insn, - prefixes ); - if ( raw_insn->mnem_flag & INS_FLAG_SUFFIX ) { - /* AMD 3DNow! suffix -- get proper operand type here */ - sfx_size = handle_insn_suffix( &buf[size], buf_len - size, - raw_insn, insn ); - if (! sfx_size ) { - /* TODO: set errno */ - MAKE_INVALID( insn, buf ); - return 0; - } - - size += sfx_size; - } - - if (! size ) { - /* invalid insn */ - MAKE_INVALID( insn, buf ); - return 0; - } - - - insn->size = size; - return size; /* return size of instruction in bytes */ -} diff --git a/intercept/libdisasm/ia32_insn.h b/intercept/libdisasm/ia32_insn.h deleted file mode 100644 index d3f36c3..0000000 --- a/intercept/libdisasm/ia32_insn.h +++ /dev/null @@ -1,506 +0,0 @@ -#ifndef IA32_INSN_H -#define IA32_INSN_H -/* this file contains the structure of opcode definitions and the - * constants they use */ - -#include -#include "libdis.h" - - -#define GET_BYTE( buf, buf_len ) buf_len ? *buf : 0 - -#define OP_SIZE_16 1 -#define OP_SIZE_32 2 -#define ADDR_SIZE_16 4 -#define ADDR_SIZE_32 8 - -#define MAX_INSTRUCTION_SIZE 20 - -/* invalid instructions are handled by returning 0 [error] from the - * function, setting the size of the insn to 1 byte, and copying - * the byte at the start of the invalid insn into the x86_insn_t. - * if the caller is saving the x86_insn_t for invalid instructions, - * instead of discarding them, this will maintain a consistent - * address space in the x86_insn_ts */ - -#define INVALID_INSN ((size_t) -1) /* return value for invalid insn */ -#define MAKE_INVALID( i, buf ) \ - strcpy( i->mnemonic, "invalid" ); \ - x86_oplist_free( i ); \ - i->size = 1; \ - i->group = insn_none; \ - i->type = insn_invalid; \ - memcpy( i->bytes, buf, 1 ); - - -size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len, - x86_insn_t *insn); - - -/* --------------------------------------------------------- Table Lookup */ -/* IA32 Instruction defintion for ia32_opcodes.c */ -typedef struct { - unsigned int table; /* escape to this sub-table */ - unsigned int mnem_flag; /* Flags referring to mnemonic */ - unsigned int notes; /* Notes for this instruction */ - unsigned int dest_flag, src_flag, aux_flag; /* and for specific operands */ - unsigned int cpu; /* minimumCPU [AND with clocks?? */ - char mnemonic[16]; /* buffers for building instruction */ - char mnemonic_att[16]; /* at&t style mnemonic name */ - int32_t dest; - int32_t src; - int32_t aux; - unsigned int flags_effected; - unsigned int implicit_ops; /* implicit operands */ -} ia32_insn_t; - - - -/* --------------------------------------------------------- Prefixes */ -/* Prefix Flags */ -/* Prefixes, same order as in the manual */ -/* had to reverse the values of the first three as they were entered into - * libdis.h incorrectly. */ -#define PREFIX_LOCK 0x0004 -#define PREFIX_REPNZ 0x0002 -#define PREFIX_REPZ 0x0001 -#define PREFIX_OP_SIZE 0x0010 -#define PREFIX_ADDR_SIZE 0x0020 -#define PREFIX_CS 0x0100 -#define PREFIX_SS 0x0200 -#define PREFIX_DS 0x0300 -#define PREFIX_ES 0x0400 -#define PREFIX_FS 0x0500 -#define PREFIX_GS 0x0600 -#define PREFIX_TAKEN 0x1000 /* branch taken */ -#define PREFIX_NOTTAKEN 0x2000 /* branch not taken */ -#define PREFIX_REG_MASK 0x0F00 -#define BRANCH_HINT_MASK 0x3000 -#define PREFIX_PRINT_MASK 0x000F /* printable prefixes */ -#define PREFIX_MASK 0xFFFF - -/* ---------------------------------------------------------- CPU Type */ - -#define cpu_8086 0x0001 -#define cpu_80286 0x0002 -#define cpu_80386 0x0003 -#define cpu_80387 0x0004 /* originally these were a co-proc */ -#define cpu_80486 0x0005 -#define cpu_PENTIUM 0x0006 -#define cpu_PENTPRO 0x0007 -#define cpu_PENTIUM2 0x0008 -#define cpu_PENTIUM3 0x0009 -#define cpu_PENTIUM4 0x000A -#define cpu_K6 0x0010 -#define cpu_K7 0x0020 -#define cpu_ATHLON 0x0030 -#define CPU_MODEL_MASK 0xFFFF -#define CPU_MODEL(cpu) (cpu & CPU_MODEL_MASK) -/* intel instruction subsets */ -#define isa_GP 0x10000 /* General Purpose Instructions */ -#define isa_FPU 0x20000 /* FPU instructions */ -#define isa_FPUMGT 0x30000 /* FPU/SIMD Management */ -#define isa_MMX 0x40000 /* MMX */ -#define isa_SSE1 0x50000 /* SSE */ -#define isa_SSE2 0x60000 /* SSE 2 */ -#define isa_SSE3 0x70000 /* SSE 3 */ -#define isa_3DNOW 0x80000 /* AMD 3d Now */ -#define isa_SYS 0x90000 /* System Instructions */ -#define ISA_SUBSET_MASK 0xFFFF0000 -#define ISA_SUBSET(isa) (isa & ISA_SUBSET_MASK) - - -/* ------------------------------------------------------ Operand Decoding */ -#define ARG_NONE 0 - -/* Using a mask allows us to store info such as OP_SIGNED in the - * operand flags field */ -#define OPFLAGS_MASK 0x0000FFFF - -/* Operand Addressing Methods, per intel manual */ -#define ADDRMETH_MASK 0x00FF0000 - -/* note: for instructions with implied operands, use no ADDRMETH */ -#define ADDRMETH_A 0x00010000 -#define ADDRMETH_C 0x00020000 -#define ADDRMETH_D 0x00030000 -#define ADDRMETH_E 0x00040000 -#define ADDRMETH_F 0x00050000 -#define ADDRMETH_G 0x00060000 -#define ADDRMETH_I 0x00070000 -#define ADDRMETH_J 0x00080000 -#define ADDRMETH_M 0x00090000 -#define ADDRMETH_O 0x000A0000 -#define ADDRMETH_P 0x000B0000 -#define ADDRMETH_Q 0x000C0000 -#define ADDRMETH_R 0x000D0000 -#define ADDRMETH_S 0x000E0000 -#define ADDRMETH_T 0x000F0000 -#define ADDRMETH_V 0x00100000 -#define ADDRMETH_W 0x00110000 -#define ADDRMETH_X 0x00120000 -#define ADDRMETH_Y 0x00130000 -#define ADDRMETH_RR 0x00140000 /* gen reg hard-coded in opcode */ -#define ADDRMETH_RS 0x00150000 /* seg reg hard-coded in opcode */ -#define ADDRMETH_RT 0x00160000 /* test reg hard-coded in opcode */ -#define ADDRMETH_RF 0x00170000 /* fpu reg hard-coded in opcode */ -#define ADDRMETH_II 0x00180000 /* immediate hard-coded in opcode */ -#define ADDRMETH_PP 0x00190000 /* mm reg ONLY in modr/m field */ -#define ADDRMETH_VV 0x001A0000 /* xmm reg ONLY in mod/rm field */ - -/* Operand Types, per intel manual */ -#define OPTYPE_MASK 0xFF000000 - -#define OPTYPE_a 0x01000000 /* BOUND: h:h or w:w */ -#define OPTYPE_b 0x02000000 /* byte */ -#define OPTYPE_c 0x03000000 /* byte or word */ -#define OPTYPE_d 0x04000000 /* word */ -#define OPTYPE_dq 0x05000000 /* qword */ -#define OPTYPE_p 0x06000000 /* 16:16 or 16:32 pointer */ -#define OPTYPE_pi 0x07000000 /* dword MMX reg */ -#define OPTYPE_ps 0x08000000 /* 128-bit single fp */ -#define OPTYPE_q 0x09000000 /* dword */ -#define OPTYPE_s 0x0A000000 /* 6-byte descriptor */ -#define OPTYPE_ss 0x0B000000 /* scalar of 128-bit single fp */ -#define OPTYPE_si 0x0C000000 /* word general register */ -#define OPTYPE_v 0x0D000000 /* hword or word */ -#define OPTYPE_w 0x0E000000 /* hword */ -#define OPTYPE_m 0x0F000000 /* to handle LEA */ -#define OPTYPE_none 0xFF000000 /* no valid operand size, INVLPG */ - -/* custom ones for FPU instructions */ -#define OPTYPE_fs 0x10000000 /* pointer to single-real*/ -#define OPTYPE_fd 0x20000000 /* pointer to double real */ -#define OPTYPE_fe 0x30000000 /* pointer to extended real */ -#define OPTYPE_fb 0x40000000 /* pointer to packed BCD */ -#define OPTYPE_fv 0x50000000 /* pointer to FPU env: 14|28-bytes */ -#define OPTYPE_ft 0x60000000 /* pointer to FPU state: 94|108-bytes */ -#define OPTYPE_fx 0x70000000 /* pointer to FPU regs: 512 bites */ -#define OPTYPE_fp 0x80000000 /* general fpu register: dbl ext */ - -/* SSE2 operand types */ -#define OPTYPE_sd 0x90000000 /* scalar of 128-bit double fp */ -#define OPTYPE_pd 0xA0000000 /* 128-bit double fp */ - - - -/* ---------------------------------------------- Opcode Table Descriptions */ -/* the table type describes how to handle byte/size increments before - * and after lookup. Some tables re-use the current byte, others - * consume a byte only if the ModR/M encodes no operands, etc */ -enum ia32_tbl_type_id { - tbl_opcode = 0, /* standard opcode table: no surprises */ - tbl_prefix, /* Prefix Override, e.g. 66/F2/F3 */ - tbl_suffix, /* 3D Now style */ - tbl_extension, /* ModR/M extension: 00-FF -> 00-07 */ - tbl_ext_ext, /* extension of modr/m using R/M field */ - tbl_fpu, /* fpu table: 00-BF -> 00-0F */ - tbl_fpu_ext /* fpu extension : C0-FF -> 00-1F */ - }; - -/* How it works: - * Bytes are 'consumed' if the next table lookup requires that the byte - * pointer be advanced in the instruction stream. 'Does not consume' means - * that, when the lookup function recurses, the same byte it re-used in the - * new table. It also means that size is not decremented, for example when - * a ModR/M byte is used. Note that tbl_extension (ModR/M) instructions that - * do not increase the size of an insn with their operands have a forced - 3 size increase in the lookup algo. Weird, yes, confusing, yes, welcome - * to the Intel ISA. Another note: tbl_prefix is used as an override, so an - * empty insn in a prefix table causes the instruction in the original table - * to be used, rather than an invalid insn being generated. - * tbl_opcode uses current byte and consumes it - * tbl_prefix uses current byte but does not consume it - * tbl_suffix uses and consumes last byte in insn - * tbl_extension uses current byte but does not consume it - * tbl_ext_ext uses current byte but does not consume it - * tbl_fpu uses current byte and consumes it - * tbl_fpu_ext uses current byte but does not consume it - */ - -/* Convenience struct for opcode tables : these will be stored in a - * 'table of tables' so we can use a table index instead of a pointer */ -typedef struct { /* Assembly instruction tables */ - ia32_insn_t *table; /* Pointer to table of instruction encodings */ - enum ia32_tbl_type_id type; - unsigned char shift; /* amount to shift modrm byte */ - unsigned char mask; /* bit mask for look up */ - unsigned char minlim,maxlim; /* limits on min/max entries. */ -} ia32_table_desc_t; - - -/* ---------------------------------------------- 'Cooked' Operand Type Info */ -/* Permissions: */ -#define OP_R 0x001 /* operand is READ */ -#define OP_W 0x002 /* operand is WRITTEN */ -#define OP_RW 0x003 /* (OP_R|OP_W): convenience macro */ -#define OP_X 0x004 /* operand is EXECUTED */ - -#define OP_PERM_MASK 0x0000007 /* perms are NOT mutually exclusive */ -#define OP_PERM( type ) (type & OP_PERM_MASK) - -/* Flags */ -#define OP_SIGNED 0x010 /* operand is signed */ - -#define OP_FLAG_MASK 0x0F0 /* mods are NOT mutually exclusive */ -#define OP_FLAGS( type ) (type & OP_FLAG_MASK) - -#define OP_REG_MASK 0x0000FFFF /* lower WORD is register ID */ -#define OP_REGTBL_MASK 0xFFFF0000 /* higher word is register type [gen/dbg] */ -#define OP_REGID( type ) (type & OP_REG_MASK) -#define OP_REGTYPE( type ) (type & OP_REGTBL_MASK) - -/* ------------------------------------------'Cooked' Instruction Type Info */ -/* high-bit opcode types/insn meta-types */ -#define INS_FLAG_PREFIX 0x10000000 /* insn is a prefix */ -#define INS_FLAG_SUFFIX 0x20000000 /* followed by a suffix byte */ -#define INS_FLAG_MASK 0xFF000000 - -/* insn notes */ -#define INS_NOTE_RING0 0x00000001 /* insn is privileged */ -#define INS_NOTE_SMM 0x00000002 /* Sys Mgt Mode only */ -#define INS_NOTE_SERIAL 0x00000004 /* serializes */ -#define INS_NOTE_NONSWAP 0x00000008 /* insn is not swapped in att format */ // could be separate field? -#define INS_NOTE_NOSUFFIX 0x00000010 /* insn has no size suffix in att format */ // could be separate field? -//#define INS_NOTE_NMI - -#define INS_INVALID 0 - -/* instruction groups */ -#define INS_EXEC 0x1000 -#define INS_ARITH 0x2000 -#define INS_LOGIC 0x3000 -#define INS_STACK 0x4000 -#define INS_COND 0x5000 -#define INS_LOAD 0x6000 -#define INS_ARRAY 0x7000 -#define INS_BIT 0x8000 -#define INS_FLAG 0x9000 -#define INS_FPU 0xA000 -#define INS_TRAPS 0xD000 -#define INS_SYSTEM 0xE000 -#define INS_OTHER 0xF000 - -#define INS_GROUP_MASK 0xF000 -#define INS_GROUP( type ) ( type & INS_GROUP_MASK ) - -/* INS_EXEC group */ -#define INS_BRANCH (INS_EXEC | 0x01) /* Unconditional branch */ -#define INS_BRANCHCC (INS_EXEC | 0x02) /* Conditional branch */ -#define INS_CALL (INS_EXEC | 0x03) /* Jump to subroutine */ -#define INS_CALLCC (INS_EXEC | 0x04) /* Jump to subroutine */ -#define INS_RET (INS_EXEC | 0x05) /* Return from subroutine */ - -/* INS_ARITH group */ -#define INS_ADD (INS_ARITH | 0x01) -#define INS_SUB (INS_ARITH | 0x02) -#define INS_MUL (INS_ARITH | 0x03) -#define INS_DIV (INS_ARITH | 0x04) -#define INS_INC (INS_ARITH | 0x05) /* increment */ -#define INS_DEC (INS_ARITH | 0x06) /* decrement */ -#define INS_SHL (INS_ARITH | 0x07) /* shift right */ -#define INS_SHR (INS_ARITH | 0x08) /* shift left */ -#define INS_ROL (INS_ARITH | 0x09) /* rotate left */ -#define INS_ROR (INS_ARITH | 0x0A) /* rotate right */ -#define INS_MIN (INS_ARITH | 0x0B) /* min func */ -#define INS_MAX (INS_ARITH | 0x0C) /* max func */ -#define INS_AVG (INS_ARITH | 0x0D) /* avg func */ -#define INS_FLR (INS_ARITH | 0x0E) /* floor func */ -#define INS_CEIL (INS_ARITH | 0x0F) /* ceiling func */ - -/* INS_LOGIC group */ -#define INS_AND (INS_LOGIC | 0x01) -#define INS_OR (INS_LOGIC | 0x02) -#define INS_XOR (INS_LOGIC | 0x03) -#define INS_NOT (INS_LOGIC | 0x04) -#define INS_NEG (INS_LOGIC | 0x05) -#define INS_NAND (INS_LOGIC | 0x06) - -/* INS_STACK group */ -#define INS_PUSH (INS_STACK | 0x01) -#define INS_POP (INS_STACK | 0x02) -#define INS_PUSHREGS (INS_STACK | 0x03) /* push register context */ -#define INS_POPREGS (INS_STACK | 0x04) /* pop register context */ -#define INS_PUSHFLAGS (INS_STACK | 0x05) /* push all flags */ -#define INS_POPFLAGS (INS_STACK | 0x06) /* pop all flags */ -#define INS_ENTER (INS_STACK | 0x07) /* enter stack frame */ -#define INS_LEAVE (INS_STACK | 0x08) /* leave stack frame */ - -/* INS_COND group */ -#define INS_TEST (INS_COND | 0x01) -#define INS_CMP (INS_COND | 0x02) - -/* INS_LOAD group */ -#define INS_MOV (INS_LOAD | 0x01) -#define INS_MOVCC (INS_LOAD | 0x02) -#define INS_XCHG (INS_LOAD | 0x03) -#define INS_XCHGCC (INS_LOAD | 0x04) -#define INS_CONV (INS_LOAD | 0x05) /* move and convert type */ - -/* INS_ARRAY group */ -#define INS_STRCMP (INS_ARRAY | 0x01) -#define INS_STRLOAD (INS_ARRAY | 0x02) -#define INS_STRMOV (INS_ARRAY | 0x03) -#define INS_STRSTOR (INS_ARRAY | 0x04) -#define INS_XLAT (INS_ARRAY | 0x05) - -/* INS_BIT group */ -#define INS_BITTEST (INS_BIT | 0x01) -#define INS_BITSET (INS_BIT | 0x02) -#define INS_BITCLR (INS_BIT | 0x03) - -/* INS_FLAG group */ -#define INS_CLEARCF (INS_FLAG | 0x01) /* clear Carry flag */ -#define INS_CLEARZF (INS_FLAG | 0x02) /* clear Zero flag */ -#define INS_CLEAROF (INS_FLAG | 0x03) /* clear Overflow flag */ -#define INS_CLEARDF (INS_FLAG | 0x04) /* clear Direction flag */ -#define INS_CLEARSF (INS_FLAG | 0x05) /* clear Sign flag */ -#define INS_CLEARPF (INS_FLAG | 0x06) /* clear Parity flag */ -#define INS_SETCF (INS_FLAG | 0x07) -#define INS_SETZF (INS_FLAG | 0x08) -#define INS_SETOF (INS_FLAG | 0x09) -#define INS_SETDF (INS_FLAG | 0x0A) -#define INS_SETSF (INS_FLAG | 0x0B) -#define INS_SETPF (INS_FLAG | 0x0C) -#define INS_TOGCF (INS_FLAG | 0x10) /* toggle */ -#define INS_TOGZF (INS_FLAG | 0x20) -#define INS_TOGOF (INS_FLAG | 0x30) -#define INS_TOGDF (INS_FLAG | 0x40) -#define INS_TOGSF (INS_FLAG | 0x50) -#define INS_TOGPF (INS_FLAG | 0x60) - -/* INS_FPU */ -#define INS_FMOV (INS_FPU | 0x1) -#define INS_FMOVCC (INS_FPU | 0x2) -#define INS_FNEG (INS_FPU | 0x3) -#define INS_FABS (INS_FPU | 0x4) -#define INS_FADD (INS_FPU | 0x5) -#define INS_FSUB (INS_FPU | 0x6) -#define INS_FMUL (INS_FPU | 0x7) -#define INS_FDIV (INS_FPU | 0x8) -#define INS_FSQRT (INS_FPU | 0x9) -#define INS_FCMP (INS_FPU | 0xA) -#define INS_FCOS (INS_FPU | 0xC) /* cosine */ -#define INS_FLDPI (INS_FPU | 0xD) /* load pi */ -#define INS_FLDZ (INS_FPU | 0xE) /* load 0 */ -#define INS_FTAN (INS_FPU | 0xF) /* tanget */ -#define INS_FSINE (INS_FPU | 0x10) /* sine */ -#define INS_FSYS (INS_FPU | 0x20) /* misc */ - -/* INS_TRAP */ -#define INS_TRAP (INS_TRAPS | 0x01) /* generate trap */ -#define INS_TRAPCC (INS_TRAPS | 0x02) /* conditional trap gen */ -#define INS_TRET (INS_TRAPS | 0x03) /* return from trap */ -#define INS_BOUNDS (INS_TRAPS | 0x04) /* gen bounds trap */ -#define INS_DEBUG (INS_TRAPS | 0x05) /* gen breakpoint trap */ -#define INS_TRACE (INS_TRAPS | 0x06) /* gen single step trap */ -#define INS_INVALIDOP (INS_TRAPS | 0x07) /* gen invalid insn */ -#define INS_OFLOW (INS_TRAPS | 0x08) /* gen overflow trap */ -#define INS_ICEBP (INS_TRAPS | 0x09) /* ICE breakpoint */ - -/* INS_SYSTEM */ -#define INS_HALT (INS_SYSTEM | 0x01) /* halt machine */ -#define INS_IN (INS_SYSTEM | 0x02) /* input form port */ -#define INS_OUT (INS_SYSTEM | 0x03) /* output to port */ -#define INS_CPUID (INS_SYSTEM | 0x04) /* identify cpu */ - -/* INS_OTHER */ -#define INS_NOP (INS_OTHER | 0x01) -#define INS_BCDCONV (INS_OTHER | 0x02) /* convert to/from BCD */ -#define INS_SZCONV (INS_OTHER | 0x03) /* convert size of operand */ -#define INS_SALC (INS_OTHER | 0x04) /* set %al on carry */ -#define INS_UNKNOWN (INS_OTHER | 0x05) - - -#define INS_TYPE_MASK 0xFFFF -#define INS_TYPE( type ) ( type & INS_TYPE_MASK ) - - /* flags effected by instruction */ -#define INS_TEST_CARRY 0x01 /* carry */ -#define INS_TEST_ZERO 0x02 /* zero/equal */ -#define INS_TEST_OFLOW 0x04 /* overflow */ -#define INS_TEST_DIR 0x08 /* direction */ -#define INS_TEST_SIGN 0x10 /* negative */ -#define INS_TEST_PARITY 0x20 /* parity */ -#define INS_TEST_OR 0x40 /* used in jle */ -#define INS_TEST_NCARRY 0x100 /* ! carry */ -#define INS_TEST_NZERO 0x200 /* ! zero */ -#define INS_TEST_NOFLOW 0x400 /* ! oflow */ -#define INS_TEST_NDIR 0x800 /* ! dir */ -#define INS_TEST_NSIGN 0x100 /* ! sign */ -#define INS_TEST_NPARITY 0x2000 /* ! parity */ -/* SF == OF */ -#define INS_TEST_SFEQOF 0x4000 -/* SF != OF */ -#define INS_TEST_SFNEOF 0x8000 - -#define INS_TEST_ALL INS_TEST_CARRY | INS_TEST_ZERO | \ - INS_TEST_OFLOW | INS_TEST_SIGN | \ - INS_TEST_PARITY - -#define INS_SET_CARRY 0x010000 /* carry */ -#define INS_SET_ZERO 0x020000 /* zero/equal */ -#define INS_SET_OFLOW 0x040000 /* overflow */ -#define INS_SET_DIR 0x080000 /* direction */ -#define INS_SET_SIGN 0x100000 /* negative */ -#define INS_SET_PARITY 0x200000 /* parity */ -#define INS_SET_NCARRY 0x1000000 -#define INS_SET_NZERO 0x2000000 -#define INS_SET_NOFLOW 0x4000000 -#define INS_SET_NDIR 0x8000000 -#define INS_SET_NSIGN 0x10000000 -#define INS_SET_NPARITY 0x20000000 -#define INS_SET_SFEQOF 0x40000000 -#define INS_SET_SFNEOF 0x80000000 - -#define INS_SET_ALL INS_SET_CARRY | INS_SET_ZERO | \ - INS_SET_OFLOW | INS_SET_SIGN | \ - INS_SET_PARITY - -#define INS_TEST_MASK 0x0000FFFF -#define INS_FLAGS_TEST(x) (x & INS_TEST_MASK) -#define INS_SET_MASK 0xFFFF0000 -#define INS_FLAGS_SET(x) (x & INS_SET_MASK) - -#if 0 -/* TODO: actually start using these */ -#define X86_PAIR_NP 1 /* not pairable; execs in U */ -#define X86_PAIR_PU 2 /* pairable in U pipe */ -#define X86_PAIR_PV 3 /* pairable in V pipe */ -#define X86_PAIR_UV 4 /* pairable in UV pipe */ -#define X86_PAIR_FX 5 /* pairable with FXCH */ - -#define X86_EXEC_PORT_0 1 -#define X86_EXEC_PORT_1 2 -#define X86_EXEC_PORT_2 4 -#define X86_EXEC_PORT_3 8 -#define X86_EXEC_PORT_4 16 - -#define X86_EXEC_UNITS - -typedef struct { /* representation of an insn during decoding */ - uint32_t flags; /* runtime settings */ - /* instruction prefixes and other foolishness */ - uint32_t prefix; /* encoding of prefix */ - char prefix_str[16]; /* mnemonics for prefix */ - uint32_t branch_hint; /* gah! */ - unsigned int cpu_ver; /* TODO: cpu version */ - unsigned int clocks; /* TODO: clock cycles: min/max */ - unsigned char last_prefix; - /* runtime intruction decoding helpers */ - unsigned char mode; /* 16, 32, 64 */ - unsigned char gen_regs; /* offset of default general reg set */ - unsigned char sz_operand; /* operand size for insn */ - unsigned char sz_address; /* address size for insn */ - unsigned char uops; /* uops per insn */ - unsigned char pairing; /* np,pu,pv.lv */ - unsigned char exec_unit; - unsigned char exec_port; - unsigned char latency; -} ia32_info_t; -#define MODE_32 0 /* default */ -#define MODE_16 1 -#define MODE_64 2 -#endif - -#endif diff --git a/intercept/libdisasm/ia32_invariant.c b/intercept/libdisasm/ia32_invariant.c deleted file mode 100644 index 68ec153..0000000 --- a/intercept/libdisasm/ia32_invariant.c +++ /dev/null @@ -1,313 +0,0 @@ -#include -#include - -#include "ia32_invariant.h" -#include "ia32_insn.h" -#include "ia32_settings.h" - -extern ia32_table_desc_t *ia32_tables; -extern ia32_settings_t ia32_settings; - -extern size_t ia32_table_lookup( unsigned char *buf, size_t buf_len, - unsigned int table, ia32_insn_t **raw_insn, - unsigned int *prefixes ); - - -/* -------------------------------- ModR/M, SIB */ -/* Convenience flags */ -#define MODRM_EA 1 /* ModR/M is an effective addr */ -#define MODRM_reg 2 /* ModR/M is a register */ - -/* ModR/M flags */ -#define MODRM_RM_SIB 0x04 /* R/M == 100 */ -#define MODRM_RM_NOREG 0x05 /* R/B == 101 */ -/* if (MODRM.MOD_NODISP && MODRM.RM_NOREG) then just disp32 */ -#define MODRM_MOD_NODISP 0x00 /* mod == 00 */ -#define MODRM_MOD_DISP8 0x01 /* mod == 01 */ -#define MODRM_MOD_DISP32 0x02 /* mod == 10 */ -#define MODRM_MOD_NOEA 0x03 /* mod == 11 */ -/* 16-bit modrm flags */ -#define MOD16_MOD_NODISP 0 -#define MOD16_MOD_DISP8 1 -#define MOD16_MOD_DISP16 2 -#define MOD16_MOD_REG 3 - -#define MOD16_RM_BXSI 0 -#define MOD16_RM_BXDI 1 -#define MOD16_RM_BPSI 2 -#define MOD16_RM_BPDI 3 -#define MOD16_RM_SI 4 -#define MOD16_RM_DI 5 -#define MOD16_RM_BP 6 -#define MOD16_RM_BX 7 - -/* SIB flags */ -#define SIB_INDEX_NONE 0x04 -#define SIB_BASE_EBP 0x05 -#define SIB_SCALE_NOBASE 0x00 - -/* Convenience struct for modR/M bitfield */ -struct modRM_byte { - unsigned int mod : 2; - unsigned int reg : 3; - unsigned int rm : 3; -}; - -/* Convenience struct for SIB bitfield */ -struct SIB_byte { - unsigned int scale : 2; - unsigned int index : 3; - unsigned int base : 3; -}; - -#ifdef WIN32 -static void byte_decode(unsigned char b, struct modRM_byte *modrm) { -#else -static inline void byte_decode(unsigned char b, struct modRM_byte *modrm) { -#endif - /* generic bitfield-packing routine */ - - modrm->mod = b >> 6; /* top 2 bits */ - modrm->reg = (b & 56) >> 3; /* middle 3 bits */ - modrm->rm = b & 7; /* bottom 3 bits */ -} -static int ia32_invariant_modrm( unsigned char *in, unsigned char *out, - unsigned int mode_16, x86_invariant_op_t *op) { - struct modRM_byte modrm; - struct SIB_byte sib; - unsigned char *c, *cin; - unsigned short *s; - unsigned int *i; - int size = 0; /* modrm byte is already counted */ - - - byte_decode(*in, &modrm); /* get bitfields */ - - out[0] = in[0]; /* save modrm byte */ - cin = &in[1]; - c = &out[1]; - s = (unsigned short *)&out[1]; - i = (unsigned int *)&out[1]; - - op->type = op_expression; - op->flags |= op_pointer; - if ( ! mode_16 && modrm.rm == MODRM_RM_SIB && - modrm.mod != MODRM_MOD_NOEA ) { - size ++; - byte_decode(*cin, (struct modRM_byte *)(void*)&sib); - - out[1] = in[1]; /* save sib byte */ - cin = &in[2]; - c = &out[2]; - s = (unsigned short *)&out[2]; - i = (unsigned int *)&out[2]; - - if ( sib.base == SIB_BASE_EBP && ! modrm.mod ) { - /* disp 32 is variant! */ - memset( i, X86_WILDCARD_BYTE, 4 ); - size += 4; - } - } - - if (! modrm.mod && modrm.rm == 101) { - if ( mode_16 ) { /* straight RVA in disp */ - memset( s, X86_WILDCARD_BYTE, 2 ); - size += 2; - } else { - memset( i, X86_WILDCARD_BYTE, 2 ); - size += 4; - } - } else if (modrm.mod && modrm.mod < 3) { - if (modrm.mod == MODRM_MOD_DISP8) { /* offset in disp */ - *c = *cin; - size += 1; - } else if ( mode_16 ) { - *s = (* ((unsigned short *) cin)); - size += 2; - } else { - *i = (*((unsigned int *) cin)); - size += 4; - } - } else if ( modrm.mod == 3 ) { - op->type = op_register; - op->flags &= ~op_pointer; - } - - return (size); -} - - -static int ia32_decode_invariant( unsigned char *buf, size_t buf_len, - ia32_insn_t *t, unsigned char *out, - unsigned int prefixes, x86_invariant_t *inv) { - - unsigned int addr_size, op_size, mode_16; - unsigned int op_flags[3] = { t->dest_flag, t->src_flag, t->aux_flag }; - int x, type, bytes = 0, size = 0, modrm = 0; - - /* set addressing mode */ - if (ia32_settings.options & opt_16_bit) { - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2; - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2; - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 0 : 1; - } else { - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4; - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4; - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 1 : 0; - } - - for (x = 0; x < 3; x++) { - inv->operands[x].access = (enum x86_op_access) - OP_PERM(op_flags[x]); - inv->operands[x].flags = (enum x86_op_flags) - (OP_FLAGS(op_flags[x]) >> 12); - - switch (op_flags[x] & OPTYPE_MASK) { - case OPTYPE_c: - size = (op_size == 4) ? 2 : 1; - break; - case OPTYPE_a: case OPTYPE_v: - size = (op_size == 4) ? 4 : 2; - break; - case OPTYPE_p: - size = (op_size == 4) ? 6 : 4; - break; - case OPTYPE_b: - size = 1; - break; - case OPTYPE_w: - size = 2; - break; - case OPTYPE_d: case OPTYPE_fs: case OPTYPE_fd: - case OPTYPE_fe: case OPTYPE_fb: case OPTYPE_fv: - case OPTYPE_si: case OPTYPE_fx: - size = 4; - break; - case OPTYPE_s: - size = 6; - break; - case OPTYPE_q: case OPTYPE_pi: - size = 8; - break; - case OPTYPE_dq: case OPTYPE_ps: case OPTYPE_ss: - case OPTYPE_pd: case OPTYPE_sd: - size = 16; - break; - case OPTYPE_m: - size = (addr_size == 4) ? 4 : 2; - break; - default: - break; - } - - type = op_flags[x] & ADDRMETH_MASK; - switch (type) { - case ADDRMETH_E: case ADDRMETH_M: case ADDRMETH_Q: - case ADDRMETH_R: case ADDRMETH_W: - modrm = 1; - bytes += ia32_invariant_modrm( buf, out, - mode_16, &inv->operands[x]); - break; - case ADDRMETH_C: case ADDRMETH_D: case ADDRMETH_G: - case ADDRMETH_P: case ADDRMETH_S: case ADDRMETH_T: - case ADDRMETH_V: - inv->operands[x].type = op_register; - modrm = 1; - break; - case ADDRMETH_A: case ADDRMETH_O: - /* pad with xF4's */ - memset( &out[bytes + modrm], X86_WILDCARD_BYTE, - size ); - bytes += size; - inv->operands[x].type = op_offset; - if ( type == ADDRMETH_O ) { - inv->operands[x].flags |= op_signed | - op_pointer; - } - break; - case ADDRMETH_I: case ADDRMETH_J: - /* grab imm value */ - if ((op_flags[x] & OPTYPE_MASK) == OPTYPE_v) { - /* assume this is an address */ - memset( &out[bytes + modrm], - X86_WILDCARD_BYTE, size ); - } else { - memcpy( &out[bytes + modrm], - &buf[bytes + modrm], size ); - } - - bytes += size; - if ( type == ADDRMETH_J ) { - if ( size == 1 ) { - inv->operands[x].type = - op_relative_near; - } else { - inv->operands[x].type = - op_relative_far; - } - inv->operands[x].flags |= op_signed; - } else { - inv->operands[x].type = op_immediate; - } - break; - case ADDRMETH_F: - inv->operands[x].type = op_register; - break; - case ADDRMETH_X: - inv->operands[x].flags |= op_signed | - op_pointer | op_ds_seg | op_string; - break; - case ADDRMETH_Y: - inv->operands[x].flags |= op_signed | - op_pointer | op_es_seg | op_string; - break; - case ADDRMETH_RR: - inv->operands[x].type = op_register; - break; - case ADDRMETH_II: - inv->operands[x].type = op_immediate; - break; - default: - inv->operands[x].type = op_unused; - break; - } - } - - return (bytes + modrm); -} - -size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len, - x86_invariant_t *inv ) { - ia32_insn_t *raw_insn = NULL; - unsigned int prefixes; - unsigned int type; - size_t size; - - /* Perform recursive table lookup starting with main table (0) */ - size = ia32_table_lookup( buf, buf_len, 0, &raw_insn, &prefixes ); - if ( size == INVALID_INSN || size > buf_len ) { - /* TODO: set errno */ - return 0; - } - - /* copy opcode bytes to buffer */ - memcpy( inv->bytes, buf, size ); - - /* set mnemonic type and group */ - type = raw_insn->mnem_flag & ~INS_FLAG_MASK; - inv->group = (enum x86_insn_group) (INS_GROUP(type)) >> 12; - inv->type = (enum x86_insn_type) INS_TYPE(type); - - /* handle operands */ - size += ia32_decode_invariant( buf + size, buf_len - size, raw_insn, - &buf[size - 1], prefixes, inv ); - - inv->size = size; - - return size; /* return size of instruction in bytes */ -} - -size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) { - x86_invariant_t inv = { {0} }; - return( ia32_disasm_invariant( buf, buf_len, &inv ) ); -} diff --git a/intercept/libdisasm/ia32_invariant.h b/intercept/libdisasm/ia32_invariant.h deleted file mode 100644 index e1cea60..0000000 --- a/intercept/libdisasm/ia32_invariant.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IA32_INVARIANT_H -#define IA32_INVARIANT_H - -#include "libdis.h" - -size_t ia32_disasm_invariant( unsigned char *buf, size_t buf_len, - x86_invariant_t *inv); - -size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ); - -#endif diff --git a/intercept/libdisasm/ia32_modrm.c b/intercept/libdisasm/ia32_modrm.c deleted file mode 100644 index b0fe2ed..0000000 --- a/intercept/libdisasm/ia32_modrm.c +++ /dev/null @@ -1,310 +0,0 @@ -#include "ia32_modrm.h" -#include "ia32_reg.h" -#include "x86_imm.h" - -/* NOTE: when decoding ModR/M and SIB, we have to add 1 to all register - * values obtained from decoding the ModR/M or SIB byte, since they - * are encoded with eAX = 0 and the tables in ia32_reg.c use eAX = 1. - * ADDENDUM: this is only the case when the register value is used - * directly as an index into the register table, not when it is added to - * a genregs offset. */ - -/* -------------------------------- ModR/M, SIB */ -/* ModR/M flags */ -#define MODRM_RM_SIB 0x04 /* R/M == 100 */ -#define MODRM_RM_NOREG 0x05 /* R/B == 101 */ - -/* if (MODRM.MOD_NODISP && MODRM.RM_NOREG) then just disp32 */ -#define MODRM_MOD_NODISP 0x00 /* mod == 00 */ -#define MODRM_MOD_DISP8 0x01 /* mod == 01 */ -#define MODRM_MOD_DISP32 0x02 /* mod == 10 */ -#define MODRM_MOD_NOEA 0x03 /* mod == 11 */ - -/* 16-bit modrm flags */ -#define MOD16_MOD_NODISP 0 -#define MOD16_MOD_DISP8 1 -#define MOD16_MOD_DISP16 2 -#define MOD16_MOD_REG 3 - -#define MOD16_RM_BXSI 0 -#define MOD16_RM_BXDI 1 -#define MOD16_RM_BPSI 2 -#define MOD16_RM_BPDI 3 -#define MOD16_RM_SI 4 -#define MOD16_RM_DI 5 -#define MOD16_RM_BP 6 -#define MOD16_RM_BX 7 - -/* SIB flags */ -#define SIB_INDEX_NONE 0x04 -#define SIB_BASE_EBP 0x05 -#define SIB_SCALE_NOBASE 0x00 - -/* Convenience struct for modR/M bitfield */ -struct modRM_byte { - unsigned int mod : 2; - unsigned int reg : 3; - unsigned int rm : 3; -}; - -/* Convenience struct for SIB bitfield */ -struct SIB_byte { - unsigned int scale : 2; - unsigned int index : 3; - unsigned int base : 3; -}; - - -#if 0 -int modrm_rm[] = {0,1,2,3,MODRM_RM_SIB,MODRM_MOD_DISP32,6,7}; -int modrm_reg[] = {0, 1, 2, 3, 4, 5, 6, 7}; -int modrm_mod[] = {0, MODRM_MOD_DISP8, MODRM_MOD_DISP32, MODRM_MOD_NOEA}; -int sib_scl[] = {0, 2, 4, 8}; -int sib_idx[] = {0, 1, 2, 3, SIB_INDEX_NONE, 5, 6, 7 }; -int sib_bas[] = {0, 1, 2, 3, 4, SIB_SCALE_NOBASE, 6, 7 }; -#endif - -/* this is needed to replace x86_imm_signsized() which does not sign-extend - * to dest */ -static unsigned int imm32_signsized( unsigned char *buf, size_t buf_len, - int32_t *dest, unsigned int size ) { - if ( size > buf_len ) { - return 0; - } - - switch (size) { - case 1: - *dest = *((signed char *) buf); - break; - case 2: - *dest = *((signed short *) buf); - break; - case 4: - default: - *dest = *((signed int *) buf); - break; - } - - return size; -} - - - -static void byte_decode(unsigned char b, struct modRM_byte *modrm) { - /* generic bitfield-packing routine */ - - modrm->mod = b >> 6; /* top 2 bits */ - modrm->reg = (b & 56) >> 3; /* middle 3 bits */ - modrm->rm = b & 7; /* bottom 3 bits */ -} - - -static size_t sib_decode( unsigned char *buf, size_t buf_len, x86_ea_t *ea, - unsigned int mod ) { - /* set Address Expression fields (scale, index, base, disp) - * according to the contents of the SIB byte. - * b points to the SIB byte in the instruction-stream buffer; the - * byte after b[0] is therefore the byte after the SIB - * returns number of bytes 'used', including the SIB byte */ - size_t size = 1; /* start at 1 for SIB byte */ - struct SIB_byte sib; - - if ( buf_len < 1 ) { - return 0; - } - - byte_decode( *buf, (struct modRM_byte *)(void*)&sib ); /* get bit-fields */ - - if ( sib.base == SIB_BASE_EBP && ! mod ) { /* if base == 101 (ebp) */ - /* IF BASE == EBP, deal with exception */ - /* IF (ModR/M did not create a Disp */ - /* ... create a 32-bit Displacement */ - imm32_signsized( &buf[1], buf_len, &ea->disp, sizeof(int32_t)); - ea->disp_size = sizeof(int32_t); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; /* add sizeof disp to count */ - - } else { - /* ELSE BASE refers to a General Register */ - ia32_handle_register( &ea->base, sib.base + 1 ); - } - - /* set scale to 1, 2, 4, 8 */ - ea->scale = 1 << sib.scale; - - if (sib.index != SIB_INDEX_NONE) { - /* IF INDEX is not 'ESP' (100) */ - ia32_handle_register( &ea->index, sib.index + 1 ); - } - - return (size); /* return number of bytes processed */ -} - -static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, struct modRM_byte *modrm ) { - /* 16-bit mode: hackish, but not as hackish as 32-bit mode ;) */ - size_t size = 1; /* # of bytes decoded [1 for modR/M byte] */ - x86_ea_t * ea = &op->data.expression; - - switch( modrm->rm ) { - case MOD16_RM_BXSI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_BXDI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); - case MOD16_RM_BPSI: - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_BPDI: - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); - ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); - break; - case MOD16_RM_SI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 6); - break; - case MOD16_RM_DI: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 7); - break; - case MOD16_RM_BP: - if ( modrm->mod != MOD16_MOD_NODISP ) { - op->flags |= op_ss_seg; - ia32_handle_register(&ea->base, - REG_WORD_OFFSET + 5); - } - break; - case MOD16_RM_BX: - ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); - break; - } - - /* move to byte after ModR/M */ - ++buf; - --buf_len; - - if ( modrm->mod == MOD16_MOD_DISP8 ) { - imm32_signsized( buf, buf_len, &ea->disp, sizeof(char) ); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - ea->disp_size = sizeof(char); - size += sizeof(char); - } else if ( modrm->mod == MOD16_MOD_DISP16 ) { - imm32_signsized( buf, buf_len, &ea->disp, sizeof(short) ); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - ea->disp_size = sizeof(short); - size += sizeof(short); - } - - return size; -} - -/* TODO : Mark index modes - Use addressing mode flags to imply arrays (index), structure (disp), - two-dimensional arrays [disp + index], classes [ea reg], and so on. -*/ -size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, x86_insn_t *insn, size_t gen_regs ) { - /* create address expression and/or fill operand based on value of - * ModR/M byte. Calls sib_decode as appropriate. - * flags specifies whether Reg or mod+R/M fields are being decoded - * returns the number of bytes in the instruction, including modR/M */ - struct modRM_byte modrm; - size_t size = 1; /* # of bytes decoded [1 for modR/M byte] */ - x86_ea_t * ea; - - - byte_decode(*buf, &modrm); /* get bitfields */ - - /* first, handle the case where the mod field is a register only */ - if ( modrm.mod == MODRM_MOD_NOEA ) { - op->type = op_register; - ia32_handle_register(&op->data.reg, modrm.rm + gen_regs); - /* increase insn size by 1 for modrm byte */ - return 1; - } - - /* then deal with cases where there is an effective address */ - ea = &op->data.expression; - op->type = op_expression; - op->flags |= op_pointer; - - if ( insn->addr_size == 2 ) { - /* gah! 16 bit mode! */ - return modrm_decode16( buf, buf_len, op, &modrm); - } - - /* move to byte after ModR/M */ - ++buf; - --buf_len; - - if (modrm.mod == MODRM_MOD_NODISP) { /* if mod == 00 */ - - /* IF MOD == No displacement, just Indirect Register */ - if (modrm.rm == MODRM_RM_NOREG) { /* if r/m == 101 */ - /* IF RM == No Register, just Displacement */ - /* This is an Intel Moronic Exception TM */ - imm32_signsized( buf, buf_len, &ea->disp, - sizeof(int32_t) ); - ea->disp_size = sizeof(int32_t); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; /* add sizeof disp to count */ - - } else if (modrm.rm == MODRM_RM_SIB) { /* if r/m == 100 */ - /* ELSE IF an SIB byte is present */ - /* TODO: check for 0 retval */ - size += sib_decode( buf, buf_len, ea, modrm.mod); - /* move to byte after SIB for displacement */ - ++buf; - --buf_len; - } else { /* modR/M specifies base register */ - /* ELSE RM encodes a general register */ - ia32_handle_register( &ea->base, modrm.rm + 1 ); - } - } else { /* mod is 01 or 10 */ - if (modrm.rm == MODRM_RM_SIB) { /* rm == 100 */ - /* IF base is an AddrExpr specified by an SIB byte */ - /* TODO: check for 0 retval */ - size += sib_decode( buf, buf_len, ea, modrm.mod); - /* move to byte after SIB for displacement */ - ++buf; - --buf_len; - } else { - /* ELSE base is a general register */ - ia32_handle_register( &ea->base, modrm.rm + 1 ); - } - - /* ELSE mod + r/m specify a disp##[base] or disp##(SIB) */ - if (modrm.mod == MODRM_MOD_DISP8) { /* mod == 01 */ - /* If this is an 8-bit displacement */ - imm32_signsized( buf, buf_len, &ea->disp, - sizeof(char)); - ea->disp_size = sizeof(char); - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 1; /* add sizeof disp to count */ - - } else { - /* Displacement is dependent on address size */ - imm32_signsized( buf, buf_len, &ea->disp, - insn->addr_size); - ea->disp_size = insn->addr_size; - ea->disp_sign = (ea->disp < 0) ? 1 : 0; - size += 4; - } - } - - return size; /* number of bytes found in instruction */ -} - -void ia32_reg_decode( unsigned char byte, x86_op_t *op, size_t gen_regs ) { - struct modRM_byte modrm; - byte_decode( byte, &modrm ); /* get bitfields */ - - /* set operand to register ID */ - op->type = op_register; - ia32_handle_register(&op->data.reg, modrm.reg + gen_regs); - - return; -} diff --git a/intercept/libdisasm/ia32_modrm.h b/intercept/libdisasm/ia32_modrm.h deleted file mode 100644 index 765cb08..0000000 --- a/intercept/libdisasm/ia32_modrm.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef IA32_MODRM_H -#define IA32_MODRM_H - -#include "libdis.h" -#include "ia32_insn.h" - -size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len, - x86_op_t *op, x86_insn_t *insn, - size_t gen_regs ); - -void ia32_reg_decode( unsigned char byte, x86_op_t *op, size_t gen_regs ); - -#endif diff --git a/intercept/libdisasm/ia32_opcode_tables.c b/intercept/libdisasm/ia32_opcode_tables.c deleted file mode 100644 index ef97c7a..0000000 --- a/intercept/libdisasm/ia32_opcode_tables.c +++ /dev/null @@ -1,2939 +0,0 @@ -#include "ia32_insn.h" - -#include "ia32_reg.h" - -#include "ia32_opcode_tables.h" - -static ia32_insn_t tbl_Main[] = { /* One-byte Opcodes */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 1, 0, 0, 0 , 33 }, - { idx_0F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, -/* 0x10 */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_ADD, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 2, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 2, 0, 0, 0 , 33 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_SIGNED | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 3, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 3, 0, 0, 0 , 33 }, -/* 0x20 */ - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_AND, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_ES, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "daa", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_CARRY|INS_SET_PARITY|INS_TEST_CARRY, 12 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_CS | PREFIX_NOTTAKEN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "das", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_CARRY|INS_SET_PARITY|INS_TEST_CARRY, 0 }, -/* 0x30 */ - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_SS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aaa", "", 0, 0, 0, INS_SET_CARRY, 1 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_G | OPTYPE_b | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_DS | PREFIX_TAKEN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aas", "", 0, 0, 0, INS_SET_CARRY, 0 }, -/* 0x40 */ - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 1, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 2, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 3, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 4, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 5, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 6, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_INC, 0, ADDRMETH_RR | OPTYPE_v | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 7, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 1, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 2, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 3, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 4, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 5, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 6, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 7, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, -/* 0x50 */ - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 1, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 2, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 3, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 4, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 5, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 6, 0, 0, 0 , 33 }, - { 0, INS_PUSH, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 7, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 1, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 2, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 3, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 4, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 5, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 6, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 7, 0, 0, 0 , 33 }, -/* 0x60 */ - { 0, INS_PUSHREGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pusha", "", 0, 0, 0, 0 , 36 }, - { 0, INS_POPREGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "popa", "", 0, 0, 0, 0 , 34 }, - { 0, INS_BOUNDS, INS_NOTE_NONSWAP, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_M | OPTYPE_a | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bound", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R | OP_W, ADDRMETH_G | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "arpl", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_FS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_GS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_66, INS_FLAG_PREFIX | PREFIX_OP_SIZE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FLAG_PREFIX | PREFIX_ADDR_SIZE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 0 }, - { 0, INS_IN, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ins", "", 0, 2, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ins", "", 0, 2, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "outs", "", 2, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_X | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "outs", "", 2, 0, 0, 0 , 0 }, -/* 0x70 */ - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ja", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "js", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, -/* 0x80 */ - { idx_80, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_81, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_v, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_82, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_83, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XCHG, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_b | OP_W, ADDRMETH_G | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_v | OP_W, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_b | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_w | OP_W, ADDRMETH_S | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_m | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lea", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_S | OPTYPE_w | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_POP, 0, ADDRMETH_E | OPTYPE_v | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 0, 0, 0, 0 , 33 }, -/* 0x90 */ - { 0, INS_NOP, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "nop", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 1, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 2, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 3, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 4, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 5, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 6, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xchg", "", 0, 7, 0, 0 , 0 }, - { 0, INS_SZCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cwde", "", 0, 0, 0, 0 , 5 }, - { 0, INS_SZCONV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cdq", "", 0, 0, 0, 0 , 11 }, - { 0, INS_CALL, 0, ADDRMETH_A | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "callf", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "wait", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSHFLAGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pushf", "", 0, 0, 0, 0 , 37 }, - { 0, INS_POPFLAGS, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "popf", "", 0, 0, 0, 0 , 35 }, - { 0, INS_MOV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sahf", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 43 }, - { 0, INS_MOV, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lahf", "", 0, 0, 0, 0 , 24 }, -/* 0xa0 */ - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_O | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_O | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_O | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_O | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRMOV, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRMOV, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_X | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_Y | OPTYPE_b | OP_R, ADDRMETH_X | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_X | OPTYPE_v | OP_R, ADDRMETH_Y | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TEST, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_STRSTOR, 0, ADDRMETH_Y | OPTYPE_b | OP_W, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "stos", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRSTOR, 0, ADDRMETH_Y | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_v |OP_R, ARG_NONE, cpu_80386 | isa_GP, "stos", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRLOAD, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_X| OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lods", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRLOAD, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_X| OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lods", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_RR | OPTYPE_b | OP_R, ADDRMETH_Y | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "scas", "", 0, 0, 0, 0 , 0 }, - { 0, INS_STRCMP, 0, ADDRMETH_RR | OPTYPE_v | OP_R, ADDRMETH_Y | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "scas", "", 0, 0, 0, 0 , 0 }, -/* 0xb0 */ - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 1, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 2, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 3, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 4, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 5, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 6, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 7, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 1, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 2, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 3, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 4, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 5, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 6, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 7, 0, 0, 0 , 0 }, -/* 0xc0 */ - { idx_C0, 0, 0, ADDRMETH_E | OPTYPE_b, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_C1, 0, 0, ADDRMETH_E | OPTYPE_v, ADDRMETH_I | OPTYPE_b, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_RET, 0, ADDRMETH_I | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ret", "", 0, 0, 0, 0 , 3 }, - { 0, INS_RET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ret", "", 0, 0, 0, 0 , 3 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_R, ARG_NONE, cpu_80386 | isa_GP, "les", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lds", "", 0, 0, 0, 0 , 0 }, - { idx_C6, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_C7, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ENTER, INS_NOTE_NONSWAP, ADDRMETH_I | OPTYPE_w | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "enter", "", 0, 0, 0, 0 , 15 }, - { 0, INS_LEAVE, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "leave", "", 0, 0, 0, 0 , 26 }, - { 0, INS_RET, 0, ADDRMETH_I | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "retf", "lret", 0, 0, 0, 0 , 3 }, - { 0, INS_RET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "retf", "lret", 0, 0, 0, 0 , 3 }, - { 0, INS_DEBUG, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "int3", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TRAP, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "int", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OFLOW, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "into", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_TRET, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "iret", "", 0, 0, 0, INS_SET_ALL|INS_SET_DIR, 0 }, -/* 0xd0 */ - { idx_D0, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D1, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D2, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { idx_D3, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 1, 0, 0 , 0 }, - { 0, INS_BCDCONV, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aam", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_BCDCONV, 0, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "aad", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 2 }, - { 0, INS_SALC, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "salc", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XLAT, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "xlat", "", 0, 0, 0, 0 , 53 }, - { idx_D8, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_D9, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DA, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DB, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DC, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DD, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_DF, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, -/* 0xe0 */ - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loopnz", "", 0, 0, 0, INS_TEST_NZERO, 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loopz", "", 0, 0, 0, INS_TEST_ZERO, 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "loop", "", 0, 0, 0, 0 , 31 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_b | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jcxz", "", 0, 0, 0, 0 , 31 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 0, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_I | OPTYPE_b | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_I | OPTYPE_b | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CALL, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 3 }, - { 0, INS_BRANCH, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_A | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_J | OPTYPE_b | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_b| OP_W, ADDRMETH_RR | OPTYPE_w| OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 2, 0, 0 , 0 }, - { 0, INS_IN, 0, ADDRMETH_RR | OPTYPE_v | OP_W, ADDRMETH_RR | OPTYPE_w| OP_R, ARG_NONE, cpu_80386 | isa_GP, "in", "", 0, 2, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_w| OP_R, ADDRMETH_RR | OPTYPE_b| OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 2, 0, 0, 0 , 0 }, - { 0, INS_OUT, 0, ADDRMETH_RR | OPTYPE_w| OP_R, ADDRMETH_RR | OPTYPE_v| OP_R, ARG_NONE, cpu_80386 | isa_GP, "out", "", 2, 0, 0, 0 , 0 }, -/* 0xf0 */ - { 0, INS_FLAG_PREFIX | PREFIX_LOCK, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ICEBP, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "icebp", "", 0, 0, 0, 0 , 0 }, - { idx_F2, INS_FLAG_PREFIX | PREFIX_REPNZ, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_F3, INS_FLAG_PREFIX | PREFIX_REPZ, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_HALT, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "hlt", "", 0, 0, 0, 0 , 0 }, - { 0, INS_TOGCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cmc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { idx_F6, 0, 0, ADDRMETH_E | OPTYPE_b, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_F7, 0, 0, ADDRMETH_E | OPTYPE_v, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CLEARCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "clc", "", 0, 0, 0, INS_SET_NCARRY, 0 }, - { 0, INS_SETCF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "stc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cli", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sti", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CLEARDF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "cld", "", 0, 0, 0, INS_SET_NDIR, 0 }, - { 0, INS_SETDF, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "std", "", 0, 0, 0, INS_SET_DIR, 0 }, - { idx_FE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_FF, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_66[] = { /* SIMD 66 one-byte Opcodes */ - { idx_660F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_F2[] = { /* SIMD F2 one-byte Opcodes */ - { idx_F20F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_F3[] = { /* SIMD F3 one-byte Opcodes */ - { idx_F30F, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pause", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */ - { idx_0F00, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F01, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lar", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "lsl", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "clts", "", 0, 0, 0, 0 , 6 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "wbinvd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_UNKNOWN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTPRO | isa_GP, "ud2", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "prefetch", "", 0, 0, 0, 0, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "femms", "", 0, 0, 0, 0, 0 }, - { idx_0F0F, INS_FLAG_SUFFIX, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movups", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movups", "", 0, 0, 0, 0 , 0 }, - { idx_0F12, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "unpcklps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "unpckhps", "", 0, 0, 0, 0 , 0 }, - { idx_0F16, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_q | OP_W, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { idx_0F18, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_C | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_D | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_C | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_D | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_R | OPTYPE_d | OP_W, ADDRMETH_T | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_T | OPTYPE_d | OP_W, ADDRMETH_R | OPTYPE_d | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movaps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movaps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvtpi2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_ps | OP_W, ADDRMETH_V | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movntps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvttps2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W , ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "cvtps2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ss | OP_W, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "ucomiss", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ss | OP_W, ARG_NONE, cpu_PENTIUM2 | isa_GP, "comiss", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "wrmsr", "", 0, 0, 0, 0 , 52 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "rdtsc", "", 0, 0, 0, 0 , 40 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "rdmsr", "", 0, 0, 0, 0 , 38 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTPRO | isa_GP, "rdpmc", "", 0, 0, 0, 0 , 39 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sysenter", "", 0, 0, 0, 0 , 50 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sysexit", "", 0, 0, 0, 0 , 51 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmova", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovs", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovp", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovnp", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "cmovg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movmskps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sqrtps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "rsqrtps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "rcpps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "andps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "andnps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OR, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "orps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XOR, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "xorps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "addps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "mulps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd, ADDRMETH_W | OPTYPE_q, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtps2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtdq2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "subps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "minps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_DIV, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "divps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "maxps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpcklbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpcklwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckldq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packsswb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpgtd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packuswb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "punpckhdq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "packssdw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_d | OP_W, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pshufw", "", 0, 0, 0, 0, 0 }, - { idx_0F71, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F72, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F73, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pcmpeqd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "emms", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_d | OP_W, ADDRMETH_P | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_Q | OPTYPE_q | OP_W, ADDRMETH_P | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "movq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jo", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jno", "", 0, 0, 0, INS_TEST_NOFLOW, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ja", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "js", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_BRANCHCC, 0, ADDRMETH_J | OPTYPE_v | OP_X | OP_SIGNED, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "seto", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setno", "", 0, 0, 0, INS_TEST_OFLOW, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setc", "", 0, 0, 0, INS_TEST_CARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setnc", "", 0, 0, 0, INS_TEST_NCARRY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setz", "", 0, 0, 0, INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setnz", "", 0, 0, 0, INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setbe", "", 0, 0, 0, INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "seta", "", 0, 0, 0, INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sets", "", 0, 0, 0, INS_TEST_SIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setns", "", 0, 0, 0, INS_TEST_NSIGN, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setpe", "", 0, 0, 0, INS_TEST_PARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setpo", "", 0, 0, 0, INS_TEST_NPARITY, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setl", "", 0, 0, 0, INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setge", "", 0, 0, 0, INS_TEST_SFEQOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setle", "", 0, 0, 0, INS_TEST_ZERO|INS_TEST_OR|INS_TEST_SFNEOF, 0 }, - { 0, INS_MOVCC, 0, ADDRMETH_E | OPTYPE_b | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "setg", "", 0, 0, 0, INS_TEST_NZERO|INS_TEST_SFEQOF, 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 4, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 4, 0, 0, 0 , 33 }, - { 0, INS_CPUID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cpuid", "", 0, 0, 0, 0 , 10 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bt", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_80386 | isa_GP, "shld", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - //{ 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OP_R | OPTYPE_b | ADDRMETH_RR, cpu_80386 | isa_GP, "shld", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_RR | OP_R | OPTYPE_b, cpu_80386 | isa_GP, "shld", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_RS | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 5, 0, 0, 0 , 33 }, - { 0, INS_POP, 0, ADDRMETH_RS | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "pop", "", 5, 0, 0, 0 , 33 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "rsm", "", 0, 0, 0, INS_SET_ALL|INS_SET_DIR, 42 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bts", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_80386 | isa_GP, "shrd", "", 0, 0, 0, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ADDRMETH_RR | OP_R | OPTYPE_b , cpu_80386 | isa_GP, "shrd", "", 0, 0, 1, INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { idx_0FAE, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_G | OPTYPE_v | OP_SIGNED | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, }, - { 0, INS_XCHGCC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W, ARG_NONE, cpu_80486 | isa_GP, "cmpxchg", "", 0, 0, 0, INS_SET_ALL, 8 }, - { 0, INS_XCHGCC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W, ARG_NONE, cpu_80486 | isa_GP, "cmpxchg", "", 0, 0, 0, INS_SET_ALL, 7 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lss", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btr", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lfs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_M | OPTYPE_p | OP_W, ARG_NONE, cpu_80386 | isa_GP, "lgs", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movzx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movzx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_UNKNOWN, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ud1", "", 0, 0, 0, 0 , 0 }, - { idx_0FBA, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_G | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btc", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_G | OPTYPE_v | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bsf", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_G | OPTYPE_v | OP_R | OP_W, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bsr", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movsx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_G | OPTYPE_v | OP_W, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, cpu_80386 | isa_GP, "movsx", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_G | OPTYPE_b | OP_W, ARG_NONE, cpu_80486 | isa_GP, "xadd", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_G | OPTYPE_v | OP_W, ARG_NONE, cpu_80486 | isa_GP, "xadd", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpps", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_M | OPTYPE_d | OP_W, ADDRMETH_G | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movnti", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pinsrw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "pextrw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_ps | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM2 | isa_GP, "shufps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_R | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxchg8b", "", 0, 0, 0, 0, 9 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 1, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 2, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 3, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 4, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 5, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 6, 0, 0, 0 , 0 }, - { 0, INS_XCHG, 0, ADDRMETH_RR | OPTYPE_d | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "bswap", "", 7, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddq", "", 0, 0, 0, 0, 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmullw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_G | OPTYPE_d | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmovmskb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubusb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubusw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pminub", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pand", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddusb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddusw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmaxub", "", 0, 0, 0, 0 , 0 }, - { 0, INS_AND, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pandn", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pavgb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pavgw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmulhuw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmulhw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_W | OPTYPE_q | OP_W, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movntq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pminsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OR, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "por", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddsb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmaxsw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XOR, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pxor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmaddwd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "psadbw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_pi | OP_W, ADDRMETH_Q | OPTYPE_pi | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "maskmovq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddb", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddd", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F[] = { /* SIMD 66 Two-byte Opcodes */ - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movupd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movupd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_M | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "unpcklpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "unpckhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_M | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movapd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MOV, 0, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movapd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpi2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_M | OPTYPE_pd | OP_R, ADDRMETH_V | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movntpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttpd2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2pi", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "ucomisd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "comisd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movmskpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_FSQRT, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "andpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_AND, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "andnpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_OR, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "orpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_XOR, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "xorpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2ps", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtps2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckldq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packsswb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpgtd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packuswb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "packssdw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpcklqdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "punpckhqdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_d | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqa", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufd", "", 0, 0, 0, 0, 0 }, - { idx_660F71, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { idx_660F72, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { idx_660F73, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pcmpeqd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "haddpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "hsubpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_V | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqa", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmppd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_w | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pinsrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_w | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pextrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "shufpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsubpd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrlw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrld", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrlq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmullw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_q | OP_R, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmovmskb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubusb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubusw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pminub", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pand", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddusb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddusw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaxub", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pandn", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pavgb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psraw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psrad", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pavgw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmulhuw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmulhw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttpd2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_M | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movntdq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubsb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pminsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "por", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddsb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaxsw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pxor", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psllw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pslld", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psllq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmaddwd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psadbw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maskmovdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddb", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddw", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "paddd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_F20F[] = { /* SIMD F2 Two-byte Opcodes */ - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_sd | OP_R, ADDRMETH_V | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movddup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsi2sd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttsd2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsd2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsd2ss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshuflw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "haddps", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "hsubps", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_sd | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpsd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addsubps", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_P | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdq2q", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_pd | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtpd2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_M | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "lddqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_F30F[] = { /* SIMD F3 Two-byte Opcodes */ - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_ss | OP_R, ADDRMETH_V | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movsldup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ps | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movshdup", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtsi2ss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttss2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_G | OPTYPE_d | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtss2si", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "sqrtss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "rsqrtss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "rcpss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "addss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mulss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_sd | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtss2sd", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_ps | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvttps2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "subss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "minss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "divss", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "maxss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufhw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_q | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_W | OPTYPE_dq | OP_R, ADDRMETH_V | OPTYPE_dq | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movdqu", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_ss | OP_R, ADDRMETH_W | OPTYPE_ss | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "cmpss", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_dq | OP_R, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "movq2dq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_UNKNOWN, 0, ADDRMETH_V | OPTYPE_pd | OP_R, ADDRMETH_W | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "cvtdq2pd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F00[] = { /* Group 6 */ - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sldt", "", 0, 0, 0, 0 , 46 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "str", "", 0, 0, 0, 0 , 49 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lldt", "", 0, 0, 0, 0 , 29 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "ltr", "", 0, 0, 0, 0 , 32 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "verr", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "verw", "", 0, 0, 0, INS_SET_ZERO, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F01[] = { /* Group 7 */ - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sgdt", "", 0, 0, 0, 0 , 44 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "sidt", "", 0, 0, 0, 0 , 45 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lgdt", "", 0, 0, 0, 0 , 27 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_s | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lidt", "", 0, 0, 0, 0 , 28 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_none | OP_R, ARG_NONE, ARG_NONE, cpu_80486 | isa_GP, "invlpg", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { idx_0F0111, 0, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "smsw", "", 0, 0, 0, 0 , 47 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_w | OP_W, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "lmsw", "", 0, 0, 0, 0 , 30 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F0111[] = { /* Monitor/MWait opcode */ - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "monitor", "", 0, 0, 0, 0, 54 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "mwait", "", 0, 0, 0, 0, 55 } -}; - - -static ia32_insn_t tbl_0F12[] = { /* Movlps Opcode */ - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movlps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_R | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R , ARG_NONE, cpu_PENTIUM4 | isa_GP, "movhlps", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F16[] = { /* Movhps Opcode */ - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_V | OPTYPE_q | OP_W, ADDRMETH_M | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movhps", "", 0, 0, 0, 0 , 0 }, - { 0, INS_MOV, 0, ADDRMETH_V | OPTYPE_ps | OP_R | OP_W, ADDRMETH_W | OPTYPE_ps | OP_R , ARG_NONE, cpu_PENTIUM4 | isa_GP, "movlhps", "", 0, 0, 0, 0, 0 } -}; - - -static ia32_insn_t tbl_0F18[] = { /* Group 16 */ - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, OP_W | OPTYPE_b | ADDRMETH_M, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetchnta", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht0", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht1", "", 1, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_RT | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "prefetcht2", "", 2, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F71[] = { /* Group 12 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F71[] = { /* Group 12 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psraw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F72[] = { /* Group 13 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F72[] = { /* Group 13 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrad", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0F73[] = { /* Group 14 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_660F73[] = { /* Group 14 SSE */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrlq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psrldq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 }, - { 0, INS_OTHER, 0, ADDRMETH_W | OPTYPE_dq | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslldq", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0FAE[] = { /* Group 15 */ - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxsave", "", 0, 0, 0, 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_E | OPTYPE_fx | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_MMX, "fxrstor", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "ldmxcsr", "", 0, 0, 0, 0 , 25 }, - { 0, INS_SYSTEM, 0, ADDRMETH_E | OPTYPE_d | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM2, "stmxcsr", "", 0, 0, 0 , 0, 48 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ADDRMETH_M | OPTYPE_b | OP_R, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "clflush", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "lfence", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "mfence", "", 0, 0, 0, 0 , 0 }, - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "sfence", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_0FBA[] = { /* Group 8 */ - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bt", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "bts", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btr", "", 0, 0, 0, INS_SET_CARRY, 0 }, - { 0, INS_BITTEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "btc", "", 0, 0, 0 , INS_SET_CARRY, 0 } -}; - - -static ia32_insn_t tbl_0FC7[] = { /* Group 9 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }, - { 0, INS_XCHGCC, 0, ADDRMETH_M | OPTYPE_q | OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM | isa_GP, "cmpxch8b", "", 0, 0, 0 , 0 , 9 } -}; - - -static ia32_insn_t tbl_0FB9[] = { /* Group 10 */ - { 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "fxsave", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_C6[] = { /* Group 11a */ - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_b | OP_W, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_C7[] = { /* Group 11b */ - { 0, INS_MOV, 0, ADDRMETH_E | OPTYPE_v | OP_W, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mov", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_80[] = { /* Group 1a */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_81[] = { /* Group 1b */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_82[] = { /* Group 1c */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_83[] = { /* Group 1d */ - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "add", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_OR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "or", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_ADD, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "adc", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sbb", "", 0, 0, 0, INS_SET_ALL|INS_TEST_CARRY, 0 }, - { 0, INS_AND, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "and", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SUB, 0, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sub", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_XOR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "xor", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_CMP, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "cmp", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_C0[] = { /* Group 2a */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_C1[] = { /* Group 2b */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 0, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 0, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D0[] = { /* Group 2c */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_II | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D1[] = { /* Group 2d */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_II | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D2[] = { /* Group 2e */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_D3[] = { /* Group 2f */ - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rol", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "ror", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW, 0 }, - { 0, INS_ROL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcl", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_ROR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "rcr", "", 0, 1, 0, INS_SET_CARRY|INS_SET_OFLOW|INS_TEST_CARRY, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shl", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "shr", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHL, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sal", "", 0, 1, 0, INS_SET_ALL, 0 }, - { 0, INS_SHR, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ADDRMETH_RR | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "sar", "", 0, 1, 0 , INS_SET_ALL, 0 } -}; - - -static ia32_insn_t tbl_F6[] = { /* Group 3a */ - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_b | OP_R, ADDRMETH_I | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_NOT, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "not", "", 0, 0, 0, 0 , 0 }, - { 0, INS_NEG, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "neg", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_MUL, 0, OPTYPE_b | ADDRMETH_RR | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 22 }, - { 0, INS_MUL, 0, OPTYPE_b | ADDRMETH_RR | OP_W | OP_SIGNED | OP_R, ADDRMETH_E | OPTYPE_b | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 22 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "div", "", 0, 0, 0, 0 , 13 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_b | OP_W | OP_R, ADDRMETH_E | OPTYPE_b | OP_R, ARG_NONE, cpu_80386 | isa_GP, "idiv", "", 0, 0, 0 , 0 , 13 } -}; - - -static ia32_insn_t tbl_F7[] = { /* Group 3b */ - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_TEST, 0, ADDRMETH_E | OPTYPE_v | OP_R, ADDRMETH_I | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "test", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_NOT, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "not", "", 0, 0, 0, 0 , 0 }, - { 0, INS_NEG, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "neg", "", 0, 0, 0, INS_SET_ALL, 0 }, - { 0, INS_MUL, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "mul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 23 }, - { 0, INS_MUL, 0, ADDRMETH_RR | OPTYPE_v | OP_SIGNED | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_SIGNED | OP_R, ARG_NONE, cpu_80386 | isa_GP, "imul", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_CARRY, 23 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "div", "", 0, 0, 0, 0 , 14 }, - { 0, INS_DIV, 0, ADDRMETH_RR | OPTYPE_v | OP_W | OP_R, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, cpu_80386 | isa_GP, "idiv", "", 0, 0, 0, 0 , 14 } -}; - - -static ia32_insn_t tbl_FE[] = { /* Group 4 */ - { 0, INS_INC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_E | OPTYPE_b | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0 , INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 } -}; - - -static ia32_insn_t tbl_FF[] = { /* Group 5 */ - { 0, INS_INC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "inc", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_DEC, 0, ADDRMETH_E | OPTYPE_v | OP_W | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "dec", "", 0, 0, 0, INS_SET_OFLOW|INS_SET_SIGN|INS_SET_ZERO|INS_SET_PARITY, 0 }, - { 0, INS_CALL, 0, ADDRMETH_E | OPTYPE_v | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 3 }, - { 0, INS_CALL, 0, ADDRMETH_M | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "call", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_E | OPTYPE_v | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_BRANCH, 0, ADDRMETH_M | OPTYPE_p | OP_X, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "jmp", "", 0, 0, 0, 0 , 0 }, - { 0, INS_PUSH, 0, ADDRMETH_E | OPTYPE_v | OP_R, ARG_NONE, ARG_NONE, cpu_80386 | isa_GP, "push", "", 0, 0, 0, 0 , 33 } -}; - - -static ia32_insn_t tbl_D8[] = { /* FPU D8 */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D8C0[] = { /* FPU D8 C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 7, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D9[] = { /* FPU D9 */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fs|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fv|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldenv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldcw", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fv|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstenv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstcw", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_D9C0[] = { /* FPU D9 C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fxch", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnop", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fchs", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fabs", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ftst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fxam", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldl2t", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldl2e", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldpi", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldlg2", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldln2", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fldz", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "f2xm1", "", 0, 0, 0 , 0 , 16 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fyl2x", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fptan", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fpatan", "", 0, 0, 0 , 0 , 18 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fxtract", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fprem1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdecstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fincstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fprem", "", 0, 0, 0 , 0 , 19 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fyl2xp1", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsqrt", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsincos", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "frndint", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fscale", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsin", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcos", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DA[] = { /* FPU DA */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fiadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fimul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidivr", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DAC0[] = { /* FPU DA C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 0, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 1, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 2, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 3, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 4, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 5, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 6, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovb", "", 0, 7, 0 , INS_TEST_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 0, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 1, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 2, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 3, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 4, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 5, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 6, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmove", "", 0, 7, 0 , INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 0, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 1, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 2, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 3, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 4, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 5, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 6, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovbe", "", 0, 7, 0 , INS_TEST_CARRY|INS_TEST_OR|INS_TEST_ZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 0, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 1, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 2, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 3, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 4, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 5, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 6, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcmovu", "", 0, 7, 0 , INS_TEST_PARITY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fucompp", "", 0, 0, 0 , 0 , 21 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DB[] = { /* FPU DB */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fist", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_d|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fe|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fe|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DBC0[] = { /* FPU DB C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 0, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 1, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 2, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 3, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 4, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 5, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 6, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnb", "", 0, 7, 0 , INS_TEST_NCARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 0, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 1, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 2, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 3, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 4, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 5, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 6, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovne", "", 0, 7, 0 , INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 0, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 1, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 2, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 3, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 4, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 5, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 6, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnbe", "", 0, 7, 0 , INS_TEST_NCARRY|INS_TEST_NZERO, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 0, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 1, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 2, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 3, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 4, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 5, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 6, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcmovnu", "", 0, 7, 0 , INS_TEST_NPARITY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnclex", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fninit", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomi", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0, }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_PENTPRO | isa_GP, "fcomi", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DC[] = { /* FPU DC */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcom", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 17 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcomp", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_DCC0[] = { /* FPU DC C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fadd", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmul", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubr", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsub", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivr", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdiv", "", 7, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DD[] = { /* FPU DD */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fd|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_ft|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "frstor", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_ft|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnsave", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstsw", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DDC0[] = { /* FPU DD C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ffree", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fst", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fstp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucom", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DE[] = { /* FPU DE */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fiadd", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fimul", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficom", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "ficomp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisub", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fisubr", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidiv", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fidivr", "", 0, 0, 0, 0 , 0 } -}; - - -static ia32_insn_t tbl_DEC0[] = { /* FPU DE C0 */ - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 0, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 1, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 2, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 3, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 4, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 5, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 6, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "faddp", "", 7, 0, 0 , 0 , 20 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fmulp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fcompp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubrp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fsubp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivrp", "", 7, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 1, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 2, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 3, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 4, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 5, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 6, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fdivp", "", 7, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DF[] = { /* FPU DF */ - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_PENTIUM4 | isa_GP, "fisttp", "", 0, 0, 0, 0, 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fist", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_w|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fb|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fbld", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fild", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_fb|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fbstp", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_M|OPTYPE_q|OP_W, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fistp", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_DFC0[] = { /* FPU DF C0 */ - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RR | OPTYPE_w | OP_R, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "fnstsw", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 1, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 2, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 3, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 4, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 5, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 6, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fucomip", "", 0, 7, 0 , 0 , 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 0, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 1, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 2, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 3, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 4, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 5, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 6, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_FPU, 0, ADDRMETH_RF | OPTYPE_fp | OP_W, ADDRMETH_RF | OPTYPE_fp | OP_R, ARG_NONE, cpu_80387 | isa_FPU, "fcomip", "", 0, 7, 0 , INS_SET_ZERO|INS_SET_PARITY|INS_SET_CARRY, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_80387 | isa_FPU, "", "", 0, 0, 0 , 0 , 0 } -}; - - -static ia32_insn_t tbl_0F0F[] = { /* 3D Now! 0F Suffix */ - /* 00 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CONV, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pi2fd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 10 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CONV, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pf2id", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 20 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 30 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 40 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 50 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 60 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 70 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - /* 80 */ { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpge", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MIN, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmin", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcp", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrsqrt", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfsub", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfadd", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpgt", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MAX, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmax", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcpit1", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrsqit1", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfsubr", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfacc", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_CMP, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfcmpeq", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfmul", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pfrcpit2", "", 0, 0, 0, 0, 0 }, - { 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pmulhrw", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_K6 | isa_3DNOW, "", "", 0, 0, 0, 0, 0 }, - { 0, INS_AVG, 0, ADDRMETH_P | OPTYPE_pi | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q |OP_R, ARG_NONE, cpu_K6 | isa_3DNOW, "pavgusb", "", 0, 0, 0, 0, 0 } -}; - - - -/* ================== Table of Opcode Tables ================== */ -ia32_table_desc_t ia32_tables[] = { - /* table, prefix table, type, shift, mask, min, max */ - { tbl_Main, tbl_opcode, 0x00, 0xFF, 0x00, 0xFF }, - { tbl_66, tbl_prefix, 0x00, 0xFF, 0x0F, 0x0F }, - { tbl_F2, tbl_prefix, 0x00, 0xFF, 0x0F, 0x0F }, - { tbl_F3, tbl_prefix, 0x00, 0xFF, 0x0F, 0x90 }, - { tbl_0F, tbl_opcode, 0x00, 0xFF, 0x00, 0xFF }, - /* 5 */ - { tbl_660F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_F20F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_F30F, tbl_prefix, 0x00, 0xFF, 0x10, 0xFF }, - { tbl_0F00, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_0F01, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 10 */ - { tbl_0F0111, tbl_ext_ext, 0x00, 0x01, 0x00, 0x01 }, - { tbl_0F12, tbl_extension, 0x06, 0x03, 0x00, 0x03 }, - { tbl_0F16, tbl_extension, 0x06, 0x03, 0x00, 0x03 }, - { tbl_0F18, tbl_extension, 0x03, 0x1F, 0x00, 0x13 }, - { tbl_0F71, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 15 */ - { tbl_660F71, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0F72, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_660F72, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0F73, tbl_extension, 0x00, 0x00, 0x00, 0x00 }, - { tbl_660F73, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - /* 20 */ - { tbl_0FAE, tbl_extension, 0x03, 0x1F, 0x00, 0x1F }, - { tbl_0FBA, tbl_extension, 0x03, 0x07, 0x04, 0x07 }, - { tbl_0FC7, tbl_extension, 0x03, 0x1F, 0x00, 0x11 }, - { tbl_0FB9, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - { tbl_C6, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - /* 25 */ - { tbl_C7, tbl_extension, 0x03, 0x07, 0x00, 0x00 }, - { tbl_80, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_81, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_82, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_83, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - /* 30 */ - { tbl_C0, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_C1, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D0, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D1, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_D2, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - /* 35 */ - { tbl_D3, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_F6, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_F7, tbl_extension, 0x03, 0x07, 0x00, 0x07 }, - { tbl_FE, tbl_extension, 0x03, 0x07, 0x00, 0x01 }, - { tbl_FF, tbl_extension, 0x03, 0x07, 0x00, 0x06 }, - /* 40 */ - { tbl_D8, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_D8C0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_D9, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_D9C0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DA, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - /* 45 */ - { tbl_DAC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DB, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DBC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DC, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DCC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - /* 50 */ - { tbl_DD, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DDC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DE, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - { tbl_DEC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_DF, tbl_fpu, 0x03, 0x07, 0x00, 0xBF }, - /* 55 */ - { tbl_DFC0, tbl_fpu_ext, 0x00, 0xFF, 0xC0, 0xFF }, - { tbl_0F0F, tbl_suffix, 0x00, 0xFF, 0x00, 0xBF } -}; -/* ia32_opcode_tables.h */ -/* Table index constants: -#define idx_Main 0 -#define idx_66 1 -#define idx_F2 2 -#define idx_F3 3 -#define idx_0F 4 -#define idx_660F 5 -#define idx_F20F 6 -#define idx_F30F 7 -#define idx_0F00 8 -#define idx_0F01 9 -#define idx_0F0111 10 -#define idx_0F12 11 -#define idx_0F16 12 -#define idx_0F18 13 -#define idx_0F71 14 -#define idx_660F71 15 -#define idx_0F72 16 -#define idx_660F72 17 -#define idx_0F73 18 -#define idx_660F73 19 -#define idx_0FAE 20 -#define idx_0FBA 21 -#define idx_0FC7 22 -#define idx_0FB9 23 -#define idx_C6 24 -#define idx_C7 25 -#define idx_80 26 -#define idx_81 27 -#define idx_82 28 -#define idx_83 29 -#define idx_C0 30 -#define idx_C1 31 -#define idx_D0 32 -#define idx_D1 33 -#define idx_D2 34 -#define idx_D3 35 -#define idx_F6 36 -#define idx_F7 37 -#define idx_FE 38 -#define idx_FF 39 -#define idx_D8 40 -#define idx_D8C0 41 -#define idx_D9 42 -#define idx_D9C0 43 -#define idx_DA 44 -#define idx_DAC0 45 -#define idx_DB 46 -#define idx_DBC0 47 -#define idx_DC 48 -#define idx_DCC0 49 -#define idx_DD 50 -#define idx_DDC0 51 -#define idx_DE 52 -#define idx_DEC0 53 -#define idx_DF 54 -#define idx_DFC0 55 -#define idx_0F0F 56 -*/ diff --git a/intercept/libdisasm/ia32_opcode_tables.h b/intercept/libdisasm/ia32_opcode_tables.h deleted file mode 100644 index bbd4fae..0000000 --- a/intercept/libdisasm/ia32_opcode_tables.h +++ /dev/null @@ -1,57 +0,0 @@ -#define idx_Main 0 -#define idx_66 1 -#define idx_F2 2 -#define idx_F3 3 -#define idx_0F 4 -#define idx_660F 5 -#define idx_F20F 6 -#define idx_F30F 7 -#define idx_0F00 8 -#define idx_0F01 9 -#define idx_0F0111 10 -#define idx_0F12 11 -#define idx_0F16 12 -#define idx_0F18 13 -#define idx_0F71 14 -#define idx_660F71 15 -#define idx_0F72 16 -#define idx_660F72 17 -#define idx_0F73 18 -#define idx_660F73 19 -#define idx_0FAE 20 -#define idx_0FBA 21 -#define idx_0FC7 22 -#define idx_0FB9 23 -#define idx_C6 24 -#define idx_C7 25 -#define idx_80 26 -#define idx_81 27 -#define idx_82 28 -#define idx_83 29 -#define idx_C0 30 -#define idx_C1 31 -#define idx_D0 32 -#define idx_D1 33 -#define idx_D2 34 -#define idx_D3 35 -#define idx_F6 36 -#define idx_F7 37 -#define idx_FE 38 -#define idx_FF 39 -#define idx_D8 40 -#define idx_D8C0 41 -#define idx_D9 42 -#define idx_D9C0 43 -#define idx_DA 44 -#define idx_DAC0 45 -#define idx_DB 46 -#define idx_DBC0 47 -#define idx_DC 48 -#define idx_DCC0 49 -#define idx_DD 50 -#define idx_DDC0 51 -#define idx_DE 52 -#define idx_DEC0 53 -#define idx_DF 54 -#define idx_DFC0 55 -#define idx_0F0F 56 diff --git a/intercept/libdisasm/ia32_operand.c b/intercept/libdisasm/ia32_operand.c deleted file mode 100644 index 8e7f16a..0000000 --- a/intercept/libdisasm/ia32_operand.c +++ /dev/null @@ -1,425 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_operand.h" -#include "ia32_modrm.h" -#include "ia32_reg.h" -#include "x86_imm.h" -#include "x86_operand_list.h" - - - -/* apply segment override to memory operand in insn */ -static void apply_seg( x86_op_t *op, unsigned int prefixes ) { - if (! prefixes ) return; - - /* apply overrides from prefix */ - switch ( prefixes & PREFIX_REG_MASK ) { - case PREFIX_CS: - op->flags |= op_cs_seg; break; - case PREFIX_SS: - op->flags |= op_ss_seg; break; - case PREFIX_DS: - op->flags |= op_ds_seg; break; - case PREFIX_ES: - op->flags |= op_es_seg; break; - case PREFIX_FS: - op->flags |= op_fs_seg; break; - case PREFIX_GS: - op->flags |= op_gs_seg; break; - } - - return; -} - -static size_t decode_operand_value( unsigned char *buf, size_t buf_len, - x86_op_t *op, x86_insn_t *insn, - unsigned int addr_meth, size_t op_size, - unsigned int op_value, unsigned char modrm, - size_t gen_regs ) { - size_t size = 0; - - /* ++ Do Operand Addressing Method / Decode operand ++ */ - switch (addr_meth) { - /* This sets the operand Size based on the Intel Opcode Map - * (Vol 2, Appendix A). Letter encodings are from section - * A.1.1, 'Codes for Addressing Method' */ - - /* ---------------------- Addressing Method -------------- */ - /* Note that decoding mod ModR/M operand adjusts the size of - * the instruction, but decoding the reg operand does not. - * This should not cause any problems, as every 'reg' operand - * has an associated 'mod' operand. - * Goddamn-Intel-Note: - * Some Intel addressing methods [M, R] specify that modR/M - * byte may only refer to a memory address/may only refer to - * a register -- however Intel provides no clues on what to do - * if, say, the modR/M for an M opcode decodes to a register - * rather than a memory address ... returning 0 is out of the - * question, as this would be an Immediate or a RelOffset, so - * instead these modR/Ms are decoded with total disregard to - * the M, R constraints. */ - - /* MODRM -- mod operand. sets size to at least 1! */ - case ADDRMETH_E: /* ModR/M present, Gen reg or memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_M: /* ModR/M only refers to memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_Q: /* ModR/M present, MMX or Memory */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - REG_MMX_OFFSET ); - break; - case ADDRMETH_R: /* ModR/M mod == gen reg */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - gen_regs ); - break; - case ADDRMETH_W: /* ModR/M present, mem or SIMD reg */ - size = ia32_modrm_decode( buf, buf_len, op, insn, - REG_SIMD_OFFSET ); - break; - - /* MODRM -- reg operand. does not effect size! */ - case ADDRMETH_C: /* ModR/M reg == control reg */ - ia32_reg_decode( modrm, op, REG_CTRL_OFFSET ); - break; - case ADDRMETH_D: /* ModR/M reg == debug reg */ - ia32_reg_decode( modrm, op, REG_DEBUG_OFFSET ); - break; - case ADDRMETH_G: /* ModR/M reg == gen-purpose reg */ - ia32_reg_decode( modrm, op, gen_regs ); - break; - case ADDRMETH_P: /* ModR/M reg == qword MMX reg */ - ia32_reg_decode( modrm, op, REG_MMX_OFFSET ); - break; - case ADDRMETH_S: /* ModR/M reg == segment reg */ - ia32_reg_decode( modrm, op, REG_SEG_OFFSET ); - break; - case ADDRMETH_T: /* ModR/M reg == test reg */ - ia32_reg_decode( modrm, op, REG_TEST_OFFSET ); - break; - case ADDRMETH_V: /* ModR/M reg == SIMD reg */ - ia32_reg_decode( modrm, op, REG_SIMD_OFFSET ); - break; - - /* No MODRM : note these set operand type explicitly */ - case ADDRMETH_A: /* No modR/M -- direct addr */ - op->type = op_absolute; - - /* segment:offset address used in far calls */ - x86_imm_sized( buf, buf_len, - &op->data.absolute.segment, 2 ); - if ( insn->addr_size == 4 ) { - x86_imm_sized( buf, buf_len, - &op->data.absolute.offset.off32, 4 ); - size = 6; - } else { - x86_imm_sized( buf, buf_len, - &op->data.absolute.offset.off16, 2 ); - size = 4; - } - - break; - case ADDRMETH_I: /* Immediate val */ - op->type = op_immediate; - /* if it ever becomes legal to have imm as dest and - * there is a src ModR/M operand, we are screwed! */ - if ( op->flags & op_signed ) { - x86_imm_signsized(buf, buf_len, &op->data.byte, - op_size); - } else { - x86_imm_sized(buf, buf_len, &op->data.byte, - op_size); - } - size = op_size; - break; - case ADDRMETH_J: /* Rel offset to add to IP [jmp] */ - /* this fills op->data.near_offset or - op->data.far_offset depending on the size of - the operand */ - op->flags |= op_signed; - if ( op_size == 1 ) { - /* one-byte near offset */ - op->type = op_relative_near; - x86_imm_signsized(buf, buf_len, - &op->data.relative_near, 1); - } else { - /* far offset...is this truly signed? */ - op->type = op_relative_far; - x86_imm_signsized(buf, buf_len, - &op->data.relative_far, op_size ); - } - size = op_size; - break; - case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ - /* NOTE: these are actually RVAs not offsets to seg!! */ - /* note bene: 'O' ADDR_METH uses addr_size to - determine operand size */ - op->type = op_offset; - op->flags |= op_pointer; - x86_imm_sized( buf, buf_len, &op->data.offset, - insn->addr_size ); - - size = insn->addr_size; - break; - - /* Hard-coded: these are specified in the insn definition */ - case ADDRMETH_F: /* EFLAGS register */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, REG_FLAGS_INDEX ); - break; - case ADDRMETH_X: /* Memory addressed by DS:SI [string] */ - op->type = op_expression; - op->flags |= op_hardcode; - op->flags |= op_ds_seg | op_pointer | op_string; - ia32_handle_register( &op->data.expression.base, - REG_DWORD_OFFSET + 6 ); - break; - case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */ - op->type = op_expression; - op->flags |= op_hardcode; - op->flags |= op_es_seg | op_pointer | op_string; - ia32_handle_register( &op->data.expression.base, - REG_DWORD_OFFSET + 7 ); - break; - case ADDRMETH_RR: /* Gen Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + gen_regs ); - break; - case ADDRMETH_RS: /* Seg Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_SEG_OFFSET ); - break; - case ADDRMETH_RF: /* FPU Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_FPU_OFFSET ); - break; - case ADDRMETH_RT: /* TST Register hard-coded in opcode */ - op->type = op_register; - op->flags |= op_hardcode; - ia32_handle_register( &op->data.reg, - op_value + REG_TEST_OFFSET ); - break; - case ADDRMETH_II: /* Immediate hard-coded in opcode */ - op->type = op_immediate; - op->data.dword = op_value; - op->flags |= op_hardcode; - break; - - case 0: /* Operand is not used */ - default: - /* ignore -- operand not used in this insn */ - op->type = op_unused; /* this shouldn't happen! */ - break; - } - - return size; -} - -static size_t decode_operand_size( unsigned int op_type, x86_insn_t *insn, - x86_op_t *op ){ - size_t size; - - /* ++ Do Operand Type ++ */ - switch (op_type) { - /* This sets the operand Size based on the Intel Opcode Map - * (Vol 2, Appendix A). Letter encodings are from section - * A.1.2, 'Codes for Operand Type' */ - /* NOTE: in this routines, 'size' refers to the size - * of the operand in the raw (encoded) instruction; - * 'datatype' stores the actual size and datatype - * of the operand */ - - /* ------------------------ Operand Type ----------------- */ - case OPTYPE_c: /* byte or word [op size attr] */ - size = (insn->op_size == 4) ? 2 : 1; - op->datatype = (size == 4) ? op_word : op_byte; - break; - case OPTYPE_a: /* 2 word or 2 dword [op size attr] */ - /* pointer to a 16:16 or 32:32 BOUNDS operand */ - size = (insn->op_size == 4) ? 8 : 4; - op->datatype = (size == 4) ? op_bounds32 : op_bounds16; - break; - case OPTYPE_v: /* word or dword [op size attr] */ - size = (insn->op_size == 4) ? 4 : 2; - op->datatype = (size == 4) ? op_dword : op_word; - break; - case OPTYPE_p: /* 32/48-bit ptr [op size attr] */ - /* technically these flags are not accurate: the - * value s a 16:16 pointer or a 16:32 pointer, where - * the first '16' is a segment */ - size = (insn->addr_size == 4) ? 6 : 4; - op->datatype = (size == 4) ? op_descr32 : op_descr16; - break; - case OPTYPE_b: /* byte, ignore op-size */ - size = 1; - op->datatype = op_byte; - break; - case OPTYPE_w: /* word, ignore op-size */ - size = 2; - op->datatype = op_word; - break; - case OPTYPE_d: /* dword , ignore op-size */ - size = 4; - op->datatype = op_dword; - break; - case OPTYPE_s: /* 6-byte psuedo-descriptor */ - /* ptr to 6-byte value which is 32:16 in 32-bit - * mode, or 8:24:16 in 16-bit mode. The high byte - * is ignored in 16-bit mode. */ - size = 6; - op->datatype = (insn->addr_size == 4) ? - op_pdescr32 : op_pdescr16; - break; - case OPTYPE_q: /* qword, ignore op-size */ - size = 8; - op->datatype = op_qword; - break; - case OPTYPE_dq: /* d-qword, ignore op-size */ - size = 16; - op->datatype = op_dqword; - break; - case OPTYPE_ps: /* 128-bit FP data */ - size = 16; - /* really this is 4 packed SP FP values */ - op->datatype = op_ssimd; - break; - case OPTYPE_pd: /* 128-bit FP data */ - size = 16; - /* really this is 2 packed DP FP values */ - op->datatype = op_dsimd; - break; - case OPTYPE_ss: /* Scalar elem of 128-bit FP data */ - size = 16; - /* this only looks at the low dword (4 bytes) - * of the xmmm register passed as a param. - * This is a 16-byte register where only 4 bytes - * are used in the insn. Painful, ain't it? */ - op->datatype = op_sssimd; - break; - case OPTYPE_sd: /* Scalar elem of 128-bit FP data */ - size = 16; - /* this only looks at the low qword (8 bytes) - * of the xmmm register passed as a param. - * This is a 16-byte register where only 8 bytes - * are used in the insn. Painful, again... */ - op->datatype = op_sdsimd; - break; - case OPTYPE_pi: /* qword mmx register */ - size = 8; - op->datatype = op_qword; - break; - case OPTYPE_si: /* dword integer register */ - size = 4; - op->datatype = op_dword; - break; - case OPTYPE_fs: /* single-real */ - size = 4; - op->datatype = op_sreal; - break; - case OPTYPE_fd: /* double real */ - size = 8; - op->datatype = op_dreal; - break; - case OPTYPE_fe: /* extended real */ - size = 10; - op->datatype = op_extreal; - break; - case OPTYPE_fb: /* packed BCD */ - size = 10; - op->datatype = op_bcd; - break; - case OPTYPE_fv: /* pointer to FPU env: 14 or 28-bytes */ - size = (insn->addr_size == 4)? 28 : 14; - op->datatype = (size == 28)? op_fpuenv32: op_fpuenv16; - break; - case OPTYPE_ft: /* pointer to FPU env: 94 or 108 bytes */ - size = (insn->addr_size == 4)? 108 : 94; - op->datatype = (size == 108)? - op_fpustate32: op_fpustate16; - break; - case OPTYPE_fx: /* 512-byte register stack */ - size = 512; - op->datatype = op_fpregset; - break; - case OPTYPE_fp: /* floating point register */ - size = 10; /* double extended precision */ - op->datatype = op_fpreg; - break; - case OPTYPE_m: /* fake operand type used for "lea Gv, M" */ - size = insn->addr_size; - op->datatype = (size == 4) ? op_dword : op_word; - break; - case OPTYPE_none: /* handle weird instructions that have no encoding but use a dword datatype, like invlpg */ - size = 0; - op->datatype = op_none; - break; - case 0: - default: - size = insn->op_size; - op->datatype = (size == 4) ? op_dword : op_word; - break; - } - return size; -} - -size_t ia32_decode_operand( unsigned char *buf, size_t buf_len, - x86_insn_t *insn, unsigned int raw_op, - unsigned int raw_flags, unsigned int prefixes, - unsigned char modrm ) { - unsigned int addr_meth, op_type, op_size, gen_regs; - x86_op_t *op; - size_t size; - - /* ++ Yank optype and addr mode out of operand flags */ - addr_meth = raw_flags & ADDRMETH_MASK; - op_type = raw_flags & OPTYPE_MASK; - - if ( raw_flags == ARG_NONE ) { - /* operand is not used in this instruction */ - return 0; - } - - /* allocate a new operand */ - op = x86_operand_new( insn ); - - /* ++ Copy flags from opcode table to x86_insn_t */ - op->access = (enum x86_op_access) OP_PERM(raw_flags); - op->flags = (enum x86_op_flags) (OP_FLAGS(raw_flags) >> 12); - - /* Get size (for decoding) and datatype of operand */ - op_size = decode_operand_size(op_type, insn, op); - - /* override default register set based on Operand Type */ - /* this allows mixing of 8, 16, and 32 bit regs in insn */ - if (op_size == 1) { - gen_regs = REG_BYTE_OFFSET; - } else if (op_size == 2) { - gen_regs = REG_WORD_OFFSET; - } else { - gen_regs = REG_DWORD_OFFSET; - } - - size = decode_operand_value( buf, buf_len, op, insn, addr_meth, - op_size, raw_op, modrm, gen_regs ); - - /* if operand is an address, apply any segment override prefixes */ - if ( op->type == op_expression || op->type == op_offset ) { - apply_seg(op, prefixes); - } - - return size; /* return number of bytes in instruction */ -} diff --git a/intercept/libdisasm/ia32_operand.h b/intercept/libdisasm/ia32_operand.h deleted file mode 100644 index 08c3074..0000000 --- a/intercept/libdisasm/ia32_operand.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IA32_OPERAND_H -#define IA32_OPERAND_H - -#include "libdis.h" -#include "ia32_insn.h" - -size_t ia32_decode_operand( unsigned char *buf, size_t buf_len, - x86_insn_t *insn, unsigned int raw_op, - unsigned int raw_flags, unsigned int prefixes, - unsigned char modrm ); -#endif diff --git a/intercept/libdisasm/ia32_reg.c b/intercept/libdisasm/ia32_reg.c deleted file mode 100644 index f270c1f..0000000 --- a/intercept/libdisasm/ia32_reg.c +++ /dev/null @@ -1,234 +0,0 @@ -#include -#include - -#include "ia32_reg.h" -#include "ia32_insn.h" - -#define NUM_X86_REGS 92 - -/* register sizes */ -#define REG_DWORD_SIZE 4 -#define REG_WORD_SIZE 2 -#define REG_BYTE_SIZE 1 -#define REG_MMX_SIZE 8 -#define REG_SIMD_SIZE 16 -#define REG_DEBUG_SIZE 4 -#define REG_CTRL_SIZE 4 -#define REG_TEST_SIZE 4 -#define REG_SEG_SIZE 2 -#define REG_FPU_SIZE 10 -#define REG_FLAGS_SIZE 4 -#define REG_FPCTRL_SIZE 2 -#define REG_FPSTATUS_SIZE 2 -#define REG_FPTAG_SIZE 2 -#define REG_EIP_SIZE 4 -#define REG_IP_SIZE 2 - -/* REGISTER ALIAS TABLE: - * - * NOTE: the MMX register mapping is fixed to the physical registers - * used by the FPU. The floating FP stack does not effect the location - * of the MMX registers, so this aliasing is not 100% accurate. - * */ -static struct { - unsigned char alias; /* id of register this is an alias for */ - unsigned char shift; /* # of bits register must be shifted */ -} ia32_reg_aliases[] = { - { 0,0 }, - { REG_DWORD_OFFSET, 0 }, /* al : 1 */ - { REG_DWORD_OFFSET, 8 }, /* ah : 2 */ - { REG_DWORD_OFFSET, 0 }, /* ax : 3 */ - { REG_DWORD_OFFSET + 1, 0 }, /* cl : 4 */ - { REG_DWORD_OFFSET + 1, 8 }, /* ch : 5 */ - { REG_DWORD_OFFSET + 1, 0 }, /* cx : 6 */ - { REG_DWORD_OFFSET + 2, 0 }, /* dl : 7 */ - { REG_DWORD_OFFSET + 2, 8 }, /* dh : 8 */ - { REG_DWORD_OFFSET + 2, 0 }, /* dx : 9 */ - { REG_DWORD_OFFSET + 3, 0 }, /* bl : 10 */ - { REG_DWORD_OFFSET + 3, 8 }, /* bh : 11 */ - { REG_DWORD_OFFSET + 3, 0 }, /* bx : 12 */ - { REG_DWORD_OFFSET + 4, 0 }, /* sp : 13 */ - { REG_DWORD_OFFSET + 5, 0 }, /* bp : 14 */ - { REG_DWORD_OFFSET + 6, 0 }, /* si : 15 */ - { REG_DWORD_OFFSET + 7, 0 }, /* di : 16 */ - { REG_EIP_INDEX, 0 }, /* ip : 17 */ - { REG_FPU_OFFSET, 0 }, /* mm0 : 18 */ - { REG_FPU_OFFSET + 1, 0 }, /* mm1 : 19 */ - { REG_FPU_OFFSET + 2, 0 }, /* mm2 : 20 */ - { REG_FPU_OFFSET + 3, 0 }, /* mm3 : 21 */ - { REG_FPU_OFFSET + 4, 0 }, /* mm4 : 22 */ - { REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */ - { REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */ - { REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */ - }; - -/* REGISTER TABLE: size, type, and name of every register in the - * CPU. Does not include MSRs since the are, after all, - * model specific. */ -static struct { - unsigned int size; - enum x86_reg_type type; - unsigned int alias; - char mnemonic[8]; -} ia32_reg_table[NUM_X86_REGS + 2] = { - { 0, 0, 0, "" }, - /* REG_DWORD_OFFSET */ - { REG_DWORD_SIZE, reg_gen | reg_ret, 0, "eax" }, - { REG_DWORD_SIZE, reg_gen | reg_count, 0, "ecx" }, - { REG_DWORD_SIZE, reg_gen, 0, "edx" }, - { REG_DWORD_SIZE, reg_gen, 0, "ebx" }, - /* REG_ESP_INDEX */ - { REG_DWORD_SIZE, reg_gen | reg_sp, 0, "esp" }, - { REG_DWORD_SIZE, reg_gen | reg_fp, 0, "ebp" }, - { REG_DWORD_SIZE, reg_gen | reg_src, 0, "esi" }, - { REG_DWORD_SIZE, reg_gen | reg_dest, 0, "edi" }, - /* REG_WORD_OFFSET */ - { REG_WORD_SIZE, reg_gen | reg_ret, 3, "ax" }, - { REG_WORD_SIZE, reg_gen | reg_count, 6, "cx" }, - { REG_WORD_SIZE, reg_gen, 9, "dx" }, - { REG_WORD_SIZE, reg_gen, 12, "bx" }, - { REG_WORD_SIZE, reg_gen | reg_sp, 13, "sp" }, - { REG_WORD_SIZE, reg_gen | reg_fp, 14, "bp" }, - { REG_WORD_SIZE, reg_gen | reg_src, 15, "si" }, - { REG_WORD_SIZE, reg_gen | reg_dest, 16, "di" }, - /* REG_BYTE_OFFSET */ - { REG_BYTE_SIZE, reg_gen, 1, "al" }, - { REG_BYTE_SIZE, reg_gen, 4, "cl" }, - { REG_BYTE_SIZE, reg_gen, 7, "dl" }, - { REG_BYTE_SIZE, reg_gen, 10, "bl" }, - { REG_BYTE_SIZE, reg_gen, 2, "ah" }, - { REG_BYTE_SIZE, reg_gen, 5, "ch" }, - { REG_BYTE_SIZE, reg_gen, 8, "dh" }, - { REG_BYTE_SIZE, reg_gen, 11, "bh" }, - /* REG_MMX_OFFSET */ - { REG_MMX_SIZE, reg_simd, 18, "mm0" }, - { REG_MMX_SIZE, reg_simd, 19, "mm1" }, - { REG_MMX_SIZE, reg_simd, 20, "mm2" }, - { REG_MMX_SIZE, reg_simd, 21, "mm3" }, - { REG_MMX_SIZE, reg_simd, 22, "mm4" }, - { REG_MMX_SIZE, reg_simd, 23, "mm5" }, - { REG_MMX_SIZE, reg_simd, 24, "mm6" }, - { REG_MMX_SIZE, reg_simd, 25, "mm7" }, - /* REG_SIMD_OFFSET */ - { REG_SIMD_SIZE, reg_simd, 0, "xmm0" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm1" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm2" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm3" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm4" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm5" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm6" }, - { REG_SIMD_SIZE, reg_simd, 0, "xmm7" }, - /* REG_DEBUG_OFFSET */ - { REG_DEBUG_SIZE, reg_sys, 0, "dr0" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr1" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr2" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr3" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr4" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr5" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr6" }, - { REG_DEBUG_SIZE, reg_sys, 0, "dr7" }, - /* REG_CTRL_OFFSET */ - { REG_CTRL_SIZE, reg_sys, 0, "cr0" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr1" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr2" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr3" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr4" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr5" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr6" }, - { REG_CTRL_SIZE, reg_sys, 0, "cr7" }, - /* REG_TEST_OFFSET */ - { REG_TEST_SIZE, reg_sys, 0, "tr0" }, - { REG_TEST_SIZE, reg_sys, 0, "tr1" }, - { REG_TEST_SIZE, reg_sys, 0, "tr2" }, - { REG_TEST_SIZE, reg_sys, 0, "tr3" }, - { REG_TEST_SIZE, reg_sys, 0, "tr4" }, - { REG_TEST_SIZE, reg_sys, 0, "tr5" }, - { REG_TEST_SIZE, reg_sys, 0, "tr6" }, - { REG_TEST_SIZE, reg_sys, 0, "tr7" }, - /* REG_SEG_OFFSET */ - { REG_SEG_SIZE, reg_seg, 0, "es" }, - { REG_SEG_SIZE, reg_seg, 0, "cs" }, - { REG_SEG_SIZE, reg_seg, 0, "ss" }, - { REG_SEG_SIZE, reg_seg, 0, "ds" }, - { REG_SEG_SIZE, reg_seg, 0, "fs" }, - { REG_SEG_SIZE, reg_seg, 0, "gs" }, - /* REG_LDTR_INDEX */ - { REG_DWORD_SIZE, reg_sys, 0, "ldtr" }, - /* REG_GDTR_INDEX */ - { REG_DWORD_SIZE, reg_sys, 0, "gdtr" }, - /* REG_FPU_OFFSET */ - { REG_FPU_SIZE, reg_fpu, 0, "st(0)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(1)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(2)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(3)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(4)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(5)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(6)" }, - { REG_FPU_SIZE, reg_fpu, 0, "st(7)" }, - /* REG_FLAGS_INDEX : 81 */ - { REG_FLAGS_SIZE, reg_cond, 0, "eflags" }, - /* REG_FPCTRL_INDEX : 82*/ - { REG_FPCTRL_SIZE, reg_fpu | reg_sys, 0, "fpctrl" }, - /* REG_FPSTATUS_INDEX : 83*/ - { REG_FPSTATUS_SIZE, reg_fpu | reg_sys, 0, "fpstat" }, - /* REG_FPTAG_INDEX : 84 */ - { REG_FPTAG_SIZE, reg_fpu | reg_sys, 0, "fptag" }, - /* REG_EIP_INDEX : 85 */ - { REG_EIP_SIZE, reg_pc, 0, "eip" }, - /* REG_IP_INDEX : 86 */ - { REG_IP_SIZE, reg_pc, 17, "ip" }, - /* REG_IDTR_INDEX : 87 */ - { REG_DWORD_SIZE, reg_sys, 0, "idtr" }, - /* REG_MXCSG_INDEX : SSE Control Reg : 88 */ - { REG_DWORD_SIZE, reg_sys | reg_simd, 0, "mxcsr" }, - /* REG_TR_INDEX : Task Register : 89 */ - { 16 + 64, reg_sys, 0, "tr" }, - /* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */ - { REG_DWORD_SIZE, reg_sys, 0, "cs_msr" }, - /* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */ - { REG_DWORD_SIZE, reg_sys, 0, "esp_msr" }, - /* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */ - { REG_DWORD_SIZE, reg_sys, 0, "eip_msr" }, - { 0 } - }; - - -static size_t sz_regtable = NUM_X86_REGS + 1; - - -void ia32_handle_register( x86_reg_t *reg, size_t id ) { - unsigned int alias; - if (! id || id > sz_regtable ) { - return; - } - - memset( reg, 0, sizeof(x86_reg_t) ); - - strncpy( reg->name, ia32_reg_table[id].mnemonic, MAX_REGNAME ); - - reg->type = ia32_reg_table[id].type; - reg->size = ia32_reg_table[id].size; - - alias = ia32_reg_table[id].alias; - if ( alias ) { - reg->alias = ia32_reg_aliases[alias].alias; - reg->shift = ia32_reg_aliases[alias].shift; - } - reg->id = id; - - return; -} - -size_t ia32_true_register_id( size_t id ) { - size_t reg; - - if (! id || id > sz_regtable ) { - return 0; - } - - reg = id; - if (ia32_reg_table[reg].alias) { - reg = ia32_reg_aliases[ia32_reg_table[reg].alias].alias; - } - return reg; -} diff --git a/intercept/libdisasm/ia32_reg.h b/intercept/libdisasm/ia32_reg.h deleted file mode 100644 index fbbc77a..0000000 --- a/intercept/libdisasm/ia32_reg.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef IA32_REG_H -#define IA32_REG_H - -#include /* for size_t */ -#include "libdis.h" /* for x86_reg_t */ - -/* NOTE these are used in opcode tables for hard-coded registers */ -#define REG_DWORD_OFFSET 1 /* 0 + 1 */ -#define REG_ECX_INDEX 2 /* 0 + 1 + 1 */ -#define REG_ESP_INDEX 5 /* 0 + 4 + 1 */ -#define REG_EBP_INDEX 6 /* 0 + 5 + 1 */ -#define REG_ESI_INDEX 7 /* 0 + 6 + 1 */ -#define REG_EDI_INDEX 8 /* 0 + 7 + 1 */ -#define REG_WORD_OFFSET 9 /* 1 * 8 + 1 */ -#define REG_BYTE_OFFSET 17 /* 2 * 8 + 1 */ -#define REG_MMX_OFFSET 25 /* 3 * 8 + 1 */ -#define REG_SIMD_OFFSET 33 /* 4 * 8 + 1 */ -#define REG_DEBUG_OFFSET 41 /* 5 * 8 + 1 */ -#define REG_CTRL_OFFSET 49 /* 6 * 8 + 1 */ -#define REG_TEST_OFFSET 57 /* 7 * 8 + 1 */ -#define REG_SEG_OFFSET 65 /* 8 * 8 + 1 */ -#define REG_LDTR_INDEX 71 /* 8 * 8 + 1 + 1 */ -#define REG_GDTR_INDEX 72 /* 8 * 8 + 2 + 1 */ -#define REG_FPU_OFFSET 73 /* 9 * 8 + 1 */ -#define REG_FLAGS_INDEX 81 /* 10 * 8 + 1 */ -#define REG_FPCTRL_INDEX 82 /* 10 * 8 + 1 + 1 */ -#define REG_FPSTATUS_INDEX 83 /* 10 * 8 + 2 + 1 */ -#define REG_FPTAG_INDEX 84 /* 10 * 8 + 3 + 1 */ -#define REG_EIP_INDEX 85 /* 10 * 8 + 4 + 1 */ -#define REG_IP_INDEX 86 /* 10 * 8 + 5 + 1 */ -#define REG_IDTR_INDEX 87 /* 10 * 8 + 6 + 1 */ -#define REG_MXCSG_INDEX 88 /* 10 * 8 + 7 + 1 */ -#define REG_TR_INDEX 89 /* 10 * 8 + 8 + 1 */ -#define REG_CSMSR_INDEX 90 /* 10 * 8 + 9 + 1 */ -#define REG_ESPMSR_INDEX 91 /* 10 * 8 + 10 + 1 */ -#define REG_EIPMSR_INDEX 92 /* 10 * 8 + 11 + 1 */ - -void ia32_handle_register( x86_reg_t *reg, size_t id ); -size_t ia32_true_register_id( size_t id ); - -#endif diff --git a/intercept/libdisasm/ia32_settings.c b/intercept/libdisasm/ia32_settings.c deleted file mode 100644 index b578e34..0000000 --- a/intercept/libdisasm/ia32_settings.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "libdis.h" -#include "ia32_settings.h" -#include "ia32_reg.h" -#include "ia32_insn.h" - -ia32_settings_t ia32_settings = { - 1, 0xF4, - MAX_INSTRUCTION_SIZE, - 4, 4, 8, 4, 8, - REG_ESP_INDEX, REG_EBP_INDEX, REG_EIP_INDEX, REG_FLAGS_INDEX, - REG_DWORD_OFFSET, REG_SEG_OFFSET, REG_FPU_OFFSET, - opt_none -}; diff --git a/intercept/libdisasm/ia32_settings.h b/intercept/libdisasm/ia32_settings.h deleted file mode 100644 index 769c0e9..0000000 --- a/intercept/libdisasm/ia32_settings.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef IA32_SETTINGS_H -#define IA32_SETTINGS_H - -#include "libdis.h" - -typedef struct { - /* options */ - unsigned char endian, /* 0 = big, 1 = little */ - wc_byte, /* wildcard byte */ - max_insn, /* max insn size */ - sz_addr, /* default address size */ - sz_oper, /* default operand size */ - sz_byte, /* # bits in byte */ - sz_word, /* # bytes in machine word */ - sz_dword; /* # bytes in machine dword */ - unsigned int id_sp_reg, /* id of stack pointer */ - id_fp_reg, /* id of frame pointer */ - id_ip_reg, /* id of instruction pointer */ - id_flag_reg, /* id of flags register */ - offset_gen_regs, /* start of general regs */ - offset_seg_regs, /* start of segment regs */ - offset_fpu_regs; /* start of floating point regs */ - /* user-controlled settings */ - enum x86_options options; -} ia32_settings_t; - -#endif diff --git a/intercept/libdisasm/libdis.h b/intercept/libdisasm/libdis.h deleted file mode 100644 index 9410339..0000000 --- a/intercept/libdisasm/libdis.h +++ /dev/null @@ -1,836 +0,0 @@ -#ifndef LIBDISASM_H -#define LIBDISASM_H - -#ifdef WIN32 -#include -#endif - -#include - -/* 'NEW" types - * __________________________________________________________________________*/ -#ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */ - #define LIBDISASM_QWORD_H - #ifdef _MSC_VER - typedef __int64 qword_t; - #else - typedef int64_t qword_t; - #endif -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* 'NEW" x86 API - * __________________________________________________________________________*/ - - -/* ========================================= Error Reporting */ -/* REPORT CODES - * These are passed to a reporter function passed at initialization. - * Each code determines the type of the argument passed to the reporter; - * this allows the report to recover from errors, or just log them. - */ -enum x86_report_codes { - report_disasm_bounds, /* RVA OUT OF BOUNDS : The disassembler could - not disassemble the supplied RVA as it is - out of the range of the buffer. The - application should store the address and - attempt to determine what section of the - binary it is in, then disassemble the - address from the bytes in that section. - data: uint32_t rva */ - report_insn_bounds, /* INSTRUCTION OUT OF BOUNDS: The disassembler - could not disassemble the instruction as - the instruction would require bytes beyond - the end of the current buffer. This usually - indicated garbage bytes at the end of a - buffer, or an incorrectly-sized buffer. - data: uint32_t rva */ - report_invalid_insn, /* INVALID INSTRUCTION: The disassembler could - not disassemble the instruction as it has an - invalid combination of opcodes and operands. - This will stop automated disassembly; the - application can restart the disassembly - after the invalid instruction. - data: uint32_t rva */ - report_unknown -}; - -/* 'arg' is optional arbitrary data provided by the code passing the - * callback -- for example, it could be 'this' or 'self' in OOP code. - * 'code' is provided by libdisasm, it is one of the above - * 'data' is provided by libdisasm and is context-specific, per the enums */ -typedef void (*DISASM_REPORTER)( enum x86_report_codes code, - void *data, void *arg ); - - -/* x86_report_error : Call the register reporter to report an error */ -void x86_report_error( enum x86_report_codes code, void *data ); - -/* ========================================= Libdisasm Management Routines */ -enum x86_options { /* these can be ORed together */ - opt_none= 0, - opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */ - opt_16_bit=2, /* 16-bit/DOS disassembly */ - opt_att_mnemonics=4, /* use AT&T syntax names for alternate opcode mnemonics */ -}; - -/* management routines */ -/* 'arg' is caller-specific data which is passed as the first argument - * to the reporter callback routine */ -int x86_init( enum x86_options options, DISASM_REPORTER reporter, void *arg); -void x86_set_reporter( DISASM_REPORTER reporter, void *arg); -void x86_set_options( enum x86_options options ); -enum x86_options x86_get_options( void ); -int x86_cleanup(void); - - -/* ========================================= Instruction Representation */ -/* these defines are only intended for use in the array decl's */ -#define MAX_REGNAME 8 - -#define MAX_PREFIX_STR 32 -#define MAX_MNEM_STR 16 -#define MAX_INSN_SIZE 20 /* same as in i386.h */ -#define MAX_OP_STRING 32 /* max possible operand size in string form */ -#define MAX_OP_RAW_STRING 64 /* max possible operand size in raw form */ -#define MAX_OP_XML_STRING 256 /* max possible operand size in xml form */ -#define MAX_NUM_OPERANDS 8 /* max # implicit and explicit operands */ -/* in these, the '2 *' is arbitrary: the max # of operands should require - * more space than the rest of the insn */ -#define MAX_INSN_STRING 512 /* 2 * 8 * MAX_OP_STRING */ -#define MAX_INSN_RAW_STRING 1024 /* 2 * 8 * MAX_OP_RAW_STRING */ -#define MAX_INSN_XML_STRING 4096 /* 2 * 8 * MAX_OP_XML_STRING */ - -enum x86_reg_type { /* NOTE: these may be ORed together */ - reg_gen = 0x00001, /* general purpose */ - reg_in = 0x00002, /* incoming args, ala RISC */ - reg_out = 0x00004, /* args to calls, ala RISC */ - reg_local = 0x00008, /* local vars, ala RISC */ - reg_fpu = 0x00010, /* FPU data register */ - reg_seg = 0x00020, /* segment register */ - reg_simd = 0x00040, /* SIMD/MMX reg */ - reg_sys = 0x00080, /* restricted/system register */ - reg_sp = 0x00100, /* stack pointer */ - reg_fp = 0x00200, /* frame pointer */ - reg_pc = 0x00400, /* program counter */ - reg_retaddr = 0x00800, /* return addr for func */ - reg_cond = 0x01000, /* condition code / flags */ - reg_zero = 0x02000, /* zero register, ala RISC */ - reg_ret = 0x04000, /* return value */ - reg_src = 0x10000, /* array/rep source */ - reg_dest = 0x20000, /* array/rep destination */ - reg_count = 0x40000 /* array/rep/loop counter */ -}; - -/* x86_reg_t : an X86 CPU register */ -typedef struct { - char name[MAX_REGNAME]; - enum x86_reg_type type; /* what register is used for */ - unsigned int size; /* size of register in bytes */ - unsigned int id; /* register ID #, for quick compares */ - unsigned int alias; /* ID of reg this is an alias for */ - unsigned int shift; /* amount to shift aliased reg by */ -} x86_reg_t; - -/* x86_ea_t : an X86 effective address (address expression) */ -typedef struct { - unsigned int scale; /* scale factor */ - x86_reg_t index, base; /* index, base registers */ - int32_t disp; /* displacement */ - char disp_sign; /* is negative? 1/0 */ - char disp_size; /* 0, 1, 2, 4 */ -} x86_ea_t; - -/* x86_absolute_t : an X86 segment:offset address (descriptor) */ -typedef struct { - unsigned short segment; /* loaded directly into CS */ - union { - unsigned short off16; /* loaded directly into IP */ - uint32_t off32; /* loaded directly into EIP */ - } offset; -} x86_absolute_t; - -enum x86_op_type { /* mutually exclusive */ - op_unused = 0, /* empty/unused operand: should never occur */ - op_register = 1, /* CPU register */ - op_immediate = 2, /* Immediate Value */ - op_relative_near = 3, /* Relative offset from IP */ - op_relative_far = 4, /* Relative offset from IP */ - op_absolute = 5, /* Absolute address (ptr16:32) */ - op_expression = 6, /* Address expression (scale/index/base/disp) */ - op_offset = 7, /* Offset from start of segment (m32) */ - op_unknown -}; - -#define x86_optype_is_address( optype ) \ - ( optype == op_absolute || optype == op_offset ) -#define x86_optype_is_relative( optype ) \ - ( optype == op_relative_near || optype == op_relative_far ) -#define x86_optype_is_memory( optype ) \ - ( optype > op_immediate && optype < op_unknown ) - -enum x86_op_datatype { /* these use Intel's lame terminology */ - op_byte = 1, /* 1 byte integer */ - op_word = 2, /* 2 byte integer */ - op_dword = 3, /* 4 byte integer */ - op_qword = 4, /* 8 byte integer */ - op_dqword = 5, /* 16 byte integer */ - op_sreal = 6, /* 4 byte real (single real) */ - op_dreal = 7, /* 8 byte real (double real) */ - op_extreal = 8, /* 10 byte real (extended real) */ - op_bcd = 9, /* 10 byte binary-coded decimal */ - op_ssimd = 10, /* 16 byte : 4 packed single FP (SIMD, MMX) */ - op_dsimd = 11, /* 16 byte : 2 packed double FP (SIMD, MMX) */ - op_sssimd = 12, /* 4 byte : scalar single FP (SIMD, MMX) */ - op_sdsimd = 13, /* 8 byte : scalar double FP (SIMD, MMX) */ - op_descr32 = 14, /* 6 byte Intel descriptor 2:4 */ - op_descr16 = 15, /* 4 byte Intel descriptor 2:2 */ - op_pdescr32 = 16, /* 6 byte Intel pseudo-descriptor 32:16 */ - op_pdescr16 = 17, /* 6 byte Intel pseudo-descriptor 8:24:16 */ - op_bounds16 = 18, /* signed 16:16 lower:upper bounds */ - op_bounds32 = 19, /* signed 32:32 lower:upper bounds */ - op_fpuenv16 = 20, /* 14 byte FPU control/environment data */ - op_fpuenv32 = 21, /* 28 byte FPU control/environment data */ - op_fpustate16 = 22, /* 94 byte FPU state (env & reg stack) */ - op_fpustate32 = 23, /* 108 byte FPU state (env & reg stack) */ - op_fpregset = 24, /* 512 bytes: register set */ - op_fpreg = 25, /* FPU register */ - op_none = 0xFF, /* operand without a datatype (INVLPG) */ -}; - -enum x86_op_access { /* ORed together */ - op_read = 1, - op_write = 2, - op_execute = 4 -}; - -enum x86_op_flags { /* ORed together, but segs are mutually exclusive */ - op_signed = 1, /* signed integer */ - op_string = 2, /* possible string or array */ - op_constant = 4, /* symbolic constant */ - op_pointer = 8, /* operand points to a memory address */ - op_sysref = 0x010, /* operand is a syscall number */ - op_implied = 0x020, /* operand is implicit in the insn */ - op_hardcode = 0x40, /* operand is hardcoded in insn definition */ - /* NOTE: an 'implied' operand is one which can be considered a side - * effect of the insn, e.g. %esp being modified by PUSH or POP. A - * 'hard-coded' operand is one which is specified in the instruction - * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference - * is that hard-coded operands are printed by disassemblers and are - * required to re-assemble, while implicit operands are invisible. */ - op_es_seg = 0x100, /* ES segment override */ - op_cs_seg = 0x200, /* CS segment override */ - op_ss_seg = 0x300, /* SS segment override */ - op_ds_seg = 0x400, /* DS segment override */ - op_fs_seg = 0x500, /* FS segment override */ - op_gs_seg = 0x600 /* GS segment override */ -}; - -/* x86_op_t : an X86 instruction operand */ -typedef struct { - enum x86_op_type type; /* operand type */ - enum x86_op_datatype datatype; /* operand size */ - enum x86_op_access access; /* operand access [RWX] */ - enum x86_op_flags flags; /* misc flags */ - union { - /* sizeof will have to work on these union members! */ - /* immediate values */ - char sbyte; - short sword; - int32_t sdword; - qword_t sqword; - unsigned char byte; - unsigned short word; - uint32_t dword; - qword_t qword; - float sreal; - double dreal; - /* misc large/non-native types */ - unsigned char extreal[10]; - unsigned char bcd[10]; - qword_t dqword[2]; - unsigned char simd[16]; - unsigned char fpuenv[28]; - /* offset from segment */ - uint32_t offset; - /* ID of CPU register */ - x86_reg_t reg; - /* offsets from current insn */ - char relative_near; - int32_t relative_far; - /* segment:offset */ - x86_absolute_t absolute; - /* effective address [expression] */ - x86_ea_t expression; - } data; - /* this is needed to make formatting operands more sane */ - void * insn; /* pointer to x86_insn_t owning operand */ -} x86_op_t; - -/* Linked list of x86_op_t; provided for manual traversal of the operand - * list in an insn. Users wishing to add operands to this list, e.g. to add - * implicit operands, should use x86_operand_new in x86_operand_list.h */ -typedef struct x86_operand_list { - x86_op_t op; - struct x86_operand_list *next; -} x86_oplist_t; - -enum x86_insn_group { - insn_none = 0, /* invalid instruction */ - insn_controlflow = 1, - insn_arithmetic = 2, - insn_logic = 3, - insn_stack = 4, - insn_comparison = 5, - insn_move = 6, - insn_string = 7, - insn_bit_manip = 8, - insn_flag_manip = 9, - insn_fpu = 10, - insn_interrupt = 13, - insn_system = 14, - insn_other = 15 -}; - -enum x86_insn_type { - insn_invalid = 0, /* invalid instruction */ - /* insn_controlflow */ - insn_jmp = 0x1001, - insn_jcc = 0x1002, - insn_call = 0x1003, - insn_callcc = 0x1004, - insn_return = 0x1005, - /* insn_arithmetic */ - insn_add = 0x2001, - insn_sub = 0x2002, - insn_mul = 0x2003, - insn_div = 0x2004, - insn_inc = 0x2005, - insn_dec = 0x2006, - insn_shl = 0x2007, - insn_shr = 0x2008, - insn_rol = 0x2009, - insn_ror = 0x200A, - /* insn_logic */ - insn_and = 0x3001, - insn_or = 0x3002, - insn_xor = 0x3003, - insn_not = 0x3004, - insn_neg = 0x3005, - /* insn_stack */ - insn_push = 0x4001, - insn_pop = 0x4002, - insn_pushregs = 0x4003, - insn_popregs = 0x4004, - insn_pushflags = 0x4005, - insn_popflags = 0x4006, - insn_enter = 0x4007, - insn_leave = 0x4008, - /* insn_comparison */ - insn_test = 0x5001, - insn_cmp = 0x5002, - /* insn_move */ - insn_mov = 0x6001, /* move */ - insn_movcc = 0x6002, /* conditional move */ - insn_xchg = 0x6003, /* exchange */ - insn_xchgcc = 0x6004, /* conditional exchange */ - /* insn_string */ - insn_strcmp = 0x7001, - insn_strload = 0x7002, - insn_strmov = 0x7003, - insn_strstore = 0x7004, - insn_translate = 0x7005, /* xlat */ - /* insn_bit_manip */ - insn_bittest = 0x8001, - insn_bitset = 0x8002, - insn_bitclear = 0x8003, - /* insn_flag_manip */ - insn_clear_carry = 0x9001, - insn_clear_zero = 0x9002, - insn_clear_oflow = 0x9003, - insn_clear_dir = 0x9004, - insn_clear_sign = 0x9005, - insn_clear_parity = 0x9006, - insn_set_carry = 0x9007, - insn_set_zero = 0x9008, - insn_set_oflow = 0x9009, - insn_set_dir = 0x900A, - insn_set_sign = 0x900B, - insn_set_parity = 0x900C, - insn_tog_carry = 0x9010, - insn_tog_zero = 0x9020, - insn_tog_oflow = 0x9030, - insn_tog_dir = 0x9040, - insn_tog_sign = 0x9050, - insn_tog_parity = 0x9060, - /* insn_fpu */ - insn_fmov = 0xA001, - insn_fmovcc = 0xA002, - insn_fneg = 0xA003, - insn_fabs = 0xA004, - insn_fadd = 0xA005, - insn_fsub = 0xA006, - insn_fmul = 0xA007, - insn_fdiv = 0xA008, - insn_fsqrt = 0xA009, - insn_fcmp = 0xA00A, - insn_fcos = 0xA00C, - insn_fldpi = 0xA00D, - insn_fldz = 0xA00E, - insn_ftan = 0xA00F, - insn_fsine = 0xA010, - insn_fsys = 0xA020, - /* insn_interrupt */ - insn_int = 0xD001, - insn_intcc = 0xD002, /* not present in x86 ISA */ - insn_iret = 0xD003, - insn_bound = 0xD004, - insn_debug = 0xD005, - insn_trace = 0xD006, - insn_invalid_op = 0xD007, - insn_oflow = 0xD008, - /* insn_system */ - insn_halt = 0xE001, - insn_in = 0xE002, /* input from port/bus */ - insn_out = 0xE003, /* output to port/bus */ - insn_cpuid = 0xE004, - /* insn_other */ - insn_nop = 0xF001, - insn_bcdconv = 0xF002, /* convert to or from BCD */ - insn_szconv = 0xF003 /* change size of operand */ -}; - -/* These flags specify special characteristics of the instruction, such as - * whether the inatruction is privileged or whether it serializes the - * pipeline. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_note { - insn_note_ring0 = 1, /* Only available in ring 0 */ - insn_note_smm = 2, /* "" in System Management Mode */ - insn_note_serial = 4, /* Serializing instruction */ - insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */ - insn_note_nosuffix = 16, /* Does not have size suffix in att-style formatting */ -}; - -/* This specifies what effects the instruction has on the %eflags register */ -enum x86_flag_status { - insn_carry_set = 0x1, /* CF */ - insn_zero_set = 0x2, /* ZF */ - insn_oflow_set = 0x4, /* OF */ - insn_dir_set = 0x8, /* DF */ - insn_sign_set = 0x10, /* SF */ - insn_parity_set = 0x20, /* PF */ - insn_carry_or_zero_set = 0x40, - insn_zero_set_or_sign_ne_oflow = 0x80, - insn_carry_clear = 0x100, - insn_zero_clear = 0x200, - insn_oflow_clear = 0x400, - insn_dir_clear = 0x800, - insn_sign_clear = 0x1000, - insn_parity_clear = 0x2000, - insn_sign_eq_oflow = 0x4000, - insn_sign_ne_oflow = 0x8000 -}; - -/* The CPU model in which the insturction first appeared; this can be used - * to mask out instructions appearing in earlier or later models or to - * check the portability of a binary. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_cpu { - cpu_8086 = 1, /* Intel */ - cpu_80286 = 2, - cpu_80386 = 3, - cpu_80387 = 4, - cpu_80486 = 5, - cpu_pentium = 6, - cpu_pentiumpro = 7, - cpu_pentium2 = 8, - cpu_pentium3 = 9, - cpu_pentium4 = 10, - cpu_k6 = 16, /* AMD */ - cpu_k7 = 32, - cpu_athlon = 48 -}; - -/* CPU ISA subsets: These are derived from the Instruction Groups in - * Intel Vol 1 Chapter 5; they represent subsets of the IA32 ISA but - * do not reflect the 'type' of the instruction in the same way that - * x86_insn_group does. In short, these are AMD/Intel's somewhat useless - * designations. - * NOTE : These may not be accurate for all instructions; updates to the - * opcode tables have not been completed. */ -enum x86_insn_isa { - isa_gp = 1, /* general purpose */ - isa_fp = 2, /* floating point */ - isa_fpumgt = 3, /* FPU/SIMD management */ - isa_mmx = 4, /* Intel MMX */ - isa_sse1 = 5, /* Intel SSE SIMD */ - isa_sse2 = 6, /* Intel SSE2 SIMD */ - isa_sse3 = 7, /* Intel SSE3 SIMD */ - isa_3dnow = 8, /* AMD 3DNow! SIMD */ - isa_sys = 9 /* system instructions */ -}; - -enum x86_insn_prefix { - insn_no_prefix = 0, - insn_rep_zero = 1, /* REPZ and REPE */ - insn_rep_notzero = 2, /* REPNZ and REPNZ */ - insn_lock = 4 /* LOCK: */ -}; - -/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */ -/* x86_insn_t : an X86 instruction */ -typedef struct { - /* information about the instruction */ - uint32_t addr; /* load address */ - uint32_t offset; /* offset into file/buffer */ - enum x86_insn_group group; /* meta-type, e.g. INS_EXEC */ - enum x86_insn_type type; /* type, e.g. INS_BRANCH */ - enum x86_insn_note note; /* note, e.g. RING0 */ - unsigned char bytes[MAX_INSN_SIZE]; - unsigned char size; /* size of insn in bytes */ - /* 16/32-bit mode settings */ - unsigned char addr_size; /* default address size : 2 or 4 */ - unsigned char op_size; /* default operand size : 2 or 4 */ - /* CPU/instruction set */ - enum x86_insn_cpu cpu; - enum x86_insn_isa isa; - /* flags */ - enum x86_flag_status flags_set; /* flags set or tested by insn */ - enum x86_flag_status flags_tested; - /* stack */ - unsigned char stack_mod; /* 0 or 1 : is the stack modified? */ - int32_t stack_mod_val; /* val stack is modified by if known */ - - /* the instruction proper */ - enum x86_insn_prefix prefix; /* prefixes ORed together */ - char prefix_string[MAX_PREFIX_STR]; /* prefixes [might be truncated] */ - char mnemonic[MAX_MNEM_STR]; - x86_oplist_t *operands; /* list of explicit/implicit operands */ - size_t operand_count; /* total number of operands */ - size_t explicit_count; /* number of explicit operands */ - /* convenience fields for user */ - void *block; /* code block containing this insn */ - void *function; /* function containing this insn */ - int tag; /* tag the insn as seen/processed */ -} x86_insn_t; - - -/* returns 0 if an instruction is invalid, 1 if valid */ -int x86_insn_is_valid( x86_insn_t *insn ); - -/* DISASSEMBLY ROUTINES - * Canonical order of arguments is - * (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func) - * ...but of course all of these are not used at the same time. - */ - - -/* Function prototype for caller-supplied callback routine - * These callbacks are intended to process 'insn' further, e.g. by - * adding it to a linked list, database, etc */ -typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg ); - -/* Function prototype for caller-supplied address resolver. - * This routine is used to determine the rva to disassemble next, given - * the 'dest' operand of a jump/call. This allows the caller to resolve - * jump/call targets stored in a register or on the stack, and also allows - * the caller to prevent endless loops by checking if an address has - * already been disassembled. If an address cannot be resolved from the - * operand, or if the address has already been disassembled, this routine - * should return -1; in all other cases the RVA to be disassembled next - * should be returned. */ -typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn, - void *arg ); - - -/* x86_disasm: Disassemble a single instruction from a buffer of bytes. - * Returns size of instruction in bytes. - * Caller is responsible for calling x86_oplist_free() on - * a reused "insn" to avoid leaking memory when calling this - * function repeatedly. - * buf : Buffer of bytes to disassemble - * buf_len : Length of the buffer - * buf_rva : Load address of the start of the buffer - * offset : Offset in buffer to disassemble - * insn : Structure to fill with disassembled instruction - */ -unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - x86_insn_t * insn ); - -/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer, - * invoking a callback function each time an instruction - * is successfully disassembled. The 'range' refers to the - * bytes between 'offset' and 'offset + len' in the buffer; - * 'len' is assumed to be less than the length of the buffer. - * Returns number of instructions processed. - * buf : Buffer of bytes to disassemble (e.g. .text section) - * buf_rva : Load address of buffer (e.g. ELF Virtual Address) - * offset : Offset in buffer to start disassembly at - * len : Number of bytes to disassemble - * func : Callback function to invoke (may be NULL) - * arg : Arbitrary data to pass to callback (may be NULL) - */ -unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva, - unsigned int offset, unsigned int len, - DISASM_CALLBACK func, void *arg ); - -/* x86_disasm_forward: Flow-of-execution disassembly of the bytes in a buffer, - * invoking a callback function each time an instruction - * is successfully disassembled. - * buf : Buffer to disassemble (e.g. .text section) - * buf_len : Number of bytes in buffer - * buf_rva : Load address of buffer (e.g. ELF Virtual Address) - * offset : Offset in buffer to start disassembly at (e.g. entry point) - * func : Callback function to invoke (may be NULL) - * arg : Arbitrary data to pass to callback (may be NULL) - * resolver: Caller-supplied address resolver. If no resolver is - * supplied, a default internal one is used -- however the - * internal resolver does NOT catch loops and could end up - * disassembling forever.. - * r_arg : Arbitrary data to pass to resolver (may be NULL) - */ -unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - DISASM_CALLBACK func, void *arg, - DISASM_RESOLVER resolver, void *r_arg ); - -/* Instruction operands: these are stored as a list of explicit and - * implicit operands. It is recommended that the 'foreach' routines - * be used to when examining operands for purposes of data flow analysis */ - -/* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the - * foreach routine, 'insn' is the x86_insn_t whose operands are being - * iterated over, and 'op' is the current x86_op_t */ -typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg); - -/* FOREACH types: these are used to limit the foreach results to - * operands which match a certain "type" (implicit or explicit) - * or which are accessed in certain ways (e.g. read or write). Note - * that this operates on the operand list of single instruction, so - * specifying the 'real' operand type (register, memory, etc) is not - * useful. Note also that by definition Execute Access implies Read - * Access and implies Not Write Access. - * The "type" (implicit or explicit) and the access method can - * be ORed together, e.g. op_wo | op_explicit */ -enum x86_op_foreach_type { - op_any = 0, /* ALL operands (explicit, implicit, rwx) */ - op_dest = 1, /* operands with Write access */ - op_src = 2, /* operands with Read access */ - op_ro = 3, /* operands with Read but not Write access */ - op_wo = 4, /* operands with Write but not Read access */ - op_xo = 5, /* operands with Execute access */ - op_rw = 6, /* operands with Read AND Write access */ - op_implicit = 0x10, /* operands that are implied by the opcode */ - op_explicit = 0x20 /* operands that are not side-effects */ -}; - - -/* free the operand list associated with an instruction -- useful for - * preventing memory leaks when free()ing an x86_insn_t */ -void x86_oplist_free( x86_insn_t *insn ); - -/* Operand foreach: invokes 'func' with 'insn' and 'arg' as arguments. The - * 'type' parameter is used to select only operands matching specific - * criteria. */ -int x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg, - enum x86_op_foreach_type type); - -/* convenience routine: returns count of operands matching 'type' */ -size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type ); - -/* accessor functions for the operands */ -x86_op_t * x86_operand_1st( x86_insn_t *insn ); -x86_op_t * x86_operand_2nd( x86_insn_t *insn ); -x86_op_t * x86_operand_3rd( x86_insn_t *insn ); - -/* these allow libdisasm 2.0 accessor functions to still be used */ -#define x86_get_dest_operand( insn ) x86_operand_1st( insn ) -#define x86_get_src_operand( insn ) x86_operand_2nd( insn ) -#define x86_get_imm_operand( insn ) x86_operand_3rd( insn ) - -/* get size of operand data in bytes */ -unsigned int x86_operand_size( x86_op_t *op ); - -/* Operand Convenience Routines: the following three routines are common - * operations on operands, intended to ease the burden of the programmer. */ - -/* Get Address: return the value of an offset operand, or the offset of - * a segment:offset absolute address */ -uint32_t x86_get_address( x86_insn_t *insn ); - -/* Get Relative Offset: return as a sign-extended int32_t the near or far - * relative offset operand, or 0 if there is none. There can be only one - * relaive offset operand in an instruction. */ -int32_t x86_get_rel_offset( x86_insn_t *insn ); - -/* Get Branch Target: return the x86_op_t containing the target of - * a jump or call operand, or NULL if there is no branch target. - * Internally, a 'branch target' is defined as any operand with - * Execute Access set. There can be only one branch target per instruction. */ -x86_op_t * x86_get_branch_target( x86_insn_t *insn ); - -/* Get Immediate: return the x86_op_t containing the immediate operand - * for this instruction, or NULL if there is no immediate operand. There - * can be only one immediate operand per instruction */ -x86_op_t * x86_get_imm( x86_insn_t *insn ); - -/* Get Raw Immediate Data: returns a pointer to the immediate data encoded - * in the instruction. This is useful for large data types [>32 bits] currently - * not supported by libdisasm, or for determining if the disassembler - * screwed up the conversion of the immediate data. Note that 'imm' in this - * context refers to immediate data encoded at the end of an instruction as - * detailed in the Intel Manual Vol II Chapter 2; it does not refer to the - * 'op_imm' operand (the third operand in instructions like 'mul' */ -unsigned char * x86_get_raw_imm( x86_insn_t *insn ); - - -/* More accessor fuctions, this time for user-defined info... */ -/* set the address (usually RVA) of the insn */ -void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ); - -/* set the offset (usually offset into file) of the insn */ -void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ); - -/* set a pointer to the function owning the instruction. The - * type of 'func' is user-defined; libdisasm does not use the func field. */ -void x86_set_insn_function( x86_insn_t *insn, void * func ); - -/* set a pointer to the block of code owning the instruction. The - * type of 'block' is user-defined; libdisasm does not use the block field. */ -void x86_set_insn_block( x86_insn_t *insn, void * block ); - -/* instruction tagging: these routines allow the programmer to mark - * instructions as "seen" in a DFS, for example. libdisasm does not use - * the tag field.*/ -/* set insn->tag to 1 */ -void x86_tag_insn( x86_insn_t *insn ); -/* set insn->tag to 0 */ -void x86_untag_insn( x86_insn_t *insn ); -/* return insn->tag */ -int x86_insn_is_tagged( x86_insn_t *insn ); - - -/* Disassembly formats: - * AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm" - * Intel is standard MASM/NASM/TASM: "mnemonic\tdest,src, imm" - * Native is tab-delimited: "RVA\tbytes\tmnemonic\tdest\tsrc\timm" - * XML is your typical ... - * Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7 - */ -enum x86_asm_format { - unknown_syntax = 0, /* never use! */ - native_syntax, /* header: 35 bytes */ - intel_syntax, /* header: 23 bytes */ - att_syntax, /* header: 23 bytes */ - xml_syntax, /* header: 679 bytes */ - raw_syntax /* header: 172 bytes */ -}; - -/* format (sprintf) an operand into 'buf' using specified syntax */ -int x86_format_operand(x86_op_t *op, char *buf, int len, - enum x86_asm_format format); - -/* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */ -int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format); - -/* format (sprintf) an instruction into 'buf' using specified syntax; - * this includes formatting all operands */ -int x86_format_insn(x86_insn_t *insn, char *buf, int len, enum x86_asm_format); - -/* fill 'buf' with a description of the format's syntax */ -int x86_format_header( char *buf, int len, enum x86_asm_format format); - -/* Endianness of an x86 CPU : 0 is big, 1 is little; always returns 1 */ -unsigned int x86_endian(void); - -/* Default address and operand size in bytes */ -unsigned int x86_addr_size(void); -unsigned int x86_op_size(void); - -/* Size of a machine word in bytes */ -unsigned int x86_word_size(void); - -/* maximum size of a code instruction */ -#define x86_max_inst_size(x) x86_max_insn_size(x) -unsigned int x86_max_insn_size(void); - -/* register IDs of Stack, Frame, Instruction pointer and Flags register */ -unsigned int x86_sp_reg(void); -unsigned int x86_fp_reg(void); -unsigned int x86_ip_reg(void); -unsigned int x86_flag_reg(void); - -/* fill 'reg' struct with details of register 'id' */ -void x86_reg_from_id( unsigned int id, x86_reg_t * reg ); - -/* convenience macro demonstrating how to get an aliased register; proto is - * void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg ) - * where 'alias_reg' is a reg operand and 'output_reg' is filled with the - * register that the operand is an alias for */ -#define x86_get_aliased_reg( alias_reg, output_reg ) \ - x86_reg_from_id( alias_reg->alias, output_reg ) - - -/* ================================== Invariant Instruction Representation */ -/* Invariant instructions are used for generating binary signatures; - * the instruction is modified so that all variant bytes in an instruction - * are replaced with a wildcard byte. - * - * A 'variant byte' is one that is expected to be modified by either the - * static or the dynamic linker: for example, an address encoded in an - * instruction. - * - * By comparing the invariant representation of one instruction [or of a - * sequence of instructions] with the invariant representation of another, - * one determine whether the two invariant representations are from the same - * relocatable object [.o] file. Thus one can use binary signatures [which - * are just sequences of invariant instruction representations] to look for - * library routines which have been statically-linked into a binary. - * - * The invariant routines are faster and smaller than the disassembly - * routines; they can be used to determine the size of an instruction - * without all of the overhead of a full instruction disassembly. - */ - -/* This byte is used to replace variant bytes */ -#define X86_WILDCARD_BYTE 0xF4 - -typedef struct { - enum x86_op_type type; /* operand type */ - enum x86_op_datatype datatype; /* operand size */ - enum x86_op_access access; /* operand access [RWX] */ - enum x86_op_flags flags; /* misc flags */ -} x86_invariant_op_t; - -typedef struct { - unsigned char bytes[64]; /* invariant representation */ - unsigned int size; /* number of bytes in insn */ - enum x86_insn_group group; /* meta-type, e.g. INS_EXEC */ - enum x86_insn_type type; /* type, e.g. INS_BRANCH */ - x86_invariant_op_t operands[3]; /* operands: dest, src, imm */ -} x86_invariant_t; - - -/* return a version of the instruction with the variant bytes masked out */ -size_t x86_invariant_disasm( unsigned char *buf, int buf_len, - x86_invariant_t *inv ); -/* return the size in bytes of the intruction pointed to by 'buf'; - * this used x86_invariant_disasm since it faster than x86_disasm */ -size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/intercept/libdisasm/qword.h b/intercept/libdisasm/qword.h deleted file mode 100644 index 5f0e803..0000000 --- a/intercept/libdisasm/qword.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LIBDISASM_QWORD_H -#define LIBDISASM_QWORD_H - -#include - -/* platform independent data types */ - -#ifdef _MSC_VER - typedef __int64 qword_t; -#else - typedef int64_t qword_t; -#endif - -#endif diff --git a/intercept/libdisasm/x86_disasm.c b/intercept/libdisasm/x86_disasm.c deleted file mode 100644 index 04574fa..0000000 --- a/intercept/libdisasm/x86_disasm.c +++ /dev/null @@ -1,210 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_invariant.h" -#include "x86_operand_list.h" - - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - -unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - x86_insn_t *insn ){ - int len, size; - unsigned char bytes[MAX_INSTRUCTION_SIZE]; - - if ( ! buf || ! insn || ! buf_len ) { - /* caller screwed up somehow */ - return 0; - } - - - /* ensure we are all NULLed up */ - memset( insn, 0, sizeof(x86_insn_t) ); - insn->addr = buf_rva + offset; - insn->offset = offset; - /* default to invalid insn */ - insn->type = insn_invalid; - insn->group = insn_none; - - if ( offset >= buf_len ) { - /* another caller screwup ;) */ - x86_report_error(report_disasm_bounds, (void*)(long)buf_rva+offset); - return 0; - } - - len = buf_len - offset; - - /* copy enough bytes for disassembly into buffer : this - * helps prevent buffer overruns at the end of a file */ - memset( bytes, 0, MAX_INSTRUCTION_SIZE ); - memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len : - MAX_INSTRUCTION_SIZE ); - - /* actually do the disassembly */ - /* TODO: allow switching when more disassemblers are added */ - size = ia32_disasm_addr( bytes, len, insn); - - /* check and see if we had an invalid instruction */ - if (! size ) { - x86_report_error(report_invalid_insn, (void*)(long)buf_rva+offset ); - return 0; - } - - /* check if we overran the end of the buffer */ - if ( size > len ) { - x86_report_error( report_insn_bounds, (void*)(long)buf_rva + offset ); - MAKE_INVALID( insn, bytes ); - return 0; - } - - /* fill bytes field of insn */ - memcpy( insn->bytes, bytes, size ); - - return size; -} - -unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva, - unsigned int offset, unsigned int len, - DISASM_CALLBACK func, void *arg ) { - x86_insn_t insn; - unsigned int buf_len, size, count = 0, bytes = 0; - - /* buf_len is implied by the arguments */ - buf_len = len + offset; - - while ( bytes < len ) { - size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, - &insn ); - if ( size ) { - /* invoke callback if it exists */ - if ( func ) { - (*func)( &insn, arg ); - } - bytes += size; - count ++; - } else { - /* error */ - bytes++; /* try next byte */ - } - - x86_oplist_free( &insn ); - } - - return( count ); -} - -static inline int follow_insn_dest( x86_insn_t *insn ) { - if ( insn->type == insn_jmp || insn->type == insn_jcc || - insn->type == insn_call || insn->type == insn_callcc ) { - return(1); - } - return(0); -} - -static inline int insn_doesnt_return( x86_insn_t *insn ) { - return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 ); -} - -static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){ - int32_t next_addr = -1; - if ( x86_optype_is_address(op->type) ) { - next_addr = op->data.sdword; - } else if ( op->type == op_relative_near ) { - next_addr = insn->addr + insn->size + op->data.relative_near; - } else if ( op->type == op_relative_far ) { - next_addr = insn->addr + insn->size + op->data.relative_far; - } - return( next_addr ); -} - -unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, - uint32_t buf_rva, unsigned int offset, - DISASM_CALLBACK func, void *arg, - DISASM_RESOLVER resolver, void *r_arg ){ - x86_insn_t insn; - x86_op_t *op; - int32_t next_addr; - uint32_t next_offset; - unsigned int size, count = 0, bytes = 0, cont = 1; - - while ( cont && bytes < buf_len ) { - size = x86_disasm( buf, buf_len, buf_rva, offset + bytes, - &insn ); - - if ( size ) { - /* invoke callback if it exists */ - if ( func ) { - (*func)( &insn, arg ); - } - bytes += size; - count ++; - } else { - /* error */ - bytes++; /* try next byte */ - } - - if ( follow_insn_dest(&insn) ) { - op = x86_get_dest_operand( &insn ); - next_addr = -1; - - /* if caller supplied a resolver, use it to determine - * the address to disassemble */ - if ( resolver ) { - next_addr = resolver(op, &insn, r_arg); - } else { - next_addr = internal_resolver(op, &insn); - } - - if (next_addr != -1 ) { - next_offset = next_addr - buf_rva; - /* if offset is in this buffer... */ - if ( next_offset >= 0 && - next_offset < buf_len ) { - /* go ahead and disassemble */ - count += x86_disasm_forward( buf, - buf_len, - buf_rva, - next_offset, - func, arg, - resolver, r_arg ); - } else { - /* report unresolved address */ - x86_report_error( report_disasm_bounds, - (void*)(long)next_addr ); - } - } - } /* end follow_insn */ - - if ( insn_doesnt_return(&insn) ) { - /* stop disassembling */ - cont = 0; - } - - x86_oplist_free( &insn ); - } - return( count ); -} - -/* invariant instruction representation */ -size_t x86_invariant_disasm( unsigned char *buf, int buf_len, - x86_invariant_t *inv ){ - if (! buf || ! buf_len || ! inv ) { - return(0); - } - - return ia32_disasm_invariant(buf, buf_len, inv); -} -size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) { - if (! buf || ! buf_len ) { - return(0); - } - - return ia32_disasm_size(buf, buf_len); -} diff --git a/intercept/libdisasm/x86_format.c b/intercept/libdisasm/x86_format.c deleted file mode 100644 index be8c250..0000000 --- a/intercept/libdisasm/x86_format.c +++ /dev/null @@ -1,1430 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - - -/* - * concatenation macros. STRNCATF concatenates a format string, buf - * only with one argument. - */ -#define STRNCAT( buf, str, len ) do { \ - int _i = strlen(str), _blen = strlen(buf), _len = len - 1; \ - if ( len ) { \ - strncat( buf, str, _len ); \ - if ( _len <= _i ) { \ - buf[_blen+_len] = '\0'; \ - len = 0; \ - } else { \ - len -= _i; \ - } \ - } \ -} while( 0 ) - -#define STRNCATF( buf, fmt, data, len ) do { \ - char _tmp[MAX_OP_STRING]; \ - \ - snprintf( _tmp, sizeof _tmp, fmt, data ); \ - STRNCAT( buf, _tmp, len ); \ -} while( 0 ) - - -#define PRINT_DISPLACEMENT( ea ) do { \ - if ( ea->disp_size && ea->disp ) { \ - if ( ea->disp_sign ) { \ - STRNCATF( buf, "-0x%" PRIX32, -ea->disp, len ); \ - } else { \ - STRNCATF( buf, "0x%" PRIX32, ea->disp, len ); \ - } \ - } \ -} while( 0 ) - -static char *prefix_strings[] = { - "", /* no prefix */ - "repz ", /* the trailing spaces make it easy to prepend to mnemonic */ - "repnz ", - "lock ", - "branch delay " /* unused in x86 */ -}; - -static int format_insn_prefix_str( enum x86_insn_prefix prefix, char *buf, - int len ) { - - int len_orig = len; - - /* concat all prefix strings */ - if ( prefix & 1 ) { STRNCAT( buf, prefix_strings[1], len ); } - if ( prefix & 2 ) { STRNCAT( buf, prefix_strings[2], len ); } - if ( prefix & 4 ) { STRNCAT( buf, prefix_strings[3], len ); } - if ( prefix & 8 ) { STRNCAT( buf, prefix_strings[4], len ); } - - /* return the number of characters added */ - return (len_orig - len); -} - -/* - * sprint's an operand's data to string str. - */ -static void get_operand_data_str( x86_op_t *op, char *str, int len ){ - - if ( op->flags & op_signed ) { - switch ( op->datatype ) { - case op_byte: - snprintf( str, len, "%" PRId8, op->data.sbyte ); - return; - case op_word: - snprintf( str, len, "%" PRId16, op->data.sword ); - return; - case op_qword: - snprintf( str, len, "%" PRId64, op->data.sqword ); - return; - default: - snprintf( str, len, "%" PRId32, op->data.sdword ); - return; - } - } - - //else - switch ( op->datatype ) { - case op_byte: - snprintf( str, len, "0x%02" PRIX8, op->data.byte ); - return; - case op_word: - snprintf( str, len, "0x%04" PRIX16, op->data.word ); - return; - case op_qword: - snprintf( str, len, "0x%08" PRIX64,op->data.sqword ); - return; - default: - snprintf( str, len, "0x%08" PRIX32, op->data.dword ); - return; - } -} - -/* - * sprints register types to a string. the register types can be ORed - * together. - */ -static void get_operand_regtype_str( int regtype, char *str, int len ) -{ - static struct { - char *name; - int value; - } operand_regtypes[] = { - {"reg_gen" , 0x00001}, - {"reg_in" , 0x00002}, - {"reg_out" , 0x00004}, - {"reg_local" , 0x00008}, - {"reg_fpu" , 0x00010}, - {"reg_seg" , 0x00020}, - {"reg_simd" , 0x00040}, - {"reg_sys" , 0x00080}, - {"reg_sp" , 0x00100}, - {"reg_fp" , 0x00200}, - {"reg_pc" , 0x00400}, - {"reg_retaddr", 0x00800}, - {"reg_cond" , 0x01000}, - {"reg_zero" , 0x02000}, - {"reg_ret" , 0x04000}, - {"reg_src" , 0x10000}, - {"reg_dest" , 0x20000}, - {"reg_count" , 0x40000}, - {NULL, 0}, //end - }; - - unsigned int i; - - memset( str, 0, len ); - - //go thru every type in the enum - for ( i = 0; operand_regtypes[i].name; i++ ) { - //skip if type is not set - if(! (regtype & operand_regtypes[i].value) ) - continue; - - //not the first time around - if( str[0] ) { - STRNCAT( str, " ", len ); - } - - STRNCAT(str, operand_regtypes[i].name, len ); - } -} - -static int format_expr( x86_ea_t *ea, char *buf, int len, - enum x86_asm_format format ) { - char str[MAX_OP_STRING]; - - if ( format == att_syntax ) { - if (ea->base.name[0] || ea->index.name[0] || ea->scale) { - PRINT_DISPLACEMENT(ea); - STRNCAT( buf, "(", len ); - - if ( ea->base.name[0]) { - STRNCATF( buf, "%%%s", ea->base.name, len ); - } - if ( ea->index.name[0]) { - STRNCATF( buf, ",%%%s", ea->index.name, len ); - if ( ea->scale > 1 ) { - STRNCATF( buf, ",%d", ea->scale, len ); - } - } - /* handle the syntactic exception */ - if ( ! ea->base.name[0] && - ! ea->index.name[0] ) { - STRNCATF( buf, ",%d", ea->scale, len ); - } - - STRNCAT( buf, ")", len ); - } else - STRNCATF( buf, "0x%" PRIX32, ea->disp, len ); - - } else if ( format == xml_syntax ){ - - if ( ea->base.name[0]) { - STRNCAT (buf, "\t\t\t\n", len); - - get_operand_regtype_str (ea->base.type, str, - sizeof str); - STRNCAT (buf, "\t\t\t\tbase.name, len); - STRNCATF (buf, "type=\"%s\" ", str, len); - STRNCATF (buf, "size=%d/>\n", ea->base.size, len); - - STRNCAT (buf, "\t\t\t\n", len); - } - - if ( ea->index.name[0]) { - STRNCAT (buf, "\t\t\t\n", len); - - get_operand_regtype_str (ea->index.type, str, - sizeof str); - - STRNCAT (buf, "\t\t\t\tindex.name, len); - STRNCATF (buf, "type=\"%s\" ", str, len); - STRNCATF (buf, "size=%d/>\n", ea->index.size, len); - - STRNCAT (buf, "\t\t\t\n", len); - } - - //scale - STRNCAT (buf, "\t\t\t\n", len); - STRNCAT (buf, "\t\t\t\t\n", ea->scale, len); - STRNCAT (buf, "\t\t\t\n", len); - - if ( ea->disp_size ) { - - STRNCAT (buf, "\t\t\t\n", len); - - if ( ea->disp_size > 1 && ! ea->disp_sign ) { - STRNCAT (buf, "\t\t\t\t
\n", ea->disp, - len); - } else { - STRNCAT (buf, "\t\t\t\t\n", ea->disp, len); - } - - STRNCAT (buf, "\t\t\t\n", len); - } - - } else if ( format == raw_syntax ) { - - PRINT_DISPLACEMENT(ea); - STRNCAT( buf, "(", len ); - - STRNCATF( buf, "%s,", ea->base.name, len ); - STRNCATF( buf, "%s,", ea->index.name, len ); - STRNCATF( buf, "%d", ea->scale, len ); - STRNCAT( buf, ")", len ); - - } else { - - STRNCAT( buf, "[", len ); - - if ( ea->base.name[0] ) { - STRNCAT( buf, ea->base.name, len ); - if ( ea->index.name[0] || - (ea->disp_size && ! ea->disp_sign) ) { - STRNCAT( buf, "+", len ); - } - } - if ( ea->index.name[0] ) { - STRNCAT( buf, ea->index.name, len ); - if ( ea->scale > 1 ) - { - STRNCATF( buf, "*%" PRId32, ea->scale, len ); - } - if ( ea->disp_size && ! ea->disp_sign ) - { - STRNCAT( buf, "+", len ); - } - } - - if ( ea->disp_size || (! ea->index.name[0] && - ! ea->base.name[0] ) ) - { - PRINT_DISPLACEMENT(ea); - } - - STRNCAT( buf, "]", len ); - } - - return( strlen(buf) ); -} - -static int format_seg( x86_op_t *op, char *buf, int len, - enum x86_asm_format format ) { - int len_orig = len; - char *reg = ""; - - if (! op || ! buf || ! len || ! op->flags) { - return(0); - } - if ( op->type != op_offset && op->type != op_expression ){ - return(0); - } - if (! (int) op->flags & 0xF00 ) { - return(0); - } - - switch (op->flags & 0xF00) { - case op_es_seg: reg = "es"; break; - case op_cs_seg: reg = "cs"; break; - case op_ss_seg: reg = "ss"; break; - case op_ds_seg: reg = "ds"; break; - case op_fs_seg: reg = "fs"; break; - case op_gs_seg: reg = "gs"; break; - default: - break; - } - - if (! reg[0] ) { - return( 0 ); - } - - switch( format ) { - case xml_syntax: - STRNCAT( buf, "\t\t\t\n", reg, len ); - break; - case att_syntax: - STRNCATF( buf, "%%%s:", reg, len ); - break; - - default: - STRNCATF( buf, "%s:", reg, len ); - break; - } - - return( len_orig - len ); /* return length of appended string */ -} - -static char *get_operand_datatype_str( x86_op_t *op ){ - - static char *types[] = { - "sbyte", /* 0 */ - "sword", - "sqword", - "sdword", - "sdqword", /* 4 */ - "byte", - "word", - "qword", - "dword", /* 8 */ - "dqword", - "sreal", - "dreal", - "extreal", /* 12 */ - "bcd", - "ssimd", - "dsimd", - "sssimd", /* 16 */ - "sdsimd", - "descr32", - "descr16", - "pdescr32", /* 20 */ - "pdescr16", - "bounds16", - "bounds32", - "fpu_env16", - "fpu_env32", /* 25 */ - "fpu_state16", - "fpu_state32", - "fp_reg_set" - }; - - /* handle signed values first */ - if ( op->flags & op_signed ) { - switch (op->datatype) { - case op_byte: return types[0]; - case op_word: return types[1]; - case op_qword: return types[2]; - case op_dqword: return types[4]; - default: return types[3]; - } - } - - switch (op->datatype) { - case op_byte: return types[5]; - case op_word: return types[6]; - case op_qword: return types[7]; - case op_dqword: return types[9]; - case op_sreal: return types[10]; - case op_dreal: return types[11]; - case op_extreal: return types[12]; - case op_bcd: return types[13]; - case op_ssimd: return types[14]; - case op_dsimd: return types[15]; - case op_sssimd: return types[16]; - case op_sdsimd: return types[17]; - case op_descr32: return types[18]; - case op_descr16: return types[19]; - case op_pdescr32: return types[20]; - case op_pdescr16: return types[21]; - case op_bounds16: return types[22]; - case op_bounds32: return types[23]; - case op_fpustate16: return types[24]; - case op_fpustate32: return types[25]; - case op_fpuenv16: return types[26]; - case op_fpuenv32: return types[27]; - case op_fpregset: return types[28]; - default: return types[8]; - } -} - -static int format_insn_eflags_str( enum x86_flag_status flags, char *buf, - int len) { - - static struct { - char *name; - int value; - } insn_flags[] = { - { "carry_set ", 0x0001 }, - { "zero_set ", 0x0002 }, - { "oflow_set ", 0x0004 }, - { "dir_set ", 0x0008 }, - { "sign_set ", 0x0010 }, - { "parity_set ", 0x0020 }, - { "carry_or_zero_set ", 0x0040 }, - { "zero_set_or_sign_ne_oflow ", 0x0080 }, - { "carry_clear ", 0x0100 }, - { "zero_clear ", 0x0200 }, - { "oflow_clear ", 0x0400 }, - { "dir_clear ", 0x0800 }, - { "sign_clear ", 0x1000 }, - { "parity_clear ", 0x2000 }, - { "sign_eq_oflow ", 0x4000 }, - { "sign_ne_oflow ", 0x8000 }, - { NULL, 0x0000 }, //end - }; - - unsigned int i; - int len_orig = len; - - for (i = 0; insn_flags[i].name; i++) { - if (! (flags & insn_flags[i].value) ) - continue; - - STRNCAT( buf, insn_flags[i].name, len ); - } - - return( len_orig - len ); -} - -static char *get_insn_group_str( enum x86_insn_group gp ) { - - static char *types[] = { - "", // 0 - "controlflow",// 1 - "arithmetic", // 2 - "logic", // 3 - "stack", // 4 - "comparison", // 5 - "move", // 6 - "string", // 7 - "bit_manip", // 8 - "flag_manip", // 9 - "fpu", // 10 - "", // 11 - "", // 12 - "interrupt", // 13 - "system", // 14 - "other", // 15 - }; - - if ( gp > sizeof (types)/sizeof(types[0]) ) - return ""; - - return types[gp]; -} - -static char *get_insn_type_str( enum x86_insn_type type ) { - - static struct { - char *name; - int value; - } types[] = { - /* insn_controlflow */ - { "jmp", 0x1001 }, - { "jcc", 0x1002 }, - { "call", 0x1003 }, - { "callcc", 0x1004 }, - { "return", 0x1005 }, - { "loop", 0x1006 }, - /* insn_arithmetic */ - { "add", 0x2001 }, - { "sub", 0x2002 }, - { "mul", 0x2003 }, - { "div", 0x2004 }, - { "inc", 0x2005 }, - { "dec", 0x2006 }, - { "shl", 0x2007 }, - { "shr", 0x2008 }, - { "rol", 0x2009 }, - { "ror", 0x200A }, - /* insn_logic */ - { "and", 0x3001 }, - { "or", 0x3002 }, - { "xor", 0x3003 }, - { "not", 0x3004 }, - { "neg", 0x3005 }, - /* insn_stack */ - { "push", 0x4001 }, - { "pop", 0x4002 }, - { "pushregs", 0x4003 }, - { "popregs", 0x4004 }, - { "pushflags", 0x4005 }, - { "popflags", 0x4006 }, - { "enter", 0x4007 }, - { "leave", 0x4008 }, - /* insn_comparison */ - { "test", 0x5001 }, - { "cmp", 0x5002 }, - /* insn_move */ - { "mov", 0x6001 }, /* move */ - { "movcc", 0x6002 }, /* conditional move */ - { "xchg", 0x6003 }, /* exchange */ - { "xchgcc", 0x6004 }, /* conditional exchange */ - /* insn_string */ - { "strcmp", 0x7001 }, - { "strload", 0x7002 }, - { "strmov", 0x7003 }, - { "strstore", 0x7004 }, - { "translate", 0x7005 }, /* xlat */ - /* insn_bit_manip */ - { "bittest", 0x8001 }, - { "bitset", 0x8002 }, - { "bitclear", 0x8003 }, - /* insn_flag_manip */ - { "clear_carry", 0x9001 }, - { "clear_zero", 0x9002 }, - { "clear_oflow", 0x9003 }, - { "clear_dir", 0x9004 }, - { "clear_sign", 0x9005 }, - { "clear_parity", 0x9006 }, - { "set_carry", 0x9007 }, - { "set_zero", 0x9008 }, - { "set_oflow", 0x9009 }, - { "set_dir", 0x900A }, - { "set_sign", 0x900B }, - { "set_parity", 0x900C }, - { "tog_carry", 0x9010 }, - { "tog_zero", 0x9020 }, - { "tog_oflow", 0x9030 }, - { "tog_dir", 0x9040 }, - { "tog_sign", 0x9050 }, - { "tog_parity", 0x9060 }, - /* insn_fpu */ - { "fmov", 0xA001 }, - { "fmovcc", 0xA002 }, - { "fneg", 0xA003 }, - { "fabs", 0xA004 }, - { "fadd", 0xA005 }, - { "fsub", 0xA006 }, - { "fmul", 0xA007 }, - { "fdiv", 0xA008 }, - { "fsqrt", 0xA009 }, - { "fcmp", 0xA00A }, - { "fcos", 0xA00C }, - { "fldpi", 0xA00D }, - { "fldz", 0xA00E }, - { "ftan", 0xA00F }, - { "fsine", 0xA010 }, - { "fsys", 0xA020 }, - /* insn_interrupt */ - { "int", 0xD001 }, - { "intcc", 0xD002 }, /* not present in x86 ISA */ - { "iret", 0xD003 }, - { "bound", 0xD004 }, - { "debug", 0xD005 }, - { "trace", 0xD006 }, - { "invalid_op", 0xD007 }, - { "oflow", 0xD008 }, - /* insn_system */ - { "halt", 0xE001 }, - { "in", 0xE002 }, /* input from port/bus */ - { "out", 0xE003 }, /* output to port/bus */ - { "cpuid", 0xE004 }, - /* insn_other */ - { "nop", 0xF001 }, - { "bcdconv", 0xF002 }, /* convert to or from BCD */ - { "szconv", 0xF003 }, /* change size of operand */ - { NULL, 0 }, //end - }; - - unsigned int i; - - //go thru every type in the enum - for ( i = 0; types[i].name; i++ ) { - if ( types[i].value == type ) - return types[i].name; - } - - return ""; -} - -static char *get_insn_cpu_str( enum x86_insn_cpu cpu ) { - static char *intel[] = { - "", // 0 - "8086", // 1 - "80286", // 2 - "80386", // 3 - "80387", // 4 - "80486", // 5 - "Pentium", // 6 - "Pentium Pro", // 7 - "Pentium 2", // 8 - "Pentium 3", // 9 - "Pentium 4" // 10 - }; - - if ( cpu < sizeof(intel)/sizeof(intel[0]) ) { - return intel[cpu]; - } else if ( cpu == 16 ) { - return "K6"; - } else if ( cpu == 32 ) { - return "K7"; - } else if ( cpu == 48 ) { - return "Athlon"; - } - - return ""; -} - -static char *get_insn_isa_str( enum x86_insn_isa isa ) { - static char *subset[] = { - NULL, // 0 - "General Purpose", // 1 - "Floating Point", // 2 - "FPU Management", // 3 - "MMX", // 4 - "SSE", // 5 - "SSE2", // 6 - "SSE3", // 7 - "3DNow!", // 8 - "System" // 9 - }; - - if ( isa > sizeof (subset)/sizeof(subset[0]) ) { - return ""; - } - - return subset[isa]; -} - -static int format_operand_att( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING]; - - memset (str, 0, sizeof str); - - switch ( op->type ) { - case op_register: - STRNCATF( buf, "%%%s", op->data.reg.name, len ); - break; - - case op_immediate: - get_operand_data_str( op, str, sizeof str ); - STRNCATF( buf, "$%s", str, len ); - break; - - case op_relative_near: - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - if (op->datatype == op_word) { - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sword + - insn->addr + insn->size), len ); - } else { - STRNCATF( buf, "0x%08X", - (unsigned int)(op->data.sdword + - insn->addr + insn->size), len ); - } - break; - - case op_absolute: - /* ATT uses the syntax $section, $offset */ - STRNCATF( buf, "$0x%04" PRIX16 ", ", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "$0x%04" PRIX16, - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "$0x%08" PRIX32, - op->data.absolute.offset.off32, len ); - } - break; - case op_offset: - /* ATT requires a '*' before JMP/CALL ops */ - if (insn->type == insn_jmp || insn->type == insn_call) - STRNCAT( buf, "*", len ); - - len -= format_seg( op, buf, len, att_syntax ); - STRNCATF( buf, "0x%08" PRIX32, op->data.sdword, len ); - break; - - case op_expression: - /* ATT requires a '*' before JMP/CALL ops */ - if (insn->type == insn_jmp || insn->type == insn_call) - STRNCAT( buf, "*", len ); - - len -= format_seg( op, buf, len, att_syntax ); - len -= format_expr( &op->data.expression, buf, len, - att_syntax ); - break; - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return ( strlen( buf ) ); -} - -static int format_operand_native( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING]; - - switch (op->type) { - case op_register: - STRNCAT( buf, op->data.reg.name, len ); - break; - - case op_immediate: - get_operand_data_str( op, str, sizeof str ); - STRNCAT( buf, str, len ); - break; - - case op_relative_near: - STRNCATF( buf, "0x%08" PRIX32, - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - if ( op->datatype == op_word ) { - STRNCATF( buf, "0x%08" PRIX32, - (unsigned int)(op->data.sword + - insn->addr + insn->size), len ); - break; - } else { - STRNCATF( buf, "0x%08" PRIX32, op->data.sdword + - insn->addr + insn->size, len ); - } - break; - - case op_absolute: - STRNCATF( buf, "$0x%04" PRIX16 ":", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "0x%04" PRIX16, - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "0x%08" PRIX32, - op->data.absolute.offset.off32, len ); - } - break; - - case op_offset: - len -= format_seg( op, buf, len, native_syntax ); - STRNCATF( buf, "[0x%08" PRIX32 "]", op->data.sdword, len ); - break; - - case op_expression: - len -= format_seg( op, buf, len, native_syntax ); - len -= format_expr( &op->data.expression, buf, len, - native_syntax ); - break; - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_STRING] = "\0"; - - switch (op->type) { - case op_register: - - get_operand_regtype_str( op->data.reg.type, str, - sizeof str ); - - STRNCAT( buf, "\t\tdata.reg.name, len ); - STRNCATF( buf, "type=\"%s\" ", str, len ); - STRNCATF( buf, "size=%d/>\n", op->data.reg.size, len ); - break; - - case op_immediate: - - get_operand_data_str( op, str, sizeof str ); - - STRNCAT( buf, "\t\t\n", str, len ); - break; - - case op_relative_near: - STRNCAT( buf, "\t\t\n", - (unsigned int)(op->data.sbyte + - insn->addr + insn->size), len ); - break; - - case op_relative_far: - STRNCAT( buf, "\t\tdatatype == op_word) { - STRNCATF( buf, "value=\"0x%08" PRIX32 "\"/>\n", - (unsigned int)(op->data.sword + - insn->addr + insn->size), len); - break; - } else { - - STRNCATF( buf, "value=\"0x%08" PRIX32 "\"/>\n", - op->data.sdword + insn->addr + insn->size, - len ); - } - break; - - case op_absolute: - - STRNCATF( buf, - "\t\tdata.absolute.segment, len ); - - if (op->datatype == op_descr16) { - STRNCATF( buf, "offset=\"0x%04" PRIX16 "\">", - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "offset=\"0x%08" PRIX32 "\">", - op->data.absolute.offset.off32, len ); - } - - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_expression: - - - STRNCAT( buf, "\t\t\n", len ); - - len -= format_seg( op, buf, len, xml_syntax ); - len -= format_expr( &op->data.expression, buf, len, - xml_syntax ); - - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_offset: - - STRNCAT( buf, "\t\t\n", len ); - - len -= format_seg( op, buf, len, xml_syntax ); - - STRNCAT( buf, "\t\t\t
\n", - op->data.sdword, len ); - STRNCAT( buf, "\t\t\n", len ); - break; - - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf, - int len){ - - char str[MAX_OP_RAW_STRING]; - char *datatype = get_operand_datatype_str(op); - - switch (op->type) { - case op_register: - - get_operand_regtype_str( op->data.reg.type, str, - sizeof str ); - - STRNCAT( buf, "reg|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%s:", op->data.reg.name, len ); - STRNCATF( buf, "%s:", str, len ); - STRNCATF( buf, "%d|", op->data.reg.size, len ); - break; - - case op_immediate: - - get_operand_data_str( op, str, sizeof str ); - - STRNCAT( buf, "immediate|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%s|", str, len ); - break; - - case op_relative_near: - /* NOTE: in raw format, we print the - * relative offset, not the actual - * address of the jump target */ - - STRNCAT( buf, "relative|", len ); - STRNCATF( buf, "%s|", datatype, len ); - STRNCATF( buf, "%" PRId8 "|", op->data.sbyte, len ); - break; - - case op_relative_far: - - STRNCAT( buf, "relative|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - if (op->datatype == op_word) { - STRNCATF( buf, "%" PRId16 "|", op->data.sword, len); - break; - } else { - STRNCATF( buf, "%" PRId32 "|", op->data.sdword, len ); - } - break; - - case op_absolute: - - STRNCAT( buf, "absolute_address|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - STRNCATF( buf, "$0x%04" PRIX16 ":", op->data.absolute.segment, - len ); - if (op->datatype == op_descr16) { - STRNCATF( buf, "0x%04" PRIX16 "|", - op->data.absolute.offset.off16, len ); - } else { - STRNCATF( buf, "0x%08" PRIX32 "|", - op->data.absolute.offset.off32, len ); - } - - break; - - case op_expression: - - STRNCAT( buf, "address_expression|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - len -= format_seg( op, buf, len, native_syntax ); - len -= format_expr( &op->data.expression, buf, len, - raw_syntax ); - - STRNCAT( buf, "|", len ); - break; - - case op_offset: - - STRNCAT( buf, "segment_offset|", len ); - STRNCATF( buf, "%s|", datatype, len ); - - len -= format_seg( op, buf, len, xml_syntax ); - - STRNCATF( buf, "%08" PRIX32 "|", op->data.sdword, len ); - break; - - case op_unused: - case op_unknown: - /* return 0-truncated buffer */ - break; - } - - return( strlen( buf ) ); -} - -int x86_format_operand( x86_op_t *op, char *buf, int len, - enum x86_asm_format format ){ - x86_insn_t *insn; - - if ( ! op || ! buf || len < 1 ) { - return(0); - } - - /* insn is stored in x86_op_t since .21-pre3 */ - insn = (x86_insn_t *) op->insn; - - memset( buf, 0, len ); - - switch ( format ) { - case att_syntax: - return format_operand_att( op, insn, buf, len ); - case xml_syntax: - return format_operand_xml( op, insn, buf, len ); - case raw_syntax: - return format_operand_raw( op, insn, buf, len ); - case native_syntax: - case intel_syntax: - default: - return format_operand_native( op, insn, buf, len ); - } -} - -#define is_imm_jmp(op) (op->type == op_absolute || \ - op->type == op_immediate || \ - op->type == op_offset) -#define is_memory_op(op) (op->type == op_absolute || \ - op->type == op_expression || \ - op->type == op_offset) - -static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) { - int size = 0; - char *suffix; - - if (! insn || ! buf || ! len ) - return(0); - - memset( buf, 0, len ); - - /* do long jump/call prefix */ - if ( insn->type == insn_jmp || insn->type == insn_call ) { - if (! is_imm_jmp( x86_operand_1st(insn) ) || - (x86_operand_1st(insn))->datatype != op_byte ) { - /* far jump/call, use "l" prefix */ - STRNCAT( buf, "l", len ); - } - STRNCAT( buf, insn->mnemonic, len ); - - return ( strlen( buf ) ); - } - - /* do mnemonic */ - STRNCAT( buf, insn->mnemonic, len ); - - /* do suffixes for memory operands */ - if (!(insn->note & insn_note_nosuffix) && - (insn->group == insn_arithmetic || - insn->group == insn_logic || - insn->group == insn_move || - insn->group == insn_stack || - insn->group == insn_string || - insn->group == insn_comparison || - insn->type == insn_in || - insn->type == insn_out - )) { - if ( x86_operand_count( insn, op_explicit ) > 0 && - is_memory_op( x86_operand_1st(insn) ) ){ - size = x86_operand_size( x86_operand_1st( insn ) ); - } else if ( x86_operand_count( insn, op_explicit ) > 1 && - is_memory_op( x86_operand_2nd(insn) ) ){ - size = x86_operand_size( x86_operand_2nd( insn ) ); - } - } - - if ( size == 1 ) suffix = "b"; - else if ( size == 2 ) suffix = "w"; - else if ( size == 4 ) suffix = "l"; - else if ( size == 8 ) suffix = "q"; - else suffix = ""; - - STRNCAT( buf, suffix, len ); - return ( strlen( buf ) ); -} - -int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format){ - char str[MAX_OP_STRING]; - - memset( buf, 0, len ); - STRNCAT( buf, insn->prefix_string, len ); - if ( format == att_syntax ) { - format_att_mnemonic( insn, str, sizeof str ); - STRNCAT( buf, str, len ); - } else { - STRNCAT( buf, insn->mnemonic, len ); - } - - return( strlen( buf ) ); -} - -struct op_string { char *buf; size_t len; }; - -static void format_op_raw( x86_op_t *op, x86_insn_t *insn, void *arg ) { - struct op_string * opstr = (struct op_string *) arg; - - format_operand_raw(op, insn, opstr->buf, opstr->len); -} - -static int format_insn_note(x86_insn_t *insn, char *buf, int len){ - char note[32] = {0}; - int len_orig = len, note_len = 32; - - if ( insn->note & insn_note_ring0 ) { - STRNCATF( note, "%s", "Ring0 ", note_len ); - } - if ( insn->note & insn_note_smm ) { - STRNCATF( note, "%s", "SMM ", note_len ); - } - if ( insn->note & insn_note_serial ) { - STRNCATF(note, "%s", "Serialize ", note_len ); - } - STRNCATF( buf, "%s|", note, len ); - - return( len_orig - len ); -} - -static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){ - struct op_string opstr = { buf, len }; - int i; - - /* RAW style: - * ADDRESS|OFFSET|SIZE|BYTES| - * PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES| - * MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED| - * STACK_MOD|STACK_MOD_VAL - * [|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]* - * - * Register values are encoded as: - * NAME:TYPE:SIZE - * - * Effective addresses are encoded as: - * disp(base_reg,index_reg,scale) - */ - STRNCATF( buf, "0x%08" PRIX32 "|", insn->addr , len ); - STRNCATF( buf, "0x%08" PRIX32 "|", insn->offset, len ); - STRNCATF( buf, "%d|" , insn->size , len ); - - /* print bytes */ - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - STRNCAT( buf, "|", len ); - - len -= format_insn_prefix_str( insn->prefix, buf, len ); - STRNCATF( buf, "|%s|", insn->prefix_string , len ); - STRNCATF( buf, "%s|", get_insn_group_str( insn->group ), len ); - STRNCATF( buf, "%s|", get_insn_type_str( insn->type ) , len ); - STRNCATF( buf, "%s|", insn->mnemonic , len ); - STRNCATF( buf, "%s|", get_insn_cpu_str( insn->cpu ) , len ); - STRNCATF( buf, "%s|", get_insn_isa_str( insn->isa ) , len ); - - /* insn note */ - len -= format_insn_note( insn, buf, len ); - - len -= format_insn_eflags_str( insn->flags_set, buf, len ); - STRNCAT( buf, "|", len ); - len -= format_insn_eflags_str( insn->flags_tested, buf, len ); - STRNCAT( buf, "|", len ); - STRNCATF( buf, "%d|", insn->stack_mod, len ); - STRNCATF( buf, "%" PRId32 "|", insn->stack_mod_val, len ); - - opstr.len = len; - x86_operand_foreach( insn, format_op_raw, &opstr, op_any ); - - return( strlen (buf) ); -} - -static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) { - char str[MAX_OP_XML_STRING]; - int i; - - STRNCAT( buf, "\n", len ); - - STRNCATF( buf, "\t
addr, len ); - STRNCATF( buf, "offset=\"0x%08" PRIX32 "\" ", insn->offset, len ); - STRNCATF( buf, "size=%d bytes=\"", insn->size, len ); - - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - STRNCAT( buf, "\"/>\n", len ); - - STRNCAT( buf, "\tprefix, buf, len ); - STRNCATF( buf, "\" string=\"%s\"/>\n", insn->prefix_string, len ); - - STRNCATF( buf, "\tgroup), len ); - STRNCATF( buf, "type=\"%s\" ", get_insn_type_str (insn->type), len ); - STRNCATF( buf, "string=\"%s\"/>\n", insn->mnemonic, len ); - - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, "\t\tflags_set, buf, len ); - STRNCAT( buf, "\"/>\n\t\n", len ); - - - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, "\t\tflags_tested, buf, len ); - STRNCAT( buf, "\"/>\n\t\n", len ); - - if ( x86_operand_1st( insn ) ) { - x86_format_operand( x86_operand_1st(insn), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - if ( x86_operand_2nd( insn ) ) { - x86_format_operand( x86_operand_2nd( insn ), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - if ( x86_operand_3rd( insn ) ) { - x86_format_operand( x86_operand_3rd(insn), str, - sizeof str, xml_syntax); - STRNCAT( buf, "\t\n", len ); - STRNCAT( buf, str, len ); - STRNCAT( buf, "\t\n", len ); - } - - STRNCAT( buf, "\n", len ); - - return strlen (buf); -} - -int x86_format_header( char *buf, int len, enum x86_asm_format format ) { - switch (format) { - case att_syntax: - snprintf( buf, len, "MNEMONIC\tSRC, DEST, IMM" ); - break; - case intel_syntax: - snprintf( buf, len, "MNEMONIC\tDEST, SRC, IMM" ); - break; - case native_syntax: - snprintf( buf, len, "ADDRESS\tBYTES\tMNEMONIC\t" - "DEST\tSRC\tIMM" ); - break; - case raw_syntax: - snprintf( buf, len, "ADDRESS|OFFSET|SIZE|BYTES|" - "PREFIX|PREFIX_STRING|GROUP|TYPE|NOTES|" - "MNEMONIC|CPU|ISA|FLAGS_SET|FLAGS_TESTED|" - "STACK_MOD|STACK_MOD_VAL" - "[|OP_TYPE|OP_DATATYPE|OP_ACCESS|OP_FLAGS|OP]*" - ); - break; - case xml_syntax: - snprintf( buf, len, - "" - "
" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "
" - "" - "" - "" - "
" - "" - "" - "" - ); - break; - case unknown_syntax: - if ( len ) { - buf[0] = '\0'; - } - break; - } - - return( strlen(buf) ); -} - -int x86_format_insn( x86_insn_t *insn, char *buf, int len, - enum x86_asm_format format ){ - char str[MAX_OP_STRING]; - x86_op_t *src, *dst; - int i; - - memset(buf, 0, len); - if ( format == intel_syntax ) { - /* INTEL STYLE: mnemonic dest, src, imm */ - STRNCAT( buf, insn->prefix_string, len ); - STRNCAT( buf, insn->mnemonic, len ); - STRNCAT( buf, "\t", len ); - - /* dest */ - if ( (dst = x86_operand_1st( insn )) && !(dst->flags & op_implied) ) { - x86_format_operand( dst, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - /* src */ - if ( (src = x86_operand_2nd( insn )) ) { - if ( !(dst->flags & op_implied) ) { - STRNCAT( buf, ", ", len ); - } - x86_format_operand( src, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - /* imm */ - if ( x86_operand_3rd( insn )) { - STRNCAT( buf, ", ", len ); - x86_format_operand( x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - } else if ( format == att_syntax ) { - /* ATT STYLE: mnemonic src, dest, imm */ - STRNCAT( buf, insn->prefix_string, len ); - format_att_mnemonic(insn, str, MAX_OP_STRING); - STRNCATF( buf, "%s\t", str, len); - - - /* not sure which is correct? sometimes GNU as requires - * an imm as the first operand, sometimes as the third... */ - /* imm */ - if ( x86_operand_3rd( insn ) ) { - x86_format_operand(x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - /* there is always 'dest' operand if there is 'src' */ - STRNCAT( buf, ", ", len ); - } - - if ( (insn->note & insn_note_nonswap ) == 0 ) { - /* regular AT&T style swap */ - src = x86_operand_2nd( insn ); - dst = x86_operand_1st( insn ); - } - else { - /* special-case instructions */ - src = x86_operand_1st( insn ); - dst = x86_operand_2nd( insn ); - } - - /* src */ - if ( src ) { - x86_format_operand(src, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - /* there is always 'dest' operand if there is 'src' */ - if ( dst && !(dst->flags & op_implied) ) { - STRNCAT( buf, ", ", len ); - } - } - - /* dest */ - if ( dst && !(dst->flags & op_implied) ) { - x86_format_operand( dst, str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - - - } else if ( format == raw_syntax ) { - format_raw_insn( insn, buf, len ); - } else if ( format == xml_syntax ) { - format_xml_insn( insn, buf, len ); - } else { /* default to native */ - /* NATIVE style: RVA\tBYTES\tMNEMONIC\tOPERANDS */ - /* print address */ - STRNCATF( buf, "%08" PRIX32 "\t", insn->addr, len ); - - /* print bytes */ - for ( i = 0; i < insn->size; i++ ) { - STRNCATF( buf, "%02X ", insn->bytes[i], len ); - } - - STRNCAT( buf, "\t", len ); - - /* print mnemonic */ - STRNCAT( buf, insn->prefix_string, len ); - STRNCAT( buf, insn->mnemonic, len ); - STRNCAT( buf, "\t", len ); - - /* print operands */ - /* dest */ - if ( x86_operand_1st( insn ) ) { - x86_format_operand( x86_operand_1st( insn ), - str, MAX_OP_STRING, format); - STRNCATF( buf, "%s\t", str, len ); - } - - /* src */ - if ( x86_operand_2nd( insn ) ) { - x86_format_operand(x86_operand_2nd( insn ), - str, MAX_OP_STRING, format); - STRNCATF( buf, "%s\t", str, len ); - } - - /* imm */ - if ( x86_operand_3rd( insn )) { - x86_format_operand( x86_operand_3rd( insn ), - str, MAX_OP_STRING, format); - STRNCAT( buf, str, len ); - } - } - - return( strlen( buf ) ); -} - diff --git a/intercept/libdisasm/x86_imm.c b/intercept/libdisasm/x86_imm.c deleted file mode 100644 index cd59bfc..0000000 --- a/intercept/libdisasm/x86_imm.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "qword.h" -#include "x86_imm.h" - -#include - -unsigned int x86_imm_signsized( unsigned char * buf, size_t buf_len, - void *dest, unsigned int size ) { - signed char *cp = (signed char *) dest; - signed short *sp = (signed short *) dest; - int32_t *lp = (int32_t *) dest; - qword_t *qp = (qword_t *) dest; - - if ( size > buf_len ) { - return 0; - } - - /* Copy 'size' bytes from *buf to *op - * return number of bytes copied */ - switch (size) { - case 1: /* BYTE */ - *cp = *((signed char *) buf); - break; - case 2: /* WORD */ - *sp = *((signed short *) buf); - break; - case 6: - case 8: /* QWORD */ - *qp = *((qword_t *) buf); - break; - case 4: /* DWORD */ - default: - *lp = *((int32_t *) buf); - break; - } - return (size); -} - -unsigned int x86_imm_sized( unsigned char * buf, size_t buf_len, void *dest, - unsigned int size ) { - unsigned char *cp = (unsigned char *) dest; - unsigned short *sp = (unsigned short *) dest; - uint32_t *lp = (uint32_t *) dest; - qword_t *qp = (qword_t *) dest; - - if ( size > buf_len ) { - return 0; - } - - /* Copy 'size' bytes from *buf to *op - * return number of bytes copied */ - switch (size) { - case 1: /* BYTE */ - *cp = *((unsigned char *) buf); - break; - case 2: /* WORD */ - *sp = *((unsigned short *) buf); - break; - case 6: - case 8: /* QWORD */ - *qp = *((qword_t *) buf); - break; - case 4: /* DWORD */ - default: - *lp = *((uint32_t *) buf); - break; - } - - return (size); -} - diff --git a/intercept/libdisasm/x86_imm.h b/intercept/libdisasm/x86_imm.h deleted file mode 100644 index fa35ff2..0000000 --- a/intercept/libdisasm/x86_imm.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef x86_IMM_H -#define x86_IMM_H - -#include "./qword.h" -#include - -#ifdef WIN32 -#include -#endif - -/* these are in the global x86 namespace but are not a part of the - * official API */ -unsigned int x86_imm_sized( unsigned char *buf, size_t buf_len, void *dest, - unsigned int size ); - -unsigned int x86_imm_signsized( unsigned char *buf, size_t buf_len, void *dest, - unsigned int size ); -#endif diff --git a/intercept/libdisasm/x86_insn.c b/intercept/libdisasm/x86_insn.c deleted file mode 100644 index 5649b89..0000000 --- a/intercept/libdisasm/x86_insn.c +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include - -#include "libdis.h" - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - -int x86_insn_is_valid( x86_insn_t *insn ) { - if ( insn && insn->type != insn_invalid && insn->size > 0 ) { - return 1; - } - - return 0; -} - -uint32_t x86_get_address( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return 0; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_offset ) { - return op_lst->op.data.offset; - } else if ( op_lst->op.type == op_absolute ) { - if ( op_lst->op.datatype == op_descr16 ) { - return (uint32_t) - op_lst->op.data.absolute.offset.off16; - } - return op_lst->op.data.absolute.offset.off32; - } - } - - return 0; -} - -int32_t x86_get_rel_offset( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return 0; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_relative_near ) { - return (int32_t) op_lst->op.data.relative_near; - } else if ( op_lst->op.type == op_relative_far ) { - return op_lst->op.data.relative_far; - } - } - - return 0; -} - -x86_op_t * x86_get_branch_target( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return NULL; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.access & op_execute ) { - return &(op_lst->op); - } - } - - return NULL; -} -x86_op_t * x86_get_imm( x86_insn_t *insn ) { - x86_oplist_t *op_lst; - if (! insn || ! insn->operands ) { - return NULL; - } - - for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { - if ( op_lst->op.type == op_immediate ) { - return &(op_lst->op); - } - } - - return NULL; -} - -#define IS_PROPER_IMM( x ) \ - x->op.type == op_immediate && ! (x->op.flags & op_hardcode) - - -/* if there is an immediate value in the instruction, return a pointer to - * it */ -unsigned char * x86_get_raw_imm( x86_insn_t *insn ) { - int size, offset; - x86_op_t *op = NULL; - - if (! insn || ! insn->operands ) { - return(NULL); - } - - /* a bit inelegant, but oh well... */ - if ( IS_PROPER_IMM( insn->operands ) ) { - op = &insn->operands->op; - } else if ( insn->operands->next ) { - if ( IS_PROPER_IMM( insn->operands->next ) ) { - op = &insn->operands->next->op; - } else if ( insn->operands->next->next && - IS_PROPER_IMM( insn->operands->next->next ) ) { - op = &insn->operands->next->next->op; - } - } - - if (! op ) { - return( NULL ); - } - - /* immediate data is at the end of the insn */ - size = x86_operand_size( op ); - offset = insn->size - size; - return( &insn->bytes[offset] ); -} - - -unsigned int x86_operand_size( x86_op_t *op ) { - switch (op->datatype ) { - case op_byte: return 1; - case op_word: return 2; - case op_dword: return 4; - case op_qword: return 8; - case op_dqword: return 16; - case op_sreal: return 4; - case op_dreal: return 8; - case op_extreal: return 10; - case op_bcd: return 10; - case op_ssimd: return 16; - case op_dsimd: return 16; - case op_sssimd: return 4; - case op_sdsimd: return 8; - case op_descr32: return 6; - case op_descr16: return 4; - case op_pdescr32: return 6; - case op_pdescr16: return 6; - case op_bounds16: return 4; - case op_bounds32: return 8; - case op_fpuenv16: return 14; - case op_fpuenv32: return 28; - case op_fpustate16: return 94; - case op_fpustate32: return 108; - case op_fpregset: return 512; - case op_fpreg: return 10; - case op_none: return 0; - } - return(4); /* default size */ -} - -void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) { - if ( insn ) insn->addr = addr; -} - -void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){ - if ( insn ) insn->offset = offset; -} - -void x86_set_insn_function( x86_insn_t *insn, void * func ){ - if ( insn ) insn->function = func; -} - -void x86_set_insn_block( x86_insn_t *insn, void * block ){ - if ( insn ) insn->block = block; -} - -void x86_tag_insn( x86_insn_t *insn ){ - if ( insn ) insn->tag = 1; -} - -void x86_untag_insn( x86_insn_t *insn ){ - if ( insn ) insn->tag = 0; -} - -int x86_insn_is_tagged( x86_insn_t *insn ){ - return insn->tag; -} - diff --git a/intercept/libdisasm/x86_misc.c b/intercept/libdisasm/x86_misc.c deleted file mode 100644 index 3d2dd0a..0000000 --- a/intercept/libdisasm/x86_misc.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include - -#include "libdis.h" -#include "ia32_insn.h" -#include "ia32_reg.h" /* for ia32_reg wrapper */ -#include "ia32_settings.h" -extern ia32_settings_t ia32_settings; - -#ifdef _MSC_VER - #define snprintf _snprintf - #define inline __inline -#endif - - -/* =========================================================== INIT/TERM */ -static DISASM_REPORTER __x86_reporter_func = NULL; -static void * __x86_reporter_arg = NULL; - -int x86_init( enum x86_options options, DISASM_REPORTER reporter, void * arg ) -{ - ia32_settings.options = options; - __x86_reporter_func = reporter; - __x86_reporter_arg = arg; - - return 1; -} - -void x86_set_reporter( DISASM_REPORTER reporter, void * arg ) { - __x86_reporter_func = reporter; - __x86_reporter_arg = arg; -} - -void x86_set_options( enum x86_options options ){ - ia32_settings.options = options; -} - -enum x86_options x86_get_options( void ) { - return ia32_settings.options; -} - -int x86_cleanup( void ) -{ - return 1; -} - -/* =========================================================== ERRORS */ -void x86_report_error( enum x86_report_codes code, void *data ) { - if ( __x86_reporter_func ) { - (*__x86_reporter_func)(code, data, __x86_reporter_arg); - } -} - - -/* =========================================================== MISC */ -unsigned int x86_endian(void) { return ia32_settings.endian; } -unsigned int x86_addr_size(void) { return ia32_settings.sz_addr; } -unsigned int x86_op_size(void) { return ia32_settings.sz_oper; } -unsigned int x86_word_size(void) { return ia32_settings.sz_word; } -unsigned int x86_max_insn_size(void) { return ia32_settings.max_insn; } -unsigned int x86_sp_reg(void) { return ia32_settings.id_sp_reg; } -unsigned int x86_fp_reg(void) { return ia32_settings.id_fp_reg; } -unsigned int x86_ip_reg(void) { return ia32_settings.id_ip_reg; } -unsigned int x86_flag_reg(void) { return ia32_settings.id_flag_reg; } - -/* wrapper function to hide the IA32 register fn */ -void x86_reg_from_id( unsigned int id, x86_reg_t * reg ) { - ia32_handle_register( reg, id ); - return; -} diff --git a/intercept/libdisasm/x86_operand_list.c b/intercept/libdisasm/x86_operand_list.c deleted file mode 100644 index 95409e0..0000000 --- a/intercept/libdisasm/x86_operand_list.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include "libdis.h" - - -static void x86_oplist_append( x86_insn_t *insn, x86_oplist_t *op ) { - x86_oplist_t *list; - - if (! insn ) { - return; - } - - list = insn->operands; - if (! list ) { - insn->operand_count = 1; - /* Note that we have no way of knowing if this is an - * exlicit operand or not, since the caller fills - * the x86_op_t after we return. We increase the - * explicit count automatically, and ia32_insn_implicit_ops - * decrements it */ - insn->explicit_count = 1; - insn->operands = op; - return; - } - - /* get to end of list */ - for ( ; list->next; list = list->next ) - ; - - insn->operand_count = insn->operand_count + 1; - insn->explicit_count = insn->explicit_count + 1; - list->next = op; - - return; -} - -x86_op_t * x86_operand_new( x86_insn_t *insn ) { - x86_oplist_t *op; - - if (! insn ) { - return(NULL); - } - op = calloc( sizeof(x86_oplist_t), 1 ); - op->op.insn = insn; - x86_oplist_append( insn, op ); - return( &(op->op) ); -} - -void x86_oplist_free( x86_insn_t *insn ) { - x86_oplist_t *op, *list; - - if (! insn ) { - return; - } - - for ( list = insn->operands; list; ) { - op = list; - list = list->next; - free(op); - } - - insn->operands = NULL; - insn->operand_count = 0; - insn->explicit_count = 0; - - return; -} - -/* ================================================== LIBDISASM API */ -/* these could probably just be #defines, but that means exposing the - enum... yet one more confusing thing in the API */ -int x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg, - enum x86_op_foreach_type type ){ - x86_oplist_t *list; - char explicit = 1, implicit = 1; - - if (! insn || ! func ) { - return 0; - } - - /* note: explicit and implicit can be ORed together to - * allow an "all" limited by access type, even though the - * user is stupid to do this since it is default behavior :) */ - if ( (type & op_explicit) && ! (type & op_implicit) ) { - implicit = 0; - } - if ( (type & op_implicit) && ! (type & op_explicit) ) { - explicit = 0; - } - - type = type & 0x0F; /* mask out explicit/implicit operands */ - - for ( list = insn->operands; list; list = list->next ) { - if (! implicit && (list->op.flags & op_implied) ) { - /* operand is implicit */ - continue; - } - - if (! explicit && ! (list->op.flags & op_implied) ) { - /* operand is not implicit */ - continue; - } - - switch ( type ) { - case op_any: - break; - case op_dest: - if (! (list->op.access & op_write) ) { - continue; - } - break; - case op_src: - if (! (list->op.access & op_read) ) { - continue; - } - break; - case op_ro: - if (! (list->op.access & op_read) || - (list->op.access & op_write ) ) { - continue; - } - break; - case op_wo: - if (! (list->op.access & op_write) || - (list->op.access & op_read ) ) { - continue; - } - break; - case op_xo: - if (! (list->op.access & op_execute) ) { - continue; - } - break; - case op_rw: - if (! (list->op.access & op_write) || - ! (list->op.access & op_read ) ) { - continue; - } - break; - case op_implicit: case op_explicit: /* make gcc happy */ - break; - } - /* any non-continue ends up here: invoke the callback */ - (*func)( &list->op, insn, arg ); - } - - return 1; -} - -static void count_operand( x86_op_t *op, x86_insn_t *insn, void *arg ) { - size_t * count = (size_t *) arg; - *count = *count + 1; -} - -size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type ) { - size_t count = 0; - - /* save us a list traversal for common counts... */ - if ( type == op_any ) { - return insn->operand_count; - } else if ( type == op_explicit ) { - return insn->explicit_count; - } - - x86_operand_foreach( insn, count_operand, &count, type ); - return count; -} - -/* accessor functions */ -x86_op_t * x86_operand_1st( x86_insn_t *insn ) { - if (! insn->explicit_count ) { - return NULL; - } - - return &(insn->operands->op); -} - -x86_op_t * x86_operand_2nd( x86_insn_t *insn ) { - if ( insn->explicit_count < 2 ) { - return NULL; - } - - return &(insn->operands->next->op); -} - -x86_op_t * x86_operand_3rd( x86_insn_t *insn ) { - if ( insn->explicit_count < 3 ) { - return NULL; - } - - return &(insn->operands->next->next->op); -} diff --git a/intercept/libdisasm/x86_operand_list.h b/intercept/libdisasm/x86_operand_list.h deleted file mode 100644 index 5366865..0000000 --- a/intercept/libdisasm/x86_operand_list.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef X86_OPERAND_LIST_H -#define X86_OPERAND_LIST_H -#include "libdis.h" - - -x86_op_t * x86_operand_new( x86_insn_t *insn ); - -#endif diff --git a/intercept/hook.c b/intercept/src/hook.c similarity index 81% rename from intercept/hook.c rename to intercept/src/hook.c index 130491d..159d34b 100644 --- a/intercept/hook.c +++ b/intercept/src/hook.c @@ -5,7 +5,7 @@ #include #include #include -#include "libdis.h" +#include "Zydis/Zydis.h" #include "hook.h" // Routines to intercept or redirect routines. @@ -21,10 +21,61 @@ // instruction (where 16 is the longest possible instruction intel allows). #define MAX_REDIRECT_LENGTH 24 +ZydisDecoder decoder; + static void __attribute__((constructor)) init(void) { - // Initialize libdisasm. - x86_init(opt_none, NULL, NULL); + // Initialize Zydis disassemble + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32); +} + +// Disassemble a buffer until max_size is reached. If no branch instructions have been found +// returns the total amount of disassembled bytes. +bool disassemble(void *buffer, uint32_t *total_disassembled, ulong max_size, uint32_t flags) +{ + ZyanUSize offset = 0; + unsigned insncount = 0; + + for (*total_disassembled = 0; *total_disassembled < max_size; insncount++) { + ZydisDecodedInstruction instruction; + + // Test if Zydis understood the instruction + if (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, buffer + offset, max_size, &instruction))) { + + // Valid, increment size. + *total_disassembled += instruction.length; + + // Check for branches just to be safe, as these instructions are + // relative and cannot be relocated safely (there are others of + // course, but these are the most likely). + if ((instruction.meta.category == ZYDIS_CATEGORY_CALL || + instruction.meta.category == ZYDIS_CATEGORY_UNCOND_BR || + instruction.meta.category == ZYDIS_CATEGORY_COND_BR || + instruction.meta.category == ZYDIS_CATEGORY_RET) && + flags != HOOK_REPLACE_FUNCTION) { + printf("error: refusing to redirect function %p due win_to_nix early controlflow manipulation (+%u)\n", + buffer, + *total_disassembled); + + return false; + } + + offset += instruction.length; + + // Next instuction. + continue; + } + + // Invalid instruction, abort. + printf("error: %s encountered an invalid instruction @%p+%u, so redirection was aborted\n", + __func__, + buffer, + *total_disassembled); + + return false; + } + + return true; } // Intercept calls to this function and execute redirect first. Depending on @@ -47,7 +98,7 @@ static void __attribute__((constructor)) init(void) // intercepting it. bool insert_function_redirect(void *function, void *redirect, uint32_t flags) { - size_t redirectsize = 0; + uint32_t redirectsize = 0; unsigned insncount = 0; struct branch *fixup; struct branch *callsite; @@ -62,45 +113,8 @@ bool insert_function_redirect(void *function, void *redirect, uint32_t flags) // screwed. Seems unlikely though, so I'm not worrying about it right // now. I could at least check for rets? // - for (redirectsize = 0; redirectsize < sizeof(struct branch) + sizeof(struct encodedsize); insncount++) { - x86_insn_t insn = {0}; - ssize_t insnlength = 0; - - // Test if libdisasm understood the instruction - if ((insnlength = x86_disasm(function, MAX_REDIRECT_LENGTH, (uintptr_t)(function), redirectsize, &insn))) { - - // Valid, increment size. - redirectsize += insnlength; - - // Check for branches just to be safe, as these instructions are - // relative and cannot be relocated safely (there are others of - // course, but these are the most likely). - if (insn.group == insn_controlflow && flags != HOOK_REPLACE_FUNCTION) { - printf("error: refusing to redirect function %p due to early controlflow manipulation (+%u)\n", - function, - redirectsize); - - // Clean up. - x86_oplist_free(&insn); - - return false; - } - - // Clean up. - x86_oplist_free(&insn); - - // Next instuction. - continue; - } - - // Invalid instruction, abort. - printf("error: %s encountered an invalid instruction @%p+%u, so redirection was aborted\n", - __func__, - function, - redirectsize); - + if (!disassemble(function, &redirectsize, sizeof(struct branch) + sizeof(struct encodedsize), flags)) return false; - } // We need to create a fixup, a small chunk of code that repairs the damage // we did redirecting the function. This basically handles calling the @@ -222,7 +236,7 @@ bool remove_function_redirect(void *function) // Let's verify this looks sane. if (callsite->opcode != X86_OPCODE_JMP_NEAR) { - printf("error: tried to remove function hook from %p, but it didnt contain a redirect (%02x)\n", + printf("error: tried win_to_nix remove function hook from %p, but it didnt contain a redirect (%02x)\n", function, callsite->opcode); return false; @@ -232,7 +246,7 @@ bool remove_function_redirect(void *function) if (savedsize->opcode != X86_OPCODE_MOV_EAX_IMM || savedsize->prefix != X86_PREFIX_DATA16 || savedsize->operand > MAX_REDIRECT_LENGTH) { - printf("error: tried to remove function hook from %p, but encoded size did not validate { %02x %02x %04x }\n", + printf("error: tried win_to_nix remove function hook from %p, but encoded size did not validate { %02x %02x %04x }\n", function, savedsize->prefix, savedsize->opcode, @@ -275,42 +289,40 @@ bool remove_function_redirect(void *function) // // redirect_call_within_function(tcp_input, inet_cksum, my_cksum_replacement); // + bool redirect_call_within_function(void *function, void *target, void *redirect) { size_t offset = 0; struct branch *callsite = NULL; while (true) { - x86_insn_t insn; - ssize_t insnlength; + ZydisDecodedInstruction instruction; - // Test if libdisasm understood the instruction - if ((insnlength = x86_disasm(function, MAX_FUNCTION_LENGTH, (uintptr_t)(function), offset, &insn))) { + // Test if Zydis understood the instruction + if (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, function + offset, MAX_FUNCTION_LENGTH, &instruction))) { - // Examine the instuction found to see if it matches the call we + // Examine the instruction found to see if it matches the call we // want to replace. - if (insn.type == insn_call) { - if (x86_get_rel_offset(&insn) == (uintptr_t)(target) - - (uintptr_t)(function + offset) - - (uintptr_t)(insnlength)) { + ZyanU64 result_address = 0; + if (instruction.mnemonic == ZYDIS_MNEMONIC_CALL) { + + if (ZydisCalcAbsoluteAddress(&instruction, + &(instruction.operands[0]), (uintptr_t) function + offset, &result_address) != ZYAN_STATUS_SUCCESS) + continue; + + if (result_address == (uintptr_t)target) { // Success, this is the location the caller wants us to patch. callsite = (struct branch *)(function + offset); // Let's move on to patching. - printf("info: found a call at %p, the target is %#x\n", callsite, x86_get_rel_offset(&insn)); - - // Clean up, then exit disassembly. - x86_oplist_free(&insn); + printf("info: found a call at %p, the target is %#x\n", callsite, result_address); break; } } // Valid, but not interesting. Increment size. - offset += insnlength; - - // Clean up. - x86_oplist_free(&insn); + offset += instruction.length; // Next instuction. continue; @@ -331,7 +343,7 @@ bool redirect_call_within_function(void *function, void *target, void *redirect) - (uintptr_t)(callsite) - (uintptr_t)(sizeof(struct branch)); - printf("info: successfully redirected call to %p at %p+%x with a call to %p\n", + printf("info: successfully redirected call to %p at %p+%x with a call win_to_nix %p\n", target, function, offset, diff --git a/intercept/src/hook_x86_64.c b/intercept/src/hook_x86_64.c new file mode 100644 index 0000000..c9caae8 --- /dev/null +++ b/intercept/src/hook_x86_64.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "Zydis/Zydis.h" +#include "subhook.h" +#include "hook.h" +#include "log.h" + +// Routines to intercept or redirect routines (x86_64). +// Author: Alessandro De Vito (cube0x8) + +// This was chosen arbitrarily, the maximum amount of code we will search to +// find a call when looking for callsites, feel free to adjust as required. +#define MAX_FUNCTION_LENGTH 2048 + +ZydisDecoder decoder; + +static void __attribute__((constructor(100))) init(void) { + // Initialize Zydis disassemble + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); +} + +/* Disassemble a buffer until max_size is reached. If no branch instructions have been found + * returns the total amount of disassembled bytes. + */ +bool disassemble(void *buffer, uint32_t *total_disassembled, ulong max_size, uint32_t flags) { + ZyanUSize offset = 0; + unsigned insncount = 0; + + for (*total_disassembled = 0; *total_disassembled < max_size; insncount++) { + ZydisDecodedInstruction instruction; + + // Test if Zydis understood the instruction + if (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, buffer + offset, max_size, &instruction))) { + // Valid, increment size. + *total_disassembled += instruction.length; + + // Check for branches just to be safe, as these instructions are + // relative and cannot be relocated safely (there are others of + // course, but these are the most likely). + if ((instruction.meta.category == ZYDIS_CATEGORY_CALL || + instruction.meta.category == ZYDIS_CATEGORY_COND_BR || + instruction.meta.category == ZYDIS_CATEGORY_UNCOND_BR || + instruction.meta.category == ZYDIS_CATEGORY_RET) && + flags != HOOK_REPLACE_FUNCTION) { + l_error("Refusing to redirect function %p due to early controlflow manipulation (total bytes disassembled: +%u)", + buffer, + *total_disassembled); + + return false; + } + + offset += instruction.length; + + // Next instuction. + continue; + } + + // Invalid instruction, abort. + l_error("%s encountered an invalid instruction @%p+%u, so redirection was aborted", + __func__, + buffer, + *total_disassembled); + + return false; + } + + return true; +} + +// Intercept calls to this function and execute redirect first. Depending on +// flags, you can either replace this function, or simply be inserted into the +// call chain. +// function The address of the function you want intercepted. +// redirect Your callback function. The prototype should be the same as +// function, except an additional first parameter which you can +// ignore (it's the return address for the caller). +// flags Options, see header file for flags available. Use HOOK_DEFAULT +// if you don't need any. +// +// *NOTE*: If you want to redirect (or intercept) a function in a dll, +// remember to declare the target function (*redirect) as WINAPI e.g: +// PVOID WINAPI my_redirect_function(...) { +// [code] +// } + +subhook_t insert_function_redirect(void *function, void *redirect, uint32_t flags) { + uint32_t redirect_size = 0; + void *fixup_area; + mov_r64_abs_insn *movabs; + struct branch64 *branch; + uintptr_t clobbered_code_offset; + size_t branch_size; + size_t jmp64_size = subhook_get_jmp_size(SUBHOOK_64BIT_OFFSET); + + if (!disassemble(function, &redirect_size, jmp64_size, flags)) + return NULL; + + branch_size = flags == HOOK_DEFAULT ? sizeof(struct branch64) : jmp64_size; + + // We need to create a fixup, a small chunk of code that repairs the damage + // we did redirecting the function. This basically handles calling the + // redirect, then fixes the damage and restores execution. So it's going to be + // sizeof(mov_r64_abs_insn) + branch_size + redirect_size + jmp64_size bytes, + // which looks like this: + // + // mov r11, your_routine + // call r11 (or "push, mov, ret" x86_64 jump, based on the flags' value) + // ; redirectsize bytes + // push, mov, ret (x86_64 jump) + // + // the "branch_size" value is determined by the flags argument's value (HOOK_DEFAULT + // or HOOK_REPLACE_FUNCTION). If HOOK_DEFAULT is selected, the branch to the user-defined + // routine is implemented as a "call r11" instruction. Instead, when HOOK_REPLACE_FUNCTION + // is selected, we create a subhook (push, mov, ret) redirect. + // + + fixup_area = calloc(sizeof(mov_r64_abs_insn) + + branch_size + + redirect_size + + jmp64_size, 1); + + /* This moves the address of the redirect function in the r11 register + * [addr+0x0]: movabs r11, *redirect + */ + movabs = fixup_area; + movabs->opcode = X86_64_OPCODE_MOV_ABS_R64; + movabs->reg = 0xBB; // r11 + movabs->imm.i = redirect; + + // Create a call or a subhook jump + if (flags == HOOK_DEFAULT) { + branch = &movabs->data; + branch->opcode = X86_64_OPCODE_CALL_REG; + branch->reg = 0xD3; // r11 + clobbered_code_offset = (uintptr_t) & branch->data; + } else { + subhook_t hook = subhook_new(&movabs->data, redirect, SUBHOOK_64BIT_OFFSET); + if (subhook_install(hook) != 0) { + l_error("Cannot install the jmp to the redirect."); + return NULL; + } + clobbered_code_offset = (uintptr_t) & movabs->data + jmp64_size; + } + + // Copy over the code we are going to clobber by installing the redirect. + memcpy((void *) clobbered_code_offset, function, redirect_size); + + // And install a branch to restore execution to the rest of the original routine. + subhook_t restore_hook = subhook_new(clobbered_code_offset + redirect_size, + function + redirect_size, + SUBHOOK_64BIT_OFFSET); + if (subhook_install(restore_hook) != 0) { + l_error("Cannot the jmp to restore the execution."); + return NULL; + } + + // Fix permissions on the redirect. + if (mprotect((void *) ((uintptr_t) fixup_area & PAGE_MASK), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { + printf("mprotect() failed on stub => %p (%m), try `sudo setenforce 0`\n", fixup_area); + return NULL; + } + + // Now I need to install the redirect, I also clobber any left over bytes + // with x86 nops, so as not to disrupt disassemblers while debugging. + subhook_t hook = subhook_new(function, fixup_area, SUBHOOK_64BIT_OFFSET); + if (subhook_install(hook) != 0) { + l_error("Cannot install redirect."); + return NULL; + } + + // Clean up the left over slack bytes (not acutally needed, as we're careful to + // restore execution to the next valid instructions, but intended to make + // sure we dont desync disassembly when debugging problems in kgdb). + memset(function + jmp64_size, + X86_OPCODE_NOP, + redirect_size - jmp64_size); + + return hook; +} + +// TODO: implement it +bool redirect_call_within_function(void *function, void *target, void *redirect) { + l_error("Not implemented."); + return false; +} + +bool remove_function_redirect(subhook_t hook) { + if (subhook_remove(hook) != 0) { + l_error("Cannot remove the hook."); + return false; + } + subhook_free(hook); + return true; +} diff --git a/intercept/subhook b/intercept/subhook new file mode 160000 index 0000000..197165d --- /dev/null +++ b/intercept/subhook @@ -0,0 +1 @@ +Subproject commit 197165da7875654ae83f5700da8d918d1936a58d diff --git a/intercept/zydis b/intercept/zydis new file mode 160000 index 0000000..25193db --- /dev/null +++ b/intercept/zydis @@ -0,0 +1 @@ +Subproject commit 25193db008e8799ff59fd655c2a26b2ffd79d40d diff --git a/peloader/log.c b/log/log.c similarity index 100% rename from peloader/log.c rename to log/log.c diff --git a/peloader/log.h b/log/log.h similarity index 100% rename from peloader/log.h rename to log/log.h diff --git a/mpclient.c b/mpclient.c index 5391235..e68e68b 100644 --- a/mpclient.c +++ b/mpclient.c @@ -50,6 +50,12 @@ #include "scanreply.h" #include "streambuffer.h" #include "openscan.h" +#include "mpclient.h" + +struct pe_image image = { + .entry = NULL, + .name = "engine/mpengine.dll", +}; // Any usage limits to prevent bugs disrupting system. const struct rlimit kUsageLimits[] = { @@ -129,10 +135,6 @@ int main(int argc, char **argv, char **envp) STREAMBUFFER_DESCRIPTOR ScanDescriptor; ENGINE_INFO EngineInfo; ENGINE_CONFIG EngineConfig; - struct pe_image image = { - .entry = NULL, - .name = "engine/mpengine.dll", - }; // Load the mpengine module. if (pe_load_library(image.name, &image.image, &image.size) == false) { diff --git a/mpclient_x64.c b/mpclient_x64.c new file mode 100644 index 0000000..bc67102 --- /dev/null +++ b/mpclient_x64.c @@ -0,0 +1,260 @@ +// +// Copyright (C) 2017 Tavis Ormandy +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. +// + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "winnt_types.h" +#include "pe_linker.h" +#include "ntoskernel.h" +#include "util.h" +#include "log.h" +#include "rsignal.h" +#include "engineboot.h" +#include "scanreply.h" +#include "streambuffer.h" +#include "openscan.h" +#include "hook.h" +#include "mpclient.h" + +struct pe_image image = { + .entry = NULL, + .name = "engine/x64/mpengine.dll", +}; + +// Any usage limits to prevent bugs disrupting system. +const struct rlimit kUsageLimits[] = { + [RLIMIT_FSIZE] = { .rlim_cur = 0x20000000, .rlim_max = 0x20000000 }, + [RLIMIT_CPU] = { .rlim_cur = 3600, .rlim_max = RLIM_INFINITY }, + [RLIMIT_CORE] = { .rlim_cur = 0, .rlim_max = 0 }, + [RLIMIT_NOFILE] = { .rlim_cur = 32, .rlim_max = 32 }, +}; + +DWORD WINAPI (* __rsignal)(PHANDLE KernelHandle, DWORD Code, PVOID Params, DWORD Size); + +static DWORD WINAPI EngineScanCallback(PSCANSTRUCT Scan) +{ + if (Scan->Flags & SCAN_MEMBERNAME) { + LogMessage("Scanning archive member %s", Scan->VirusName); + } + if (Scan->Flags & SCAN_FILENAME) { + LogMessage("Scanning %s", Scan->FileName); + } + if (Scan->Flags & SCAN_PACKERSTART) { + LogMessage("Packer %s identified.", Scan->VirusName); + } + if (Scan->Flags & SCAN_ENCRYPTED) { + LogMessage("File is encrypted."); + } + if (Scan->Flags & SCAN_CORRUPT) { + LogMessage("File may be corrupt."); + } + if (Scan->Flags & SCAN_FILETYPE) { + LogMessage("File %s is identified as %s", Scan->FileName, Scan->VirusName); + } + if (Scan->Flags & 0x08000022) { + LogMessage("Threat %s identified.", Scan->VirusName); + } + // This may indicate PUA. + if ((Scan->Flags & 0x40010000) == 0x40010000) { + LogMessage("Threat %s identified.", Scan->VirusName); + } + return 0; +} + +static DWORD WINAPI ReadStream(PVOID this, ULONGLONG Offset, PVOID Buffer, DWORD Size, PDWORD SizeRead) +{ + fseek(this, Offset, SEEK_SET); + *SizeRead = fread(Buffer, 1, Size, this); + return TRUE; +} + +static DWORD WINAPI GetStreamSize(PVOID this, PULONGLONG FileSize) +{ + fseek(this, 0, SEEK_END); + *FileSize = ftell(this); + return TRUE; +} + +static PWCHAR WINAPI GetStreamName(PVOID this) +{ + return L"input"; +} + +// These are available for pintool. +BOOL __noinline InstrumentationCallback(PVOID ImageStart, SIZE_T ImageSize) +{ + // Prevent the call from being optimized away. + asm volatile (""); + return TRUE; +} + +int main(int argc, char **argv, char **envp) +{ + PIMAGE_DOS_HEADER DosHeader; + PIMAGE_NT_HEADERS PeHeader; + HANDLE KernelHandle; + SCAN_REPLY ScanReply; + BOOTENGINE_PARAMS BootParams; + SCANSTREAM_PARAMS ScanParams; + STREAMBUFFER_DESCRIPTOR ScanDescriptor; + ENGINE_INFO EngineInfo; + ENGINE_CONFIG EngineConfig; + + // Load the mpengine module. + if (pe_load_library(image.name, &image.image, &image.size) == false) { + LogMessage("You must add the dll and vdm files to the engine directory"); + return 1; + } + + // Handle relocations, imports, etc. + link_pe_images(&image, 1); + + // Fetch the headers to get base offsets. + DosHeader = (PIMAGE_DOS_HEADER) image.image; + PeHeader = (PIMAGE_NT_HEADERS)(image.image + DosHeader->e_lfanew); + + // Load any additional exports. + if (!process_extra_exports(image.image, PeHeader->OptionalHeader.BaseOfCode, "engine/x64/mpengine.map")) { +#ifndef NDEBUG + LogMessage("The map file wasn't found, symbols wont be available"); +#endif + } else { + // Calculate the commands needed to get export and map symbols visible in gdb. + if (IsGdbPresent()) { + LogMessage("GDB: add-symbol-file %s %#x+%#x", + image.name, + image.image, + PeHeader->OptionalHeader.BaseOfCode); + LogMessage("GDB: shell bash genmapsym.sh %#x+%#x symbols_%d.o < %s", + image.image, + PeHeader->OptionalHeader.BaseOfCode, + getpid(), + "engine/mpengine.map"); + LogMessage("GDB: add-symbol-file symbols_%d.o 0", getpid()); + __debugbreak(); + } + } + + if (get_export("__rsignal", &__rsignal) == -1) { + errx(EXIT_FAILURE, "Failed to resolve mpengine entrypoint"); + } + + VOID ResourceExhaustedHandler(int Signal) + { + errx(EXIT_FAILURE, "Resource Limits Exhausted, Signal %s", strsignal(Signal)); + } + + if (argc < 2) { + LogMessage("usage: %s [filenames...]", *argv); + return 1; + } + + // Call DllMain() + image.entry((PVOID) 'MPENENGN', DLL_PROCESS_ATTACH, NULL); + + // Install usage limits to prevent system crash. + setrlimit(RLIMIT_CORE, &kUsageLimits[RLIMIT_CORE]); + setrlimit(RLIMIT_CPU, &kUsageLimits[RLIMIT_CPU]); + setrlimit(RLIMIT_FSIZE, &kUsageLimits[RLIMIT_FSIZE]); + setrlimit(RLIMIT_NOFILE, &kUsageLimits[RLIMIT_NOFILE]); + + signal(SIGXCPU, ResourceExhaustedHandler); + signal(SIGXFSZ, ResourceExhaustedHandler); + +# ifndef NDEBUG + // Enable Maximum heap checking. + mcheck_pedantic(NULL); +# endif + + ZeroMemory(&BootParams, sizeof BootParams); + ZeroMemory(&EngineInfo, sizeof EngineInfo); + ZeroMemory(&EngineConfig, sizeof EngineConfig); + + BootParams.ClientVersion = BOOTENGINE_PARAMS_VERSION; + BootParams.Attributes = BOOT_ATTR_NORMAL; + BootParams.SignatureLocation = L"engine\\x64"; + BootParams.ProductName = L"Legitimate Antivirus"; + EngineConfig.QuarantineLocation = L"quarantine"; + EngineConfig.Inclusions = L"*.*"; + EngineConfig.EngineFlags = 1 << 1; + BootParams.EngineInfo = &EngineInfo; + BootParams.EngineConfig = &EngineConfig; + KernelHandle = NULL; + + if (__rsignal(&KernelHandle, RSIG_BOOTENGINE, &BootParams, sizeof BootParams) != 0) { + LogMessage("__rsignal(RSIG_BOOTENGINE) returned failure, missing definitions?"); + LogMessage("Make sure the VDM files and mpengine.dll are in the engine directory"); + return 1; + } + + ZeroMemory(&ScanParams, sizeof ScanParams); + ZeroMemory(&ScanDescriptor, sizeof ScanDescriptor); + ZeroMemory(&ScanReply, sizeof ScanReply); + + ScanParams.Descriptor = &ScanDescriptor; + ScanParams.ScanReply = &ScanReply; + ScanReply.EngineScanCallback = EngineScanCallback; + ScanReply.field_C = 0x7fffffff; + ScanDescriptor.Read = ReadStream; + ScanDescriptor.GetSize = GetStreamSize; + ScanDescriptor.GetName = GetStreamName; + + // Enable Instrumentation. + InstrumentationCallback(image.image, image.size); + + for (char *filename = *++argv; *argv; ++argv) { + ScanDescriptor.UserPtr = fopen(*argv, "r"); + + if (ScanDescriptor.UserPtr == NULL) { + LogMessage("failed to open file %s", *argv); + return 1; + } + + LogMessage("Scanning %s...", *argv); + + if (__rsignal(&KernelHandle, RSIG_SCAN_STREAMBUFFER, &ScanParams, sizeof ScanParams) != 0) { + LogMessage("__rsignal(RSIG_SCAN_STREAMBUFFER) returned failure, file unreadable?"); + return 1; + } + + fclose(ScanDescriptor.UserPtr); + } + + return 0; +} diff --git a/peloader/Makefile b/peloader/Makefile index 60fe9e8..c982c24 100644 --- a/peloader/Makefile +++ b/peloader/Makefile @@ -1,6 +1,19 @@ -CFLAGS = -O3 -march=native -ggdb3 -m32 -std=gnu99 -fshort-wchar -Wno-multichar -Iinclude -mstackrealign -CPPFLAGS=-DNDEBUG -D_GNU_SOURCE -I. -LDFLAGS = $(CFLAGS) -m32 -lm +CFLAGS = -march=native -ggdb3 -std=gnu99 -fshort-wchar -fno-omit-frame-pointer -Wno-multichar -I../include -I../log -mstackrealign -maccumulate-outgoing-args +CPPFLAGS = -D_GNU_SOURCE -I. -I../intercept/include +LDFLAGS = $(CFLAGS) -lm +ARCH = x64 +OBJECT_FILES = winstrings.o pe_linker.o crt.o util.o extra.o file_mapping.o + +ifeq ($(ARCH),x86) + CFLAGS += -m32 + LDFLAGS += -m32 +else ifneq ($(ARCH),x64) +$(error Supported target architectures: x86 or x64) +endif + +RELEASE_CFLAGS = -O3 +RELEASE_CPPFLAGS = -DNDEBUG +DEBUG_CFLAGS = -O0 -g .PHONY: clean @@ -9,10 +22,15 @@ WINAPI = $(patsubst %.c,%.o,$(wildcard winapi/*.c)) TARGETS=libpeloader.a +all: CFLAGS += $(RELEASE_CFLAGS) +all: CPPFLAGS += $(RELEASE_CPPFLAGS) all: $(TARGETS) -libpeloader.a: $(WINAPI) winstrings.o pe_linker.o crt.o log.o util.o extra.o +debug: CFLAGS += $(DEBUG_CFLAGS) +debug: $(TARGETS) + +libpeloader.a: $(WINAPI) $(OBJECT_FILES) $(AR) $(ARFLAGS) $@ $^ clean: - rm -f a.out core *.o core.* vgcore.* gmon.out winapi/*.o $(TARGETS) + rm -f a.out core *.o core.* vgcore.* gmon.out winapi/*.o $(TARGETS) \ No newline at end of file diff --git a/peloader/file_mapping.c b/peloader/file_mapping.c new file mode 100644 index 0000000..6e04b8a --- /dev/null +++ b/peloader/file_mapping.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +#include "file_mapping.h" + + +void AddMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list) +{ + MappedFileEntry *current; + + if (list->head == NULL) { + list->head = mapped_file; + return; + } + + current = list->head; + + while(current->next != NULL) { + current = current->next; + } + + current->next = mapped_file; +} + +bool DeleteMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list) +{ + MappedFileEntry *to_delete = NULL; + + if (list == NULL) + return false; + + MappedFileEntry *current = list->head; + + // mapped_file is the first in the list + if (current == mapped_file) { + to_delete = current; + list->head = NULL; + free(to_delete); + return true; + } + + while(current != NULL) { + if (current->next == mapped_file) { + to_delete = current->next; + current->next = to_delete->next; + free(to_delete); + return true; + } + current = current->next; + } + + return false; +} + +MappedFileEntry* SearchMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list) +{ + if (list == NULL) + return NULL; + MappedFileEntry *current = list->head; + while(current != NULL && current != mapped_file) + current = current->next; + return current; +} diff --git a/peloader/file_mapping.h b/peloader/file_mapping.h new file mode 100644 index 0000000..582f74d --- /dev/null +++ b/peloader/file_mapping.h @@ -0,0 +1,22 @@ +#ifndef LOADLIBRARY_FILE_MAPPING_H +#define LOADLIBRARY_FILE_MAPPING_H + +typedef struct mapped_file_entry { + void *next; + intptr_t start; + intptr_t end; + int64_t size; + int fd; +} MappedFileEntry; + +typedef struct mapped_file_object_list { + MappedFileEntry *head; +} MappedFileObjectList; + +extern MappedFileObjectList *FileMappingList; + +void AddMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list); +bool DeleteMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list); +MappedFileEntry* SearchMappedFile(MappedFileEntry *mapped_file, MappedFileObjectList *list); + +#endif //LOADLIBRARY_FILE_MAPPING_H diff --git a/peloader/ntoskernel.h b/peloader/ntoskernel.h index 6e6f14f..551569e 100644 --- a/peloader/ntoskernel.h +++ b/peloader/ntoskernel.h @@ -39,17 +39,6 @@ struct wrap_export { /* map name s to f - if f is different from s */ #define WIN_SYMBOL_MAP(s, f) -struct pe_image { - char name[128]; - BOOL WINAPI (*entry)(PVOID hinstDLL, DWORD fdwReason, PVOID lpvReserved); - void *image; - int size; - int type; - - IMAGE_NT_HEADERS *nt_hdr; - IMAGE_OPTIONAL_HEADER *opt_hdr; -}; - struct ntos_work_item { struct nt_list list; void *arg1; @@ -57,6 +46,17 @@ struct ntos_work_item { NTOS_WORK_FUNC func; }; +struct pe_image { + char name[128]; + BOOL WINAPI (*entry)(PVOID hinstDLL, DWORD fdwReason, PVOID lpvReserved); + void *image; + int size; + int type; + + IMAGE_NT_HEADERS *nt_hdr; + IMAGE_OPTIONAL_HEADER *opt_hdr; +}; + #define WRAP_DRIVER_CLIENT_ID 1 diff --git a/peloader/pe_linker.c b/peloader/pe_linker.c index b209886..b0ba6a3 100644 --- a/peloader/pe_linker.c +++ b/peloader/pe_linker.c @@ -34,12 +34,14 @@ #include #include #include +#include #include "winnt_types.h" #include "pe_linker.h" #include "ntoskernel.h" #include "util.h" #include "log.h" +#include "hook.h" struct pe_exports { char *dll; @@ -179,7 +181,7 @@ static void *get_dll_init(char *name) * Find and validate the coff header * */ -static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) +int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) { int i; WORD attr; @@ -194,21 +196,21 @@ static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) opt_hdr = &nt_hdr->OptionalHeader; - if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" - "bad magic: %04X", opt_hdr->Magic); + if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && + opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + ERROR("bad magic: %04X", opt_hdr->Magic); return -EINVAL; } /* Validate the image for the current architecture. */ - if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { - ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" - " (PE signature is %04X)", nt_hdr->FileHeader.Machine); + if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 && + nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { + ERROR(" (PE signature %04X not supported)", nt_hdr->FileHeader.Machine); return -EINVAL; } /* Must have attributes */ - attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE; + attr = IMAGE_FILE_EXECUTABLE_IMAGE; if ((nt_hdr->FileHeader.Characteristics & attr) != attr) return -EINVAL; @@ -247,7 +249,7 @@ static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) return -EINVAL; } -static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) +int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) { ULONG_PTR *lookup_tbl, *address_tbl; char *symname = NULL; @@ -279,7 +281,6 @@ static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) else { symname = RVA2VA(image, ((lookup_tbl[i] & ~IMAGE_ORDINAL_FLAG) + 2), char *); } - if (get_export(symname, &adr) < 0) { ERROR("unknown symbol: %s:%s", dll, symname); address_tbl[i] = (ULONG) unknown_symbol_stub; @@ -294,7 +295,7 @@ static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) return 0; } -static int read_exports(struct pe_image *pe) +int read_exports(struct pe_image *pe) { IMAGE_EXPORT_DIRECTORY *export_dir_table; int i; @@ -347,7 +348,7 @@ static int read_exports(struct pe_image *pe) return 0; } -static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr) +int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr) { int i; char *name; @@ -664,6 +665,18 @@ bool pe_load_library(const char *filename, void **image, size_t *size) return false; } +// Unmap and unlink a dll +bool pe_unload_library(struct pe_image pe) +{ + // Search PE exports + free(pe_exports); + num_pe_exports = 0; + + munmap(pe.image, pe.size); + + return true; +} + bool setup_nt_threadinfo(PEXCEPTION_HANDLER ExceptionHandler) { static EXCEPTION_FRAME ExceptionFrame; @@ -685,6 +698,9 @@ bool setup_nt_threadinfo(PEXCEPTION_HANDLER ExceptionHandler) .limit_in_pages = 0, .seg_not_present = 0, .useable = 1, +#ifdef __x86_64__ + .lm = 1, +#endif }; if (ExceptionHandler) { @@ -696,12 +712,20 @@ bool setup_nt_threadinfo(PEXCEPTION_HANDLER ExceptionHandler) ThreadEnvironment.Tib.ExceptionList = &ExceptionFrame; } - if (syscall(__NR_set_thread_area, &pebdescriptor) != 0) { +#ifdef __x86_64__ + long set_tib_syscall_result = syscall(__NR_arch_prctl, ARCH_SET_GS, &ThreadEnvironment); +#else + long set_tib_syscall_result = syscall(__NR_set_thread_area, &pebdescriptor); +#endif + if (set_tib_syscall_result != 0) { + int error = errno; + l_error("Failed to set the thread area. Error: %u", error); return false; } - +#ifndef __x86_64__ // Install descriptor asm("mov %[segment], %%fs" :: [segment] "r"(pebdescriptor.entry_number*8+3)); +#endif return true; } diff --git a/peloader/pe_linker.h b/peloader/pe_linker.h index 166d154..63fdd49 100644 --- a/peloader/pe_linker.h +++ b/peloader/pe_linker.h @@ -27,6 +27,7 @@ /* * File formats definitions */ + typedef struct _IMAGE_DOS_HEADER { WORD e_magic; /* 00: MZ Header signature */ WORD e_cblp; /* 02: Bytes on last page of file */ @@ -49,8 +50,6 @@ typedef struct _IMAGE_DOS_HEADER { DWORD e_lfanew; /* 3c: Offset to extended header */ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; -struct pe_image; - #define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ #define IMAGE_OS2_SIGNATURE 0x454E /* NE */ #define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ @@ -365,8 +364,14 @@ typedef struct _IMAGE_OPTIONAL_HEADER64 { IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +#if __x86_64__ +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +#else typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +#endif typedef struct _IMAGE_NT_HEADERS32 { DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ @@ -380,8 +385,13 @@ typedef struct _IMAGE_NT_HEADERS64 { IMAGE_OPTIONAL_HEADER64 OptionalHeader; /* 0x18 */ } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; +#if __x86_64__ +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif #define IMAGE_SIZEOF_SHORT_NAME 8 @@ -1091,14 +1101,21 @@ struct user_desc { unsigned int limit_in_pages : 1; unsigned int seg_not_present : 1; unsigned int useable : 1; +#ifdef __x86_64__ + unsigned int lm : 1; +#endif }; #define LDT_READ 0 #define LDT_WRITE 1 +struct pe_image; + bool pe_load_library(const char *filename, void **image, size_t *size); -void * get_export_address(const char *name); + +void *get_export_address(const char *name); int link_pe_images(struct pe_image *pe_image, unsigned short n); +bool pe_unload_library(struct pe_image pe); int get_export(const char *name, void *func); int get_data_export(char *name, uint32_t base, void *result); bool setup_nt_threadinfo(PEXCEPTION_HANDLER handler); @@ -1107,4 +1124,8 @@ bool process_extra_exports(void *imagebase, size_t base, const char *filename); extern PKUSER_SHARED_DATA SharedUserData; +int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr); +int read_exports(struct pe_image *pe); +int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr); + #endif diff --git a/peloader/util.c b/peloader/util.c index 8db615a..adf91cd 100644 --- a/peloader/util.c +++ b/peloader/util.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "log.h" #include "winnt_types.h" @@ -64,3 +65,97 @@ bool IsGdbPresent() return result; } +#ifdef __x86_64__ +static void swap_fp_register(PM128A MSFpReg, struct _libc_xmmreg *NixFpReg) { + memcpy(&(MSFpReg->Low), &NixFpReg[0], 4); + memcpy(((uint32_t *) &MSFpReg->Low) + 1, &NixFpReg[1], 4); + memcpy(&(MSFpReg->High), &NixFpReg[2], 4); + memcpy(((uint32_t *) &MSFpReg->High) + 1,&NixFpReg[3], 4); +} + +void nix_2_ms_context_swap(ucontext_t *pNixContext, CONTEXT *pMSContext) { + // General purpose registers + pMSContext->Rax = pNixContext->uc_mcontext.gregs[REG_RAX]; + pMSContext->Rcx = pNixContext->uc_mcontext.gregs[REG_RCX]; + pMSContext->Rdx = pNixContext->uc_mcontext.gregs[REG_RDX]; + pMSContext->Rbx = pNixContext->uc_mcontext.gregs[REG_RBX]; + pMSContext->Rsp = pNixContext->uc_mcontext.gregs[REG_RSP]; + pMSContext->Rbp = pNixContext->uc_mcontext.gregs[REG_RBP]; + pMSContext->Rsi = pNixContext->uc_mcontext.gregs[REG_RSI]; + pMSContext->Rdi = pNixContext->uc_mcontext.gregs[REG_RDI]; + pMSContext->Rip = pNixContext->uc_mcontext.gregs[REG_RIP]; + pMSContext->R8 = pNixContext->uc_mcontext.gregs[REG_R8]; + pMSContext->R9 = pNixContext->uc_mcontext.gregs[REG_R9]; + pMSContext->R10 = pNixContext->uc_mcontext.gregs[REG_R10]; + pMSContext->R11 = pNixContext->uc_mcontext.gregs[REG_R11]; + pMSContext->R12 = pNixContext->uc_mcontext.gregs[REG_R12]; + pMSContext->R13 = pNixContext->uc_mcontext.gregs[REG_R13]; + pMSContext->R14 = pNixContext->uc_mcontext.gregs[REG_R14]; + pMSContext->R15 = pNixContext->uc_mcontext.gregs[REG_R15]; + + // XMM0 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm0), + &(pNixContext->uc_mcontext.fpregs->_xmm[0])); + + // XMM1 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm1), + &(pNixContext->uc_mcontext.fpregs->_xmm[1])); + + // XMM2 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm2), + &(pNixContext->uc_mcontext.fpregs->_xmm[2])); + + // XMM3 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm3), + &(pNixContext->uc_mcontext.fpregs->_xmm[3])); + + // XMM4 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm4), + &(pNixContext->uc_mcontext.fpregs->_xmm[4])); + + // XMM5 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm5), + &(pNixContext->uc_mcontext.fpregs->_xmm[5])); + + // XMM6 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm6), + &(pNixContext->uc_mcontext.fpregs->_xmm[6])); + + // XMM7 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm7), + &(pNixContext->uc_mcontext.fpregs->_xmm[7])); + + // XMM8 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm8), + &(pNixContext->uc_mcontext.fpregs->_xmm[8])); + + // XMM9 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm9), + &(pNixContext->uc_mcontext.fpregs->_xmm[9])); + + // XMM10 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm10), + &(pNixContext->uc_mcontext.fpregs->_xmm[10])); + + // XMM11 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm11), + &(pNixContext->uc_mcontext.fpregs->_xmm[11])); + + // XMM12 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm12), + &(pNixContext->uc_mcontext.fpregs->_xmm[12])); + + // XMM13 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm13), + &(pNixContext->uc_mcontext.fpregs->_xmm[13])); + + // XMM14 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm14), + &(pNixContext->uc_mcontext.fpregs->_xmm[14])); + + // XMM15 + swap_fp_register(&(pMSContext->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm15), + &(pNixContext->uc_mcontext.fpregs->_xmm[15])); + +} +#endif diff --git a/peloader/util.h b/peloader/util.h index 4d579ba..be81dff 100644 --- a/peloader/util.h +++ b/peloader/util.h @@ -2,6 +2,8 @@ #define __UTIL_H #pragma once +#include + bool IsGdbPresent(); #ifdef __linux__ @@ -22,11 +24,22 @@ bool IsGdbPresent(); #define MIN(x, y) ((x) > (y) ? (y) : (x)) + static inline void *ZeroMemory(void *s, size_t n) { return memset(s, 0, n); } +union long_int64 { + int64_t value; + struct { + int32_t low; + int32_t high; + }; +}; + +void nix_2_ms_context_swap(ucontext_t *pNixContext, CONTEXT *pMSContext); + #else # warning util.h included twice #endif diff --git a/peloader/winapi/CriticalSection.c b/peloader/winapi/CriticalSection.c index d9a025c..d4a4c2d 100644 --- a/peloader/winapi/CriticalSection.c +++ b/peloader/winapi/CriticalSection.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "winnt_types.h" #include "pe_linker.h" @@ -13,39 +14,44 @@ // I don't implement threads, so critical sections are easy. -STATIC VOID WINAPI DeleteCriticalSection(PVOID lpCriticalSection) -{ +STATIC VOID WINAPI DeleteCriticalSection(PVOID lpCriticalSection) { + DebugLog(""); return; } -STATIC VOID WINAPI EnterCriticalSection(PVOID lpCriticalSection) -{ +STATIC VOID WINAPI EnterCriticalSection(PVOID lpCriticalSection) { + DebugLog(""); return; } -STATIC VOID WINAPI LeaveCriticalSection(PVOID lpCriticalSection) -{ +STATIC VOID WINAPI LeaveCriticalSection(PVOID lpCriticalSection) { + DebugLog(""); return; } -STATIC BOOL WINAPI InitializeCriticalSectionAndSpinCount(PVOID lpCriticalSection, DWORD dwSpinCount) -{ +STATIC BOOL WINAPI InitializeCriticalSectionAndSpinCount(PVOID lpCriticalSection, DWORD dwSpinCount) { + DebugLog(""); return TRUE; } -STATIC BOOL WINAPI InitializeCriticalSectionEx(PVOID lpCriticalSection, DWORD dwSpinCount, DWORD Flags) -{ +STATIC BOOL WINAPI InitializeCriticalSectionEx(PVOID lpCriticalSection, DWORD dwSpinCount, DWORD Flags) { + DebugLog(""); return TRUE; } -STATIC VOID WINAPI InitializeCriticalSection(PVOID lpCriticalSection) -{ +STATIC VOID WINAPI InitializeCriticalSection(PVOID lpCriticalSection) { + DebugLog(""); return; } DECLARE_CRT_EXPORT("DeleteCriticalSection", DeleteCriticalSection); + DECLARE_CRT_EXPORT("LeaveCriticalSection", LeaveCriticalSection); + DECLARE_CRT_EXPORT("EnterCriticalSection", EnterCriticalSection); + DECLARE_CRT_EXPORT("InitializeCriticalSectionAndSpinCount", InitializeCriticalSectionAndSpinCount); + DECLARE_CRT_EXPORT("InitializeCriticalSectionEx", InitializeCriticalSectionEx); + DECLARE_CRT_EXPORT("InitializeCriticalSection", InitializeCriticalSection); diff --git a/peloader/winapi/Crypt.c b/peloader/winapi/Crypt.c index 7ed60ef..4da09d2 100644 --- a/peloader/winapi/Crypt.c +++ b/peloader/winapi/Crypt.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "winnt_types.h" #include "pe_linker.h" @@ -19,88 +20,86 @@ #include "winstrings.h" typedef struct _CRYPT_BIT_BLOB { - DWORD cbData; - BYTE *pbData; - DWORD cUnusedBits; + DWORD cbData; + BYTE *pbData; + DWORD cUnusedBits; } CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB; typedef struct _CRYPTOAPI_BLOB { - DWORD cbData; - BYTE *pbData; + DWORD cbData; + BYTE *pbData; } CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB, - CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB, - CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB, - CERT_NAME_BLOB, CERT_RDN_VALUE_BLOB, - *PCERT_NAME_BLOB, *PCERT_RDN_VALUE_BLOB, - CERT_BLOB, *PCERT_BLOB, - CRL_BLOB, *PCRL_BLOB, - DATA_BLOB, *PDATA_BLOB, - CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB, - CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB, - CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB, - CRYPT_DER_BLOB, PCRYPT_DER_BLOB, - CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB; + CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB, + CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB, + CERT_NAME_BLOB, CERT_RDN_VALUE_BLOB, + *PCERT_NAME_BLOB, *PCERT_RDN_VALUE_BLOB, + CERT_BLOB, *PCERT_BLOB, + CRL_BLOB, *PCRL_BLOB, + DATA_BLOB, *PDATA_BLOB, + CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB, + CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB, + CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB, + CRYPT_DER_BLOB, PCRYPT_DER_BLOB, + CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB; typedef struct _CRYPT_ALGORITHM_IDENTIFIER { - PVOID pszObjId; - CRYPT_OBJID_BLOB Parameters; + PVOID pszObjId; + CRYPT_OBJID_BLOB Parameters; } CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER; typedef struct _CERT_PUBLIC_KEY_INFO { - CRYPT_ALGORITHM_IDENTIFIER Algorithm; - CRYPT_BIT_BLOB PublicKey; + CRYPT_ALGORITHM_IDENTIFIER Algorithm; + CRYPT_BIT_BLOB PublicKey; } CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO; typedef struct _CERT_EXTENSION { - PVOID pszObjId; - BOOL fCritical; - CRYPT_OBJID_BLOB Value; + PVOID pszObjId; + BOOL fCritical; + CRYPT_OBJID_BLOB Value; } CERT_EXTENSION, *PCERT_EXTENSION; typedef struct _CERT_INFO { - DWORD dwVersion; - CRYPT_INTEGER_BLOB SerialNumber; - CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; - CERT_NAME_BLOB Issuer; - FILETIME NotBefore; - FILETIME NotAfter; - CERT_NAME_BLOB Subject; - CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; - CRYPT_BIT_BLOB IssuerUniqueId; - CRYPT_BIT_BLOB SubjectUniqueId; - DWORD cExtension; - PCERT_EXTENSION rgExtension; + DWORD dwVersion; + CRYPT_INTEGER_BLOB SerialNumber; + CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; + CERT_NAME_BLOB Issuer; + FILETIME NotBefore; + FILETIME NotAfter; + CERT_NAME_BLOB Subject; + CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo; + CRYPT_BIT_BLOB IssuerUniqueId; + CRYPT_BIT_BLOB SubjectUniqueId; + DWORD cExtension; + PCERT_EXTENSION rgExtension; } CERT_INFO, *PCERT_INFO; typedef struct _CERT_CONTEXT { - DWORD dwCertEncodingType; - BYTE *pbCertEncoded; - DWORD cbCertEncoded; - PCERT_INFO pCertInfo; - HANDLE hCertStore; + DWORD dwCertEncodingType; + BYTE *pbCertEncoded; + DWORD cbCertEncoded; + PCERT_INFO pCertInfo; + HANDLE hCertStore; } CERT_CONTEXT, *PCERT_CONTEXT; -static NTSTATUS WINAPI BCryptOpenAlgorithmProvider(PVOID phAlgorithm, PWCHAR pszAlgId, PWCHAR pszImplementation, DWORD dwFlags) -{ +static NTSTATUS WINAPI +BCryptOpenAlgorithmProvider(PVOID phAlgorithm, PWCHAR pszAlgId, PWCHAR pszImplementation, DWORD dwFlags) { + DebugLog(""); return STATUS_SUCCESS; } -static NTSTATUS WINAPI BCryptCloseAlgorithmProvider(HANDLE hAlgorithm, ULONG dwFlags) -{ +static NTSTATUS WINAPI BCryptCloseAlgorithmProvider(HANDLE hAlgorithm, ULONG dwFlags) { + DebugLog(""); return STATUS_SUCCESS; } -static NTSTATUS WINAPI BCryptGenRandom(PVOID phAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags) -{ +static NTSTATUS WINAPI BCryptGenRandom(PVOID phAlgorithm, PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags) { static int randomfd = -1; - void __constructor init() - { + void __constructor init() { randomfd = open("/dev/urandom", O_RDONLY); } - void __destructor fini() - { + void __destructor fini() { close(randomfd); } @@ -119,19 +118,18 @@ static BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, - PVOID ppszError) -{ + PVOID ppszError) { uint16_t CertName[] = L"Totally Legitimate Certificate Name"; char *name = CreateAnsiFromWide(pszX500); DebugLog("%u, %p [%s], %u, %p, %p, %p, %p", dwCertEncodingType, - pszX500, - name, - dwStrType, - pvReserved, - pbEncoded, - pcbEncoded, - ppszError); + pszX500, + name, + dwStrType, + pvReserved, + pbEncoded, + pcbEncoded, + ppszError); free(name); *pcbEncoded = sizeof(CertName); @@ -147,8 +145,8 @@ static HANDLE WINAPI CertOpenStore(PCHAR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, PVOID hCryptProv, DWORD dwFlags, - PVOID pvPara) -{ + PVOID pvPara) { + DebugLog(""); return (HANDLE) 'STOR'; } @@ -157,7 +155,6 @@ enum { }; - #include "rootcert.h" static PVOID WINAPI CertFindCertificateInStore(HANDLE hCertStore, @@ -165,19 +162,18 @@ static PVOID WINAPI CertFindCertificateInStore(HANDLE hCertStore, DWORD dwFindFlags, DWORD dwFindType, PVOID pvFindPara, - PVOID pPrevCertContext) -{ + PVOID pPrevCertContext) { static CERT_INFO FakeInfo = {0}; static CERT_CONTEXT FakeCert = {0}; DebugLog("%p, %u, %#x, %#x, %p, %p", hCertStore, - dwCertEncodingType, - dwFindFlags, - dwFindType, - pvFindPara, - pPrevCertContext); + dwCertEncodingType, + dwFindFlags, + dwFindType, + pvFindPara, + pPrevCertContext); - switch (dwFindType) { + switch (dwFindType) { case CERT_FIND_SUBJECT_NAME: { DebugLog("\tCERT_FIND_SUBJECT_NAME"); break; @@ -195,18 +191,17 @@ static PVOID WINAPI CertFindCertificateInStore(HANDLE hCertStore, return &FakeCert; } -static BOOL WINAPI CertCloseStore(HANDLE hCertStore, DWORD dwFlags) -{ +static BOOL WINAPI CertCloseStore(HANDLE hCertStore, DWORD dwFlags) { + DebugLog(""); return TRUE; } -static BOOL WINAPI CryptAcquireContextW(PVOID phProv, PWCHAR pszContainer, PWCHAR pszProvider, DWORD dwProvType, DWORD dwFlags) -{ +static BOOL WINAPI +CryptAcquireContextW(PVOID phProv, PWCHAR pszContainer, PWCHAR pszProvider, DWORD dwProvType, DWORD dwFlags) { return TRUE; } -static BOOL WINAPI CertFreeCertificateContext(PVOID pCertContext) -{ +static BOOL WINAPI CertFreeCertificateContext(PVOID pCertContext) { return TRUE; } @@ -215,8 +210,7 @@ enum { CALG_SHA1 = 0x8004, }; -static BOOL WINAPI CryptCreateHash(PVOID hProv, DWORD Algid, HANDLE hKey, DWORD dwFlags, PDWORD phHash) -{ +static BOOL WINAPI CryptCreateHash(PVOID hProv, DWORD Algid, HANDLE hKey, DWORD dwFlags, PDWORD phHash) { DebugLog("%p, %#x, %p, %#x, %p", hProv, Algid, hKey, dwFlags, phHash); switch (Algid) { @@ -233,15 +227,13 @@ static BOOL WINAPI CryptCreateHash(PVOID hProv, DWORD Algid, HANDLE hKey, DWORD return TRUE; } -enum HashParameters -{ +enum HashParameters { HP_ALGID = 0x0001, // Hash algorithm HP_HASHVAL = 0x0002, // Hash value HP_HASHSIZE = 0x0004 // Hash value size }; -static BOOL WINAPI CryptGetHashParam(DWORD hHash, DWORD dwParam, PDWORD pbData, PDWORD pdwDataLen, DWORD dwFlags) -{ +static BOOL WINAPI CryptGetHashParam(DWORD hHash, DWORD dwParam, PDWORD pbData, PDWORD pdwDataLen, DWORD dwFlags) { DebugLog("%#x, %u, %p, %p, %#x", hHash, dwParam, pbData, pdwDataLen, dwFlags); switch (dwParam) { @@ -249,8 +241,12 @@ static BOOL WINAPI CryptGetHashParam(DWORD hHash, DWORD dwParam, PDWORD pbData, *pdwDataLen = sizeof(DWORD); switch (hHash) { - case 'SHA2': *pbData = 32; break; - case 'SHA1': *pbData = 20; break; + case 'SHA2': + *pbData = 32; + break; + case 'SHA1': + *pbData = 20; + break; default: DebugLog("unknown hHash, this might fail."); } @@ -260,18 +256,18 @@ static BOOL WINAPI CryptGetHashParam(DWORD hHash, DWORD dwParam, PDWORD pbData, return TRUE; } -static BOOL WINAPI CryptSetHashParam(PVOID hHash, DWORD dwParam, PVOID pbData, DWORD dwFlags) -{ +static BOOL WINAPI CryptSetHashParam(PVOID hHash, DWORD dwParam, PVOID pbData, DWORD dwFlags) { return TRUE; } -static BOOL WINAPI CryptImportPublicKeyInfo(HANDLE hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HANDLE *phKey) -{ +static BOOL WINAPI +CryptImportPublicKeyInfo(HANDLE hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HANDLE *phKey) { return TRUE; } -static BOOL WINAPI CryptVerifySignatureW(DWORD hHash, PVOID pbSignature, DWORD dwSigLen, HANDLE hPubKey, PVOID sDescription, DWORD dwFlags) -{ +static BOOL WINAPI +CryptVerifySignatureW(DWORD hHash, PVOID pbSignature, DWORD dwSigLen, HANDLE hPubKey, PVOID sDescription, + DWORD dwFlags) { switch (hHash) { case 'SHA2': { if (dwSigLen != 256) { @@ -285,20 +281,20 @@ static BOOL WINAPI CryptVerifySignatureW(DWORD hHash, PVOID pbSignature, DWORD d } break; } - default: DebugLog("unrecognized hHash %#x, something went wrong", hHash); + default: + DebugLog("unrecognized hHash %#x, something went wrong", hHash); } DebugLog("Signature verification is not implemented #YOLO"); return TRUE; } -static BOOL WINAPI CertVerifyCertificateChainPolicy(PVOID pszPolicyOID, PVOID pChainContext, PVOID pPolicyPara, PVOID pPolicyStatus) -{ +static BOOL WINAPI +CertVerifyCertificateChainPolicy(PVOID pszPolicyOID, PVOID pChainContext, PVOID pPolicyPara, PVOID pPolicyStatus) { DebugLog("Certificate policy verification is not implemented #YOLO"); return TRUE; } -static BOOL WINAPI CryptDestroyHash(DWORD hHash) -{ +static BOOL WINAPI CryptDestroyHash(DWORD hHash) { DebugLog("%p", hHash); assert(hHash == 'SHA2' || hHash == 'SHA1'); @@ -307,19 +303,33 @@ static BOOL WINAPI CryptDestroyHash(DWORD hHash) } DECLARE_CRT_EXPORT("CertCloseStore", CertCloseStore); + DECLARE_CRT_EXPORT("CertFindCertificateInStore", CertFindCertificateInStore); + DECLARE_CRT_EXPORT("CertFreeCertificateContext", CertFreeCertificateContext); + DECLARE_CRT_EXPORT("CertOpenStore", CertOpenStore); + DECLARE_CRT_EXPORT("CertStrToNameW", CertStrToNameW); + DECLARE_CRT_EXPORT("CertVerifyCertificateChainPolicy", CertVerifyCertificateChainPolicy); + DECLARE_CRT_EXPORT("CryptImportPublicKeyInfo", CryptImportPublicKeyInfo); + DECLARE_CRT_EXPORT("CryptCreateHash", CryptCreateHash); + DECLARE_CRT_EXPORT("BCryptOpenAlgorithmProvider", BCryptOpenAlgorithmProvider); + DECLARE_CRT_EXPORT("BCryptCloseAlgorithmProvider", BCryptCloseAlgorithmProvider); + DECLARE_CRT_EXPORT("BCryptGenRandom", BCryptGenRandom); + DECLARE_CRT_EXPORT("CryptAcquireContextW", CryptAcquireContextW); + DECLARE_CRT_EXPORT("CryptGetHashParam", CryptGetHashParam); + DECLARE_CRT_EXPORT("CryptSetHashParam", CryptSetHashParam); + DECLARE_CRT_EXPORT("CryptVerifySignatureW", CryptVerifySignatureW); -DECLARE_CRT_EXPORT("CryptDestroyHash", CryptDestroyHash); +DECLARE_CRT_EXPORT("CryptDestroyHash", CryptDestroyHash); diff --git a/peloader/winapi/Debugger.c b/peloader/winapi/Debugger.c index 71760c4..b93cca1 100644 --- a/peloader/winapi/Debugger.c +++ b/peloader/winapi/Debugger.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "winnt_types.h" #include "pe_linker.h" @@ -18,8 +19,7 @@ #include "util.h" #include "winstrings.h" -static BOOL WINAPI IsDebuggerPresent() -{ +static BOOL WINAPI IsDebuggerPresent() { DebugLog(""); return false; } diff --git a/peloader/winapi/EncodePointer.c b/peloader/winapi/EncodePointer.c index 9b598fa..e2459bb 100644 --- a/peloader/winapi/EncodePointer.c +++ b/peloader/winapi/EncodePointer.c @@ -13,21 +13,20 @@ #include "util.h" -STATIC PVOID WINAPI EncodePointer(PVOID Ptr) -{ +STATIC PVOID WINAPI EncodePointer(PVOID Ptr) { DebugLog("%p", Ptr); // Super secret high-security encryption algorithm. - return (PVOID)((DWORD)(Ptr) ^ ~0); + return (PVOID) ((uintptr_t) (Ptr) ^ ~0); } -STATIC PVOID WINAPI DecodePointer(PVOID Ptr) -{ +STATIC PVOID WINAPI DecodePointer(PVOID Ptr) { DebugLog("%p", Ptr); - return (PVOID)((DWORD)(Ptr) ^ ~0); + return (PVOID) ((uintptr_t) (Ptr) ^ ~0); } DECLARE_CRT_EXPORT("EncodePointer", EncodePointer); + DECLARE_CRT_EXPORT("DecodePointer", DecodePointer); diff --git a/peloader/winapi/EncodePointer.h b/peloader/winapi/EncodePointer.h new file mode 100644 index 0000000..15f18bd --- /dev/null +++ b/peloader/winapi/EncodePointer.h @@ -0,0 +1,7 @@ +#ifndef LOADLIBRARY_ENCODEPOINTER_H +#define LOADLIBRARY_ENCODEPOINTER_H + +PVOID WINAPI EncodePointer(PVOID Ptr); +PVOID WINAPI DecodePointer(PVOID Ptr); + +#endif //LOADLIBRARY_ENCODEPOINTER_H diff --git a/peloader/winapi/Environment.c b/peloader/winapi/Environment.c index cccb685..ad41688 100644 --- a/peloader/winapi/Environment.c +++ b/peloader/winapi/Environment.c @@ -19,26 +19,22 @@ extern void WINAPI SetLastError(DWORD dwErrCode); WCHAR EnvironmentStrings[] = - L"ALLUSERSPROFILE=AllUsersProfile\0" - L"ALLUSERSAPPDATA=AllUsersAppdata\0" -; + L"ALLUSERSPROFILE=AllUsersProfile\0" + L"ALLUSERSAPPDATA=AllUsersAppdata\0"; -STATIC PVOID WINAPI GetEnvironmentStringsW(void) -{ +STATIC PVOID WINAPI GetEnvironmentStringsW(void) { DebugLog(""); return EnvironmentStrings; } -STATIC BOOL WINAPI FreeEnvironmentStringsW(PVOID lpszEnvironmentBlock) -{ +STATIC BOOL WINAPI FreeEnvironmentStringsW(PVOID lpszEnvironmentBlock) { DebugLog("%p", lpszEnvironmentBlock); return TRUE; } -STATIC DWORD WINAPI GetEnvironmentVariableW(PWCHAR lpName, PVOID lpBuffer, DWORD nSize) -{ +STATIC DWORD WINAPI GetEnvironmentVariableW(PWCHAR lpName, PVOID lpBuffer, DWORD nSize) { char *AnsiName = CreateAnsiFromWide(lpName); DebugLog("%p [%s], %p, %u", lpName, AnsiName, lpBuffer, nSize); @@ -62,23 +58,22 @@ STATIC DWORD WINAPI GetEnvironmentVariableW(PWCHAR lpName, PVOID lpBuffer, DWORD } // MPENGINE is very fussy about what ExpandEnvironmentStringsW returns. -STATIC DWORD WINAPI ExpandEnvironmentStringsW(PWCHAR lpSrc, PWCHAR lpDst, DWORD nSize) -{ +STATIC DWORD WINAPI ExpandEnvironmentStringsW(PWCHAR lpSrc, PWCHAR lpDst, DWORD nSize) { PCHAR AnsiString = CreateAnsiFromWide(lpSrc); DWORD Result; struct { - PCHAR Src; - PWCHAR Dst; + PCHAR Src; + PWCHAR Dst; } KnownPaths[] = { - { "%ProgramFiles%", L"C:\\Program Files" }, - { "%AllUsersProfile%", L"C:\\ProgramData" }, - { "%PATH%", L"C:\\Path" }, - { "%windir%", L"C:\\Windows" }, - { "%ProgramFiles(x86)%", L"C:\\Program Files" }, - { "%WINDIR%\\system32\\drivers", L"C:\\WINDOWS\\system32\\drivers" }, - { "%windir%\\temp", L"C:\\WINDOWS\\temp" }, - { "%CommonProgramFiles%", L"C:\\CommonProgramFiles" }, - { NULL }, + {"%ProgramFiles%", L"C:\\Program Files"}, + {"%AllUsersProfile%", L"C:\\ProgramData"}, + {"%PATH%", L"C:\\Path"}, + {"%windir%", L"C:\\Windows"}, + {"%ProgramFiles(x86)%", L"C:\\Program Files"}, + {"%WINDIR%\\system32\\drivers", L"C:\\WINDOWS\\system32\\drivers"}, + {"%windir%\\temp", L"C:\\WINDOWS\\temp"}, + {"%CommonProgramFiles%", L"C:\\CommonProgramFiles"}, + {NULL}, }; DebugLog("%p [%s], %p, %u", lpSrc, AnsiString, lpDst, nSize); @@ -104,19 +99,22 @@ STATIC DWORD WINAPI ExpandEnvironmentStringsW(PWCHAR lpSrc, PWCHAR lpDst, DWORD return CountWideChars(lpSrc) + 1; -finish: + finish: free(AnsiString); return Result; } -static DWORD WINAPI GetEnvironmentVariableA(PCHAR lpName, PVOID lpBuffer, DWORD nSize) -{ +static DWORD WINAPI GetEnvironmentVariableA(PCHAR lpName, PVOID lpBuffer, DWORD nSize) { DebugLog("%s, %p, %u", lpName, lpBuffer, nSize); return 0; } DECLARE_CRT_EXPORT("GetEnvironmentStringsW", GetEnvironmentStringsW); + DECLARE_CRT_EXPORT("FreeEnvironmentStringsW", FreeEnvironmentStringsW); + DECLARE_CRT_EXPORT("GetEnvironmentVariableW", GetEnvironmentVariableW); + DECLARE_CRT_EXPORT("ExpandEnvironmentStringsW", ExpandEnvironmentStringsW); + DECLARE_CRT_EXPORT("GetEnvironmentVariableA", GetEnvironmentVariableA); diff --git a/peloader/winapi/Event.c b/peloader/winapi/Event.c index c432527..dc4efca 100644 --- a/peloader/winapi/Event.c +++ b/peloader/winapi/Event.c @@ -17,8 +17,7 @@ extern void WINAPI SetLastError(DWORD dwErrCode); -static HANDLE WINAPI CreateEventW(PVOID lpEventAttributes, BOOL bManualReset, BOOL bInitialState, PWCHAR lpName) -{ +static HANDLE WINAPI CreateEventW(PVOID lpEventAttributes, BOOL bManualReset, BOOL bInitialState, PWCHAR lpName) { char *AnsiName; #ifndef NDEBUG AnsiName = lpName ? CreateAnsiFromWide(lpName) : NULL; @@ -35,18 +34,35 @@ static HANDLE WINAPI CreateEventW(PVOID lpEventAttributes, BOOL bManualReset, BO return (HANDLE) 'EVNT'; } -static BOOL WINAPI SetEvent(HANDLE hEvent) -{ +static BOOL WINAPI SetEvent(HANDLE hEvent) { DebugLog("%p", hEvent); return TRUE; } -static BOOL WINAPI ResetEvent(HANDLE hEvent) -{ +static BOOL WINAPI ResetEvent(HANDLE hEvent) { DebugLog("%p", hEvent); return TRUE; } +STATIC DWORD WINAPI EventSetInformation(HANDLE RegHandle, + EVENT_INFO_CLASS InformationClass, + PVOID EventInformation, + ULONG InformationLength) { + DebugLog(""); + return STATUS_SUCCESS; +} + +STATIC ULONG WINAPI EventUnregister(HANDLE RegHandle) { + DebugLog(""); + return STATUS_SUCCESS; +} + DECLARE_CRT_EXPORT("CreateEventW", CreateEventW); + DECLARE_CRT_EXPORT("SetEvent", SetEvent); + DECLARE_CRT_EXPORT("ResetEvent", ResetEvent); + +DECLARE_CRT_EXPORT("EventSetInformation", EventSetInformation); + +DECLARE_CRT_EXPORT("EventUnregister", EventUnregister); diff --git a/peloader/winapi/EventTracing.c b/peloader/winapi/EventTracing.c index 852c67f..583554d 100644 --- a/peloader/winapi/EventTracing.c +++ b/peloader/winapi/EventTracing.c @@ -13,40 +13,39 @@ #include "util.h" STATIC ULONG WINAPI RegisterTraceGuidsW(PVOID RequestAddress, - PVOID RequestContext, - PVOID ControlGuid, - ULONG GuidCount, - PVOID TraceGuidReg, - PVOID MofImagePath, - PVOID MofResourceName, - PVOID RegistrationHandle) -{ + PVOID RequestContext, + PVOID ControlGuid, + ULONG GuidCount, + PVOID TraceGuidReg, + PVOID MofImagePath, + PVOID MofResourceName, + PVOID RegistrationHandle) { DebugLog("%p, %p, %p, %u, %p, %p, %p, %p", - RequestAddress, - RequestContext, - ControlGuid, - GuidCount, - TraceGuidReg, - MofImagePath, - MofResourceName, - RegistrationHandle); + RequestAddress, + RequestContext, + ControlGuid, + GuidCount, + TraceGuidReg, + MofImagePath, + MofResourceName, + RegistrationHandle); return STATUS_SUCCESS; } -STATIC ULONG WINAPI UnregisterTraceGuids(HANDLE RegistrationHandle) -{ +STATIC ULONG WINAPI UnregisterTraceGuids(HANDLE RegistrationHandle) { DebugLog("%p", RegistrationHandle); return STATUS_SUCCESS; } -static ULONG WINAPI EventActivityIdControl(ULONG ControlCode, LPGUID ActivityId) -{ +static ULONG WINAPI EventActivityIdControl(ULONG ControlCode, LPGUID ActivityId) { DebugLog("%u, %p", ControlCode, ActivityId); return STATUS_SUCCESS; }; DECLARE_CRT_EXPORT("EventActivityIdControl", EventActivityIdControl); + DECLARE_CRT_EXPORT("RegisterTraceGuidsW", RegisterTraceGuidsW); + DECLARE_CRT_EXPORT("UnregisterTraceGuids", UnregisterTraceGuids); diff --git a/peloader/winapi/Exception.c b/peloader/winapi/Exception.c index b21a8a3..fac5ab7 100644 --- a/peloader/winapi/Exception.c +++ b/peloader/winapi/Exception.c @@ -1,5 +1,5 @@ #ifndef __USE_GNU -# define __USE_GNU +#define __USE_GNU #endif #include @@ -10,6 +10,7 @@ #include #include #include +#include #include "winnt_types.h" #include "pe_linker.h" @@ -17,94 +18,1135 @@ #include "log.h" #include "winexports.h" #include "util.h" +#include "mpclient.h" -#ifndef NDEBUG -// You can use `call DumpExceptionChain()` in gdb, like !exchain in windbg if -// you need to debug exception handling. -VOID DumpExceptionChain(VOID) -{ - PEXCEPTION_FRAME ExceptionList; - DWORD Depth; +#ifdef __x86_64__ - // Fetch Exception List - asm("mov %%fs:0, %[list]" : [list] "=r"(ExceptionList)); +extern struct thing *__start_RtlExecuteHandlerForExceptionSection; +extern struct thing *__stop_RtlExecuteHandlerForExceptionSection; +extern struct thing *__start_RtlDispatchExceptionSection; +extern struct thing *__stop_RtlDispatchExceptionSection; +extern struct thing *__start_RaiseExceptionSection; +extern struct thing *__stop_RaiseExceptionSection; - DebugLog("ExceptionList %p, Dumping SEH Chain...", ExceptionList); +EXCEPTION_DISPOSITION WINAPI ExceptionHandler(struct _EXCEPTION_RECORD *ExceptionRecord, + struct _EXCEPTION_FRAME *EstablisherFrame, + struct _CONTEXT *ContextRecord, + struct _EXCEPTION_FRAME **DispatcherContext) { + LogMessage("Toplevel Exception Handler Caught Exception"); + abort(); +} - for (Depth = 0; ExceptionList; ExceptionList = ExceptionList->prev) { - DebugLog("%*s @%p { Prev: %p, Handler: %p }", - Depth++, "", - ExceptionList, - ExceptionList->prev, - ExceptionList->handler); +#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m))) + +/* ALIGNMENT MACROS */ +#define ALIGN_DOWN_BY(size, align) ((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1)) +#define ALIGN_UP_BY(size, align) (ALIGN_DOWN_BY(((ULONG_PTR)(size) + (align) - 1), align)) +#define ALIGN_UP_POINTER_BY(ptr, align) ((PVOID)ALIGN_UP_BY(ptr, align)) + +enum { + RTL_EXECUTE_HANDLER_FOR_EXCEPTION = 0, + RTL_DISPATCH_EXCEPTION, + RAISE_EXCEPTION, + MAIN_FUNCTION +}; + +PCONTEXT MSContextPtrs[3] = {0}; + + +STATIC WINAPI + +DWORD64 __inline GetReg(PCONTEXT Context, BYTE Reg) { + return ((DWORD64 *) (&Context->Rax))[Reg]; +} + + +STATIC WINAPI + +void __inline SetReg(PCONTEXT Context, BYTE Reg, DWORD64 Value) { + ((DWORD64 *) (&Context->Rax))[Reg] = Value; +} + +STATIC WINAPI + +VOID __inline SetRegFromStackValue(PCONTEXT Context, + PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, + BYTE Reg, + PDWORD64 ValuePointer) { + SetReg(Context, Reg, *ValuePointer); + if (ContextPointers != NULL) { + ContextPointers->DUMMYUNIONNAME2.IntegerContext[Reg] = ValuePointer; } } -#endif -static WINAPI PVOID RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, PVOID Arguments) -{ - PEXCEPTION_FRAME ExceptionList; - PEXCEPTION_FRAME Dispatch = NULL; - DWORD Disposition; - DWORD Depth; - CONTEXT Context = {0}; - EXCEPTION_RECORD Record = { - .ExceptionCode = dwExceptionCode, - .ExceptionFlags = dwExceptionFlags, - .ExceptionAddress = &&finished, - .NumberParameters = nNumberOfArguments, - }; +STATIC WINAPI - // Setup Record - memcpy(&Record.ExceptionInformation, Arguments, nNumberOfArguments * sizeof(ULONG)); +__inline VOID SetXmmReg(PCONTEXT Context, + BYTE Reg, + M128A Value) { + ((M128A *) (&Context->DUMMYUNIONNAME.DUMMYSTRUCTNAME.Xmm0))[Reg] = Value; +} - // No need to log C++ Exceptions, this is the common case. - if (dwExceptionCode != 0xE06D7363) { - LogMessage("%#x, %#x, %u, %p", dwExceptionCode, dwExceptionFlags, nNumberOfArguments, Arguments); +STATIC WINAPI + +__inline VOID SetXmmRegFromStackValue(PCONTEXT Context, + PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, + BYTE Reg, + M128A *ValuePointer) { + SetXmmReg(Context, Reg, *ValuePointer); + if (ContextPointers != NULL) { + ContextPointers->DUMMYUNIONNAME.FloatingContext[Reg] = ValuePointer; } +} - // Fetch Exception List - asm("mov %%fs:0, %[list]" : [list] "=r"(ExceptionList)); +STATIC WINAPI - DebugLog("C++ Exception %#x! ExceptionList %p, Dumping SEH Chain...", dwExceptionCode, ExceptionList); +VOID __inline PopReg(PCONTEXT Context, + PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, + BYTE Reg) { + SetRegFromStackValue(Context, ContextPointers, Reg, (PDWORD64) Context->Rsp); + Context->Rsp += sizeof(DWORD64); +} - for (Depth = 0; ExceptionList; ExceptionList = ExceptionList->prev) { - DWORD Result; +STATIC WINAPI - DebugLog("%*s @%p { Prev: %p, Handler: %p }", - Depth++, "", - ExceptionList, - ExceptionList->prev, - ExceptionList->handler); +__inline ULONG UnwindOpSlots(UNWIND_CODE UnwindCode) { + static const UCHAR UnwindOpExtraSlotTable[] = + { + 0, // UWOP_PUSH_NONVOL + 1, // UWOP_ALLOC_LARGE (or 3, special cased in lookup code) + 0, // UWOP_ALLOC_SMALL + 0, // UWOP_SET_FPREG + 1, // UWOP_SAVE_NONVOL + 2, // UWOP_SAVE_NONVOL_FAR + 1, // UWOP_EPILOG // previously UWOP_SAVE_XMM + 2, // UWOP_SPARE_CODE // previously UWOP_SAVE_XMM_FAR + 1, // UWOP_SAVE_XMM128 + 2, // UWOP_SAVE_XMM128_FAR + 0, // UWOP_PUSH_MACHFRAME + 2, // UWOP_SET_FPREG_LARGE + }; - Result = ExceptionList->handler(&Record, ExceptionList, &Context, &Dispatch); + if ((UnwindCode.UnwindOp == UWOP_ALLOC_LARGE) && + (UnwindCode.OpInfo != 0)) { + return 3; + } else { + return UnwindOpExtraSlotTable[UnwindCode.UnwindOp] + 1; + } +} - DebugLog("%*s Handler Result: %u, Dispatch: %p", Depth, "", Result, Dispatch); +STATIC WINAPI - if (Result == ExceptionContinueSearch) { +PVOID RtlPcToFileHeader(PVOID PcValue, PVOID *BaseOfImage) { + PVOID ImageBase; + + DebugLog("%p %p", PcValue, BaseOfImage); + + if ((ULONG_PTR) PcValue >= (ULONG_PTR) image.image && + (ULONG_PTR) PcValue < (ULONG_PTR) image.image + image.size) { + ImageBase = image.image; + } else { + // If we end up here, PcValue is probably somewhere in libpeloader.a + ImageBase = NULL; + } + + *BaseOfImage = ImageBase; + + return ImageBase; +} + +// Shamelessly copy-pasted from ReactOs +// (https://doxygen.reactos.org/d8/d2f/unwind_8c.html#ae54b6e92ac33487731d412097a83cf7a) + +STATIC WINAPI + +PRUNTIME_FUNCTION RtlLookupFunctionTable(DWORD64 ControlPc, + PDWORD64 ImageBase, + PULONG Length) { + DebugLog(""); + ULONG Size; + + PVOID Table = NULL; + size_t NumberOfSections = image.nt_hdr->FileHeader.NumberOfSections; + PIMAGE_SECTION_HEADER Section = IMAGE_FIRST_SECTION(image.nt_hdr); + + /* Find corresponding file header from code address */ + if (!RtlPcToFileHeader((PVOID) ControlPc, (PVOID *) ImageBase)) { + /* Nothing found */ + return NULL; + } + + /* Locate the exception directory */ + for (int i = 0; i < NumberOfSections; Section++) { + if (strncmp(Section->Name, ".pdata", IMAGE_SIZEOF_SHORT_NAME) == 0) { + Table = (PRUNTIME_FUNCTION) ((uintptr_t) image.image + Section->VirtualAddress); + Size = (ULONG) Section->Misc.VirtualSize; + break; + } + } + + if (Table != NULL) + /* Return the number of entries */ + *Length = Size / sizeof(RUNTIME_FUNCTION); + + /* Return the address of the table */ + return Table; +} + +STATIC + +BOOL LookupPeloaderFunction(DWORD64 ControlPc, PRUNTIME_FUNCTION FunctionEntry) { + Dl_info *info; + int dladdr_result; + + /* Check if we are unwinding a libpeloader function */ + if (ControlPc >= (DWORD64) &__start_RtlExecuteHandlerForExceptionSection && + ControlPc <= (DWORD64) &__stop_RtlExecuteHandlerForExceptionSection) { + FunctionEntry->BeginAddress = (uintptr_t) &__start_RtlExecuteHandlerForExceptionSection; + FunctionEntry->EndAddress = (uintptr_t) &__stop_RtlExecuteHandlerForExceptionSection; + FunctionEntry->UnwindData = RTL_EXECUTE_HANDLER_FOR_EXCEPTION; + return TRUE; + } + + if (ControlPc >= (DWORD64) &__start_RtlDispatchExceptionSection && + ControlPc <= (DWORD64) &__stop_RtlDispatchExceptionSection) { + FunctionEntry->BeginAddress = (uintptr_t) &__start_RtlDispatchExceptionSection; + FunctionEntry->EndAddress = (uintptr_t) &__stop_RtlDispatchExceptionSection; + FunctionEntry->UnwindData = RTL_DISPATCH_EXCEPTION; + return TRUE; + } + + if (ControlPc >= (DWORD64) &__start_RaiseExceptionSection && + ControlPc <= (DWORD64) &__stop_RaiseExceptionSection) { + FunctionEntry->BeginAddress = (uintptr_t) &__start_RaiseExceptionSection; + FunctionEntry->EndAddress = (uintptr_t) &__stop_RaiseExceptionSection; + FunctionEntry->UnwindData = RAISE_EXCEPTION; + return TRUE; + } + + /* + * If we passed the previous ifs and dladdr returns a not-null value, it means we unwound till main + * and we can safely abort (uncaught exception) + */ + info = (Dl_info *) calloc(1, sizeof(Dl_info)); + dladdr_result = dladdr((void *) ControlPc, info); + if (dladdr_result != 0) { + FunctionEntry->BeginAddress = 0; + FunctionEntry->EndAddress = 0; + FunctionEntry->UnwindData = MAIN_FUNCTION; + free(info); + return TRUE; + } + + free(info); + return FALSE; +} + +// Shamelessly copy-pasted from ReactOs and re-adapted +// (https://doxygen.reactos.org/d8/d2f/unwind_8c.html#a8de4364298b3176587d39e35e644a3c0) + +STATIC WINAPI + +PRUNTIME_FUNCTION RtlLookupFunctionEntry(DWORD64 ControlPc, + PDWORD64 ImageBase, + PUNWIND_HISTORY_TABLE HistoryTable) { + DebugLog("%p, %p", ControlPc, ImageBase); + PRUNTIME_FUNCTION FunctionTable, PDataFunctionEntry; + BOOL PeloaderFunctionEntryFound; + ULONG TableLength; + ULONG IndexLo, IndexHi, IndexMid; + + PRUNTIME_FUNCTION FunctionEntry = (PRUNTIME_FUNCTION) malloc(sizeof(RUNTIME_FUNCTION)); + if (!FunctionEntry) { + return NULL; + } + + PeloaderFunctionEntryFound = LookupPeloaderFunction(ControlPc, FunctionEntry); + + if (PeloaderFunctionEntryFound) { + return FunctionEntry; + } + + /* Find the corresponding table */ + FunctionTable = RtlLookupFunctionTable(ControlPc, ImageBase, &TableLength); + + /* Fail, if no table is found */ + if (!FunctionTable) { + return NULL; + } + + /* Use relative virtual address */ + ControlPc -= *ImageBase; + + /* Do a binary search */ + IndexLo = 0; + IndexHi = TableLength; + while (IndexHi > IndexLo) { + IndexMid = (IndexLo + IndexHi) / 2; + PDataFunctionEntry = &FunctionTable[IndexMid]; + + if (ControlPc < PDataFunctionEntry->BeginAddress) { + /* Continue search in lower half */ + IndexHi = IndexMid; + } else if (ControlPc >= PDataFunctionEntry->EndAddress) { + /* Continue search in upper half */ + IndexLo = IndexMid + 1; + } else { + /* ControlPc is within limits, return entry */ + FunctionEntry->BeginAddress = PDataFunctionEntry->BeginAddress; + FunctionEntry->EndAddress = PDataFunctionEntry->EndAddress; + FunctionEntry->UnwindData = PDataFunctionEntry->UnwindData; + return FunctionEntry; + } + } + + /* Nothing found, return NULL */ + return NULL; +} + +// Shamelessly copy-pasted from ReactOS +// (https://doxygen.reactos.org/d8/d2f/unwind_8c.html#a57ef599c611dcdefb93d5bda32af4819) + +STATIC WINAPI + +ULONG64 GetEstablisherFrame( + PCONTEXT Context, + PUNWIND_INFO UnwindInfo, + ULONG_PTR CodeOffset) { + + DebugLog(""); + + ULONG i; + + /* Check if we have a frame register */ + if (UnwindInfo->FrameRegister == 0) { + /* No frame register means we use Rsp */ + return Context->Rsp; + } + + if ((CodeOffset >= UnwindInfo->SizeOfProlog) || + ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0)) { + return GetReg(Context, UnwindInfo->FrameRegister) - + UnwindInfo->FrameOffset * 16; + } + + /* Loop all unwind ops */ + for (i = 0; + i < UnwindInfo->CountOfCodes; + i += UnwindOpSlots(UnwindInfo->UnwindCode[i])) { + /* Check for SET_FPREG */ + if (UnwindInfo->UnwindCode[i].UnwindOp == UWOP_SET_FPREG) { + return GetReg(Context, UnwindInfo->FrameRegister) - + UnwindInfo->FrameOffset * 16; + } + } + + return Context->Rsp; +} + +// Shamelessly copy-pasted from ReactOS +// (https://doxygen.reactos.org/d8/d2f/unwind_8c.html#ab1254c449095abb6946019d9f3a00fd7) + +STATIC WINAPI + +BOOLEAN RtlpTryToUnwindEpilog( + PCONTEXT Context, + PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, + ULONG64 ImageBase, + PRUNTIME_FUNCTION FunctionEntry) { + CONTEXT LocalContext; + BYTE *InstrPtr; + DWORD Instr; + BYTE Reg, Mod; + ULONG64 EndAddress; + + /* Make a local copy of the context */ + LocalContext = *Context; + + InstrPtr = (BYTE *) LocalContext.Rip; + + /* Check if first instruction of epilog is "add rsp, x" */ + Instr = *(DWORD *) InstrPtr; + if ((Instr & 0x00fffdff) == 0x00c48148) { + if ((Instr & 0x0000ff00) == 0x8300) { + /* This is "add rsp, 0x??" */ + LocalContext.Rsp += Instr >> 24; + InstrPtr += 4; + } else { + /* This is "add rsp, 0x???????? */ + LocalContext.Rsp += *(DWORD *) (InstrPtr + 3); + InstrPtr += 7; + } + } + /* Check if first instruction of epilog is "lea rsp, ..." */ + else if ((Instr & 0x38fffe) == 0x208d48) { + /* Get the register */ + Reg = ((Instr << 8) | (Instr >> 16)) & 0x7; + + LocalContext.Rsp = GetReg(&LocalContext, Reg); + + /* Get adressing mode */ + Mod = (Instr >> 22) & 0x3; + if (Mod == 0) { + /* No displacement */ + InstrPtr += 3; + } else if (Mod == 1) { + /* 1 byte displacement */ + LocalContext.Rsp += Instr >> 24; + InstrPtr += 4; + } else if (Mod == 2) { + /* 4 bytes displacement */ + LocalContext.Rsp += *(DWORD *) (InstrPtr + 3); + InstrPtr += 7; + } + } + + /* Loop the following instructions before the ret */ + EndAddress = FunctionEntry->EndAddress + ImageBase - 1; + while ((DWORD64) InstrPtr < EndAddress) { + Instr = *(DWORD *) InstrPtr; + + /* Check for a simple pop */ + if ((Instr & 0xf8) == 0x58) { + /* Opcode pops a basic register from stack */ + Reg = Instr & 0x7; + PopReg(&LocalContext, ContextPointers, Reg); + InstrPtr++; continue; } - // I've never seen any other handler return code with mpengine. - __debugbreak(); + /* Check for REX + pop */ + if ((Instr & 0xf8fb) == 0x5841) { + /* Opcode is pop r8 .. r15 */ + Reg = ((Instr >> 8) & 0x7) + 8; + PopReg(&LocalContext, ContextPointers, Reg); + InstrPtr += 2; + continue; + } + + /* Opcode not allowed for Epilog */ + return FALSE; } - // Unhandled Exception? - DebugLog("%u Element SEH Chain Complete.", Depth); + // check for popfq + + // also allow end with jmp imm, jmp [target], iretq + + /* Check if we are at the ret instruction */ + if ((DWORD64) InstrPtr != EndAddress) { + /* If we went past the end of the function, something is broken! */ + //ASSERT((DWORD64)InstrPtr <= EndAddress); + return FALSE; + } + + /* Make sure this is really a ret instruction */ + if (*InstrPtr != 0xc3) { + //ASSERT(FALSE); + return FALSE; + } + + /* Unwind is finished, pop new Rip from Stack */ + LocalContext.Rip = *(DWORD64 *) LocalContext.Rsp; + LocalContext.Rsp += sizeof(DWORD64); + + *Context = LocalContext; + return TRUE; +} + +STATIC WINAPI + +VOID UnwindLibPeloaderFunction(PRUNTIME_FUNCTION pFunction, PCONTEXT pContext) { + PCONTEXT LibPeloaderFunctionContext = MSContextPtrs[pFunction->UnwindData]; + pContext->Rsp = LibPeloaderFunctionContext->Rsp; + pContext->Rbp = LibPeloaderFunctionContext->Rbp; + pContext->Rip = LibPeloaderFunctionContext->Rip; +} + +// Shamelessly copy-pasted from ReactOS and re-adapted +// (https://doxygen.reactos.org/d8/d2f/unwind_8c.html#a03c91b6c437066272ebc2c2fff051a4c) + +STATIC WINAPI + +PEXCEPTION_ROUTINE RtlVirtualUnwind( + ULONG HandlerType, + ULONG64 ImageBase, + ULONG64 ControlPc, + PRUNTIME_FUNCTION FunctionEntry, + PCONTEXT Context, + PVOID *HandlerData, + PULONG64 EstablisherFrame, + PKNONVOLATILE_CONTEXT_POINTERS ContextPointers) { + PUNWIND_INFO UnwindInfo; + ULONG_PTR CodeOffset; + ULONG i, Offset; + UNWIND_CODE UnwindCode; + BYTE Reg; + PULONG LanguageHandler; + + DebugLog(""); + + // peloader functions do not have an handler + if (FunctionEntry->UnwindData == RTL_EXECUTE_HANDLER_FOR_EXCEPTION || + FunctionEntry->UnwindData == RTL_DISPATCH_EXCEPTION || + FunctionEntry->UnwindData == RAISE_EXCEPTION) { + UnwindLibPeloaderFunction(FunctionEntry, Context); + return NULL; + } + + // If we reached main, abort. + if (FunctionEntry->UnwindData == MAIN_FUNCTION) { + return (PEXCEPTION_ROUTINE) ExceptionHandler; + } + + /* Use relative virtual address */ + ControlPc -= ImageBase; + + /* Sanity checks */ + if ((ControlPc < FunctionEntry->BeginAddress) || + (ControlPc >= FunctionEntry->EndAddress)) { + return NULL; + } -finished: + /* Get a pointer to the unwind info */ + UnwindInfo = RVA(ImageBase, FunctionEntry->UnwindData); + + /* Check for chained info */ + if (UnwindInfo->Flags & UNW_FLAG_CHAININFO) { + //UNIMPLEMENTED_DBGBREAK(); + + /* See https://docs.microsoft.com/en-us/cpp/build/chained-unwind-info-structures */ + FunctionEntry = (PRUNTIME_FUNCTION) &(UnwindInfo->UnwindCode[(UnwindInfo->CountOfCodes + 1) & ~1]); + UnwindInfo = RVA(ImageBase, FunctionEntry->UnwindData); + } + + /* The language specific handler data follows the unwind info */ + LanguageHandler = ALIGN_UP_POINTER_BY(&UnwindInfo->UnwindCode[UnwindInfo->CountOfCodes], sizeof(ULONG)); + *HandlerData = (LanguageHandler + 1); + + /* Calculate relative offset to function start */ + CodeOffset = ControlPc - FunctionEntry->BeginAddress; + + *EstablisherFrame = GetEstablisherFrame(Context, UnwindInfo, CodeOffset); + + // Check if we are in the function epilog and try to finish it + if (CodeOffset > UnwindInfo->SizeOfProlog) { + if (RtlpTryToUnwindEpilog(Context, ContextPointers, ImageBase, FunctionEntry)) { + // There's no exception routine + return NULL; + } + } + + /* Skip all Ops with an offset greater than the current Offset */ + i = 0; + while ((i < UnwindInfo->CountOfCodes) && + (UnwindInfo->UnwindCode[i].CodeOffset > CodeOffset)) { + i += UnwindOpSlots(UnwindInfo->UnwindCode[i]); + } + + /* Process the remaining unwind ops */ + while (i < UnwindInfo->CountOfCodes) { + UnwindCode = UnwindInfo->UnwindCode[i]; + switch (UnwindCode.UnwindOp) { + case UWOP_PUSH_NONVOL: + Reg = UnwindCode.OpInfo; + PopReg(Context, ContextPointers, Reg); + i++; + break; + + case UWOP_ALLOC_LARGE: + if (UnwindCode.OpInfo) { + Offset = *(ULONG *) (&UnwindInfo->UnwindCode[i + 1]); + Context->Rsp += Offset; + i += 3; + } else { + Offset = UnwindInfo->UnwindCode[i + 1].FrameOffset; + Context->Rsp += Offset * 8; + i += 2; + } + break; + + case UWOP_ALLOC_SMALL: + Context->Rsp += (UnwindCode.OpInfo + 1) * 8; + i++; + break; + + case UWOP_SET_FPREG: + Reg = UnwindInfo->FrameRegister; + Context->Rsp = GetReg(Context, Reg) - UnwindInfo->FrameOffset * 16; + i++; + break; + + case UWOP_SAVE_NONVOL: + Reg = UnwindCode.OpInfo; + Offset = *(USHORT *) (&UnwindInfo->UnwindCode[i + 1]); + SetRegFromStackValue(Context, ContextPointers, Reg, (DWORD64 *) Context->Rsp + Offset); + i += 2; + break; + + case UWOP_SAVE_NONVOL_FAR: + Reg = UnwindCode.OpInfo; + Offset = *(ULONG *) (&UnwindInfo->UnwindCode[i + 1]); + SetRegFromStackValue(Context, ContextPointers, Reg, (DWORD64 *) Context->Rsp + Offset); + i += 3; + break; + + case UWOP_EPILOG: + i += 1; + break; + + case UWOP_SPARE_CODE: + // ASSERT(FALSE); + i += 2; + break; + + case UWOP_SAVE_XMM128: + Reg = UnwindCode.OpInfo; + Offset = *(USHORT *) (&UnwindInfo->UnwindCode[i + 1]); + SetXmmRegFromStackValue(Context, ContextPointers, Reg, (M128A *) (Context->Rsp + Offset)); + i += 2; + break; + + case UWOP_SAVE_XMM128_FAR: + Reg = UnwindCode.OpInfo; + Offset = *(ULONG *) (&UnwindInfo->UnwindCode[i + 1]); + SetXmmRegFromStackValue(Context, ContextPointers, Reg, (M128A *) (Context->Rsp + Offset)); + i += 3; + break; + + case UWOP_PUSH_MACHFRAME: + /* OpInfo is 1, when an error code was pushed, otherwise 0. */ + Context->Rsp += UnwindCode.OpInfo * sizeof(DWORD64); + + /* Now pop the MACHINE_FRAME (Yes, "magic numbers", deal with it) */ + Context->Rip = *(PDWORD64) (Context->Rsp + 0x00); + Context->SegCs = *(PDWORD64) (Context->Rsp + 0x08); + Context->EFlags = *(PDWORD64) (Context->Rsp + 0x10); + Context->SegSs = *(PDWORD64) (Context->Rsp + 0x20); + Context->Rsp = *(PDWORD64) (Context->Rsp + 0x18); + // ASSERT((i + 1) == UnwindInfo->CountOfCodes); + goto Exit; + } + } + + /* Unwind is finished, pop new Rip from Stack */ + if (Context->Rsp != 0) { + Context->Rip = *(DWORD64 *) Context->Rsp; + Context->Rsp += sizeof(DWORD64); + } + + Exit: + + /* Check if we have a handler and return it */ + if (UnwindInfo->Flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) { + return RVA(ImageBase, *LanguageHandler); + } + + return NULL; +} + +STATIC WINAPI + +EXCEPTION_DISPOSITION __attribute__ ((noinline, section ("RtlExecuteHandlerForExceptionSection"))) +RtlExecuteHandlerForException(PEXCEPTION_RECORD pFunction, + PVOID EstablisherFrame, + PCONTEXT lpContext, + PDISPATCHER_CONTEXT lpDispatcherContext) { + DebugLog(""); + EXCEPTION_DISPOSITION ExceptionDisposition; + // Store the return address in the CONTEXT structure (useful during the unwinding) + PCONTEXT pContext = MSContextPtrs[RTL_EXECUTE_HANDLER_FOR_EXCEPTION]; + pContext->Rip = (DWORD64) __builtin_return_address(0); + + PDISPATCHER_CONTEXT DispatcherContext = lpDispatcherContext; + + ExceptionDisposition = DispatcherContext->LanguageHandler(pFunction, EstablisherFrame, lpContext, lpDispatcherContext); + free(DispatcherContext->FunctionEntry); + + return ExceptionDisposition; +} + +STATIC WINAPI + +VOID RtlRestoreContext(PCONTEXT pContext, PEXCEPTION_RECORD pExceptionRecord) { + PVOID WINAPI (*CxxCallCatchBlock)(PEXCEPTION_RECORD ExceptionRecord); + PVOID RestoreExecutionPoint; + if (pExceptionRecord != NULL) { + if (pExceptionRecord->ExceptionCode == STATUS_UNWIND_CONSOLIDATE) { + if (pExceptionRecord->NumberParameters > 1) { + CxxCallCatchBlock = pExceptionRecord->ExceptionInformation[0]; + RestoreExecutionPoint = CxxCallCatchBlock(pExceptionRecord); + pContext->Rip = (DWORD64) RestoreExecutionPoint; + } + } else { + // TODO: implement this + __debugbreak(); + } + } + + // Consolidate frames and restore execution + asm("mov %[context], %%rbp\n" + "mov 248(%%rbp), %%rax\n" // Context[RIP] -> RAX + "mov 152(%%rbp), %%rsp\n" // Change stack pointer + "push %%rax\n" // push new return value + "fxrstor 256(%%rbp)\n" + "movaps 416(%%rbp), %%xmm0\n" + "movaps 432(%%rbp), %%xmm1\n" + "movaps 448(%%rbp), %%xmm2\n" + "movaps 464(%%rbp), %%xmm3\n" + "movaps 480(%%rbp), %%xmm4\n" + "movaps 496(%%rbp), %%xmm5\n" + "movaps 512(%%rbp), %%xmm6\n" + "movaps 528(%%rbp), %%xmm7\n" + "movaps 544(%%rbp), %%xmm8\n" + "movaps 560(%%rbp), %%xmm9\n" + "movaps 576(%%rbp), %%xmm10\n" + "movaps 592(%%rbp), %%xmm11\n" + "movaps 608(%%rbp), %%xmm12\n" + "movaps 624(%%rbp), %%xmm13\n" + "movaps 640(%%rbp), %%xmm14\n" + "movaps 656(%%rbp), %%xmm15\n" + "ldmxcsr 52(%%rbp)\n" + "mov 120(%%rbp), %%rax\n" + "mov 128(%%rbp), %%rcx\n" + "mov 136(%%rbp), %%rdx\n" + "mov 144(%%rbp), %%rbx\n" + "mov 168(%%rbp), %%rsi\n" + "mov 176(%%rbp), %%rdi\n" + "mov 184(%%rbp), %%r8\n" + "mov 192(%%rbp), %%r9\n" + "mov 200(%%rbp), %%r10\n" + "mov 208(%%rbp), %%r11\n" + "mov 216(%%rbp), %%r12\n" + "mov 224(%%rbp), %%r13\n" + "mov 232(%%rbp), %%r14\n" + "mov 240(%%rbp), %%r15\n" + "mov 160(%%rbp), %%rbp\n" + "ret":: [context] "r"((uintptr_t) pContext)); +} + +STATIC WINAPI + +BOOL RtlUnwindInternal( + PVOID TargetFrame, + PVOID TargetIp, + PEXCEPTION_RECORD ExceptionRecord, + PVOID ReturnValue, + PCONTEXT ContextRecord, + struct _UNWIND_HISTORY_TABLE *HistoryTable, + ULONG HandlerType) { + DISPATCHER_CONTEXT DispatcherContext; + PEXCEPTION_ROUTINE ExceptionRoutine; + EXCEPTION_DISPOSITION Disposition; + PRUNTIME_FUNCTION FunctionEntry; + ULONG_PTR StackLow, StackHigh; + ULONG64 ImageBase, EstablisherFrame; + CONTEXT UnwindContext; + + /* Copy the context */ + UnwindContext = *ContextRecord; + + /* Set up the constant fields of the dispatcher context */ + DispatcherContext.ContextRecord = ContextRecord; + DispatcherContext.HistoryTable = HistoryTable; + DispatcherContext.TargetIp = (ULONG64) TargetIp; + + /* Start looping */ + while (TRUE) { + /* Lookup the FunctionEntry for the current RIP */ + FunctionEntry = RtlLookupFunctionEntry(UnwindContext.Rip, &ImageBase, NULL); + if (FunctionEntry == NULL) { + /* No function entry, so this must be a leaf function. Pop the return address from the stack. + Note: this can happen after the first frame as the result of an exception */ + UnwindContext.Rip = *(DWORD64 *) UnwindContext.Rsp; + UnwindContext.Rsp += sizeof(DWORD64); + continue; + } + + /* Do a virtual unwind to get the next frame */ + ExceptionRoutine = RtlVirtualUnwind(HandlerType, + ImageBase, + UnwindContext.Rip, + FunctionEntry, + &UnwindContext, + &DispatcherContext.HandlerData, + &EstablisherFrame, + NULL); + + /* Check if we have an exception routine */ + if (ExceptionRoutine != NULL) { + /* Check if this is the target frame */ + if (EstablisherFrame == (ULONG64) TargetFrame) { + /* Set flag to inform the language handler */ + ExceptionRecord->ExceptionFlags |= EXCEPTION_TARGET_UNWIND; + } + + /* Set up the variable fields of the dispatcher context */ + DispatcherContext.ControlPc = ContextRecord->Rip; + DispatcherContext.ImageBase = ImageBase; + DispatcherContext.FunctionEntry = FunctionEntry; + DispatcherContext.LanguageHandler = ExceptionRoutine; + DispatcherContext.EstablisherFrame = EstablisherFrame; + DispatcherContext.ScopeIndex = 0; + + /* Store the return value in the unwind context */ + UnwindContext.Rax = (ULONG64) ReturnValue; + + /* Loop all nested handlers */ + do { + /* Call the language specific handler */ + Disposition = ExceptionRoutine(ExceptionRecord, + (PVOID) EstablisherFrame, + &UnwindContext, + &DispatcherContext); + + /* Clear exception flags for the next iteration */ + ExceptionRecord->ExceptionFlags &= ~(EXCEPTION_TARGET_UNWIND | + EXCEPTION_COLLIDED_UNWIND); + + /* Check if we do exception handling */ + if (HandlerType == UNW_FLAG_EHANDLER) { + if (Disposition == ExceptionContinueExecution) { + /* Check if it was non-continuable */ + if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) { + __debugbreak(); + // RtlRaiseStatus(EXCEPTION_NONCONTINUABLE_EXCEPTION); + } + + /* Execution continues */ + return TRUE; + } else if (Disposition == ExceptionNestedException) { + __debugbreak(); + } + } + + if (Disposition == ExceptionCollidedUnwind) { + __debugbreak(); + } + + /* This must be ExceptionContinueSearch now */ + if (Disposition != ExceptionContinueSearch) { + __debugbreak(); + // RtlRaiseStatus(STATUS_INVALID_DISPOSITION); + } + } while (ExceptionRecord->ExceptionFlags & EXCEPTION_COLLIDED_UNWIND); + } + + if (EstablisherFrame == (ULONG64) TargetFrame) { + break; + } + + /* We have successfully unwound a frame. Copy the unwind context back. */ + *ContextRecord = UnwindContext; + } + + if (ExceptionRecord->ExceptionCode != STATUS_UNWIND_CONSOLIDATE) { + ContextRecord->Rip = (ULONG64) TargetIp; + } + + /* Set the return value */ + ContextRecord->Rax = (ULONG64) ReturnValue; + + /* Restore the context */ + RtlRestoreContext(ContextRecord, ExceptionRecord); + __debugbreak(); + + /* Should never get here! */ + return FALSE; +} + +STATIC WINAPI + +BOOL RtlUnwindEx( + PVOID TargetFrame, + PVOID TargetIp, + PEXCEPTION_RECORD ExceptionRecord, + PVOID ReturnValue, + PCONTEXT ContextRecord, + struct _UNWIND_HISTORY_TABLE *HistoryTable) { + EXCEPTION_RECORD LocalExceptionRecord; + ucontext_t Context; + CONTEXT MSContext = {0}; + + uintptr_t ControlPc; + + // Save current registers + if (getcontext(&Context) != 0) { + abort(); + } + nix_2_ms_context_swap(&Context, &MSContext); + + /* + * Get the return address of the current (RaiseException) function. + * ControlPc will point to the body of some DLL's function, + * which called RaiseException. + */ + ControlPc = (uintptr_t) __builtin_return_address(0); + /* + * Now, we have to manually unwind the context to the previous call (VCRUTIMEVXX!_CxxThrowException), + * since we do not have a RUNTIME_FUNCTION available for the current (RaiseException) + * function, and then we cannot use RtlVirtualUnwind on it. + * After we unwound to the previous frame, we call DispatchContext and we should be + * able to loop back starting from it. + */ + uintptr_t *rbp = ((uintptr_t *) (__builtin_frame_address(0)))[0]; + uintptr_t *rsp = ((uintptr_t) (__builtin_frame_address(0))) + 0x8 + 0x8; // Find rsp + 0x8 + 0x8 (rsi + rdi maybe?) + + MSContext.Rsp = (DWORD64) rsp; + MSContext.Rbp = (DWORD64) rbp; + MSContext.Rip = (DWORD64) ControlPc; + + /* Check if we have an exception record */ + if (ExceptionRecord == NULL) { + /* No exception record was passed, so set up a local one */ + LocalExceptionRecord.ExceptionCode = STATUS_UNWIND; + LocalExceptionRecord.ExceptionAddress = (PVOID) ContextRecord->Rip; + LocalExceptionRecord.ExceptionRecord = NULL; + LocalExceptionRecord.NumberParameters = 0; + ExceptionRecord = &LocalExceptionRecord; + } + + /* Call the internal function */ + RtlUnwindInternal(TargetFrame, + TargetIp, + ExceptionRecord, + ReturnValue, + &MSContext, + HistoryTable, + UNW_FLAG_UHANDLER); +} + +STATIC WINAPI + +BOOL __attribute__ ((noinline, section ("RtlDispatchExceptionSection"))) +RtlDispatchException(PEXCEPTION_RECORD ExceptionRecord, CONTEXT *pContext) { + DWORD64 ImageBase; + PVOID HandlerData; + ULONG64 EstablisherFrame; + DISPATCHER_CONTEXT DispatcherContext; + EXCEPTION_DISPOSITION Disposition; + ucontext_t Context; + PCONTEXT pMSContext; + //CONTEXT UnwindContext = { 0 }; + + //CopyContext(pContext, &UnwindContext); + + DebugLog("%p, %p", ExceptionRecord, pContext); + // Store the return address in the CONTEXT structure (useful during the unwinding) + PCONTEXT pRtlDispatchMSContext = MSContextPtrs[RTL_DISPATCH_EXCEPTION]; + pRtlDispatchMSContext->Rip = (DWORD64) __builtin_return_address(0); + + while (TRUE) { + // Take RIP from the CONTEXT + DWORD64 ControlPc = pContext->Rip; + + // RtlLookupFunctionEntry passing RIP as argument + PRUNTIME_FUNCTION RuntimeFunction = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); + // Check if a RUNTIME_FUNCTION is associated with it + if (!RuntimeFunction) { + pContext->Rip = pContext->Rsp; + pContext->Rsp = pContext->Rsp + 0x8; + continue; + } + + DispatcherContext.FunctionEntry = RuntimeFunction; + + // TODO: Copy the CONTEXT? + + // Unwind to the caller + PEXCEPTION_ROUTINE ExceptionRoutine = RtlVirtualUnwind(UNW_FLAG_EHANDLER, + ImageBase, + ControlPc, + RuntimeFunction, + pContext, + &DispatcherContext.HandlerData, + &EstablisherFrame, + NULL); + + // Check if an EXCEPTION_ROUTINE has been found + if (ExceptionRoutine != NULL) { + + // Initialize the dispatcher context + DispatcherContext.ControlPc = ControlPc; + DispatcherContext.ImageBase = ImageBase; + DispatcherContext.EstablisherFrame = EstablisherFrame; + DispatcherContext.ContextRecord = pContext; + DispatcherContext.LanguageHandler = ExceptionRoutine; + DispatcherContext.ScopeIndex = 0; + + + // Capture the context. We will need it during the unwinding + pMSContext = (PCONTEXT) malloc(sizeof(CONTEXT)); + if (pMSContext == NULL) { + return FALSE; + } + memset(pMSContext, 0, sizeof(CONTEXT)); + if (getcontext(&Context) != 0) { + abort(); + } + nix_2_ms_context_swap(&Context, pMSContext); + MSContextPtrs[RTL_EXECUTE_HANDLER_FOR_EXCEPTION] = pMSContext; + + // Call the LanguageHandler + Disposition = RtlExecuteHandlerForException(ExceptionRecord, + (PVOID) EstablisherFrame, + pContext, + &DispatcherContext); + + /* Clear exception flags for the next iteration */ + ExceptionRecord->ExceptionFlags &= ~(EXCEPTION_TARGET_UNWIND | + EXCEPTION_COLLIDED_UNWIND); + + } + } +} + +STATIC WINAPI + +PVOID __attribute__ ((noinline, section ("RaiseExceptionSection"))) +RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, PVOID Arguments) { + uintptr_t ControlPc; + uintptr_t CallerFrame; + PUNWIND_INFO UnwindInfo; + PRUNTIME_FUNCTION FunctionEntry; + PEXCEPTION_ROUTINE ExceptionRoutine; + KNONVOLATILE_CONTEXT_POINTERS ContextPointers; + PULONG LanguageHandler; + PVOID HandlerData; + ULONG64 EstablisherFrame; + ucontext_t Context; + ucontext_t RtlDispatchExceptionContext; + + DebugLog("%#x, %#x, %#x", dwExceptionCode, dwExceptionFlags, nNumberOfArguments); + + NTSTATUS Status = STATUS_INVALID_DISPOSITION; + CONTEXT MSContext = {0}; + PCONTEXT pRtlDispatchExceptionMSContext; + PCONTEXT pRaiseExceptionMSContext; + DWORD64 ImageBase = 0; + + EXCEPTION_RECORD ExceptionRecord = { + .ExceptionCode = dwExceptionCode, + .ExceptionFlags = dwExceptionFlags, + .ExceptionAddress = RaiseException, + .NumberParameters = nNumberOfArguments, + }; + + // Setup Record + memcpy(&ExceptionRecord.ExceptionInformation, Arguments, nNumberOfArguments * sizeof(long)); + + // Save current registers + if (getcontext(&Context) != 0) { + abort(); + } + nix_2_ms_context_swap(&Context, &MSContext); + /* + * Get the return address of the current (RaiseException) function. + * ControlPc will point to the body of some DLL's function, + * which called RaiseException. + */ + ControlPc = (uintptr_t) __builtin_return_address(0); + /* + * Now, we have to manually unwind the context to the previous call (VCRUTIMEVXX!_CxxThrowException), + * since we do not have a RUNTIME_FUNCTION available for the current (RaiseException) + * function, and then we cannot use RtlVirtualUnwind on it. + * After we unwound to the previous frame, we call DispatchContext and we should be + * able to loop back starting from it. + */ + uintptr_t *rbp = ((uintptr_t *) (__builtin_frame_address(0)))[0]; + uintptr_t *rsp = ((uintptr_t) (__builtin_frame_address(0))) + 0x8 + 0x8; // Find rsp + 0x8 + 0x8 (rsi + rdi maybe?) + + + MSContext.Rsp = (DWORD64) rsp; + MSContext.Rbp = (DWORD64) rbp; + MSContext.Rip = (DWORD64) ControlPc; + pRaiseExceptionMSContext = (PCONTEXT) malloc(sizeof(CONTEXT)); + if (pRaiseExceptionMSContext == NULL) { + return FALSE; + } + memset(pRaiseExceptionMSContext, 0, sizeof(CONTEXT)); + pRaiseExceptionMSContext->Rsp = MSContext.Rsp; + pRaiseExceptionMSContext->Rbp = MSContext.Rbp; + pRaiseExceptionMSContext->Rip = MSContext.Rip; + MSContextPtrs[RAISE_EXCEPTION] = pRaiseExceptionMSContext; + + /* Get the function entry of RaiseException caller */ + FunctionEntry = RtlLookupFunctionEntry((DWORD64) ControlPc, + &ImageBase, + NULL); + + // Check if we found the RuntimeFunction of VCRUTIMEVXX!_CxxThrowException + if (FunctionEntry) { + // Unwind to the caller of VCRUTIMEVXX!_CxxThrowException + RtlVirtualUnwind(UNW_FLAG_EHANDLER, + ImageBase, + ControlPc, + FunctionEntry, + &MSContext, + &HandlerData, + &EstablisherFrame, + &ContextPointers); + + /* + * Usually VCRUTIMEVXX!_CxxThrowException does not have a EXCEPTION_ROUTINE structure associated. + * At this point, we can safely call RtlDispatchException passing as argument the EXCEPTION_RECORD of + * VCRUTIMEVXX!_CxxThrowException and the CONTEXT unwound to the caller of VCRUTIMEVXX!_CxxThrowException, + * which is some function defined in the DLL. + */ + ExceptionRecord.ExceptionAddress = (PVOID) ControlPc; + + // Store the context before calling RtlDispatchException, which will be used during unwinding procedure + pRtlDispatchExceptionMSContext = (PCONTEXT) malloc(sizeof(CONTEXT)); + if (pRtlDispatchExceptionMSContext == NULL) { + return FALSE; + } + memset(pRtlDispatchExceptionMSContext, 0, sizeof(CONTEXT)); + if (getcontext(&RtlDispatchExceptionContext) != 0) { + abort(); + } + nix_2_ms_context_swap(&RtlDispatchExceptionContext, pRtlDispatchExceptionMSContext); + MSContextPtrs[RTL_DISPATCH_EXCEPTION] = pRtlDispatchExceptionMSContext; + // Dispatch the exception + if (!RtlDispatchException(&ExceptionRecord, &MSContext)) { + __debugbreak(); + } else { + // Continue, go back to previous context + // Status = ZwContinue(&Context, FALSE); + } + } + + finished: // I've never seen this reached, I'm not sure if it works. __debugbreak(); return NULL; } +#else +#ifndef NDEBUG + +// You can use `call DumpExceptionChain()` in gdb, like !exchain in windbg if +// you need to debug exception handling. +VOID DumpExceptionChain(VOID) { + PEXCEPTION_FRAME ExceptionList; + DWORD Depth; + + // Fetch Exception List + asm("mov %%fs:0, %[list]" : [list] "=r"(ExceptionList)); + + DebugLog("ExceptionList %p, Dumping SEH Chain...", ExceptionList); + + for (Depth = 0; ExceptionList; ExceptionList = ExceptionList->prev) { + DebugLog("%*s @%p { Prev: %p, Handler: %p }", + Depth++, "", + ExceptionList, + ExceptionList->prev, + ExceptionList->handler); + } +} -#define EH_NONCONTINUABLE 0x01 -#define EH_UNWINDING 0x02 -#define EH_EXIT_UNWIND 0x04 -#define EH_STACK_INVALID 0x08 -#define EH_NESTED_CALL 0x10 +#endif + +STATIC WINAPI -static WINAPI void RtlUnwind(PEXCEPTION_FRAME TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD ExceptionRecord, PVOID ReturnValue) +void RtlUnwind(PEXCEPTION_FRAME TargetFrame, PVOID TargetIp, PEXCEPTION_RECORD ExceptionRecord, PVOID ReturnValue) { PEXCEPTION_FRAME ExceptionList; DWORD Depth; @@ -137,10 +1179,10 @@ static WINAPI void RtlUnwind(PEXCEPTION_FRAME TargetFrame, PVOID TargetIp, PEXCE DWORD Dispatch = 0; DebugLog("%*s @%p { Prev: %p, Handler: %p }", - Depth++, "", - ExceptionList, - ExceptionList->prev, - ExceptionList->handler); + Depth++, "", + ExceptionList, + ExceptionList->prev, + ExceptionList->handler); // You don't call the final handler, you just install the new context. if (ExceptionList == TargetFrame) { @@ -170,6 +1212,71 @@ static WINAPI void RtlUnwind(PEXCEPTION_FRAME TargetFrame, PVOID TargetIp, PEXCE __debugbreak(); } +STATIC WINAPI + +PVOID RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, PVOID Arguments) { + PEXCEPTION_FRAME ExceptionList; + PEXCEPTION_FRAME Dispatch = NULL; + DWORD Disposition; + DWORD Depth; + CONTEXT Context = {0}; + EXCEPTION_RECORD Record = { + .ExceptionCode = dwExceptionCode, + .ExceptionFlags = dwExceptionFlags, + .ExceptionAddress = &&finished, + .NumberParameters = nNumberOfArguments, + }; + + // Setup Record + memcpy(&Record.ExceptionInformation, Arguments, nNumberOfArguments * sizeof(ULONG)); + + // No need to log C++ Exceptions, this is the common case. + if (dwExceptionCode != 0xE06D7363) { + LogMessage("%#x, %#x, %u, %p", dwExceptionCode, dwExceptionFlags, nNumberOfArguments, Arguments); + } + + // Fetch Exception List + asm("mov %%fs:0, %[list]" : [list] "=r"(ExceptionList)); + + DebugLog("C++ Exception %#x! ExceptionList %p, Dumping SEH Chain...", dwExceptionCode, ExceptionList); + + for (Depth = 0; ExceptionList; ExceptionList = ExceptionList->prev) { + DWORD Result; + + DebugLog("%*s @%p { Prev: %p, Handler: %p }", + Depth++, "", + ExceptionList, + ExceptionList->prev, + ExceptionList->handler); + + Result = ExceptionList->handler(&Record, ExceptionList, &Context, &Dispatch); + + DebugLog("%*s Handler Result: %u, Dispatch: %p", Depth, "", Result, Dispatch); + + if (Result == ExceptionContinueSearch) { + continue; + } + + // I've never seen any other handler return code with mpengine. + __debugbreak(); + } + + // Unhandled Exception? + DebugLog("%u Element SEH Chain Complete.", Depth); + + finished: + // I've never seen this reached, I'm not sure if it works. + __debugbreak(); + return NULL; +} + +#endif DECLARE_CRT_EXPORT("RaiseException", RaiseException); + +#ifdef __x86_64__ +DECLARE_CRT_EXPORT("RtlUnwindEx", RtlUnwindEx); +DECLARE_CRT_EXPORT("RtlPcToFileHeader", RtlPcToFileHeader); +#else DECLARE_CRT_EXPORT("RtlUnwind", RtlUnwind); +#endif diff --git a/peloader/winapi/Files.c b/peloader/winapi/Files.c index f469367..657d5c8 100644 --- a/peloader/winapi/Files.c +++ b/peloader/winapi/Files.c @@ -18,13 +18,14 @@ #include "winstrings.h" typedef struct _WIN32_FILE_ATTRIBUTE_DATA { - DWORD dwFileAttributes; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; - DWORD nFileSizeHigh; - DWORD nFileSizeLow; + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + extern void WINAPI SetLastError(DWORD dwErrCode); #define ERROR_FILE_NOT_FOUND 2 @@ -34,25 +35,24 @@ extern void WINAPI SetLastError(DWORD dwErrCode); #define INVALID_FILE_ATTRIBUTES -1; -static DWORD WINAPI GetFileAttributesW(PVOID lpFileName) -{ +static DWORD WINAPI GetFileAttributesW(PVOID lpFileName) { DWORD Result = FILE_ATTRIBUTE_NORMAL; char *filename = CreateAnsiFromWide(lpFileName); DebugLog("%p [%s]", lpFileName, filename); if (strstr(filename, "RebootActions") || strstr(filename, "RtSigs") - ) { + ) { Result = INVALID_FILE_ATTRIBUTES; goto finish; } -finish: + finish: free(filename); return Result; } -static DWORD WINAPI GetFileAttributesExW(PWCHAR lpFileName, DWORD fInfoLevelId, LPWIN32_FILE_ATTRIBUTE_DATA lpFileInformation) -{ +static DWORD WINAPI +GetFileAttributesExW(PWCHAR lpFileName, DWORD fInfoLevelId, LPWIN32_FILE_ATTRIBUTE_DATA lpFileInformation) { char *filename = CreateAnsiFromWide(lpFileName); DebugLog("%p [%s], %u, %p", lpFileName, filename, fInfoLevelId, lpFileInformation); @@ -64,15 +64,15 @@ static DWORD WINAPI GetFileAttributesExW(PWCHAR lpFileName, DWORD fInfoLevelId, } enum { - CREATE_NEW = 1, - CREATE_ALWAYS = 2, - OPEN_EXISTING = 3, - OPEN_ALWAYS = 4, - TRUNCATE_EXISTING = 5 + CREATE_NEW = 1, + CREATE_ALWAYS = 2, + OPEN_EXISTING = 3, + OPEN_ALWAYS = 4, + TRUNCATE_EXISTING = 5 }; -static HANDLE WINAPI CreateFileA(PCHAR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PVOID lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) -{ +static HANDLE WINAPI CreateFileA(PCHAR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PVOID lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { FILE *FileHandle; DebugLog("%p [%s], %#x, %#x, %p, %#x, %#x, %p", lpFileName, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); @@ -92,7 +92,7 @@ static HANDLE WINAPI CreateFileA(PCHAR lpFileName, DWORD dwDesiredAccess, DWORD case CREATE_ALWAYS: FileHandle = fopen("/dev/null", "w"); break; - // This is the disposition used by CreateTempFile(). + // This is the disposition used by CreateTempFile(). case CREATE_NEW: if (strstr(lpFileName, "/faketemp/")) { FileHandle = fopen(lpFileName, "w"); @@ -113,8 +113,9 @@ static HANDLE WINAPI CreateFileA(PCHAR lpFileName, DWORD dwDesiredAccess, DWORD } -static HANDLE WINAPI CreateFileW(PWCHAR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PVOID lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) -{ +static HANDLE WINAPI +CreateFileW(PWCHAR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PVOID lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { FILE *FileHandle; char *filename = CreateAnsiFromWide(lpFileName); @@ -137,12 +138,16 @@ static HANDLE WINAPI CreateFileW(PWCHAR lpFileName, DWORD dwDesiredAccess, DWORD case CREATE_ALWAYS: FileHandle = fopen("/dev/null", "w"); break; - // This is the disposition used by CreateTempFile(). + // This is the disposition used by CreateTempFile(). case CREATE_NEW: if (strstr(filename, "/faketemp/")) { FileHandle = fopen(filename, "w"); // Unlink it immediately so it's cleaned up on exit. unlink(filename); + /* + } else if (strstr(filename, "mpcache-")) { + FileHandle = fopen(filename, "w"); + */ } else { FileHandle = fopen("/dev/null", "w"); } @@ -162,8 +167,8 @@ static HANDLE WINAPI CreateFileW(PWCHAR lpFileName, DWORD dwDesiredAccess, DWORD /** * TODO: handle 64 bit */ -static DWORD WINAPI SetFilePointer(HANDLE hFile, LONG liDistanceToMove, LONG *lpDistanceToMoveHigh, DWORD dwMoveMethod) -{ +static DWORD WINAPI +SetFilePointer(HANDLE hFile, LONG liDistanceToMove, LONG *lpDistanceToMoveHigh, DWORD dwMoveMethod) { int result; DebugLog("%p, %llu, %p, %u", hFile, liDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); @@ -180,8 +185,8 @@ static DWORD WINAPI SetFilePointer(HANDLE hFile, LONG liDistanceToMove, LONG *l } -static BOOL WINAPI SetFilePointerEx(HANDLE hFile, uint64_t liDistanceToMove, uint64_t *lpNewFilePointer, DWORD dwMoveMethod) -{ +static BOOL WINAPI +SetFilePointerEx(HANDLE hFile, uint64_t liDistanceToMove, uint64_t *lpNewFilePointer, DWORD dwMoveMethod) { int result; //DebugLog("%p, %llu, %p, %u", hFile, liDistanceToMove, lpNewFilePointer, dwMoveMethod); @@ -195,33 +200,31 @@ static BOOL WINAPI SetFilePointerEx(HANDLE hFile, uint64_t liDistanceToMove, ui // Windows is permissive here. return TRUE; - //return result != -1; + //return result != -1; } -static BOOL WINAPI CloseHandle(HANDLE hObject) -{ +static BOOL WINAPI CloseHandle(HANDLE hObject) { DebugLog("%p", hObject); if (hObject != (HANDLE) 'EVNT' - && hObject != INVALID_HANDLE_VALUE - && hObject != (HANDLE) 'SEMA') + && hObject != INVALID_HANDLE_VALUE + && hObject != (HANDLE) 'SEMA') fclose(hObject); return TRUE; } -static BOOL WINAPI ReadFile(HANDLE hFile, PVOID lpBuffer, DWORD nNumberOfBytesToRead, PDWORD lpNumberOfBytesRead, PVOID lpOverlapped) -{ +static BOOL WINAPI +ReadFile(HANDLE hFile, PVOID lpBuffer, DWORD nNumberOfBytesToRead, PDWORD lpNumberOfBytesRead, PVOID lpOverlapped) { *lpNumberOfBytesRead = fread(lpBuffer, 1, nNumberOfBytesToRead, hFile); return TRUE; } -static BOOL WINAPI WriteFile(HANDLE hFile, PVOID lpBuffer, DWORD nNumberOfBytesToWrite, PDWORD lpNumberOfBytesWritten, PVOID lpOverlapped) -{ - *lpNumberOfBytesWritten = fwrite(lpBuffer, 1, nNumberOfBytesToWrite, hFile); +static BOOL WINAPI WriteFile(HANDLE hFile, PVOID lpBuffer, DWORD nNumberOfBytesToWrite, PDWORD lpNumberOfBytesWritten, + PVOID lpOverlapped) { + //*lpNumberOfBytesWritten = fwrite(lpBuffer, 1, nNumberOfBytesToWrite, hFile); return TRUE; } -static BOOL WINAPI DeleteFileW(PWCHAR lpFileName) -{ +static BOOL WINAPI DeleteFileW(PWCHAR lpFileName) { char *AnsiFilename = CreateAnsiFromWide(lpFileName); DebugLog("%p [%s]", lpFileName, AnsiFilename); @@ -230,8 +233,7 @@ static BOOL WINAPI DeleteFileW(PWCHAR lpFileName) return TRUE; } -static BOOL WINAPI GetFileSizeEx(HANDLE hFile, uint64_t *lpFileSize) -{ +static BOOL WINAPI GetFileSizeEx(HANDLE hFile, uint64_t *lpFileSize) { long curpos = ftell(hFile); fseek(hFile, 0, SEEK_END); @@ -246,8 +248,7 @@ static BOOL WINAPI GetFileSizeEx(HANDLE hFile, uint64_t *lpFileSize) return TRUE; } -static HANDLE WINAPI FindFirstFileW(PWCHAR lpFileName, PVOID lpFindFileData) -{ +static HANDLE WINAPI FindFirstFileW(PWCHAR lpFileName, PVOID lpFindFileData) { char *name = CreateAnsiFromWide(lpFileName); DebugLog("%p [%s], %p", lpFileName, name, lpFindFileData); @@ -259,115 +260,171 @@ static HANDLE WINAPI FindFirstFileW(PWCHAR lpFileName, PVOID lpFindFileData) return INVALID_HANDLE_VALUE; } -static DWORD WINAPI NtOpenSymbolicLinkObject(PHANDLE LinkHandle, DWORD DesiredAccess, PVOID ObjectAttributes) -{ +static DWORD WINAPI NtOpenSymbolicLinkObject(PHANDLE LinkHandle, DWORD DesiredAccess, PVOID ObjectAttributes) { + DebugLog(""); *LinkHandle = (HANDLE) 'SYMB'; return STATUS_SUCCESS; } -static NTSTATUS WINAPI NtQuerySymbolicLinkObject(HANDLE LinkHandle, PUNICODE_STRING LinkTarget, PULONG ReturnedLength) -{ +static NTSTATUS WINAPI NtQuerySymbolicLinkObject(HANDLE LinkHandle, PUNICODE_STRING LinkTarget, PULONG ReturnedLength) { + DebugLog(""); return STATUS_SUCCESS; } -static NTSTATUS WINAPI NtClose(HANDLE Handle) -{ +static NTSTATUS WINAPI NtClose(HANDLE Handle) { return STATUS_SUCCESS; } static BOOL WINAPI DeviceIoControl( - HANDLE hDevice, - DWORD dwIoControlCode, - PVOID lpInBuffer, - DWORD nInBufferSize, - PVOID lpOutBuffer, - DWORD nOutBufferSize, - PDWORD lpBytesReturned, - PVOID lpOverlapped) -{ + HANDLE hDevice, + DWORD dwIoControlCode, + PVOID lpInBuffer, + DWORD nInBufferSize, + PVOID lpOutBuffer, + DWORD nOutBufferSize, + PDWORD lpBytesReturned, + PVOID lpOverlapped) { DebugLog(""); return FALSE; } -static NTSTATUS NtQueryVolumeInformationFile( - HANDLE FileHandle, - PVOID IoStatusBlock, - PVOID FsInformation, - ULONG Length, - DWORD FsInformationClass) -{ +static NTSTATUS NtQueryVolumeInformationFile( + HANDLE FileHandle, + PVOID IoStatusBlock, + PVOID FsInformation, + ULONG Length, + DWORD FsInformationClass) { DebugLog(""); return 1; } static DWORD WINAPI GetFullPathNameW( - PWCHAR lpFileName, - DWORD nBufferLength, - PWCHAR lpBuffer, - PWCHAR *lpFilePart) -{ + PWCHAR lpFileName, + DWORD nBufferLength, + PWCHAR lpBuffer, + PWCHAR *lpFilePart) { DebugLog(""); return 0; } -static BOOL SetEndOfFile(HANDLE hFile) -{ +static BOOL SetEndOfFile(HANDLE hFile) { DebugLog(""); return ftruncate(fileno(hFile), ftell(hFile)) != -1; } -static DWORD WINAPI GetFileVersionInfoSizeExW(DWORD dwFlags, PWCHAR lptstrFilename, PDWORD lpdwHandle) -{ +static DWORD WINAPI GetFileVersionInfoSizeExW(DWORD dwFlags, PWCHAR lptstrFilename, PDWORD lpdwHandle) { DebugLog("%#x, %p, %p", dwFlags, lptstrFilename, lpdwHandle); return 0; } -static BOOL WINAPI GetFileVersionInfoExW(DWORD dwFlags, PWCHAR lptstrFilename, DWORD dwHandle, DWORD dwLen, PVOID lpData) -{ +static BOOL WINAPI +GetFileVersionInfoExW(DWORD dwFlags, PWCHAR lptstrFilename, DWORD dwHandle, DWORD dwLen, PVOID lpData) { DebugLog(""); return FALSE; } -static BOOL WINAPI VerQueryValueW(PVOID pBlock, PWCHAR lpSubBlock, PVOID *lplpBuffer, PDWORD puLen) -{ +static BOOL WINAPI VerQueryValueW(PVOID pBlock, PWCHAR lpSubBlock, PVOID *lplpBuffer, PDWORD puLen) { DebugLog(""); return FALSE; } -static DWORD WINAPI QueryDosDevice(PVOID lpDeviceName, PVOID lpTargetPath, DWORD ucchMax) -{ - DebugLog(""); - return 0; +static DWORD WINAPI QueryDosDevice(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax) { + + char *device_name = CreateAnsiFromWide(lpDeviceName); + DebugLog("%p [%s] %p", lpDeviceName, device_name, lpTargetPath); + free(device_name); + + *lpTargetPath = L"\\Device\\HarddiskVolume3"; + + // Return the length, in TCHARs, of *lpTargetPath + return 25; } -static BOOL WINAPI GetDiskFreeSpaceExW(PWCHAR lpDirectoryName, PVOID lpFreeBytesAvailableToCaller, PVOID lpTotalNumberOfBytes, QWORD *lpTotalNumberOfFreeBytes) -{ +static BOOL WINAPI +GetDiskFreeSpaceExW(PWCHAR lpDirectoryName, PVOID lpFreeBytesAvailableToCaller, PVOID lpTotalNumberOfBytes, + QWORD *lpTotalNumberOfFreeBytes) { DebugLog("%S", lpDirectoryName); *lpTotalNumberOfFreeBytes = 0x000000000ULL; return FALSE; } +STATIC BOOL WINAPI SetFileInformationByHandle(HANDLE hFile, + FILE_INFO_BY_HANDLE_CLASS FileInformationClass, + LPVOID lpFileInformation, + DWORD dwBufferSize) { + DebugLog("%p %p %hhx", hFile, lpFileInformation, dwBufferSize); + return true; +} + +STATIC DWORD WINAPI GetFileSize(HANDLE hFile, + LPDWORD lpFileSizeHigh) { + union long_int64 file_size; + file_size.high = 0; + file_size.low = 0; + + long curpos = ftell(hFile); + + fseek(hFile, 0, SEEK_END); + file_size.value = ftell(hFile); + + if (lpFileSizeHigh != NULL) + *lpFileSizeHigh = file_size.high; + + fseek(hFile, curpos, SEEK_SET); + + DebugLog("%p %hhx %hhx", hFile, file_size.high, file_size.low); + + return file_size.low; +} + DECLARE_CRT_EXPORT("VerQueryValueW", VerQueryValueW); + DECLARE_CRT_EXPORT("GetFileVersionInfoExW", GetFileVersionInfoExW); + DECLARE_CRT_EXPORT("GetFileVersionInfoSizeExW", GetFileVersionInfoSizeExW); + DECLARE_CRT_EXPORT("GetFileAttributesW", GetFileAttributesW); + DECLARE_CRT_EXPORT("GetFileAttributesExW", GetFileAttributesExW); + DECLARE_CRT_EXPORT("CreateFileA", CreateFileA); + DECLARE_CRT_EXPORT("CreateFileW", CreateFileW); + DECLARE_CRT_EXPORT("SetFilePointer", SetFilePointer); + DECLARE_CRT_EXPORT("SetFilePointerEx", SetFilePointerEx); + DECLARE_CRT_EXPORT("CloseHandle", CloseHandle); + DECLARE_CRT_EXPORT("ReadFile", ReadFile); + DECLARE_CRT_EXPORT("WriteFile", WriteFile); + DECLARE_CRT_EXPORT("DeleteFileW", DeleteFileW); + DECLARE_CRT_EXPORT("GetFileSizeEx", GetFileSizeEx); + DECLARE_CRT_EXPORT("FindFirstFileW", FindFirstFileW); + DECLARE_CRT_EXPORT("NtOpenSymbolicLinkObject", NtOpenSymbolicLinkObject); + DECLARE_CRT_EXPORT("NtQuerySymbolicLinkObject", NtQuerySymbolicLinkObject); + DECLARE_CRT_EXPORT("NtClose", NtClose); + DECLARE_CRT_EXPORT("DeviceIoControl", DeviceIoControl); + DECLARE_CRT_EXPORT("NtQueryVolumeInformationFile", NtQueryVolumeInformationFile); + DECLARE_CRT_EXPORT("GetFullPathNameW", GetFullPathNameW); + DECLARE_CRT_EXPORT("SetEndOfFile", SetEndOfFile); + DECLARE_CRT_EXPORT("QueryDosDeviceW", QueryDosDevice); + DECLARE_CRT_EXPORT("GetDiskFreeSpaceExW", GetDiskFreeSpaceExW); + +DECLARE_CRT_EXPORT("SetFileInformationByHandle", SetFileInformationByHandle); + +DECLARE_CRT_EXPORT("GetFileSize", GetFileSize); diff --git a/peloader/winapi/FunctionTable.c b/peloader/winapi/FunctionTable.c new file mode 100644 index 0000000..489bb71 --- /dev/null +++ b/peloader/winapi/FunctionTable.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include + +#include "winnt_types.h" +#include "pe_linker.h" +#include "ntoskernel.h" +#include "log.h" +#include "winexports.h" +#include "util.h" + +STATIC WINAPI BOOLEAN RtlAddFunctionTable(PVOID FunctionTable, + DWORD EntryCount, + DWORD64 BaseAddress) { + DebugLog("%p %hhx %p", FunctionTable, EntryCount, BaseAddress); + return true; +} + +STATIC WINAPI BOOLEAN RtlDeleteFunctionTable(PVOID FunctionTable) { + DebugLog("%p", FunctionTable); + return true; +} + +DECLARE_CRT_EXPORT("RtlAddFunctionTable", RtlAddFunctionTable); + +DECLARE_CRT_EXPORT("RtlDeleteFunctionTable", RtlDeleteFunctionTable); diff --git a/peloader/winapi/GetLastError.c b/peloader/winapi/GetLastError.c index 6882bb4..5c58fb7 100644 --- a/peloader/winapi/GetLastError.c +++ b/peloader/winapi/GetLastError.c @@ -13,18 +13,19 @@ STATIC DWORD LastError; -STATIC DWORD WINAPI GetLastError(void) -{ +STATIC DWORD WINAPI GetLastError(void) { DebugLog("GetLastError() => %#x", LastError); return LastError; } -void WINAPI SetLastError(DWORD dwErrCode) -{ - //DebugLog("SetLastError(%#x)", dwErrCode); +VOID WINAPI SetLastError(DWORD dwErrCode) { + DebugLog("SetLastError(%#x)", dwErrCode); LastError = dwErrCode; + + return; } DECLARE_CRT_EXPORT("GetLastError", GetLastError); + DECLARE_CRT_EXPORT("SetLastError", SetLastError); diff --git a/peloader/winapi/GetStartupInfoW.c b/peloader/winapi/GetStartupInfoW.c index c068e57..c6c6d6e 100644 --- a/peloader/winapi/GetStartupInfoW.c +++ b/peloader/winapi/GetStartupInfoW.c @@ -12,55 +12,58 @@ #include "util.h" typedef struct _STARTUPINFO { - DWORD cb; - PVOID lpReserved; - PVOID lpDesktop; - PVOID lpTitle; - DWORD dwX; - DWORD dwY; - DWORD dwXSize; - DWORD dwYSize; - DWORD dwXCountChars; - DWORD dwYCountChars; - DWORD dwFillAttribute; - DWORD dwFlags; - WORD wShowWindow; - WORD cbReserved2; - PVOID lpReserved2; - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; + DWORD cb; + PVOID lpReserved; + PVOID lpDesktop; + PVOID lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + PVOID lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO; -STATIC void WINAPI GetStartupInfoA(LPSTARTUPINFO lpStartupInfo) -{ +STATIC void WINAPI GetStartupInfoA(LPSTARTUPINFO lpStartupInfo) { memset(lpStartupInfo, 0, sizeof *lpStartupInfo); DebugLog("GetStartupInfoA(%p)", lpStartupInfo); + + return; } -STATIC void WINAPI GetStartupInfoW(LPSTARTUPINFO lpStartupInfo) -{ +STATIC void WINAPI GetStartupInfoW(LPSTARTUPINFO lpStartupInfo) { memset(lpStartupInfo, 0, sizeof *lpStartupInfo); DebugLog("GetStartupInfoW(%p)", lpStartupInfo); + + return; } -STATIC PVOID WINAPI GetCommandLineA(void) -{ +STATIC PVOID WINAPI GetCommandLineA(void) { DebugLog(""); return "totallylegit.exe notfake very real"; } -STATIC PVOID WINAPI GetCommandLineW(void) -{ +STATIC PVOID WINAPI GetCommandLineW(void) { DebugLog(""); return L"totallylegit.exe notfake very real"; } DECLARE_CRT_EXPORT("GetStartupInfoA", GetStartupInfoA); + DECLARE_CRT_EXPORT("GetStartupInfoW", GetStartupInfoW); + DECLARE_CRT_EXPORT("GetCommandLineA", GetCommandLineA); + DECLARE_CRT_EXPORT("GetCommandLineW", GetCommandLineW); diff --git a/peloader/winapi/GetStdHandle.c b/peloader/winapi/GetStdHandle.c index c9ec8ea..a2925c3 100644 --- a/peloader/winapi/GetStdHandle.c +++ b/peloader/winapi/GetStdHandle.c @@ -21,8 +21,7 @@ #define FILE_TYPE_REMOTE 0x8000 #define FILE_TYPE_UNKNOWN 0x0000 -STATIC HANDLE WINAPI GetStdHandle(DWORD nStdHandle) -{ +STATIC HANDLE WINAPI GetStdHandle(DWORD nStdHandle) { DebugLog("%d", nStdHandle); switch (nStdHandle) { @@ -37,12 +36,12 @@ STATIC HANDLE WINAPI GetStdHandle(DWORD nStdHandle) return INVALID_HANDLE_VALUE; } -STATIC DWORD WINAPI GetFileType(HANDLE hFile) -{ +STATIC DWORD WINAPI GetFileType(HANDLE hFile) { DebugLog("%p", hFile); return FILE_TYPE_CHAR; } DECLARE_CRT_EXPORT("GetStdHandle", GetStdHandle); + DECLARE_CRT_EXPORT("GetFileType", GetFileType); diff --git a/peloader/winapi/GetSystemDirectory.c b/peloader/winapi/GetSystemDirectory.c index 7dac8d7..db350b2 100644 --- a/peloader/winapi/GetSystemDirectory.c +++ b/peloader/winapi/GetSystemDirectory.c @@ -14,8 +14,7 @@ static uint16_t SystemDirectory[] = L"C:\\SYSTEM32\\"; -STATIC UINT WINAPI GetSystemDirectoryW(PWCHAR Buffer, UINT uSize) -{ +STATIC UINT WINAPI GetSystemDirectoryW(PWCHAR Buffer, UINT uSize) { DebugLog("%p, %u", Buffer, uSize); // Srsly?! @@ -27,8 +26,7 @@ STATIC UINT WINAPI GetSystemDirectoryW(PWCHAR Buffer, UINT uSize) } } -STATIC UINT WINAPI GetSystemWindowsDirectoryW(PWCHAR Buffer, UINT uSize) -{ +STATIC UINT WINAPI GetSystemWindowsDirectoryW(PWCHAR Buffer, UINT uSize) { DebugLog("%p, %u", Buffer, uSize); // Srsly?! @@ -40,13 +38,14 @@ STATIC UINT WINAPI GetSystemWindowsDirectoryW(PWCHAR Buffer, UINT uSize) } } -STATIC UINT WINAPI GetSystemWow64DirectoryW(PWCHAR lpBuffer, UINT uSize) -{ +STATIC UINT WINAPI GetSystemWow64DirectoryW(PWCHAR lpBuffer, UINT uSize) { DebugLog("%p, %u", lpBuffer, uSize); return 0; } DECLARE_CRT_EXPORT("GetSystemDirectoryW", GetSystemDirectoryW); + DECLARE_CRT_EXPORT("GetSystemWindowsDirectoryW", GetSystemWindowsDirectoryW); + DECLARE_CRT_EXPORT("GetSystemWow64DirectoryW", GetSystemWow64DirectoryW); diff --git a/peloader/winapi/Handle.c b/peloader/winapi/Handle.c index b77d543..b04c776 100644 --- a/peloader/winapi/Handle.c +++ b/peloader/winapi/Handle.c @@ -14,8 +14,9 @@ #include "util.h" #include "strings.h" -STATIC BOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, PHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions) -{ +STATIC BOOL WINAPI +DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, PHANDLE lpTargetHandle, + DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions) { DebugLog("%p, %p, %p, %p, %#x, %u, %#x", hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions); // lol i dunno @@ -23,12 +24,12 @@ STATIC BOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHa return TRUE; } -STATIC UINT WINAPI SetHandleCount(UINT handleCount) -{ +STATIC UINT WINAPI SetHandleCount(UINT handleCount) { DebugLog("%u", handleCount); return handleCount; } DECLARE_CRT_EXPORT("DuplicateHandle", DuplicateHandle); + DECLARE_CRT_EXPORT("SetHandleCount", SetHandleCount); diff --git a/peloader/winapi/Heap.c b/peloader/winapi/Heap.c index 5747232..773c659 100644 --- a/peloader/winapi/Heap.c +++ b/peloader/winapi/Heap.c @@ -13,25 +13,24 @@ #include "log.h" #include "winexports.h" #include "util.h" +#include "Heap.h" #define HEAP_ZERO_MEMORY 8 -STATIC HANDLE WINAPI GetProcessHeap(void) -{ +STATIC HANDLE WINAPI GetProcessHeap(void) { + DebugLog(""); return (HANDLE) 'HEAP'; } -STATIC HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) -{ +STATIC HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) { DebugLog("%#x, %u, %u", flOptions, dwInitialSize, dwMaximumSize); return (HANDLE) 'HEAP'; } -STATIC PVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) -{ +PVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) { PVOID Buffer; - // DebugLog("%p, %#x, %u", hHeap, dwFlags, dwBytes); + //DebugLog("%p, %#x, %u", hHeap, dwFlags, dwBytes); if (dwFlags & HEAP_ZERO_MEMORY) { Buffer = calloc(dwBytes, 1); @@ -42,17 +41,15 @@ STATIC PVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) return Buffer; } -STATIC BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, PVOID lpMem) -{ - // DebugLog("%p, %#x, %p", hHeap, dwFlags, lpMem); +BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, PVOID lpMem) { + //DebugLog("%p, %#x, %p", hHeap, dwFlags, lpMem); free(lpMem); return TRUE; } -STATIC BOOL WINAPI RtlFreeHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress) -{ +STATIC BOOL WINAPI RtlFreeHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress) { DebugLog("%p, %#x, %p", HeapHandle, Flags, BaseAddress); free(BaseAddress); @@ -60,18 +57,17 @@ STATIC BOOL WINAPI RtlFreeHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress) return TRUE; } -STATIC SIZE_T WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, PVOID lpMem) -{ +STATIC SIZE_T WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, PVOID lpMem) { + DebugLog(""); return malloc_usable_size(lpMem); } -STATIC PVOID WINAPI HeapReAlloc(HANDLE hHeap, DWORD dwFlags, PVOID lpMem, SIZE_T dwBytes) -{ +STATIC PVOID WINAPI HeapReAlloc(HANDLE hHeap, DWORD dwFlags, PVOID lpMem, SIZE_T dwBytes) { + DebugLog(""); return realloc(lpMem, dwBytes); } -STATIC PVOID WINAPI LocalAlloc(UINT uFlags, SIZE_T uBytes) -{ +STATIC PVOID WINAPI LocalAlloc(UINT uFlags, SIZE_T uBytes) { PVOID Buffer = malloc(uBytes); assert(uFlags == 0); @@ -80,8 +76,7 @@ STATIC PVOID WINAPI LocalAlloc(UINT uFlags, SIZE_T uBytes) return Buffer; } -STATIC PVOID WINAPI LocalFree(PVOID hMem) -{ +STATIC PVOID WINAPI LocalFree(PVOID hMem) { DebugLog("%p", hMem); free(hMem); return NULL; @@ -92,23 +87,21 @@ STATIC PVOID WINAPI RtlCreateHeap(ULONG Flags, SIZE_T ReserveSize, SIZE_T CommitSize, PVOID Lock, - PVOID Parameters) -{ + PVOID Parameters) { DebugLog("%#x, %p, %#x, %#x, %p, %p", - Flags, - HeapBase, - ReserveSize, - CommitSize, - Lock, - Parameters); + Flags, + HeapBase, + ReserveSize, + CommitSize, + Lock, + Parameters); return (HANDLE) 'HEAP'; } STATIC PVOID WINAPI RtlAllocateHeap(PVOID HeapHandle, ULONG Flags, - SIZE_T Size) -{ + SIZE_T Size) { DebugLog("%p, %#x, %u", HeapHandle, Flags, Size); return malloc(Size); @@ -117,14 +110,12 @@ STATIC PVOID WINAPI RtlAllocateHeap(PVOID HeapHandle, STATIC NTSTATUS WINAPI RtlSetHeapInformation(PVOID Heap, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation, - SIZE_T HeapInformationLength) -{ + SIZE_T HeapInformationLength) { DebugLog("%p, %d", Heap, HeapInformationLength); return 0; } -STATIC PVOID WINAPI GlobalAlloc(UINT uFlags, SIZE_T uBytes) -{ +STATIC PVOID WINAPI GlobalAlloc(UINT uFlags, SIZE_T uBytes) { PVOID Buffer = malloc(uBytes); assert(uFlags == 0); @@ -133,24 +124,36 @@ STATIC PVOID WINAPI GlobalAlloc(UINT uFlags, SIZE_T uBytes) return Buffer; } -STATIC PVOID WINAPI GlobalFree(PVOID hMem) -{ +STATIC PVOID WINAPI GlobalFree(PVOID hMem) { DebugLog("%p", hMem); free(hMem); return NULL; } DECLARE_CRT_EXPORT("HeapCreate", HeapCreate); + DECLARE_CRT_EXPORT("GetProcessHeap", GetProcessHeap); + DECLARE_CRT_EXPORT("HeapAlloc", HeapAlloc); + DECLARE_CRT_EXPORT("HeapFree", HeapFree); + DECLARE_CRT_EXPORT("RtlFreeHeap", RtlFreeHeap); + DECLARE_CRT_EXPORT("RtlSetHeapInformation", RtlSetHeapInformation); + DECLARE_CRT_EXPORT("HeapSize", HeapSize); + DECLARE_CRT_EXPORT("HeapReAlloc", HeapReAlloc); + DECLARE_CRT_EXPORT("LocalAlloc", LocalAlloc); + DECLARE_CRT_EXPORT("LocalFree", LocalFree); + DECLARE_CRT_EXPORT("RtlCreateHeap", RtlCreateHeap); + DECLARE_CRT_EXPORT("RtlAllocateHeap", RtlAllocateHeap); + DECLARE_CRT_EXPORT("GlobalAlloc", GlobalAlloc); + DECLARE_CRT_EXPORT("GlobalFree", GlobalFree); diff --git a/peloader/winapi/Heap.h b/peloader/winapi/Heap.h new file mode 100644 index 0000000..c2412f6 --- /dev/null +++ b/peloader/winapi/Heap.h @@ -0,0 +1,7 @@ +#ifndef LOADLIBRARY_HEAP_H +#define LOADLIBRARY_HEAP_H + +PVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); +BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, PVOID lpMem); + +#endif //LOADLIBRARY_HEAP_H diff --git a/peloader/winapi/InitializeSListHead.c b/peloader/winapi/InitializeSListHead.c index 30f502f..5f11aec 100644 --- a/peloader/winapi/InitializeSListHead.c +++ b/peloader/winapi/InitializeSListHead.c @@ -13,16 +13,15 @@ #include "winexports.h" #include "util.h" -STATIC VOID WINAPI InitializeSListHead(PVOID ListHead) -{ +STATIC VOID WINAPI InitializeSListHead(PVOID ListHead) { DebugLog("%p", ListHead); } -STATIC PVOID WINAPI InterlockedFlushSList(PVOID ListHead) -{ +STATIC PVOID WINAPI InterlockedFlushSList(PVOID ListHead) { DebugLog("%p", ListHead); return NULL; } DECLARE_CRT_EXPORT("InitializeSListHead", InitializeSListHead); + DECLARE_CRT_EXPORT("InterlockedFlushSList", InterlockedFlushSList); diff --git a/peloader/winapi/Internal.c b/peloader/winapi/Internal.c index e20dcb9..05fd28a 100644 --- a/peloader/winapi/Internal.c +++ b/peloader/winapi/Internal.c @@ -13,39 +13,33 @@ #include "util.h" #include "winstrings.h" -void WINAPI RtlAcquirePebLock(void) -{ +void WINAPI RtlAcquirePebLock(void) { DebugLog(""); return; } -void WINAPI RtlReleasePebLock(void) -{ +void WINAPI RtlReleasePebLock(void) { DebugLog(""); return; } -NTSTATUS WINAPI LdrGetDllHandle(PWCHAR pwPath, PVOID unused, PUNICODE_STRING ModuleFileName, PHANDLE pHModule) -{ +NTSTATUS WINAPI LdrGetDllHandle(PWCHAR pwPath, PVOID unused, PUNICODE_STRING ModuleFileName, PHANDLE pHModule) { DebugLog("%S %p %p %p", pwPath, unused, ModuleFileName, pHModule); pHModule = (HANDLE) 'LDRP'; return 0; } -NTSTATUS WINAPI EtwRegister(PVOID ProvideId, PVOID EnableCallback, PVOID CallbackContext, PVOID RegHandle) -{ +NTSTATUS WINAPI EtwRegister(PVOID ProvideId, PVOID EnableCallback, PVOID CallbackContext, PVOID RegHandle) { DebugLog(""); return 0; } -NTSTATUS WINAPI EtwUnregister(HANDLE RegHandle) -{ +NTSTATUS WINAPI EtwUnregister(HANDLE RegHandle) { DebugLog(""); return 0; } -ULONG WINAPI EtwEventWrite(HANDLE RegHAndle, PVOID EventDescriptor, ULONG UserDataCount, PVOID UserData, PVOID a5) -{ +ULONG WINAPI EtwEventWrite(HANDLE RegHAndle, PVOID EventDescriptor, ULONG UserDataCount, PVOID UserData, PVOID a5) { DebugLog(""); return 0; } @@ -53,8 +47,7 @@ ULONG WINAPI EtwEventWrite(HANDLE RegHAndle, PVOID EventDescriptor, ULONG UserDa static NTSTATUS WINAPI LdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFilename, - PHANDLE ModuleHandle) -{ + PHANDLE ModuleHandle) { char *PathToFileA = CreateAnsiFromWide(PathToFile); char *ModuleFilenameA = CreateAnsiFromWide(ModuleFilename->Buffer); @@ -77,15 +70,14 @@ static NTSTATUS WINAPI LdrUnloadDll(HANDLE ModuleHandle) { static NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE Module, PANSI_STRING Name, WORD Ordinal, - PVOID *Address) -{ + PVOID *Address) { DebugLog("%p %s %hu %p", Module, Name->buf, Ordinal, Address); // Recognizable value to crash on. *Address = (PVOID) 'LDRZ'; // Search if the requested function has been already exported. - ENTRY e = { Name->buf, NULL }, *ep; + ENTRY e = {Name->buf, NULL}, *ep; hsearch_r(e, FIND, &ep, &crtexports); // If found, store the pointer and return. @@ -108,8 +100,13 @@ static NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE Module, } DECLARE_CRT_EXPORT("RtlAcquirePebLock", RtlAcquirePebLock); + DECLARE_CRT_EXPORT("RtlReleasePebLock", RtlReleasePebLock); + DECLARE_CRT_EXPORT("LdrGetDllHandle", LdrGetDllHandle); + DECLARE_CRT_EXPORT("LdrLoadDll", LdrLoadDll); + DECLARE_CRT_EXPORT("LdrUnloadDll", LdrUnloadDll); + DECLARE_CRT_EXPORT("LdrGetProcedureAddress", LdrGetProcedureAddress); diff --git a/peloader/winapi/IsProcessorFeaturePresent.c b/peloader/winapi/IsProcessorFeaturePresent.c index 52b09a2..1220765 100644 --- a/peloader/winapi/IsProcessorFeaturePresent.c +++ b/peloader/winapi/IsProcessorFeaturePresent.c @@ -16,8 +16,7 @@ #define PF_FASTFAIL_AVAILABLE 23 #define PF_MMX_INSTRUCTIONS_AVAILABLE 3 -STATIC BOOL WINAPI IsProcessorFeaturePresent(DWORD ProcessorFeature) -{ +STATIC BOOL WINAPI IsProcessorFeaturePresent(DWORD ProcessorFeature) { switch (ProcessorFeature) { case PF_XMMI64_INSTRUCTIONS_AVAILABLE: case PF_FLOATING_POINT_PRECISION_ERRATA: diff --git a/peloader/winapi/LoadLibrary.c b/peloader/winapi/LoadLibrary.c index cc95e05..8dcb112 100644 --- a/peloader/winapi/LoadLibrary.c +++ b/peloader/winapi/LoadLibrary.c @@ -15,8 +15,7 @@ #include "winstrings.h" -static HANDLE WINAPI LoadLibraryExW(PVOID lpFileName, HANDLE hFile, DWORD dwFlags) -{ +static HANDLE WINAPI LoadLibraryExW(PVOID lpFileName, HANDLE hFile, DWORD dwFlags) { char *name = CreateAnsiFromWide(lpFileName); DebugLog("%p [%s], %p, %#x", lpFileName, name, hFile, dwFlags); @@ -26,18 +25,17 @@ static HANDLE WINAPI LoadLibraryExW(PVOID lpFileName, HANDLE hFile, DWORD dwFlag return (HANDLE) 'LOAD'; } -static HANDLE WINAPI LoadLibraryW(PVOID lpFileName) -{ +static HANDLE WINAPI LoadLibraryW(PVOID lpFileName) { DebugLog("%p", lpFileName); return (HANDLE) 'LOAD'; } -static PVOID WINAPI GetProcAddress(HANDLE hModule, PCHAR lpProcName) -{ - ENTRY key = { lpProcName }, *item; +static PVOID WINAPI GetProcAddress(HANDLE hModule, PCHAR lpProcName) { + ENTRY key = {lpProcName}, *item; - assert(hModule == (HANDLE) NULL || hModule == (HANDLE) 'LOAD' || hModule == (HANDLE) 'MPEN' || hModule == (HANDLE) 'VERS' || hModule == (HANDLE) 'KERN'); + assert(hModule == (HANDLE) NULL || hModule == (HANDLE) 'LOAD' || hModule == (HANDLE) 'MPEN' || + hModule == (HANDLE) 'VERS' || hModule == (HANDLE) 'KERN'); if (hsearch_r(key, FIND, &item, &crtexports)) { return item->data; @@ -48,8 +46,7 @@ static PVOID WINAPI GetProcAddress(HANDLE hModule, PCHAR lpProcName) return NULL; } -static HANDLE WINAPI GetModuleHandleW(PVOID lpModuleName) -{ +static HANDLE WINAPI GetModuleHandleW(PVOID lpModuleName) { char *name = CreateAnsiFromWide(lpModuleName); DebugLog("%p [%s]", lpModuleName, name); @@ -73,8 +70,7 @@ static HANDLE WINAPI GetModuleHandleW(PVOID lpModuleName) return (HANDLE) NULL; } -static DWORD WINAPI GetModuleFileNameA(HANDLE hModule, PCHAR lpFilename, DWORD nSize) -{ +static DWORD WINAPI GetModuleFileNameA(HANDLE hModule, PCHAR lpFilename, DWORD nSize) { DebugLog("%p, %p, %u", hModule, lpFilename, nSize); strncpy(lpFilename, "C:\\dummy\\fakename.exe", nSize); @@ -82,8 +78,7 @@ static DWORD WINAPI GetModuleFileNameA(HANDLE hModule, PCHAR lpFilename, DWORD n return strlen(lpFilename); } -static DWORD WINAPI GetModuleFileNameW(HANDLE hModule, PWCHAR lpFilename, DWORD nSize) -{ +static DWORD WINAPI GetModuleFileNameW(HANDLE hModule, PWCHAR lpFilename, DWORD nSize) { DebugLog("%p, %p, %u", hModule, lpFilename, nSize); if (nSize > strlen("C:\\dummy\\fakename.exe")) { @@ -93,23 +88,57 @@ static DWORD WINAPI GetModuleFileNameW(HANDLE hModule, PWCHAR lpFilename, DWORD return strlen("C:\\dummy\\fakename.exe"); } -static HANDLE WINAPI GetModuleHandleA(PCHAR lpModuleName) -{ +static HANDLE WINAPI GetModuleHandleA(PCHAR lpModuleName) { DebugLog("%p [%s]", lpModuleName, lpModuleName); return (HANDLE) NULL; } -static VOID WINAPI FreeLibrary(PVOID hLibModule) -{ +static BOOL WINAPI GetModuleHandleExA(DWORD dwFlags, + LPCSTR lpModuleName, + HMODULE *phModule) { + DebugLog("%p [%s]", lpModuleName, lpModuleName); + + if (lpModuleName && memcmp(lpModuleName, "mpengine.dll", sizeof("mpengine.dll")) == 0) + *phModule = (HANDLE) 'MPEN'; + + if (lpModuleName && memcmp(lpModuleName, "bcrypt.dll", sizeof("bcrypt.dll")) == 0) + *phModule = (HANDLE) 'LOAD'; + + if (lpModuleName && memcmp(lpModuleName, "KERNEL32.DLL", sizeof("KERNEL32.DLL")) == 0) + *phModule = (HANDLE) 'KERN'; + + if (lpModuleName && memcmp(lpModuleName, "kernel32.dll", sizeof("kernel32.dll")) == 0) + *phModule = (HANDLE) 'KERN'; + + if (lpModuleName && memcmp(lpModuleName, "version.dll", sizeof("version.dll")) == 0) + *phModule = (HANDLE) 'VERS'; + + if (lpModuleName && memcmp(lpModuleName, "ntdll.dll", sizeof("ntdll.dll")) == 0) + *phModule = (HANDLE) 'NTDL'; + + *phModule = (HANDLE) NULL; + return true; +} + +static VOID WINAPI FreeLibrary(PVOID hLibModule) { DebugLog("FreeLibrary(%p)", hLibModule); } DECLARE_CRT_EXPORT("FreeLibrary", FreeLibrary); + DECLARE_CRT_EXPORT("LoadLibraryExW", LoadLibraryExW); + DECLARE_CRT_EXPORT("LoadLibraryW", LoadLibraryW); + DECLARE_CRT_EXPORT("GetProcAddress", GetProcAddress); + DECLARE_CRT_EXPORT("GetModuleHandleW", GetModuleHandleW); + DECLARE_CRT_EXPORT("GetModuleHandleA", GetModuleHandleA); + DECLARE_CRT_EXPORT("GetModuleFileNameA", GetModuleFileNameA); + DECLARE_CRT_EXPORT("GetModuleFileNameW", GetModuleFileNameW); + +DECLARE_CRT_EXPORT("GetModuleHandleExA", GetModuleHandleExA); diff --git a/peloader/winapi/Locale.c b/peloader/winapi/Locale.c index f8344cb..5f69840 100644 --- a/peloader/winapi/Locale.c +++ b/peloader/winapi/Locale.c @@ -16,45 +16,41 @@ #define MAX_LEADBYTES 12 typedef struct _cpinfo { - UINT MaxCharSize; - BYTE DefaultChar[MAX_DEFAULTCHAR]; - BYTE LeadByte[MAX_LEADBYTES]; + UINT MaxCharSize; + BYTE DefaultChar[MAX_DEFAULTCHAR]; + BYTE LeadByte[MAX_LEADBYTES]; } CPINFO, *LPCPINFO; -STATIC UINT GetACP(void) -{ +STATIC UINT GetACP(void) { DebugLog(""); return 65001; // UTF-8 } -STATIC WINAPI BOOL IsValidCodePage(UINT CodePage) -{ +STATIC WINAPI BOOL IsValidCodePage(UINT CodePage) { DebugLog("%u", CodePage); return TRUE; } -STATIC WINAPI BOOL GetCPInfo(UINT CodePage, LPCPINFO lpCPInfo) -{ +STATIC WINAPI BOOL GetCPInfo(UINT CodePage, LPCPINFO lpCPInfo) { DebugLog("%u, %p", CodePage, lpCPInfo); memset(lpCPInfo, 0, sizeof *lpCPInfo); - lpCPInfo->MaxCharSize = 1; - lpCPInfo->DefaultChar[0] = '?'; + lpCPInfo->MaxCharSize = 1; + lpCPInfo->DefaultChar[0] = '?'; return TRUE; } -STATIC DWORD LocaleNameToLCID(PVOID lpName, DWORD dwFlags) -{ +STATIC DWORD LocaleNameToLCID(PVOID lpName, DWORD dwFlags) { DebugLog("%p, %#x", lpName, dwFlags); return 0; } -STATIC WINAPI int LCMapStringW(DWORD Locale, DWORD dwMapFlags, PVOID lpSrcStr, int cchSrc, PVOID lpDestStr, int cchDest) -{ +STATIC WINAPI int +LCMapStringW(DWORD Locale, DWORD dwMapFlags, PVOID lpSrcStr, int cchSrc, PVOID lpDestStr, int cchDest) { DebugLog("%u, %#x, %p, %d, %p, %d", Locale, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest); return 1; } @@ -62,8 +58,10 @@ STATIC WINAPI int LCMapStringW(DWORD Locale, DWORD dwMapFlags, PVOID lpSrcStr, i #define LOCALE_NAME_USER_DEFAULT NULL #define NORM_IGNORENONSPACE 1 #define LCMAP_UPPERCASE 512 -STATIC WINAPI int LCMapStringEx(PVOID lpLocaleName, DWORD dwMapFlags, PVOID lpSrcStr, int cchSrc, PVOID lpDestStr, int cchDest, PVOID lpVersionInformation, PVOID lpReserved, PVOID sortHandle) -{ + +STATIC WINAPI int +LCMapStringEx(PVOID lpLocaleName, DWORD dwMapFlags, PVOID lpSrcStr, int cchSrc, PVOID lpDestStr, int cchDest, + PVOID lpVersionInformation, PVOID lpReserved, PVOID sortHandle) { DebugLog("%p, %#x, %p, %d, %p, %d, %p, %p, %p", lpLocaleName, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest, lpVersionInformation, lpReserved, sortHandle); assert(lpLocaleName == LOCALE_NAME_USER_DEFAULT); @@ -77,16 +75,21 @@ STATIC WINAPI int LCMapStringEx(PVOID lpLocaleName, DWORD dwMapFlags, PVOID lpSr return cchDest > cchSrc ? cchSrc : cchDest; } -STATIC WINAPI int GetLocaleInfoEx(LPCWSTR lpLocaleName, DWORD LCType, LPWSTR lpLCData, int cchData) -{ +STATIC WINAPI int GetLocaleInfoEx(LPCWSTR lpLocaleName, DWORD LCType, LPWSTR lpLCData, int cchData) { DebugLog("%S, %d, %S, %d", lpLocaleName, LCType, lpLCData, cchData); return 0; } DECLARE_CRT_EXPORT("GetACP", GetACP); + DECLARE_CRT_EXPORT("IsValidCodePage", IsValidCodePage); + DECLARE_CRT_EXPORT("GetCPInfo", GetCPInfo); + DECLARE_CRT_EXPORT("LocaleNameToLCID", LocaleNameToLCID); + DECLARE_CRT_EXPORT("LCMapStringW", LCMapStringW); + DECLARE_CRT_EXPORT("LCMapStringEx", LCMapStringEx); + DECLARE_CRT_EXPORT("GetLocaleInfoEx", GetLocaleInfoEx); diff --git a/peloader/winapi/MapFile.c b/peloader/winapi/MapFile.c new file mode 100644 index 0000000..4ae831d --- /dev/null +++ b/peloader/winapi/MapFile.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "winnt_types.h" +#include "pe_linker.h" +#include "ntoskernel.h" +#include "log.h" +#include "winexports.h" +#include "util.h" +#include "winstrings.h" +#include "file_mapping.h" + + +MappedFileObjectList *FileMappingList = NULL; + + +STATIC HANDLE WINAPI CreateFileMappingW(HANDLE hFile, + PVOID lpFileMappingAttributes, + DWORD flProtect, + DWORD dwMaximumSizeHigh, + DWORD dwMaximumSizeLow, + LPCWSTR lpName) { + union long_int64 file_size; + + char *file_name = CreateAnsiFromWide(lpName); + + DebugLog("%p, %#x, %#x, %#x, %p [%s]", hFile, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName, file_name); + + if (dwMaximumSizeHigh != 0 || dwMaximumSizeLow != 0) { + file_size.high = dwMaximumSizeHigh; + file_size.low = dwMaximumSizeLow; + } else { + long curpos = ftell(hFile); + fseek(hFile, 0, SEEK_END); + + file_size.value = ftell(hFile); + + fseek(hFile, curpos, SEEK_SET); + } + + MappedFileEntry *mapped_file_object = (MappedFileEntry *) calloc(1, sizeof(MappedFileEntry)); + + int fd = fileno(hFile); + mapped_file_object->fd = fd; + + PVOID addr = mmap(NULL, file_size.value, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + DebugLog("[ERROR] failed to create file object mapping: %s", strerror(errno)); + free(mapped_file_object); + return INVALID_HANDLE_VALUE; + } + mapped_file_object->start = (intptr_t) addr; + mapped_file_object->end = (intptr_t) addr + file_size.value; + mapped_file_object->size = file_size.value; + + if (FileMappingList == NULL) { + FileMappingList = (MappedFileObjectList *) malloc(sizeof(MappedFileObjectList)); + FileMappingList->head = NULL; + } + + AddMappedFile(mapped_file_object, FileMappingList); + + DebugLog("%p => %p", hFile, mapped_file_object); + + return mapped_file_object; +} + +STATIC PVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject, + DWORD dwDesiredAccess, + DWORD dwFileOffsetHigh, + DWORD dwFileOffsetLow, + SIZE_T dwNumberOfBytesToMap) { + DebugLog("%p, %#x, %#x, %#x, %#x", hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap); + union long_int64 file_offset; + file_offset.high = dwFileOffsetHigh; + file_offset.low = dwFileOffsetLow; + + MappedFileEntry *MappedFile = (MappedFileEntry *) hFileMappingObject; + + PVOID FileView = malloc(dwNumberOfBytesToMap); + if (dwNumberOfBytesToMap == 0) { + dwNumberOfBytesToMap = MappedFile->size - file_offset.value; + FileView = realloc(FileView, dwNumberOfBytesToMap); + + } + if (FileView == NULL) { + DebugLog("[ERROR] failed to allocate view of file: %s ", strerror(errno)); + return NULL; + } + + memcpy(FileView, (void *) MappedFile->start + file_offset.value, dwNumberOfBytesToMap); + + return FileView; +} + +DECLARE_CRT_EXPORT("CreateFileMappingW", CreateFileMappingW); + +DECLARE_CRT_EXPORT("MapViewOfFile", MapViewOfFile); diff --git a/peloader/winapi/Memory.c b/peloader/winapi/Memory.c index 1618e35..566a73b 100644 --- a/peloader/winapi/Memory.c +++ b/peloader/winapi/Memory.c @@ -24,8 +24,7 @@ #define MEM_RELEASE 0x8000 -STATIC PVOID WINAPI VirtualAlloc(PVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) -{ +STATIC PVOID WINAPI VirtualAlloc(PVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) { if (flAllocationType & ~(MEM_COMMIT | MEM_RESERVE)) { DebugLog("flAllocationType %#x not implemnted", flAllocationType); return NULL; @@ -43,27 +42,41 @@ STATIC PVOID WINAPI VirtualAlloc(PVOID lpAddress, SIZE_T dwSize, DWORD flAllocat return NULL; } -STATIC BOOL WINAPI VirtualProtect(PVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) -{ +STATIC BOOL WINAPI VirtualProtect(PVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) { if (flNewProtect != PAGE_READONLY) { DebugLog("unimplemented VirtualProtect() request, %#x", flNewProtect); } return TRUE; } -STATIC BOOL WINAPI VirtualUnlock(PVOID lpAddress, SIZE_T dwSize) -{ +STATIC BOOL WINAPI VirtualUnlock(PVOID lpAddress, SIZE_T dwSize) { return TRUE; } -STATIC BOOL WINAPI VirtualFree(PVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) -{ +STATIC BOOL WINAPI VirtualFree(PVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) { if (dwFreeType == MEM_RELEASE) code_free(lpAddress); return TRUE; } +STATIC BOOL WINAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer) { + lpBuffer->dwMemoryLoad = 40; + lpBuffer->ullTotalPhys = 2147483648; + lpBuffer->ullAvailPhys = 2147483648; + lpBuffer->ullTotalPageFile = 2147483648; + lpBuffer->ullAvailPageFile = 2147483648; + lpBuffer->ullTotalVirtual = 2147483648; + lpBuffer->ullAvailVirtual = 2147483648; + lpBuffer->ullAvailExtendedVirtual = 0; + return true; +} + DECLARE_CRT_EXPORT("VirtualAlloc", VirtualAlloc); + DECLARE_CRT_EXPORT("VirtualProtect", VirtualProtect); + DECLARE_CRT_EXPORT("VirtualUnlock", VirtualUnlock); + DECLARE_CRT_EXPORT("VirtualFree", VirtualFree); + +DECLARE_CRT_EXPORT("GlobalMemoryStatusEx", GlobalMemoryStatusEx); diff --git a/peloader/winapi/NotImplemented.c b/peloader/winapi/NotImplemented.c new file mode 100644 index 0000000..482a775 --- /dev/null +++ b/peloader/winapi/NotImplemented.c @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include +#include + +#include "winnt_types.h" +#include "pe_linker.h" +#include "ntoskernel.h" +#include "log.h" +#include "winexports.h" +#include "util.h" + +/* Here goes all the APIs requested by GetProcAddress in order to quickly identify which one is being called and + * needs to be implemented + */ + +STATIC PVOID WINAPI AreFileApisANSI() { + DebugLog(""); + return 0; +} + +STATIC PVOID WINAPI CompareStringEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI EnumSystemLocalesEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetDateFormatEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetTimeFormatEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI IsValidLocaleName() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI LCIDToLocaleName() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI CancelSynchronousIo() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI CreateSymbolicLinkW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI DeleteProcThreadAttributeList() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI FindFirstFileNameW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI FindNextFileNameW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetFileInformationByHandleEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetFinalPathNameByHandleW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetFirmwareEnvironmentVariableA() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetFirmwareEnvironmentVariableExW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetFirmwareType() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetProcessInformation() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetThreadInformation() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI GetUserDefaultLocaleName() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI InitializeProcThreadAttributeList() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32EnumPageFilesW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32EnumProcessModules() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32EnumProcesses() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetMappedFileNameW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetModuleBaseNameW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetModuleFileNameExW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetModuleInformation() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetProcessImageFileNameW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32GetProcessMemoryInfo() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI K32QueryWorkingSetEx() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI PrefetchVirtualMemory() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI SetThreadInformation() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI TryAcquireSRWLockExclusive() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI UpdateProcThreadAttribute() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC long WINAPI EventRegister(PVOID ProviderId, + PVOID EnableCallback, + PVOID CallbackContext, + HANDLE RegHandle) { + DebugLog(""); + return 0; +} + +STATIC PVOID WINAPI EventWriteTransfer() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI NotifyServiceStatusChangeW() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI RegDisableReflectionKey() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI RegEnableReflectionKey() { + DebugLog("Not implemented."); + exit(1); +} + +STATIC PVOID WINAPI RegQueryReflectionKey() { + DebugLog("Not implemented."); + exit(1); +} + +DECLARE_CRT_EXPORT("AreFileApisANSI", AreFileApisANSI); +//DECLARE_CRT_EXPORT("CompareStringEx", CompareStringEx); +DECLARE_CRT_EXPORT("EnumSystemLocalesEx", EnumSystemLocalesEx); + +DECLARE_CRT_EXPORT("GetDateFormatEx", GetDateFormatEx); + +DECLARE_CRT_EXPORT("GetTimeFormatEx", GetTimeFormatEx); + +DECLARE_CRT_EXPORT("GetUserDefaultLocaleName", GetUserDefaultLocaleName); + +DECLARE_CRT_EXPORT("IsValidLocaleName", IsValidLocaleName); + +DECLARE_CRT_EXPORT("LCIDToLocaleName", LCIDToLocaleName); + +DECLARE_CRT_EXPORT("CancelSynchronousIo", CancelSynchronousIo); + +DECLARE_CRT_EXPORT("CreateSymbolicLinkW", CreateSymbolicLinkW); + +DECLARE_CRT_EXPORT("DeleteProcThreadAttributeList", DeleteProcThreadAttributeList); + +DECLARE_CRT_EXPORT("FindFirstFileNameW", FindFirstFileNameW); + +DECLARE_CRT_EXPORT("FindNextFileNameW", FindNextFileNameW); + +DECLARE_CRT_EXPORT("GetFileInformationByHandleEx", GetFileInformationByHandleEx); + +DECLARE_CRT_EXPORT("GetFinalPathNameByHandleW", GetFinalPathNameByHandleW); + +DECLARE_CRT_EXPORT("GetFirmwareEnvironmentVariableA", GetFirmwareEnvironmentVariableA); + +DECLARE_CRT_EXPORT("GetFirmwareEnvironmentVariableExW", GetFirmwareEnvironmentVariableExW); + +DECLARE_CRT_EXPORT("GetFirmwareType", GetFirmwareType); + +DECLARE_CRT_EXPORT("GetProcessInformation", GetProcessInformation); + +DECLARE_CRT_EXPORT("GetThreadInformation", GetThreadInformation); + +DECLARE_CRT_EXPORT("InitializeProcThreadAttributeList", InitializeProcThreadAttributeList); + +DECLARE_CRT_EXPORT("K32EnumPageFilesW", K32EnumPageFilesW); + +DECLARE_CRT_EXPORT("K32EnumProcessModules", K32EnumProcessModules); + +DECLARE_CRT_EXPORT("K32EnumProcesses", K32EnumProcesses); + +DECLARE_CRT_EXPORT("K32GetMappedFileNameW", K32GetMappedFileNameW); + +DECLARE_CRT_EXPORT("K32GetModuleBaseNameW", K32GetModuleBaseNameW); + +DECLARE_CRT_EXPORT("K32GetModuleFileNameExW", K32GetModuleFileNameExW); + +DECLARE_CRT_EXPORT("K32GetModuleInformation", K32GetModuleInformation); + +DECLARE_CRT_EXPORT("K32GetProcessImageFileNameW", K32GetProcessImageFileNameW); + +DECLARE_CRT_EXPORT("K32GetProcessMemoryInfo", K32GetProcessMemoryInfo); + +DECLARE_CRT_EXPORT("K32QueryWorkingSetEx", K32QueryWorkingSetEx); + +DECLARE_CRT_EXPORT("PrefetchVirtualMemory", PrefetchVirtualMemory); + +DECLARE_CRT_EXPORT("SetThreadInformation", SetThreadInformation); + +DECLARE_CRT_EXPORT("TryAcquireSRWLockExclusive", TryAcquireSRWLockExclusive); + +DECLARE_CRT_EXPORT("UpdateProcThreadAttribute", UpdateProcThreadAttribute); + +DECLARE_CRT_EXPORT("EventRegister", EventRegister); + +DECLARE_CRT_EXPORT("EventWriteTransfer", EventWriteTransfer); + +DECLARE_CRT_EXPORT("NotifyServiceStatusChangeW", NotifyServiceStatusChangeW); + +DECLARE_CRT_EXPORT("RegDisableReflectionKey", RegDisableReflectionKey); + +DECLARE_CRT_EXPORT("RegEnableReflectionKey", RegEnableReflectionKey); + +DECLARE_CRT_EXPORT("RegQueryReflectionKey", RegQueryReflectionKey); diff --git a/peloader/winapi/Ole.c b/peloader/winapi/Ole.c index 3d1186d..807e574 100644 --- a/peloader/winapi/Ole.c +++ b/peloader/winapi/Ole.c @@ -14,46 +14,45 @@ #include "util.h" #include "strings.h" -STATIC DWORD WINAPI CoCreateGuid(PVOID pguid) -{ +STATIC DWORD WINAPI CoCreateGuid(PVOID pguid) { DebugLog("%p", pguid); memcpy(pguid, "GUIDGUIDGUIDGUIDGUIDGUIDGUIDGUID", 16); return 0; } -STATIC DWORD CoCreateInstance(PVOID rclsid, PVOID pUnkOuter, DWORD dwClsContext, PVOID riid, PVOID *ppv) -{ +STATIC DWORD CoCreateInstance(PVOID rclsid, PVOID pUnkOuter, DWORD dwClsContext, PVOID riid, PVOID *ppv) { DebugLog("%p, %p, %u, %p, %p", rclsid, pUnkOuter, dwClsContext, riid, ppv); return -1; } -STATIC DWORD CoInitializeEx(PVOID pvReserved, DWORD dCwoInit) -{ +STATIC DWORD CoInitializeEx(PVOID pvReserved, DWORD dCwoInit) { DebugLog("%p, %u", pvReserved, dCwoInit); return -1; } -STATIC DWORD CoSetProxyBlanket(PVOID a) -{ +STATIC DWORD CoSetProxyBlanket(PVOID a) { DebugLog(""); return -1; } -STATIC DWORD CoUninitialize(PVOID a) -{ +STATIC DWORD CoUninitialize(PVOID a) { DebugLog(""); return -1; } -STATIC DWORD IIDFromString(PVOID a) -{ +STATIC DWORD IIDFromString(PVOID a) { DebugLog(""); return -1; } DECLARE_CRT_EXPORT("CoCreateGuid", CoCreateGuid); + DECLARE_CRT_EXPORT("CoCreateInstance", CoCreateInstance); + DECLARE_CRT_EXPORT("CoInitializeEx", CoInitializeEx); + DECLARE_CRT_EXPORT("CoSetProxyBlanket", CoSetProxyBlanket); + DECLARE_CRT_EXPORT("CoUninitialize", CoUninitialize); + DECLARE_CRT_EXPORT("IIDFromString", IIDFromString); diff --git a/peloader/winapi/Paths.c b/peloader/winapi/Paths.c index 6cb00ea..e3ab615 100644 --- a/peloader/winapi/Paths.c +++ b/peloader/winapi/Paths.c @@ -16,8 +16,7 @@ static const uint16_t kTempPath[] = L".\\FAKETEMP\\"; -DWORD WINAPI GetTempPathW(DWORD nBufferLength, PVOID lpBuffer) -{ +DWORD WINAPI GetTempPathW(DWORD nBufferLength, PVOID lpBuffer) { DebugLog("%u, %p", nBufferLength, lpBuffer); memcpy(lpBuffer, kTempPath, sizeof(kTempPath)); @@ -25,8 +24,7 @@ DWORD WINAPI GetTempPathW(DWORD nBufferLength, PVOID lpBuffer) return sizeof(kTempPath) - 2; } -DWORD WINAPI GetLogicalDrives(void) -{ +DWORD WINAPI GetLogicalDrives(void) { DebugLog(""); return 1 << 2; @@ -34,8 +32,7 @@ DWORD WINAPI GetLogicalDrives(void) #define DRIVE_FIXED 3 -UINT WINAPI GetDriveTypeW(PWCHAR lpRootPathName) -{ +UINT WINAPI GetDriveTypeW(PWCHAR lpRootPathName) { char *path = CreateAnsiFromWide(lpRootPathName); DebugLog("%p [%s]", lpRootPathName, path); free(path); @@ -44,8 +41,7 @@ UINT WINAPI GetDriveTypeW(PWCHAR lpRootPathName) DWORD WINAPI GetLongPathNameA(LPCSTR lpszShortPath, LPSTR lpszLongPath, - DWORD cchBuffer) -{ + DWORD cchBuffer) { // For now we just return the 8.3 format path as the long path if (cchBuffer > strlen(lpszShortPath)) { memcpy(lpszLongPath, lpszShortPath, sizeof(lpszShortPath)); @@ -56,8 +52,7 @@ DWORD WINAPI GetLongPathNameA(LPCSTR lpszShortPath, DWORD WINAPI GetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, - DWORD cchBuffer) -{ + DWORD cchBuffer) { // For now we just return the 8.3 format path as the long path if (cchBuffer > CountWideChars(lpszShortPath)) { memcpy(lpszLongPath, lpszShortPath, CountWideChars(lpszShortPath) * sizeof(WCHAR)); @@ -67,7 +62,11 @@ DWORD WINAPI GetLongPathNameW(LPCWSTR lpszShortPath, } DECLARE_CRT_EXPORT("GetTempPathW", GetTempPathW); + DECLARE_CRT_EXPORT("GetLogicalDrives", GetLogicalDrives); + DECLARE_CRT_EXPORT("GetDriveTypeW", GetDriveTypeW); + DECLARE_CRT_EXPORT("GetLongPathNameA", GetLongPathNameA); + DECLARE_CRT_EXPORT("GetLongPathNameW", GetLongPathNameW); diff --git a/peloader/winapi/Process.c b/peloader/winapi/Process.c index b28ed0a..ff0cc52 100644 --- a/peloader/winapi/Process.c +++ b/peloader/winapi/Process.c @@ -15,10 +15,43 @@ STATIC NTSTATUS WINAPI NtSetInformationProcess(HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, PVOID ProcessInformation, - ULONG ProcessInformationLength) -{ + ULONG ProcessInformationLength) { DebugLog("%p", ProcessHandle); return 0; } +STATIC BOOL WINAPI QueryFullProcessImageNameW(HANDLE hProcess, + DWORD dwFlags, + LPWSTR lpExeName, + PDWORD lpdwSize) { + DebugLog(""); + if (dwFlags == 0) + lpExeName = L"C:\\nice\\path\\to\\binary.exe"; + else + lpExeName = L"\\??\\C:\\nice\\path\\to\\binary.exe"; + return true; +} + +STATIC BOOL WINAPI GetProcessMitigationPolicy(HANDLE hProcess, + PROCESS_MITIGATION_POLICY MitigationPolicy, + PVOID lpBuffer, + SIZE_T dwLength) { + DebugLog("%p %hx %p", hProcess, MitigationPolicy, lpBuffer); + return true; +} + +STATIC BOOL WINAPI SetProcessInformation(HANDLE hProcess, + PROCESS_INFORMATION_CLASS ProcessInformationClass, + PVOID ProcessInformation, + DWORD ProcessInformationSize) { + DebugLog("%p %hx %p", hProcess, ProcessInformationClass, ProcessInformation); + return true; +} + +DECLARE_CRT_EXPORT("QueryFullProcessImageNameW", QueryFullProcessImageNameW); + DECLARE_CRT_EXPORT("NtSetInformationProcess", NtSetInformationProcess); + +DECLARE_CRT_EXPORT("GetProcessMitigationPolicy", GetProcessMitigationPolicy); + +DECLARE_CRT_EXPORT("SetProcessInformation", SetProcessInformation); diff --git a/peloader/winapi/ProcessThreads.c b/peloader/winapi/ProcessThreads.c index 726b33c..744716c 100644 --- a/peloader/winapi/ProcessThreads.c +++ b/peloader/winapi/ProcessThreads.c @@ -16,46 +16,38 @@ #include "util.h" #include "winstrings.h" -static PVOID WINAPI CreateThreadpoolTimer(PVOID pfnti, PVOID pv, PVOID pcbe) -{ +static PVOID WINAPI CreateThreadpoolTimer(PVOID pfnti, PVOID pv, PVOID pcbe) { // DebugLog("%p, %p, %p", pfnti, pv, pcbe); return (PVOID) 'POOL'; } -static VOID WINAPI InitializeSRWLock(PVOID SRWLock) -{ +static VOID WINAPI InitializeSRWLock(PVOID SRWLock) { DebugLog("%p", SRWLock); } -static VOID WINAPI SetThreadpoolTimer(PVOID pti, PVOID pftDueTime, DWORD msPeriod, DWORD msWindowLength) -{ +static VOID WINAPI SetThreadpoolTimer(PVOID pti, PVOID pftDueTime, DWORD msPeriod, DWORD msWindowLength) { DebugLog("%p, %p, %u, %u", pti, pftDueTime, msPeriod, msWindowLength); } -static VOID WINAPI WaitForThreadpoolTimerCallbacks(PVOID pti, BOOL fCancelPendingCallbacks) -{ +static VOID WINAPI WaitForThreadpoolTimerCallbacks(PVOID pti, BOOL fCancelPendingCallbacks) { DebugLog("%p, %u", pti, fCancelPendingCallbacks); } -static VOID WINAPI CloseThreadpoolTimer(PVOID pti) -{ +static VOID WINAPI CloseThreadpoolTimer(PVOID pti) { DebugLog("%p", pti); } -static LONG InterlockedDecrement(PULONG Addend) -{ +static LONG InterlockedDecrement(PULONG Addend) { DebugLog("%p", Addend); return --*Addend; } -static LONG InterlockedIncrement(PULONG Addend) -{ +static LONG InterlockedIncrement(PULONG Addend) { DebugLog("%p", Addend); return ++*Addend; } -static LONG InterlockedCompareExchange(PULONG Destination, LONG Exchange, LONG Comparand) -{ +static LONG InterlockedCompareExchange(PULONG Destination, LONG Exchange, LONG Comparand) { DebugLog("%p", Destination); if (*Destination == Comparand) { *Destination = Exchange; @@ -63,8 +55,8 @@ static LONG InterlockedCompareExchange(PULONG Destination, LONG Exchange, LONG C return *Destination; } -static HANDLE WINAPI CreateSemaphoreW(PVOID lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, PWCHAR lpName) -{ +static HANDLE WINAPI +CreateSemaphoreW(PVOID lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, PWCHAR lpName) { char *name; #ifndef NDEBUG name = CreateAnsiFromWide(lpName); @@ -76,66 +68,55 @@ static HANDLE WINAPI CreateSemaphoreW(PVOID lpSemaphoreAttributes, LONG lInitial return (HANDLE) 'SEMA'; } -static HANDLE WINAPI GetCurrentProcess(VOID) -{ +static HANDLE WINAPI GetCurrentProcess(VOID) { return (HANDLE) -1; } -static HANDLE WINAPI GetCurrentThread(VOID) -{ +static HANDLE WINAPI GetCurrentThread(VOID) { return (HANDLE) -1; } -static DWORD WINAPI GetCurrentThreadId(VOID) -{ +static DWORD WINAPI GetCurrentThreadId(VOID) { return getpid(); } -static DWORD WINAPI GetCurrentProcessId(VOID) -{ +static DWORD WINAPI GetCurrentProcessId(VOID) { return getpid(); } -static BOOL WINAPI RegisterWaitForSingleObject(PHANDLE phNewWaitObject, HANDLE hObject, PVOID Callback, PVOID Context, ULONG dwMilliseconds, ULONG dwFlags) -{ +static BOOL WINAPI RegisterWaitForSingleObject(PHANDLE phNewWaitObject, HANDLE hObject, PVOID Callback, PVOID Context, + ULONG dwMilliseconds, ULONG dwFlags) { DebugLog(""); return TRUE; } -static VOID WINAPI AcquireSRWLockExclusive(PVOID SRWLock) -{ +static VOID WINAPI AcquireSRWLockExclusive(PVOID SRWLock) { DebugLog("%p", SRWLock); } -static VOID WINAPI AcquireSRWLockShared(PVOID SRWLock) -{ +static VOID WINAPI AcquireSRWLockShared(PVOID SRWLock) { DebugLog("%p", SRWLock); } -static VOID WINAPI ReleaseSRWLockExclusive(PVOID SRWLock) -{ +static VOID WINAPI ReleaseSRWLockExclusive(PVOID SRWLock) { DebugLog("%p", SRWLock); } -static VOID WINAPI ReleaseSRWLockShared(PVOID SRWLock) -{ +static VOID WINAPI ReleaseSRWLockShared(PVOID SRWLock) { DebugLog("%p", SRWLock); } -static HANDLE WINAPI CreateMutexW(PVOID lpMutexAttributes, BOOL bInitialOwner, PWCHAR lpName) -{ +static HANDLE WINAPI CreateMutexW(PVOID lpMutexAttributes, BOOL bInitialOwner, PWCHAR lpName) { DebugLog("%p, %u, %p"); return INVALID_HANDLE_VALUE; } -static DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) -{ +static DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { DebugLog("%p, %u", hHandle, dwMilliseconds); return -1; } -static ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status) -{ +static ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status) { DebugLog("%#x", Status); return Status; } @@ -146,8 +127,7 @@ static BOOL WINAPI CreateTimerQueueTimer(PHANDLE phNewTimer, PVOID Parameter, DWORD DueTime, DWORD Period, - ULONG Flags) -{ + ULONG Flags) { DebugLog(""); return TRUE; } @@ -156,50 +136,68 @@ static BOOL WINAPI GetThreadTimes(HANDLE hThread, PFILETIME lpCreationTime, PFILETIME lpExitTime, PFILETIME lpKernelTime, - PFILETIME lpUserTime) -{ + PFILETIME lpUserTime) { DebugLog(""); return TRUE; } -static ULONG WINAPI RtlNtStatusToDosError(NTSTATUS Status) -{ +static ULONG WINAPI RtlNtStatusToDosError(NTSTATUS Status) { DebugLog("%#x", Status); return 5; } -static BOOL WINAPI SetThreadToken(PHANDLE Thread, HANDLE Token) -{ +static BOOL WINAPI SetThreadToken(PHANDLE Thread, HANDLE Token) { DebugLog(""); return FALSE; } -static BOOL WINAPI ProcessIdToSessionId(DWORD dwProcessId, DWORD *pSessionId) -{ +static BOOL WINAPI ProcessIdToSessionId(DWORD dwProcessId, DWORD *pSessionId) { DebugLog(""); return FALSE; } DECLARE_CRT_EXPORT("RtlNtStatusToDosError", RtlNtStatusToDosError); + DECLARE_CRT_EXPORT("GetThreadTimes", GetThreadTimes); + DECLARE_CRT_EXPORT("GetCurrentThread", GetCurrentThread); + DECLARE_CRT_EXPORT("CreateTimerQueueTimer", CreateTimerQueueTimer); + DECLARE_CRT_EXPORT("RegisterWaitForSingleObject", RegisterWaitForSingleObject); + DECLARE_CRT_EXPORT("WaitForSingleObject", WaitForSingleObject); + DECLARE_CRT_EXPORT("GetCurrentProcess", GetCurrentProcess); + DECLARE_CRT_EXPORT("LsaNtStatusToWinError", LsaNtStatusToWinError); + DECLARE_CRT_EXPORT("SetThreadToken", SetThreadToken); + DECLARE_CRT_EXPORT("InterlockedDecrement", InterlockedDecrement); + DECLARE_CRT_EXPORT("InterlockedIncrement", InterlockedIncrement); + DECLARE_CRT_EXPORT("InterlockedCompareExchange", InterlockedCompareExchange); + DECLARE_CRT_EXPORT("CreateSemaphoreW", CreateSemaphoreW); + DECLARE_CRT_EXPORT("AcquireSRWLockExclusive", AcquireSRWLockExclusive); + DECLARE_CRT_EXPORT("AcquireSRWLockShared", AcquireSRWLockShared); + DECLARE_CRT_EXPORT("InitializeSRWLock", InitializeSRWLock); + DECLARE_CRT_EXPORT("ReleaseSRWLockExclusive", ReleaseSRWLockExclusive); + DECLARE_CRT_EXPORT("ReleaseSRWLockShared", ReleaseSRWLockShared); + DECLARE_CRT_EXPORT("SetThreadpoolTimer", SetThreadpoolTimer); + DECLARE_CRT_EXPORT("WaitForThreadpoolTimerCallbacks", WaitForThreadpoolTimerCallbacks); + DECLARE_CRT_EXPORT("GetCurrentThreadId", GetCurrentThreadId); + DECLARE_CRT_EXPORT("GetCurrentProcessId", GetCurrentProcessId); + DECLARE_CRT_EXPORT("ProcessIdToSessionId", ProcessIdToSessionId); diff --git a/peloader/winapi/ProcessThreads.h b/peloader/winapi/ProcessThreads.h new file mode 100644 index 0000000..5d9798c --- /dev/null +++ b/peloader/winapi/ProcessThreads.h @@ -0,0 +1,6 @@ +#ifndef LOADLIBRARY_PROCESSTHREADS_H +#define LOADLIBRARY_PROCESSTHREADS_H + +VOID WINAPI AcquireSRWLockExclusive(PVOID SRWLock); + +#endif //LOADLIBRARY_PROCESSTHREADS_H diff --git a/peloader/winapi/Registry.c b/peloader/winapi/Registry.c index 5b8b86e..1d09602 100644 --- a/peloader/winapi/Registry.c +++ b/peloader/winapi/Registry.c @@ -17,21 +17,20 @@ typedef struct _KEY_VALUE_BASIC_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG NameLength; - WCHAR Name[1]; + ULONG TitleIndex; + ULONG Type; + ULONG NameLength; + WCHAR Name[1]; } KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION; typedef struct _KEY_VALUE_PARTIAL_INFORMATION { - ULONG TitleIndex; - ULONG Type; - ULONG DataLength; - UCHAR Data[1]; + ULONG TitleIndex; + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; } KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; -STATIC LONG WINAPI RegOpenKeyExW(HANDLE hKey, PVOID lpSubKey, DWORD ulOptions, DWORD samDesired, PHANDLE phkResult) -{ +STATIC LONG WINAPI RegOpenKeyExW(HANDLE hKey, PVOID lpSubKey, DWORD ulOptions, DWORD samDesired, PHANDLE phkResult) { LONG Result = -1; char *ansikey = CreateAnsiFromWide(lpSubKey); @@ -51,39 +50,59 @@ STATIC LONG WINAPI RegOpenKeyExW(HANDLE hKey, PVOID lpSubKey, DWORD ulOptions, D return Result; } -STATIC LONG WINAPI RegCloseKey(HANDLE hKey) -{ +STATIC LONG WINAPI RegCloseKey(HANDLE hKey) { DebugLog("%p"); return 0; } STATIC LONG WINAPI RegQueryInfoKeyW( - HANDLE hKey, - PWCHAR lpClass, - PDWORD lpcClass, - PDWORD lpReserved, - PDWORD lpcSubKeys, - PDWORD lpcMaxSubKeyLen, - PDWORD lpcMaxClassLen, - PDWORD lpcValues, - PDWORD lpcMaxValueNameLen, - PDWORD lpcMaxValueLen, - PDWORD lpcbSecurityDescriptor, - PVOID lpftLastWriteTime) -{ - DebugLog(""); - + HANDLE hKey, + PWCHAR lpClass, + PDWORD lpcClass, + PDWORD lpReserved, + PDWORD lpcSubKeys, + PDWORD lpcMaxSubKeyLen, + PDWORD lpcMaxClassLen, + PDWORD lpcValues, + PDWORD lpcMaxValueNameLen, + PDWORD lpcMaxValueLen, + PDWORD lpcbSecurityDescriptor, + PVOID lpftLastWriteTime) { + DebugLog("%p %p %p %p %p %p %p %p %p %p %p %p", hKey, lpClass, lpcClass, lpReserved, lpcSubKeys, lpcMaxSubKeyLen, lpcMaxClassLen, lpcValues, lpcMaxValueNameLen, lpcMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime); + +#ifdef __x86_64__ + if (lpClass || lpcClass || lpReserved || lpcSubKeys || lpcMaxSubKeyLen || lpcMaxClassLen || lpftLastWriteTime) { + DebugLog("NOT SUPPORTED"); + return -1; + } +#else if (lpClass || lpcClass || lpReserved || lpcSubKeys || lpcMaxSubKeyLen || lpcMaxClassLen || lpcMaxValueLen || lpcbSecurityDescriptor || lpftLastWriteTime) { DebugLog("NOT SUPPORTED"); return -1; } +#endif switch ((DWORD) hKey) { case 'REG0': +#ifdef __x86_64__ + *lpcValues = 0xc; + *lpcMaxValueNameLen = 0x1b; + break; +#endif case 'REG1': +#ifdef __x86_64__ + *lpcValues = 0xb; + *lpcMaxValueNameLen = 0x26; + break; +#endif case 'REG2': +#ifdef __x86_64__ + *lpcValues = 0x4; + *lpcMaxValueNameLen = 0x11; +#else *lpcValues = 1; *lpcMaxValueNameLen = 1024; +#endif break; default: DebugLog("NOT SUPPROTED KEY"); @@ -94,12 +113,12 @@ STATIC LONG WINAPI RegQueryInfoKeyW( } STATIC NTSTATUS WINAPI NtEnumerateValueKey( - HANDLE KeyHandle, - ULONG Index, - DWORD KeyValueInformationClass, - PKEY_VALUE_BASIC_INFORMATION KeyValueInformation, - ULONG Length, - PULONG ResultLength + HANDLE KeyHandle, + ULONG Index, + DWORD KeyValueInformationClass, + PKEY_VALUE_BASIC_INFORMATION KeyValueInformation, + ULONG Length, + PULONG ResultLength ) { DebugLog("%p, %u, %u, %p, %u, %p", KeyHandle, Index, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); @@ -110,19 +129,19 @@ STATIC NTSTATUS WINAPI NtEnumerateValueKey( switch ((DWORD) KeyHandle) { case 'REG1': - KeyValueInformation->Type = REG_SZ; + KeyValueInformation->Type = REG_SZ; KeyValueInformation->NameLength = sizeof(L"Common AppDatz") - 2; memcpy(&KeyValueInformation->Name[0], L"Common AppData", KeyValueInformation->NameLength); *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + KeyValueInformation->NameLength; break; case 'REG0': - KeyValueInformation->Type = REG_SZ; + KeyValueInformation->Type = REG_SZ; KeyValueInformation->NameLength = sizeof(L"Common AppDatz") - 2; memcpy(&KeyValueInformation->Name[0], L"Common AppData", KeyValueInformation->NameLength); *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + KeyValueInformation->NameLength; break; case 'REG2': - KeyValueInformation->Type = REG_SZ; + KeyValueInformation->Type = REG_SZ; KeyValueInformation->NameLength = sizeof(L"Common AppDatz") - 2; memcpy(&KeyValueInformation->Name[0], L"Common AppData", KeyValueInformation->NameLength); *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + KeyValueInformation->NameLength; @@ -136,14 +155,13 @@ STATIC NTSTATUS WINAPI NtEnumerateValueKey( } STATIC NTSTATUS WINAPI NtQueryValueKey( - HANDLE KeyHandle, - PVOID ValueName, - DWORD KeyValueInformationClass, - PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation, - ULONG Length, - PULONG ResultLength -) -{ + HANDLE KeyHandle, + PVOID ValueName, + DWORD KeyValueInformationClass, + PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation, + ULONG Length, + PULONG ResultLength +) { DebugLog("%p, %p, %u, %u, %u, %p", KeyHandle, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength); if (KeyValueInformationClass != 2) { @@ -178,26 +196,32 @@ STATIC NTSTATUS WINAPI NtQueryValueKey( return 0; } -STATIC LONG WINAPI RegCreateKeyExW(HANDLE hKey, PVOID lpSubKey, DWORD Reserved, PVOID lpClass, DWORD dwOptions, PVOID samDesired, PVOID lpSecurityAttributes, PVOID phkResult, PDWORD lpdwDisposition) -{ +STATIC LONG WINAPI +RegCreateKeyExW(HANDLE hKey, PVOID lpSubKey, DWORD Reserved, PVOID lpClass, DWORD dwOptions, PVOID samDesired, + PVOID lpSecurityAttributes, PVOID phkResult, PDWORD lpdwDisposition) { DebugLog("%p, %p, %#x, %p, %#x, %p, %p, %p, %p", - hKey, - lpSubKey, - Reserved, - lpClass, - dwOptions, - samDesired, - lpSecurityAttributes, - phkResult, - lpdwDisposition); + hKey, + lpSubKey, + Reserved, + lpClass, + dwOptions, + samDesired, + lpSecurityAttributes, + phkResult, + lpdwDisposition); return 0; } DECLARE_CRT_EXPORT("RegOpenKeyExW", RegOpenKeyExW); + DECLARE_CRT_EXPORT("RegCloseKey", RegCloseKey); + DECLARE_CRT_EXPORT("RegQueryInfoKeyW", RegQueryInfoKeyW); + DECLARE_CRT_EXPORT("NtEnumerateValueKey", NtEnumerateValueKey); + DECLARE_CRT_EXPORT("NtQueryValueKey", NtQueryValueKey); + DECLARE_CRT_EXPORT("RegCreateKeyExW", RegCreateKeyExW); diff --git a/peloader/winapi/Security.c b/peloader/winapi/Security.c index 62386b9..23accdf 100644 --- a/peloader/winapi/Security.c +++ b/peloader/winapi/Security.c @@ -12,8 +12,7 @@ #include "winexports.h" #include "util.h" -BOOL WINAPI LookupPrivilegeValueW(PVOID lpSystemName, PVOID lpName, PVOID lpLuid) -{ +BOOL WINAPI LookupPrivilegeValueW(PVOID lpSystemName, PVOID lpName, PVOID lpLuid) { DebugLog("%p, %p, %p", lpSystemName, lpName, lpLuid); return FALSE; diff --git a/peloader/winapi/Strings.c b/peloader/winapi/Strings.c index 05f9883..9252d4b 100644 --- a/peloader/winapi/Strings.c +++ b/peloader/winapi/Strings.c @@ -18,8 +18,9 @@ #define MB_ERR_INVALID_CHARS 8 #define MB_PRECOMPOSED 1 -STATIC int WINAPI MultiByteToWideChar(UINT CodePage, DWORD dwFlags, PCHAR lpMultiByteStr, int cbMultiByte, PUSHORT lpWideCharStr, int cchWideChar) -{ +STATIC int WINAPI +MultiByteToWideChar(UINT CodePage, DWORD dwFlags, PCHAR lpMultiByteStr, int cbMultiByte, PUSHORT lpWideCharStr, + int cchWideChar) { size_t i; DebugLog("%u, %#x, %p, %u, %p, %u", CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar); @@ -59,8 +60,9 @@ STATIC int WINAPI MultiByteToWideChar(UINT CodePage, DWORD dwFlags, PCHAR lpMul return i; } -STATIC int WINAPI WideCharToMultiByte(UINT CodePage, DWORD dwFlags, PVOID lpWideCharStr, int cchWideChar, PVOID lpMultiByteStr, int cbMultiByte, PVOID lpDefaultChar, PVOID lpUsedDefaultChar) -{ +STATIC int WINAPI +WideCharToMultiByte(UINT CodePage, DWORD dwFlags, PVOID lpWideCharStr, int cchWideChar, PVOID lpMultiByteStr, + int cbMultiByte, PVOID lpDefaultChar, PVOID lpUsedDefaultChar) { char *ansi = NULL; DebugLog("%u, %#x, %p, %d, %p, %d, %p, %p", CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); @@ -96,8 +98,7 @@ STATIC int WINAPI WideCharToMultiByte(UINT CodePage, DWORD dwFlags, PVOID lpWide return 0; } -STATIC BOOL WINAPI GetStringTypeA(DWORD locale, DWORD dwInfoType, PUSHORT lpSrcStr, int cchSrc, PUSHORT lpCharType) -{ +STATIC BOOL WINAPI GetStringTypeA(DWORD locale, DWORD dwInfoType, PUSHORT lpSrcStr, int cchSrc, PUSHORT lpCharType) { DebugLog("%u, %u, %p, %d, %p", locale, dwInfoType, lpSrcStr, cchSrc, lpCharType); memset(lpCharType, 1, cchSrc * sizeof(USHORT)); @@ -106,8 +107,7 @@ STATIC BOOL WINAPI GetStringTypeA(DWORD locale, DWORD dwInfoType, PUSHORT lpSrcS } -STATIC BOOL WINAPI GetStringTypeW(DWORD dwInfoType, PUSHORT lpSrcStr, int cchSrc, PUSHORT lpCharType) -{ +STATIC BOOL WINAPI GetStringTypeW(DWORD dwInfoType, PUSHORT lpSrcStr, int cchSrc, PUSHORT lpCharType) { DebugLog("%u, %p, %d, %p", dwInfoType, lpSrcStr, cchSrc, lpCharType); memset(lpCharType, 1, cchSrc * sizeof(USHORT)); @@ -115,15 +115,13 @@ STATIC BOOL WINAPI GetStringTypeW(DWORD dwInfoType, PUSHORT lpSrcStr, int cchSrc return FALSE; } -STATIC VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PWCHAR SourceString) -{ +STATIC VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PWCHAR SourceString) { DestinationString->Length = CountWideChars(SourceString) * 2; DestinationString->MaximumLength = DestinationString->Length; DestinationString->Buffer = SourceString; } -STATIC PVOID WINAPI UuidFromStringW(PUSHORT StringUuid, PBYTE Uuid) -{ +STATIC PVOID WINAPI UuidFromStringW(PUSHORT StringUuid, PBYTE Uuid) { int i; DebugLog("%S, %p", StringUuid, Uuid); @@ -135,8 +133,7 @@ STATIC PVOID WINAPI UuidFromStringW(PUSHORT StringUuid, PBYTE Uuid) return 0; } -STATIC INT WINAPI UuidCreate(PBYTE Uuid) -{ +STATIC INT WINAPI UuidCreate(PBYTE Uuid) { int i; DebugLog("%p", Uuid); @@ -148,11 +145,35 @@ STATIC INT WINAPI UuidCreate(PBYTE Uuid) return 0; } +STATIC int WINAPI CompareStringOrdinal(LPCWCH lpString1, + int cchCount1, + LPCWCH lpString2, + int cchCount2, + BOOL bIgnoreCase) { + char *string1 = CreateAnsiFromWide(lpString1); + char *string2 = CreateAnsiFromWide(lpString2); + DebugLog("%p [%s] %hhx %p [%s] %hhx", lpString1, string1, cchCount1, lpString2, string2, cchCount2); + + if (strlen(string1) < strlen(string2)) + return CSTR_LESS_THAN; + else if (strlen(string1) == strlen(string2)) + return CSTR_EQUAL; + else + return CSTR_GREATER_THAN; +} + DECLARE_CRT_EXPORT("MultiByteToWideChar", MultiByteToWideChar); + DECLARE_CRT_EXPORT("WideCharToMultiByte", WideCharToMultiByte); + DECLARE_CRT_EXPORT("GetStringTypeA", GetStringTypeA); + DECLARE_CRT_EXPORT("GetStringTypeW", GetStringTypeW); + DECLARE_CRT_EXPORT("RtlInitUnicodeString", RtlInitUnicodeString); + DECLARE_CRT_EXPORT("UuidFromStringW", UuidFromStringW); + DECLARE_CRT_EXPORT("UuidCreate", UuidCreate); +DECLARE_CRT_EXPORT("CompareStringOrdinal", CompareStringOrdinal); diff --git a/peloader/winapi/Sync.c b/peloader/winapi/Sync.c new file mode 100644 index 0000000..04c3dd4 --- /dev/null +++ b/peloader/winapi/Sync.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "winnt_types.h" +#include "pe_linker.h" +#include "ntoskernel.h" +#include "log.h" +#include "winexports.h" +#include "util.h" +#include "winstrings.h" + +typedef PRTL_RUN_ONCE LPINIT_ONCE; + +STATIC WINAPI BOOL InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, + DWORD dwFlags, + PBOOL fPending, + LPVOID *lpContext) { + + DebugLog("%p %hhx %p %p", lpInitOnce, dwFlags, fPending, lpContext); + + return true; +} + +DECLARE_CRT_EXPORT("InitOnceBeginInitialize", InitOnceBeginInitialize); diff --git a/peloader/winapi/SystemTime.c b/peloader/winapi/SystemTime.c index 26b65d7..98dd4ad 100644 --- a/peloader/winapi/SystemTime.c +++ b/peloader/winapi/SystemTime.c @@ -13,14 +13,14 @@ #include "util.h" typedef struct _SYSTEMTIME { - WORD wYear; - WORD wMonth; - WORD wDayOfWeek; - WORD wDay; - WORD wHour; - WORD wMinute; - WORD wSecond; - WORD wMilliseconds; + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; } SYSTEMTIME, *PSYSTEMTIME; extern void WINAPI SetLastError(DWORD dwErrCode); @@ -28,32 +28,27 @@ extern void WINAPI SetLastError(DWORD dwErrCode); // These routines are called to check if signing certificates have expired, so // should return similar values. -STATIC VOID WINAPI GetSystemTime(PSYSTEMTIME lpSystemTime) -{ +STATIC VOID WINAPI GetSystemTime(PSYSTEMTIME lpSystemTime) { memset(lpSystemTime, 0, sizeof(SYSTEMTIME)); return; } -STATIC BOOL WINAPI SystemTimeToFileTime(SYSTEMTIME *lpSystemTime, PFILETIME lpFileTime) -{ +STATIC BOOL WINAPI SystemTimeToFileTime(SYSTEMTIME *lpSystemTime, PFILETIME lpFileTime) { memset(lpFileTime, 0, sizeof(FILETIME)); return TRUE; } -STATIC VOID WINAPI GetSystemTimePreciseAsFileTime(PFILETIME lpSystemTimeAsFileTime) -{ +STATIC VOID WINAPI GetSystemTimePreciseAsFileTime(PFILETIME lpSystemTimeAsFileTime) { memset(lpSystemTimeAsFileTime, 0, sizeof(FILETIME)); return; } -STATIC VOID WINAPI GetSystemTimeAsFileTime(PVOID lpSystemTimeAsFileTime) -{ +STATIC VOID WINAPI GetSystemTimeAsFileTime(PVOID lpSystemTimeAsFileTime) { memset(lpSystemTimeAsFileTime, 0, sizeof(FILETIME)); return; } -STATIC BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) -{ +STATIC BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) { struct timespec tm; DebugLog(""); @@ -67,18 +62,15 @@ STATIC BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) return TRUE; } -STATIC DWORD WINAPI GetTickCount(VOID) -{ +STATIC DWORD WINAPI GetTickCount(VOID) { return 0; } -STATIC ULONGLONG WINAPI GetTickCount64(VOID) -{ +STATIC ULONGLONG WINAPI GetTickCount64(VOID) { return 0; } -STATIC BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) -{ +STATIC BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) { struct timespec tm; DebugLog(""); @@ -93,33 +85,42 @@ STATIC BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) return TRUE; } -STATIC BOOL WINAPI GetProcessTimes(HANDLE hProcess, PFILETIME lpCreationTime, PFILETIME lpExitTime, PFILETIME lpKernelTime, PFILETIME lpUserTime) -{ +STATIC BOOL WINAPI +GetProcessTimes(HANDLE hProcess, PFILETIME lpCreationTime, PFILETIME lpExitTime, PFILETIME lpKernelTime, + PFILETIME lpUserTime) { SetLastError(0); DebugLog(""); return FALSE; } -STATIC BOOL WINAPI DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, PFILETIME lpFileTime) -{ +STATIC BOOL WINAPI DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, PFILETIME lpFileTime) { DebugLog(""); return FALSE; } -STATIC BOOL WINAPI FileTimeToSystemTime(PFILETIME lpFileTime, PSYSTEMTIME lpSystemTime) -{ +STATIC BOOL WINAPI FileTimeToSystemTime(PFILETIME lpFileTime, PSYSTEMTIME lpSystemTime) { DebugLog(""); return FALSE; } DECLARE_CRT_EXPORT("GetSystemTime", GetSystemTime); + DECLARE_CRT_EXPORT("SystemTimeToFileTime", SystemTimeToFileTime); + DECLARE_CRT_EXPORT("GetSystemTimePreciseAsFileTime", GetSystemTimePreciseAsFileTime); + DECLARE_CRT_EXPORT("GetSystemTimeAsFileTime", GetSystemTimeAsFileTime); + DECLARE_CRT_EXPORT("QueryPerformanceCounter", QueryPerformanceCounter); + DECLARE_CRT_EXPORT("QueryPerformanceFrequency", QueryPerformanceFrequency); + DECLARE_CRT_EXPORT("GetTickCount", GetTickCount); + DECLARE_CRT_EXPORT("GetTickCount64", GetTickCount64); + DECLARE_CRT_EXPORT("GetProcessTimes", GetProcessTimes); + DECLARE_CRT_EXPORT("DosDateTimeToFileTime", DosDateTimeToFileTime); + DECLARE_CRT_EXPORT("FileTimeToSystemTime", FileTimeToSystemTime); diff --git a/peloader/winapi/Threads.c b/peloader/winapi/Threads.c index ad2f512..51ee3c4 100644 --- a/peloader/winapi/Threads.c +++ b/peloader/winapi/Threads.c @@ -15,101 +15,176 @@ #include "util.h" #include "winstrings.h" -static __stdcall PVOID CreateThreadPoolWait(PVOID pwa) -{ +static WINAPI PVOID CreateThreadPoolWait(PVOID pwa) { DebugLog(""); return (PVOID) 0x41414141; } -static __stdcall PVOID CreateThreadPool(PVOID reserved) -{ +static WINAPI PVOID CreateThreadPool(PVOID reserved) { DebugLog(""); return (PVOID) 0x41414141; } -static __stdcall PVOID CreateThreadpoolTimer(PVOID pfnti, PVOID pv, PVOID pcbe) -{ +static WINAPI PVOID CreateThreadpoolTimer(PVOID pfnti, PVOID pv, PVOID pcbe) { DebugLog(""); return (PVOID) 0x41414141; } -static __stdcall PVOID CreateThreadpoolWork(PVOID pfnwk, PVOID pv, PVOID pcbe) -{ +static WINAPI PVOID CreateThreadpoolWork(PVOID pfnwk, PVOID pv, PVOID pcbe) { DebugLog(""); return (PVOID) 0x41414141; } -static __stdcall void CloseThreadpoolTimer(PVOID pti) -{ +static WINAPI void CloseThreadpoolTimer(PVOID pti) { DebugLog("%p", pti); } -static __stdcall void InitializeConditionVariable(PVOID ConditionVariable) -{ +static WINAPI void InitializeConditionVariable(PVOID ConditionVariable) { DebugLog("%p", ConditionVariable); } -static __stdcall BOOL SleepConditionVariableCS(PVOID ConditionVariable, - PVOID CriticalSection, - DWORD dwMilliseconds) -{ +static WINAPI BOOL SleepConditionVariableCS(PVOID ConditionVariable, + PVOID CriticalSection, + DWORD dwMilliseconds) { DebugLog("%p %p %u", ConditionVariable, CriticalSection, dwMilliseconds); return TRUE; } -static __stdcall void WakeAllConditionVariable(PVOID ConditionVariable) -{ +static WINAPI void WakeAllConditionVariable(PVOID ConditionVariable) { DebugLog("%p", ConditionVariable); } -static __stdcall PVOID CreateThreadpoolWait() { DebugLog(""); return NULL; } -static __stdcall PVOID SetThreadpoolWait() { DebugLog(""); return NULL; } -static __stdcall PVOID SubmitThreadpoolWork() { DebugLog(""); return NULL; } -static __stdcall PVOID CancelThreadpoolIo() { DebugLog(""); return NULL; } -static __stdcall PVOID CloseThreadpool() { DebugLog(""); return NULL; } -static __stdcall PVOID CloseThreadpoolIo() { DebugLog(""); return NULL; } -static __stdcall PVOID CloseThreadpoolWait() { DebugLog(""); return NULL; } -static __stdcall void CloseThreadpoolWork(PVOID pwk) -{ +static WINAPI PVOID CreateThreadpoolWait() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID SetThreadpoolWait() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID SubmitThreadpoolWork() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID CancelThreadpoolIo() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID CloseThreadpool() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID CloseThreadpoolIo() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID CloseThreadpoolWait() { + DebugLog(""); + return NULL; +} + +static WINAPI void CloseThreadpoolWork(PVOID pwk) { DebugLog("%p", pwk); } -static __stdcall PVOID CreateThreadpool() { DebugLog(""); return NULL; } -static __stdcall PVOID CreateThreadpoolIo() { DebugLog(""); return NULL; } -static __stdcall PVOID SetThreadpoolThreadMaximum() { DebugLog(""); return NULL; } -static __stdcall PVOID SetThreadpoolThreadMinimum() { DebugLog(""); return NULL; } -static __stdcall PVOID StartThreadpoolIo() { DebugLog(""); return NULL; } -static __stdcall PVOID WaitForThreadpoolIoCallbacks() { DebugLog(""); return NULL; } -static __stdcall PVOID WaitForThreadpoolWaitCallbacks() { DebugLog(""); return NULL; } -static __stdcall void WaitForThreadpoolWorkCallbacks(PVOID pwk, BOOL fCancelPendingCallbacks) -{ +static WINAPI PVOID CreateThreadpool() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID CreateThreadpoolIo() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID SetThreadpoolThreadMaximum() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID SetThreadpoolThreadMinimum() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID StartThreadpoolIo() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID WaitForThreadpoolIoCallbacks() { + DebugLog(""); + return NULL; +} + +static WINAPI PVOID WaitForThreadpoolWaitCallbacks() { + DebugLog(""); + return NULL; +} + +static WINAPI void WaitForThreadpoolWorkCallbacks(PVOID pwk, BOOL fCancelPendingCallbacks) { DebugLog("%p %d", pwk, fCancelPendingCallbacks); } +static WINAPI void name() { + DebugLog(""); + __debugbreak(); +} + DECLARE_CRT_EXPORT("CreateThreadPoolWait", CreateThreadPoolWait); + DECLARE_CRT_EXPORT("CreateThreadPool", CreateThreadPool); + DECLARE_CRT_EXPORT("InitializeConditionVariable", InitializeConditionVariable); + DECLARE_CRT_EXPORT("SleepConditionVariableCS", SleepConditionVariableCS); + DECLARE_CRT_EXPORT("WakeAllConditionVariable", WakeAllConditionVariable); DECLARE_CRT_EXPORT("CreateThreadpoolTimer", CreateThreadpoolTimer); + DECLARE_CRT_EXPORT("CloseThreadpoolTimer", CloseThreadpoolTimer); + DECLARE_CRT_EXPORT("CreateThreadpoolWait", CreateThreadpoolWait); + DECLARE_CRT_EXPORT("SetThreadpoolWait", SetThreadpoolWait); + DECLARE_CRT_EXPORT("CloseThreadpoolWait", CloseThreadpoolWait); + DECLARE_CRT_EXPORT("CreateThreadpoolWork", CreateThreadpoolWork); + DECLARE_CRT_EXPORT("SubmitThreadpoolWork", SubmitThreadpoolWork); + DECLARE_CRT_EXPORT("CancelThreadpoolIo", CancelThreadpoolIo); + DECLARE_CRT_EXPORT("CloseThreadpool", CloseThreadpool); + DECLARE_CRT_EXPORT("CloseThreadpoolIo", CloseThreadpoolIo); + DECLARE_CRT_EXPORT("CloseThreadpoolWork", CloseThreadpoolWork); + DECLARE_CRT_EXPORT("CreateThreadpool", CreateThreadpool); + DECLARE_CRT_EXPORT("CreateThreadpoolIo", CreateThreadpoolIo); + DECLARE_CRT_EXPORT("SetThreadpoolThreadMaximum", SetThreadpoolThreadMaximum); + DECLARE_CRT_EXPORT("SetThreadpoolThreadMinimum", SetThreadpoolThreadMinimum); + DECLARE_CRT_EXPORT("StartThreadpoolIo", StartThreadpoolIo); + DECLARE_CRT_EXPORT("WaitForThreadpoolIoCallbacks", WaitForThreadpoolIoCallbacks); + DECLARE_CRT_EXPORT("WaitForThreadpoolWaitCallbacks", WaitForThreadpoolWaitCallbacks); + DECLARE_CRT_EXPORT("WaitForThreadpoolWorkCallbacks", WaitForThreadpoolWorkCallbacks); + +DECLARE_CRT_EXPORT("name", name); diff --git a/peloader/winapi/TlsAlloc.c b/peloader/winapi/TlsAlloc.c index 17e506a..ab813f9 100644 --- a/peloader/winapi/TlsAlloc.c +++ b/peloader/winapi/TlsAlloc.c @@ -1,4 +1,3 @@ - #include #include #include @@ -21,8 +20,8 @@ static int TlsIndex = 1; extern uintptr_t LocalStorage[1024]; extern PFLS_CALLBACK_FUNCTION FlsCallbacks[1024]; -STATIC DWORD WINAPI TlsAlloc(void) -{ + +STATIC DWORD WINAPI TlsAlloc(void) { if (TlsIndex >= ARRAY_SIZE(LocalStorage) - 1) { DebugLog("TlsAlloc() => %#x", TlsIndex); return TLS_OUT_OF_INDEXES; @@ -31,8 +30,7 @@ STATIC DWORD WINAPI TlsAlloc(void) return TlsIndex++; } -STATIC BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, PVOID lpTlsValue) -{ +STATIC BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, PVOID lpTlsValue) { DebugLog("TlsSetValue(%u, %p)", dwTlsIndex, lpTlsValue); if (dwTlsIndex < ARRAY_SIZE(LocalStorage)) { @@ -44,8 +42,7 @@ STATIC BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, PVOID lpTlsValue) return FALSE; } -STATIC DWORD WINAPI TlsGetValue(DWORD dwTlsIndex) -{ +STATIC PVOID WINAPI TlsGetValue(DWORD dwTlsIndex) { if (dwTlsIndex < ARRAY_SIZE(LocalStorage)) { return LocalStorage[dwTlsIndex]; } @@ -53,8 +50,7 @@ STATIC DWORD WINAPI TlsGetValue(DWORD dwTlsIndex) return 0; } -STATIC BOOL WINAPI TlsFree(DWORD dwTlsIndex) -{ +STATIC BOOL WINAPI TlsFree(DWORD dwTlsIndex) { if (dwTlsIndex < ARRAY_SIZE(LocalStorage)) { LocalStorage[dwTlsIndex] = (uintptr_t) NULL; return TRUE; @@ -63,8 +59,7 @@ STATIC BOOL WINAPI TlsFree(DWORD dwTlsIndex) return FALSE; } -static DWORD WINAPI FlsAlloc(PVOID lpCallback) -{ +static DWORD WINAPI FlsAlloc(PVOID lpCallback) { DWORD Result; DebugLog("%p", lpCallback); @@ -76,37 +71,44 @@ static DWORD WINAPI FlsAlloc(PVOID lpCallback) return Result; } -static DWORD WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData) -{ +static DWORD WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData) { DebugLog("%#x, %p", dwFlsIndex, lpFlsData); return TlsSetValue(dwFlsIndex, lpFlsData); } -static DWORD WINAPI FlsGetValue(DWORD dwFlsIndex) -{ +static PVOID WINAPI FlsGetValue(DWORD dwFlsIndex) { DebugLog("%#x", dwFlsIndex); - return TlsGetValue(dwFlsIndex); + if (dwFlsIndex < ARRAY_SIZE(LocalStorage)) { + return LocalStorage[dwFlsIndex]; + } + + return 0; } -static BOOL WINAPI FlsFree(DWORD dwFlsIndex) -{ +static BOOL WINAPI FlsFree(DWORD dwFlsIndex) { DebugLog("%#x", dwFlsIndex); if (FlsCallbacks[dwFlsIndex]) { - FlsCallbacks[dwFlsIndex]((PVOID)(TlsGetValue(dwFlsIndex))); + FlsCallbacks[dwFlsIndex]((PVOID) (TlsGetValue(dwFlsIndex))); } return TlsFree(dwFlsIndex); } DECLARE_CRT_EXPORT("TlsFree", TlsFree); + DECLARE_CRT_EXPORT("TlsAlloc", TlsAlloc); + DECLARE_CRT_EXPORT("TlsSetValue", TlsSetValue); + DECLARE_CRT_EXPORT("TlsGetValue", TlsGetValue); DECLARE_CRT_EXPORT("FlsFree", FlsFree); + DECLARE_CRT_EXPORT("FlsAlloc", FlsAlloc); + DECLARE_CRT_EXPORT("FlsSetValue", FlsSetValue); + DECLARE_CRT_EXPORT("FlsGetValue", FlsGetValue); diff --git a/peloader/winapi/TlsAlloc.h b/peloader/winapi/TlsAlloc.h new file mode 100644 index 0000000..51437cc --- /dev/null +++ b/peloader/winapi/TlsAlloc.h @@ -0,0 +1,13 @@ +#ifndef LOADLIBRARY_TLSALLOC_H +#define LOADLIBRARY_TLSALLOC_H + +DWORD WINAPI TlsAlloc(void); +BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, PVOID lpTlsValue); +DWORD WINAPI TlsGetValue(DWORD dwTlsIndex); +BOOL WINAPI TlsFree(DWORD dwTlsIndex); +DWORD WINAPI FlsAlloc(PVOID lpCallback); +DWORD WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData); +DWORD WINAPI FlsGetValue(DWORD dwFlsIndex); +BOOL WINAPI FlsFree(DWORD dwFlsIndex); + +#endif //LOADLIBRARY_TLSALLOC_H diff --git a/peloader/winapi/Version.c b/peloader/winapi/Version.c index fc40205..7dbe968 100644 --- a/peloader/winapi/Version.c +++ b/peloader/winapi/Version.c @@ -13,41 +13,40 @@ #include "util.h" typedef struct _OSVERSIONINFOEXW { - ULONG dwOSVersionInfoSize; - ULONG dwMajorVersion; - ULONG dwMinorVersion; - ULONG dwBuildNumber; - ULONG dwPlatformId; - WCHAR szCSDVersion[128]; + ULONG dwOSVersionInfoSize; + ULONG dwMajorVersion; + ULONG dwMinorVersion; + ULONG dwBuildNumber; + ULONG dwPlatformId; + WCHAR szCSDVersion[128]; USHORT wServicePackMajor; USHORT wServicePackMinor; USHORT wSuiteMask; - UCHAR wProductType; - UCHAR wReserved; + UCHAR wProductType; + UCHAR wReserved; } RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW; typedef struct _SYSTEM_INFO { - WORD wProcessorArchitecture; - WORD wReserved; - DWORD dwPageSize; - PVOID lpMinimumApplicationAddress; - PVOID lpMaximumApplicationAddress; - PVOID dwActiveProcessorMask; - DWORD dwNumberOfProcessors; - DWORD dwProcessorType; - DWORD dwAllocationGranularity; - WORD wProcessorLevel; - WORD wProcessorRevision; + WORD wProcessorArchitecture; + WORD wReserved; + DWORD dwPageSize; + PVOID lpMinimumApplicationAddress; + PVOID lpMaximumApplicationAddress; + PVOID dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; } SYSTEM_INFO, *LPSYSTEM_INFO; -static DWORD WINAPI RtlGetVersion(PRTL_OSVERSIONINFOEXW lpVersionInformation) -{ - if (lpVersionInformation->dwOSVersionInfoSize == sizeof (RTL_OSVERSIONINFOEXW)) { +static DWORD WINAPI RtlGetVersion(PRTL_OSVERSIONINFOEXW lpVersionInformation) { + if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) { DebugLog("%p (RTL_OSVERSIONINFOEXW)", lpVersionInformation); } else { DebugLog("%p (%u dwOSVersionInfoSize)", - lpVersionInformation, - lpVersionInformation->dwOSVersionInfoSize); + lpVersionInformation, + lpVersionInformation->dwOSVersionInfoSize); } // Windows XP @@ -59,16 +58,18 @@ static DWORD WINAPI RtlGetVersion(PRTL_OSVERSIONINFOEXW lpVersionInformation) #define PROCESSOR_ARCHITECTURE_INTEL 0 -static VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) -{ +static VOID WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) { DebugLog("%p", lpSystemInfo); lpSystemInfo->wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; lpSystemInfo->dwPageSize = 0x1000; } -static DWORD GetSystemDefaultLCID(void) -{ +static VOID WINAPI GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { + return GetSystemInfo(lpSystemInfo); +} + +static DWORD WINAPI GetSystemDefaultLCID(void) { DebugLog(""); return 0x0800; // I dunno } @@ -76,16 +77,14 @@ static DWORD GetSystemDefaultLCID(void) static NTSTATUS WINAPI NtQuerySystemInformation(DWORD SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, - PULONG ReturnLength) -{ + PULONG ReturnLength) { DebugLog(""); return -1; } static BOOL WINAPI GetComputerNameExW(DWORD NameType, PWCHAR lpBuffer, - PDWORD lpnSize) -{ + PDWORD lpnSize) { DebugLog(""); return FALSE; } @@ -94,31 +93,38 @@ static BOOL WINAPI GetProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, - PDWORD pdwReturnedProductType) -{ + PDWORD pdwReturnedProductType) { + // TODO: reformat all the debuglog DebugLog(""); *pdwReturnedProductType = 6; return TRUE; } -static DWORD WINAPI GetVersion(void) -{ +static DWORD WINAPI GetVersion(void) { DebugLog(""); return 0x80000000; } -static DWORD WINAPI GetVersionExA(PRTL_OSVERSIONINFOEXW lpVersionInformation) -{ +static DWORD WINAPI GetVersionExA(PRTL_OSVERSIONINFOEXW lpVersionInformation) { DebugLog(""); return TRUE; } DECLARE_CRT_EXPORT("GetVersion", GetVersion); + DECLARE_CRT_EXPORT("GetVersionExA", GetVersionExA); + DECLARE_CRT_EXPORT("RtlGetVersion", RtlGetVersion); + DECLARE_CRT_EXPORT("GetSystemInfo", GetSystemInfo); + +DECLARE_CRT_EXPORT("GetNativeSystemInfo", GetNativeSystemInfo); + DECLARE_CRT_EXPORT("GetSystemDefaultLCID", GetSystemDefaultLCID); + DECLARE_CRT_EXPORT("NtQuerySystemInformation", NtQuerySystemInformation); + DECLARE_CRT_EXPORT("GetComputerNameExW", GetComputerNameExW); + DECLARE_CRT_EXPORT("GetProductInfo", GetProductInfo); diff --git a/peloader/winapi/Wer.c b/peloader/winapi/Wer.c index b052164..21d52c7 100644 --- a/peloader/winapi/Wer.c +++ b/peloader/winapi/Wer.c @@ -13,8 +13,7 @@ #include "util.h" HRESULT WINAPI WerRegisterMemoryBlock(PVOID pvAddress, - DWORD dwSize) -{ + DWORD dwSize) { DebugLog("%p, %d", pvAddress, dwSize); return 0; } diff --git a/peloader/winapi/WinTrust.c b/peloader/winapi/WinTrust.c index a8ddcb3..549c079 100644 --- a/peloader/winapi/WinTrust.c +++ b/peloader/winapi/WinTrust.c @@ -13,34 +13,71 @@ #include "winexports.h" #include "util.h" -STATIC WINAPI BOOL CryptCATAdminAcquireContext(PVOID phCatAdmin, PVOID pgSubsystem, DWORD dwFlags) -{ +STATIC WINAPI BOOL CryptCATAdminAcquireContext(PVOID phCatAdmin, PVOID pgSubsystem, DWORD dwFlags) { DebugLog("%p, %p, %#x", phCatAdmin, pgSubsystem, dwFlags); return TRUE; } -STATIC WINAPI HANDLE CryptCATAdminEnumCatalogFromHash(HANDLE hCatAdmin, BYTE *pbHash, DWORD cbHash, DWORD dwFlags, PVOID phPrevCatInfo) -{ +STATIC WINAPI HANDLE +CryptCATAdminEnumCatalogFromHash(HANDLE hCatAdmin, BYTE *pbHash, DWORD cbHash, DWORD dwFlags, PVOID phPrevCatInfo) { DebugLog("%p, %p, %u, %#x, %p", hCatAdmin, pbHash, cbHash, dwFlags, phPrevCatInfo); return NULL; } -STATIC BOOL CryptCATAdminCalcHashFromFileHandle(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL CryptCATAdminReleaseCatalogContext(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL CryptCATAdminReleaseContext(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL CryptCATCatalogInfoFromContext(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL WTHelperGetProvCertFromChain(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL WTHelperGetProvSignerFromChain(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL WTHelperProvDataFromStateData(VOID) { DebugLog("FIXME"); return 0; } -STATIC BOOL WinVerifyTrust(VOID) { DebugLog("FIXME"); return 0; } +STATIC BOOL CryptCATAdminCalcHashFromFileHandle(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL CryptCATAdminReleaseCatalogContext(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL CryptCATAdminReleaseContext(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL CryptCATCatalogInfoFromContext(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL WTHelperGetProvCertFromChain(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL WTHelperGetProvSignerFromChain(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL WTHelperProvDataFromStateData(VOID) { + DebugLog("FIXME"); + return 0; +} + +STATIC BOOL WinVerifyTrust(VOID) { + DebugLog("FIXME"); + return 0; +} DECLARE_CRT_EXPORT("CryptCATAdminAcquireContext", CryptCATAdminAcquireContext); + DECLARE_CRT_EXPORT("CryptCATAdminCalcHashFromFileHandle", CryptCATAdminCalcHashFromFileHandle); + DECLARE_CRT_EXPORT("CryptCATAdminEnumCatalogFromHash", CryptCATAdminEnumCatalogFromHash); + DECLARE_CRT_EXPORT("CryptCATAdminReleaseCatalogContext", CryptCATAdminReleaseCatalogContext); + DECLARE_CRT_EXPORT("CryptCATAdminReleaseContext", CryptCATAdminReleaseContext); + DECLARE_CRT_EXPORT("CryptCATCatalogInfoFromContext", CryptCATCatalogInfoFromContext); + DECLARE_CRT_EXPORT("WTHelperGetProvCertFromChain", WTHelperGetProvCertFromChain); -DECLARE_CRT_EXPORT("WTHelperGetProvSignerFromChain", WTHelperGetProvSignerFromChain); +//DECLARE_CRT_EXPORT("WTHelperGetProvSignerFromChain", WTHelperGetProvSignerFromChain); DECLARE_CRT_EXPORT("WTHelperProvDataFromStateData", WTHelperProvDataFromStateData); + DECLARE_CRT_EXPORT("WinVerifyTrust", WinVerifyTrust); diff --git a/peloader/winapi/rtlbitmap.c b/peloader/winapi/rtlbitmap.c index 9503c8e..8a43dbf 100644 --- a/peloader/winapi/rtlbitmap.c +++ b/peloader/winapi/rtlbitmap.c @@ -48,21 +48,21 @@ #define FIXME DebugLog /* Bits set from LSB to MSB; used as mask for runs < 8 bits */ -static const BYTE NTDLL_maskBits[8] = { 0, 1, 3, 7, 15, 31, 63, 127 }; +static const BYTE NTDLL_maskBits[8] = {0, 1, 3, 7, 15, 31, 63, 127}; /* Number of set bits for each value of a nibble; used for counting */ static const BYTE NTDLL_nibbleBitCount[16] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; /* First set bit in a nibble; used for determining least significant bit */ static const BYTE NTDLL_leastSignificant[16] = { - 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; /* Last set bit in a nibble; used for determining most significant bit */ static const signed char NTDLL_mostSignificant[16] = { - -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 + -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 }; /************************************************************************* @@ -82,11 +82,10 @@ static const signed char NTDLL_mostSignificant[16] = { * lpBuff must be aligned on a ULONG suitable boundary, to a multiple of 32 bytes * in size (irrespective of ulSize given). */ -VOID WINAPI RtlInitializeBitMap(PRTL_BITMAP lpBits, PULONG lpBuff, ULONG ulSize) -{ - TRACE("(%p,%p,%u)\n", lpBits,lpBuff,ulSize); - lpBits->SizeOfBitMap = ulSize; - lpBits->Buffer = (PVOID) lpBuff; +VOID WINAPI RtlInitializeBitMap(PRTL_BITMAP lpBits, PULONG lpBuff, ULONG ulSize) { + TRACE("(%p,%p,%u)\n", lpBits, lpBuff, ulSize); + lpBits->SizeOfBitMap = ulSize; + lpBits->Buffer = (PVOID) lpBuff; } /************************************************************************* @@ -100,10 +99,9 @@ VOID WINAPI RtlInitializeBitMap(PRTL_BITMAP lpBits, PULONG lpBuff, ULONG ulSize) * RETURNS * Nothing. */ -VOID WINAPI RtlSetAllBits(PRTL_BITMAP lpBits) -{ - TRACE("(%p)\n", lpBits); - memset(lpBits->Buffer, 0xff, ((lpBits->SizeOfBitMap + 31) & ~31) >> 3); +VOID WINAPI RtlSetAllBits(PRTL_BITMAP lpBits) { + TRACE("(%p)\n", lpBits); + memset(lpBits->Buffer, 0xff, ((lpBits->SizeOfBitMap + 31) & ~31) >> 3); } /************************************************************************* @@ -117,10 +115,9 @@ VOID WINAPI RtlSetAllBits(PRTL_BITMAP lpBits) * RETURNS * Nothing. */ -VOID WINAPI RtlClearAllBits(PRTL_BITMAP lpBits) -{ - TRACE("(%p)\n", lpBits); - memset(lpBits->Buffer, 0, ((lpBits->SizeOfBitMap + 31) & ~31) >> 3); +VOID WINAPI RtlClearAllBits(PRTL_BITMAP lpBits) { + TRACE("(%p)\n", lpBits); + memset(lpBits->Buffer, 0, ((lpBits->SizeOfBitMap + 31) & ~31) >> 3); } /************************************************************************* @@ -136,52 +133,46 @@ VOID WINAPI RtlClearAllBits(PRTL_BITMAP lpBits) * RETURNS * Nothing. */ -VOID WINAPI RtlSetBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) -{ - LPBYTE lpOut; - - TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); - - if (!lpBits || !ulCount || - ulStart >= lpBits->SizeOfBitMap || - ulCount > lpBits->SizeOfBitMap - ulStart) - return; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - /* Set bits in first byte, if ulStart isn't a byte boundary */ - if (ulStart & 7) - { - if (ulCount > 7) - { - /* Set from start bit to the end of the byte */ - *lpOut++ |= 0xff << (ulStart & 7); - ulCount -= (8 - (ulStart & 7)); +VOID WINAPI RtlSetBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) { + LPBYTE lpOut; + + TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); + + if (!lpBits || !ulCount || + ulStart >= lpBits->SizeOfBitMap || + ulCount > lpBits->SizeOfBitMap - ulStart) + return; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + /* Set bits in first byte, if ulStart isn't a byte boundary */ + if (ulStart & 7) { + if (ulCount > 7) { + /* Set from start bit to the end of the byte */ + *lpOut++ |= 0xff << (ulStart & 7); + ulCount -= (8 - (ulStart & 7)); + } else { + /* Set from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); + + *lpOut |= (initialWord & 0xff); + if (initialWord >> 8) lpOut[1] |= (initialWord >> 8); + return; + } } - else - { - /* Set from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); - - *lpOut |= (initialWord & 0xff); - if (initialWord >> 8) lpOut[1] |= (initialWord >> 8); - return; + + /* Set bits up to complete byte count */ + if (ulCount >> 3) { + memset(lpOut, 0xff, ulCount >> 3); + lpOut = lpOut + (ulCount >> 3); } - } - - /* Set bits up to complete byte count */ - if (ulCount >> 3) - { - memset(lpOut, 0xff, ulCount >> 3); - lpOut = lpOut + (ulCount >> 3); - } - - /* Set remaining bits, if any */ - if (ulCount & 0x7) - *lpOut |= NTDLL_maskBits[ulCount & 0x7]; + + /* Set remaining bits, if any */ + if (ulCount & 0x7) + *lpOut |= NTDLL_maskBits[ulCount & 0x7]; } /************************************************************************* @@ -197,52 +188,46 @@ VOID WINAPI RtlSetBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) * RETURNS * Nothing. */ -VOID WINAPI RtlClearBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) -{ - LPBYTE lpOut; - - TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); - - if (!lpBits || !ulCount || - ulStart >= lpBits->SizeOfBitMap || - ulCount > lpBits->SizeOfBitMap - ulStart) - return; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - /* Clear bits in first byte, if ulStart isn't a byte boundary */ - if (ulStart & 7) - { - if (ulCount > 7) - { - /* Clear from start bit to the end of the byte */ - *lpOut++ &= ~(0xff << (ulStart & 7)); - ulCount -= (8 - (ulStart & 7)); +VOID WINAPI RtlClearBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) { + LPBYTE lpOut; + + TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); + + if (!lpBits || !ulCount || + ulStart >= lpBits->SizeOfBitMap || + ulCount > lpBits->SizeOfBitMap - ulStart) + return; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + /* Clear bits in first byte, if ulStart isn't a byte boundary */ + if (ulStart & 7) { + if (ulCount > 7) { + /* Clear from start bit to the end of the byte */ + *lpOut++ &= ~(0xff << (ulStart & 7)); + ulCount -= (8 - (ulStart & 7)); + } else { + /* Clear from the start bit, possibly into the next byte also */ + USHORT initialWord = ~(NTDLL_maskBits[ulCount] << (ulStart & 7)); + + *lpOut &= (initialWord & 0xff); + if ((initialWord >> 8) != 0xff) lpOut[1] &= (initialWord >> 8); + return; + } } - else - { - /* Clear from the start bit, possibly into the next byte also */ - USHORT initialWord = ~(NTDLL_maskBits[ulCount] << (ulStart & 7)); - - *lpOut &= (initialWord & 0xff); - if ((initialWord >> 8) != 0xff) lpOut[1] &= (initialWord >> 8); - return; + + /* Clear bits (in blocks of 8) on whole byte boundaries */ + if (ulCount >> 3) { + memset(lpOut, 0, ulCount >> 3); + lpOut = lpOut + (ulCount >> 3); } - } - - /* Clear bits (in blocks of 8) on whole byte boundaries */ - if (ulCount >> 3) - { - memset(lpOut, 0, ulCount >> 3); - lpOut = lpOut + (ulCount >> 3); - } - - /* Clear remaining bits, if any */ - if (ulCount & 0x7) - *lpOut &= ~NTDLL_maskBits[ulCount & 0x7]; + + /* Clear remaining bits, if any */ + if (ulCount & 0x7) + *lpOut &= ~NTDLL_maskBits[ulCount & 0x7]; } /************************************************************************* @@ -259,63 +244,57 @@ VOID WINAPI RtlClearBits(PRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) * TRUE, If ulCount bits from ulStart are set. * FALSE, Otherwise. */ -BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) -{ - LPBYTE lpOut; - ULONG ulRemainder; - - TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); - - if (!lpBits || !ulCount || - ulStart >= lpBits->SizeOfBitMap || - ulCount > lpBits->SizeOfBitMap - ulStart) - return FALSE; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - /* Check bits in first byte, if ulStart isn't a byte boundary */ - if (ulStart & 7) - { - if (ulCount > 7) - { - /* Check from start bit to the end of the byte */ - if ((*lpOut & - ((0xff << (ulStart & 7))) & 0xff) != ((0xff << (ulStart & 7) & 0xff))) +BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) { + LPBYTE lpOut; + ULONG ulRemainder; + + TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); + + if (!lpBits || !ulCount || + ulStart >= lpBits->SizeOfBitMap || + ulCount > lpBits->SizeOfBitMap - ulStart) return FALSE; - lpOut++; - ulCount -= (8 - (ulStart & 7)); + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + /* Check bits in first byte, if ulStart isn't a byte boundary */ + if (ulStart & 7) { + if (ulCount > 7) { + /* Check from start bit to the end of the byte */ + if ((*lpOut & + ((0xff << (ulStart & 7))) & 0xff) != ((0xff << (ulStart & 7) & 0xff))) + return FALSE; + lpOut++; + ulCount -= (8 - (ulStart & 7)); + } else { + /* Check from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); + + if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff)) + return FALSE; + if ((initialWord & 0xff00) && + ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8))) + return FALSE; + return TRUE; + } } - else - { - /* Check from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); - if ((*lpOut & (initialWord & 0xff)) != (initialWord & 0xff)) - return FALSE; - if ((initialWord & 0xff00) && - ((lpOut[1] & (initialWord >> 8)) != (initialWord >> 8))) - return FALSE; - return TRUE; + /* Check bits in blocks of 8 bytes */ + ulRemainder = ulCount & 7; + ulCount >>= 3; + while (ulCount--) { + if (*lpOut++ != 0xff) + return FALSE; } - } - - /* Check bits in blocks of 8 bytes */ - ulRemainder = ulCount & 7; - ulCount >>= 3; - while (ulCount--) - { - if (*lpOut++ != 0xff) - return FALSE; - } - - /* Check remaining bits, if any */ - if (ulRemainder && - (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder]) - return FALSE; - return TRUE; + + /* Check remaining bits, if any */ + if (ulRemainder && + (*lpOut & NTDLL_maskBits[ulRemainder]) != NTDLL_maskBits[ulRemainder]) + return FALSE; + return TRUE; } /************************************************************************* @@ -332,60 +311,54 @@ BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) * TRUE, If ulCount bits from ulStart are clear. * FALSE, Otherwise. */ -BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) -{ - LPBYTE lpOut; - ULONG ulRemainder; - - TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); - - if (!lpBits || !ulCount || - ulStart >= lpBits->SizeOfBitMap || - ulCount > lpBits->SizeOfBitMap - ulStart) - return FALSE; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - /* Check bits in first byte, if ulStart isn't a byte boundary */ - if (ulStart & 7) - { - if (ulCount > 7) - { - /* Check from start bit to the end of the byte */ - if (*lpOut & ((0xff << (ulStart & 7)) & 0xff)) +BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount) { + LPBYTE lpOut; + ULONG ulRemainder; + + TRACE("(%p,%u,%u)\n", lpBits, ulStart, ulCount); + + if (!lpBits || !ulCount || + ulStart >= lpBits->SizeOfBitMap || + ulCount > lpBits->SizeOfBitMap - ulStart) return FALSE; - lpOut++; - ulCount -= (8 - (ulStart & 7)); + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + /* Check bits in first byte, if ulStart isn't a byte boundary */ + if (ulStart & 7) { + if (ulCount > 7) { + /* Check from start bit to the end of the byte */ + if (*lpOut & ((0xff << (ulStart & 7)) & 0xff)) + return FALSE; + lpOut++; + ulCount -= (8 - (ulStart & 7)); + } else { + /* Check from the start bit, possibly into the next byte also */ + USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); + + if (*lpOut & (initialWord & 0xff)) + return FALSE; + if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8))) + return FALSE; + return TRUE; + } } - else - { - /* Check from the start bit, possibly into the next byte also */ - USHORT initialWord = NTDLL_maskBits[ulCount] << (ulStart & 7); - if (*lpOut & (initialWord & 0xff)) - return FALSE; - if ((initialWord & 0xff00) && (lpOut[1] & (initialWord >> 8))) - return FALSE; - return TRUE; + /* Check bits in blocks of 8 bytes */ + ulRemainder = ulCount & 7; + ulCount >>= 3; + while (ulCount--) { + if (*lpOut++) + return FALSE; } - } - - /* Check bits in blocks of 8 bytes */ - ulRemainder = ulCount & 7; - ulCount >>= 3; - while (ulCount--) - { - if (*lpOut++) - return FALSE; - } - - /* Check remaining bits, if any */ - if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder]) - return FALSE; - return TRUE; + + /* Check remaining bits, if any */ + if (ulRemainder && *lpOut & NTDLL_maskBits[ulRemainder]) + return FALSE; + return TRUE; } /************************************************************************* @@ -401,38 +374,34 @@ BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP lpBits, ULONG ulStart, ULONG ulCount * RETURNS * The bit at which the match was found, or -1 if no match was found. */ -ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) -{ - ULONG ulPos, ulEnd; +ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) { + ULONG ulPos, ulEnd; - TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); + TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); - if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap) - return ~0U; + if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap) + return ~0U; - ulEnd = lpBits->SizeOfBitMap; + ulEnd = lpBits->SizeOfBitMap; - if (ulHint + ulCount > lpBits->SizeOfBitMap) - ulHint = 0; + if (ulHint + ulCount > lpBits->SizeOfBitMap) + ulHint = 0; - ulPos = ulHint; + ulPos = ulHint; - while (ulPos < ulEnd) - { - /* FIXME: This could be made a _lot_ more efficient */ - if (RtlAreBitsSet(lpBits, ulPos, ulCount)) - return ulPos; + while (ulPos < ulEnd) { + /* FIXME: This could be made a _lot_ more efficient */ + if (RtlAreBitsSet(lpBits, ulPos, ulCount)) + return ulPos; - /* Start from the beginning if we hit the end and had a hint */ - if (ulPos == ulEnd - 1 && ulHint) - { - ulEnd = ulHint; - ulPos = ulHint = 0; + /* Start from the beginning if we hit the end and had a hint */ + if (ulPos == ulEnd - 1 && ulHint) { + ulEnd = ulHint; + ulPos = ulHint = 0; + } else + ulPos++; } - else - ulPos++; - } - return ~0U; + return ~0U; } /************************************************************************* @@ -448,38 +417,34 @@ ULONG WINAPI RtlFindSetBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) * RETURNS * The bit at which the match was found, or -1 if no match was found. */ -ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) -{ - ULONG ulPos, ulEnd; +ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) { + ULONG ulPos, ulEnd; - TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); + TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); - if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap) - return ~0U; + if (!lpBits || !ulCount || ulCount > lpBits->SizeOfBitMap) + return ~0U; - ulEnd = lpBits->SizeOfBitMap; + ulEnd = lpBits->SizeOfBitMap; - if (ulHint + ulCount > lpBits->SizeOfBitMap) - ulHint = 0; + if (ulHint + ulCount > lpBits->SizeOfBitMap) + ulHint = 0; - ulPos = ulHint; + ulPos = ulHint; - while (ulPos < ulEnd) - { - /* FIXME: This could be made a _lot_ more efficient */ - if (RtlAreBitsClear(lpBits, ulPos, ulCount)) - return ulPos; + while (ulPos < ulEnd) { + /* FIXME: This could be made a _lot_ more efficient */ + if (RtlAreBitsClear(lpBits, ulPos, ulCount)) + return ulPos; - /* Start from the beginning if we hit the end and started from ulHint */ - if (ulPos == ulEnd - 1 && ulHint) - { - ulEnd = ulHint; - ulPos = ulHint = 0; + /* Start from the beginning if we hit the end and started from ulHint */ + if (ulPos == ulEnd - 1 && ulHint) { + ulEnd = ulHint; + ulPos = ulHint = 0; + } else + ulPos++; } - else - ulPos++; - } - return ~0U; + return ~0U; } /************************************************************************* @@ -495,16 +460,15 @@ ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) * RETURNS * The bit at which the match was found, or -1 if no match was found. */ -ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) -{ - ULONG ulPos; +ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) { + ULONG ulPos; - TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); + TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); - ulPos = RtlFindSetBits(lpBits, ulCount, ulHint); - if (ulPos != ~0U) - RtlClearBits(lpBits, ulPos, ulCount); - return ulPos; + ulPos = RtlFindSetBits(lpBits, ulCount, ulHint); + if (ulPos != ~0U) + RtlClearBits(lpBits, ulPos, ulCount); + return ulPos; } /************************************************************************* @@ -520,16 +484,15 @@ ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulH * RETURNS * The bit at which the match was found, or -1 if no match was found. */ -ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) -{ - ULONG ulPos; +ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulHint) { + ULONG ulPos; - TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); + TRACE("(%p,%u,%u)\n", lpBits, ulCount, ulHint); - ulPos = RtlFindClearBits(lpBits, ulCount, ulHint); - if (ulPos != ~0U) - RtlSetBits(lpBits, ulPos, ulCount); - return ulPos; + ulPos = RtlFindClearBits(lpBits, ulCount, ulHint); + if (ulPos != ~0U) + RtlSetBits(lpBits, ulPos, ulCount); + return ulPos; } /************************************************************************* @@ -543,36 +506,32 @@ ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP lpBits, ULONG ulCount, ULONG ulH * RETURNS * The number of set bits. */ -ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP lpBits) -{ - ULONG ulSet = 0; - - TRACE("(%p)\n", lpBits); - - if (lpBits) - { - LPBYTE lpOut = (BYTE *)lpBits->Buffer; - ULONG ulCount, ulRemainder; - BYTE bMasked; - - ulCount = lpBits->SizeOfBitMap >> 3; - ulRemainder = lpBits->SizeOfBitMap & 0x7; - - while (ulCount--) - { - ulSet += NTDLL_nibbleBitCount[*lpOut >> 4]; - ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf]; - lpOut++; - } +ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP lpBits) { + ULONG ulSet = 0; + + TRACE("(%p)\n", lpBits); + + if (lpBits) { + LPBYTE lpOut = (BYTE *) lpBits->Buffer; + ULONG ulCount, ulRemainder; + BYTE bMasked; + + ulCount = lpBits->SizeOfBitMap >> 3; + ulRemainder = lpBits->SizeOfBitMap & 0x7; - if (ulRemainder) - { - bMasked = *lpOut & NTDLL_maskBits[ulRemainder]; - ulSet += NTDLL_nibbleBitCount[bMasked >> 4]; - ulSet += NTDLL_nibbleBitCount[bMasked & 0xf]; + while (ulCount--) { + ulSet += NTDLL_nibbleBitCount[*lpOut >> 4]; + ulSet += NTDLL_nibbleBitCount[*lpOut & 0xf]; + lpOut++; + } + + if (ulRemainder) { + bMasked = *lpOut & NTDLL_maskBits[ulRemainder]; + ulSet += NTDLL_nibbleBitCount[bMasked >> 4]; + ulSet += NTDLL_nibbleBitCount[bMasked & 0xf]; + } } - } - return ulSet; + return ulSet; } /************************************************************************* @@ -586,13 +545,12 @@ ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP lpBits) * RETURNS * The number of clear bits. */ -ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP lpBits) -{ - TRACE("(%p)\n", lpBits); +ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP lpBits) { + TRACE("(%p)\n", lpBits); - if (lpBits) - return lpBits->SizeOfBitMap - RtlNumberOfSetBits(lpBits); - return 0; + if (lpBits) + return lpBits->SizeOfBitMap - RtlNumberOfSetBits(lpBits); + return 0; } /************************************************************************* @@ -603,28 +561,23 @@ ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP lpBits) * RETURNS * The position of the most significant bit. */ -CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) -{ +CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) { signed char ret = 32; DWORD dw; - if (!(dw = (ulLong >> 32))) - { + if (!(dw = (ulLong >> 32))) { ret = 0; - dw = (DWORD)ulLong; + dw = (DWORD) ulLong; } - if (dw & 0xffff0000) - { + if (dw & 0xffff0000) { dw >>= 16; ret += 16; } - if (dw & 0xff00) - { + if (dw & 0xff00) { dw >>= 8; ret += 8; } - if (dw & 0xf0) - { + if (dw & 0xf0) { dw >>= 4; ret += 4; } @@ -639,28 +592,23 @@ CCHAR WINAPI RtlFindMostSignificantBit(ULONGLONG ulLong) * RETURNS * The position of the least significant bit. */ -CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) -{ +CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) { signed char ret = 0; DWORD dw; - if (!(dw = (DWORD)ulLong)) - { + if (!(dw = (DWORD) ulLong)) { ret = 32; if (!(dw = ulLong >> 32)) return -1; } - if (!(dw & 0xffff)) - { + if (!(dw & 0xffff)) { dw >>= 16; ret += 16; } - if (!(dw & 0xff)) - { + if (!(dw & 0xff)) { dw >>= 8; ret += 8; } - if (!(dw & 0x0f)) - { + if (!(dw & 0x0f)) { dw >>= 4; ret += 4; } @@ -672,11 +620,10 @@ CCHAR WINAPI RtlFindLeastSignificantBit(ULONGLONG ulLong) * * Internal helper: qsort comparison function for RTL_BITMAP_RUN arrays */ -static int NTDLL_RunSortFn(const void *lhs, const void *rhs) -{ - if (((const RTL_BITMAP_RUN*)lhs)->NumberOfBits > ((const RTL_BITMAP_RUN*)rhs)->NumberOfBits) - return -1; - return 1; +static int NTDLL_RunSortFn(const void *lhs, const void *rhs) { + if (((const RTL_BITMAP_RUN *) lhs)->NumberOfBits > ((const RTL_BITMAP_RUN *) rhs)->NumberOfBits) + return -1; + return 1; } /************************************************************************* @@ -684,96 +631,86 @@ static int NTDLL_RunSortFn(const void *lhs, const void *rhs) * * Internal helper: Find the next run of set bits in a bitmap. */ -static ULONG NTDLL_FindSetRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) -{ - LPBYTE lpOut; - ULONG ulFoundAt = 0, ulCount = 0; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - while (1) - { - /* Check bits in first byte */ - const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; - const BYTE bFirst = *lpOut & bMask; - - if (bFirst) - { - /* Have a set bit in first byte */ - if (bFirst != bMask) - { - /* Not every bit is set */ - ULONG ulOffset; - - if (bFirst & 0x0f) - ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; - else - ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; - ulStart += ulOffset; - ulFoundAt = ulStart; - for (;ulOffset < 8; ulOffset++) - { - if (!(bFirst & (1 << ulOffset))) - { - *lpSize = ulCount; - return ulFoundAt; /* Set from start, but not until the end */ - } - ulCount++; - ulStart++; +static ULONG NTDLL_FindSetRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) { + LPBYTE lpOut; + ULONG ulFoundAt = 0, ulCount = 0; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + while (1) { + /* Check bits in first byte */ + const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; + const BYTE bFirst = *lpOut & bMask; + + if (bFirst) { + /* Have a set bit in first byte */ + if (bFirst != bMask) { + /* Not every bit is set */ + ULONG ulOffset; + + if (bFirst & 0x0f) + ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; + else + ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; + ulStart += ulOffset; + ulFoundAt = ulStart; + for (; ulOffset < 8; ulOffset++) { + if (!(bFirst & (1 << ulOffset))) { + *lpSize = ulCount; + return ulFoundAt; /* Set from start, but not until the end */ + } + ulCount++; + ulStart++; + } + /* Set to the end - go on to count further bits */ + lpOut++; + break; + } + /* every bit from start until the end of the byte is set */ + ulFoundAt = ulStart; + ulCount = 8 - (ulStart & 7); + ulStart = (ulStart & ~7u) + 8; + lpOut++; + break; } - /* Set to the end - go on to count further bits */ + ulStart = (ulStart & ~7u) + 8; lpOut++; - break; - } - /* every bit from start until the end of the byte is set */ - ulFoundAt = ulStart; - ulCount = 8 - (ulStart & 7); - ulStart = (ulStart & ~7u) + 8; - lpOut++; - break; + if (ulStart >= lpBits->SizeOfBitMap) + return ~0U; } - ulStart = (ulStart & ~7u) + 8; - lpOut++; - if (ulStart >= lpBits->SizeOfBitMap) - return ~0U; - } - - /* Check if reached the end of bitmap */ - if (ulStart >= lpBits->SizeOfBitMap) { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; - } - - /* Count blocks of 8 set bits */ - while (*lpOut == 0xff) - { - ulCount += 8; - ulStart += 8; - if (ulStart >= lpBits->SizeOfBitMap) - { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; + + /* Check if reached the end of bitmap */ + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; } - lpOut++; - } - - /* Count remaining contiguous bits, if any */ - if (*lpOut & 1) - { - ULONG ulOffset = 0; - - for (;ulOffset < 7u; ulOffset++) - { - if (!(*lpOut & (1 << ulOffset))) - break; - ulCount++; + + /* Count blocks of 8 set bits */ + while (*lpOut == 0xff) { + ulCount += 8; + ulStart += 8; + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + lpOut++; } - } - *lpSize = ulCount; - return ulFoundAt; + + /* Count remaining contiguous bits, if any */ + if (*lpOut & 1) { + ULONG ulOffset = 0; + + for (; ulOffset < 7u; ulOffset++) { + if (!(*lpOut & (1 << ulOffset))) + break; + ulCount++; + } + } + *lpSize = ulCount; + return ulFoundAt; } /************************************************************************* @@ -781,96 +718,86 @@ static ULONG NTDLL_FindSetRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) * * Internal helper: Find the next run of set bits in a bitmap. */ -static ULONG NTDLL_FindClearRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) -{ - LPBYTE lpOut; - ULONG ulFoundAt = 0, ulCount = 0; - - /* FIXME: It might be more efficient/cleaner to manipulate four bytes - * at a time. But beware of the pointer arithmetics... - */ - lpOut = ((BYTE*)lpBits->Buffer) + (ulStart >> 3u); - - while (1) - { - /* Check bits in first byte */ - const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; - const BYTE bFirst = (~*lpOut) & bMask; - - if (bFirst) - { - /* Have a clear bit in first byte */ - if (bFirst != bMask) - { - /* Not every bit is clear */ - ULONG ulOffset; - - if (bFirst & 0x0f) - ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; - else - ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; - ulStart += ulOffset; - ulFoundAt = ulStart; - for (;ulOffset < 8; ulOffset++) - { - if (!(bFirst & (1 << ulOffset))) - { - *lpSize = ulCount; - return ulFoundAt; /* Clear from start, but not until the end */ - } - ulCount++; - ulStart++; +static ULONG NTDLL_FindClearRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSize) { + LPBYTE lpOut; + ULONG ulFoundAt = 0, ulCount = 0; + + /* FIXME: It might be more efficient/cleaner to manipulate four bytes + * at a time. But beware of the pointer arithmetics... + */ + lpOut = ((BYTE *) lpBits->Buffer) + (ulStart >> 3u); + + while (1) { + /* Check bits in first byte */ + const BYTE bMask = (0xff << (ulStart & 7)) & 0xff; + const BYTE bFirst = (~*lpOut) & bMask; + + if (bFirst) { + /* Have a clear bit in first byte */ + if (bFirst != bMask) { + /* Not every bit is clear */ + ULONG ulOffset; + + if (bFirst & 0x0f) + ulOffset = NTDLL_leastSignificant[bFirst & 0x0f]; + else + ulOffset = 4 + NTDLL_leastSignificant[bFirst >> 4]; + ulStart += ulOffset; + ulFoundAt = ulStart; + for (; ulOffset < 8; ulOffset++) { + if (!(bFirst & (1 << ulOffset))) { + *lpSize = ulCount; + return ulFoundAt; /* Clear from start, but not until the end */ + } + ulCount++; + ulStart++; + } + /* Clear to the end - go on to count further bits */ + lpOut++; + break; + } + /* Every bit from start until the end of the byte is clear */ + ulFoundAt = ulStart; + ulCount = 8 - (ulStart & 7); + ulStart = (ulStart & ~7u) + 8; + lpOut++; + break; } - /* Clear to the end - go on to count further bits */ + ulStart = (ulStart & ~7u) + 8; lpOut++; - break; - } - /* Every bit from start until the end of the byte is clear */ - ulFoundAt = ulStart; - ulCount = 8 - (ulStart & 7); - ulStart = (ulStart & ~7u) + 8; - lpOut++; - break; + if (ulStart >= lpBits->SizeOfBitMap) + return ~0U; } - ulStart = (ulStart & ~7u) + 8; - lpOut++; - if (ulStart >= lpBits->SizeOfBitMap) - return ~0U; - } - - /* Check if reached the end of bitmap */ - if (ulStart >= lpBits->SizeOfBitMap) { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; - } - - /* Count blocks of 8 clear bits */ - while (!*lpOut) - { - ulCount += 8; - ulStart += 8; - if (ulStart >= lpBits->SizeOfBitMap) - { - *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); - return ulFoundAt; + + /* Check if reached the end of bitmap */ + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; } - lpOut++; - } - - /* Count remaining contiguous bits, if any */ - if (!(*lpOut & 1)) - { - ULONG ulOffset = 0; - - for (;ulOffset < 7u; ulOffset++) - { - if (*lpOut & (1 << ulOffset)) - break; - ulCount++; + + /* Count blocks of 8 clear bits */ + while (!*lpOut) { + ulCount += 8; + ulStart += 8; + if (ulStart >= lpBits->SizeOfBitMap) { + *lpSize = ulCount - (ulStart - lpBits->SizeOfBitMap); + return ulFoundAt; + } + lpOut++; } - } - *lpSize = ulCount; - return ulFoundAt; + + /* Count remaining contiguous bits, if any */ + if (!(*lpOut & 1)) { + ULONG ulOffset = 0; + + for (; ulOffset < 7u; ulOffset++) { + if (*lpOut & (1 << ulOffset)) + break; + ulCount++; + } + } + *lpSize = ulCount; + return ulFoundAt; } /************************************************************************* @@ -888,16 +815,15 @@ static ULONG NTDLL_FindClearRun(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpSiz * the start of the run. * Failure: 0, if no run is found or any parameters are invalid. */ -ULONG WINAPI RtlFindNextForwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) -{ - ULONG ulSize = 0; +ULONG WINAPI RtlFindNextForwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) { + ULONG ulSize = 0; - TRACE("(%p,%u,%p)\n", lpBits, ulStart, lpPos); + TRACE("(%p,%u,%p)\n", lpBits, ulStart, lpPos); - if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos) - *lpPos = NTDLL_FindSetRun(lpBits, ulStart, &ulSize); + if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos) + *lpPos = NTDLL_FindSetRun(lpBits, ulStart, &ulSize); - return ulSize; + return ulSize; } /************************************************************************* @@ -915,16 +841,15 @@ ULONG WINAPI RtlFindNextForwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG * the start of the run. * Failure: 0, if no run is found or any parameters are invalid. */ -ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) -{ - ULONG ulSize = 0; +ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) { + ULONG ulSize = 0; - TRACE("(%p,%u,%p)\n", lpBits, ulStart, lpPos); + TRACE("(%p,%u,%p)\n", lpBits, ulStart, lpPos); - if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos) - *lpPos = NTDLL_FindClearRun(lpBits, ulStart, &ulSize); + if (lpBits && ulStart < lpBits->SizeOfBitMap && lpPos) + *lpPos = NTDLL_FindClearRun(lpBits, ulStart, &ulSize); - return ulSize; + return ulSize; } /************************************************************************* @@ -942,10 +867,9 @@ ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULO * the start of the run. * Failure: 0, if no run is found or any parameters are invalid. */ -ULONG WINAPI RtlFindLastBackwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) -{ - FIXME("(%p,%u,%p)-stub!\n", lpBits, ulStart, lpPos); - return 0; +ULONG WINAPI RtlFindLastBackwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) { + FIXME("(%p,%u,%p)-stub!\n", lpBits, ulStart, lpPos); + return 0; } /************************************************************************* @@ -963,10 +887,9 @@ ULONG WINAPI RtlFindLastBackwardRunSet(PCRTL_BITMAP lpBits, ULONG ulStart, PULON * to the start of the run. * Failure: 0, if no run is found or any parameters are invalid. */ -ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) -{ - FIXME("(%p,%u,%p)-stub!\n", lpBits, ulStart, lpPos); - return 0; +ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PULONG lpPos) { + FIXME("(%p,%u,%p)-stub!\n", lpBits, ulStart, lpPos); + return 0; } /************************************************************************* @@ -976,54 +899,48 @@ ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP lpBits, ULONG ulStart, PUL */ static ULONG NTDLL_FindRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, ULONG ulCount, BOOLEAN bLongest, - ULONG (*fn)(PCRTL_BITMAP,ULONG,PULONG)) -{ - BOOL bNeedSort = ulCount > 1; - ULONG ulPos = 0, ulRuns = 0; - - TRACE("(%p,%p,%d,%d)\n", lpBits, lpSeries, ulCount, bLongest); - - if (!ulCount) - return ~0U; - - while (ulPos < lpBits->SizeOfBitMap) - { - /* Find next set/clear run */ - ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize); - - if (ulNextPos == ~0U) - break; - - if (bLongest && ulRuns == ulCount) - { - /* Sort runs with shortest at end, if they are out of order */ - if (bNeedSort) - qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn); - - /* Replace last run if this one is bigger */ - if (ulSize > lpSeries[ulRuns - 1].NumberOfBits) - { - lpSeries[ulRuns - 1].StartingIndex = ulNextPos; - lpSeries[ulRuns - 1].NumberOfBits = ulSize; - - /* We need to re-sort the array, _if_ we didn't leave it sorted */ - if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].NumberOfBits) - bNeedSort = TRUE; - } - } - else - { - /* Append to found runs */ - lpSeries[ulRuns].StartingIndex = ulNextPos; - lpSeries[ulRuns].NumberOfBits = ulSize; - ulRuns++; - - if (!bLongest && ulRuns == ulCount) - break; + ULONG (*fn)(PCRTL_BITMAP, ULONG, PULONG)) { + BOOL bNeedSort = ulCount > 1; + ULONG ulPos = 0, ulRuns = 0; + + TRACE("(%p,%p,%d,%d)\n", lpBits, lpSeries, ulCount, bLongest); + + if (!ulCount) + return ~0U; + + while (ulPos < lpBits->SizeOfBitMap) { + /* Find next set/clear run */ + ULONG ulSize, ulNextPos = fn(lpBits, ulPos, &ulSize); + + if (ulNextPos == ~0U) + break; + + if (bLongest && ulRuns == ulCount) { + /* Sort runs with shortest at end, if they are out of order */ + if (bNeedSort) + qsort(lpSeries, ulRuns, sizeof(RTL_BITMAP_RUN), NTDLL_RunSortFn); + + /* Replace last run if this one is bigger */ + if (ulSize > lpSeries[ulRuns - 1].NumberOfBits) { + lpSeries[ulRuns - 1].StartingIndex = ulNextPos; + lpSeries[ulRuns - 1].NumberOfBits = ulSize; + + /* We need to re-sort the array, _if_ we didn't leave it sorted */ + if (ulRuns > 1 && ulSize > lpSeries[ulRuns - 2].NumberOfBits) + bNeedSort = TRUE; + } + } else { + /* Append to found runs */ + lpSeries[ulRuns].StartingIndex = ulNextPos; + lpSeries[ulRuns].NumberOfBits = ulSize; + ulRuns++; + + if (!bLongest && ulRuns == ulCount) + break; + } + ulPos = ulNextPos + ulSize; } - ulPos = ulNextPos + ulSize; - } - return ulRuns; + return ulRuns; } /************************************************************************* @@ -1041,11 +958,10 @@ static ULONG NTDLL_FindRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, * The number of set runs found. */ ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, - ULONG ulCount, BOOLEAN bLongest) -{ - TRACE("(%p,%p,%u,%d)\n", lpBits, lpSeries, ulCount, bLongest); + ULONG ulCount, BOOLEAN bLongest) { + TRACE("(%p,%p,%u,%d)\n", lpBits, lpSeries, ulCount, bLongest); - return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindSetRun); + return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindSetRun); } /************************************************************************* @@ -1063,11 +979,10 @@ ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, * The number of clear runs found. */ ULONG WINAPI RtlFindClearRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, - ULONG ulCount, BOOLEAN bLongest) -{ - TRACE("(%p,%p,%u,%d)\n", lpBits, lpSeries, ulCount, bLongest); + ULONG ulCount, BOOLEAN bLongest) { + TRACE("(%p,%p,%u,%d)\n", lpBits, lpSeries, ulCount, bLongest); - return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindClearRun); + return NTDLL_FindRuns(lpBits, lpSeries, ulCount, bLongest, NTDLL_FindClearRun); } /************************************************************************* @@ -1082,19 +997,17 @@ ULONG WINAPI RtlFindClearRuns(PCRTL_BITMAP lpBits, PRTL_BITMAP_RUN lpSeries, * RETURNS * The length of the run found, or 0 if no run is found. */ -ULONG WINAPI RtlFindLongestRunSet(PCRTL_BITMAP lpBits, PULONG pulStart) -{ - RTL_BITMAP_RUN br; - - TRACE("(%p,%p)\n", lpBits, pulStart); - - if (RtlFindSetRuns(lpBits, &br, 1, TRUE) == 1) - { - if (pulStart) - *pulStart = br.StartingIndex; - return br.NumberOfBits; - } - return 0; +ULONG WINAPI RtlFindLongestRunSet(PCRTL_BITMAP lpBits, PULONG pulStart) { + RTL_BITMAP_RUN br; + + TRACE("(%p,%p)\n", lpBits, pulStart); + + if (RtlFindSetRuns(lpBits, &br, 1, TRUE) == 1) { + if (pulStart) + *pulStart = br.StartingIndex; + return br.NumberOfBits; + } + return 0; } /************************************************************************* @@ -1109,21 +1022,21 @@ ULONG WINAPI RtlFindLongestRunSet(PCRTL_BITMAP lpBits, PULONG pulStart) * RETURNS * The length of the run found, or 0 if no run is found. */ -ULONG WINAPI RtlFindLongestRunClear(PCRTL_BITMAP lpBits, PULONG pulStart) -{ - RTL_BITMAP_RUN br; - - TRACE("(%p,%p)\n", lpBits, pulStart); - - if (RtlFindClearRuns(lpBits, &br, 1, TRUE) == 1) - { - if (pulStart) - *pulStart = br.StartingIndex; - return br.NumberOfBits; - } - return 0; +ULONG WINAPI RtlFindLongestRunClear(PCRTL_BITMAP lpBits, PULONG pulStart) { + RTL_BITMAP_RUN br; + + TRACE("(%p,%p)\n", lpBits, pulStart); + + if (RtlFindClearRuns(lpBits, &br, 1, TRUE) == 1) { + if (pulStart) + *pulStart = br.StartingIndex; + return br.NumberOfBits; + } + return 0; } DECLARE_CRT_EXPORT("RtlFindClearBitsAndSet", RtlFindClearBitsAndSet); + DECLARE_CRT_EXPORT("RtlClearBits", RtlClearBits); + DECLARE_CRT_EXPORT("RtlAreBitsSet", RtlAreBitsSet); diff --git a/peloader/winexports.h b/peloader/winexports.h index af12b58..99c85b2 100644 --- a/peloader/winexports.h +++ b/peloader/winexports.h @@ -3,16 +3,15 @@ extern struct hsearch_data crtexports; -#define DECLARE_CRT_EXPORT(_name, _func) \ - static void __constructor __const__ ## _func (void) \ - { \ - ENTRY e = { _name, _func }, *ep; \ - if (crtexports.table == NULL) \ - hcreate_r(1024, &crtexports); \ - hsearch_r(e, ENTER, &ep, &crtexports); \ - return; \ + +#define DECLARE_CRT_EXPORT(_name, _func) \ + static void __constructor __const__ ## _func (void) \ + { \ + ENTRY e = { _name, _func }, *ep; \ + if (crtexports.table == NULL) \ + hcreate_r(1024, &crtexports); \ + hsearch_r(e, ENTER, &ep, &crtexports); \ + return; \ } -#else -# warn winexports.h included twice #endif diff --git a/peloader/winnt_types.h b/peloader/winnt_types.h index 9ae9544..f03c74d 100644 --- a/peloader/winnt_types.h +++ b/peloader/winnt_types.h @@ -62,6 +62,10 @@ #define STATUS_DEVICE_NOT_CONNECTED 0xC000009D #define STATUS_BUFFER_OVERFLOW 0x80000005 +#define STATUS_LONG_JUMP 0x80000026 +#define STATUS_UNWIND_CONSOLIDATE 0x80000029 +#define STATUS_UNWIND 0xC0000027 + #define SL_PENDING_RETURNED 0x01 #define SL_INVOKE_ON_CANCEL 0x20 @@ -132,44 +136,49 @@ #define wfastcall __attribute__((fastcall)) #define STATIC static #define VOID void +#ifdef __x86_64__ +#define WINAPI __attribute__((ms_abi)) +#else #define WINAPI __attribute__((__stdcall__)) +#endif #define KI_USER_SHARED_DATA 0xffdf0000 #define MM_SHARED_USER_DATA_VA 0x7ffe0000 -typedef uint8_t BOOLEAN, BOOL; -typedef void *PVOID; -typedef uint8_t BYTE; -typedef uint8_t *PBYTE; -typedef uint8_t *LPBYTE; -typedef int8_t CHAR; -typedef char *PCHAR; -typedef wchar_t WCHAR; -typedef CHAR *LPSTR; -typedef const char *LPCSTR; -typedef WCHAR *LPWSTR; -typedef const WCHAR *LPCWSTR; -typedef WCHAR *PWSTR; -typedef uint8_t UCHAR; -typedef uint8_t *PUCHAR; -typedef uint16_t SHORT; -typedef uint16_t USHORT; -typedef uint16_t *PUSHORT; -typedef uint16_t WORD; -typedef int32_t INT; -typedef uint32_t UINT; -typedef uint32_t DWORD, *PDWORD; -typedef int32_t LONG; -typedef uint32_t ULONG; -typedef uint32_t *PULONG; -typedef int64_t LONGLONG; -typedef uint64_t ULONGLONG, *PULONGLONG; -typedef uint64_t ULONGULONG; -typedef uint64_t ULONG64; -typedef uint64_t QWORD, *PQWORD; -typedef uint16_t WCHAR, *PWCHAR; -typedef HANDLE *PHANDLE; -typedef LONG HRESULT; +typedef uint8_t BOOLEAN, BOOL, *PBOOL, UBYTE; +typedef void *PVOID, *LPVOID; +typedef uint8_t BYTE; +typedef uint8_t *PBYTE; +typedef uint8_t *LPBYTE; +typedef int8_t CHAR; +typedef char *PCHAR; +typedef CHAR *LPSTR; +typedef const char *LPCSTR; +typedef uint16_t WCHAR, *PWCHAR; +typedef WCHAR *LPWSTR; +typedef const WCHAR *LPCWSTR, *LPCWCH; +typedef WCHAR *PWSTR; +typedef uint8_t UCHAR; +typedef uint8_t *PUCHAR; +typedef uint16_t SHORT; +typedef uint16_t USHORT; +typedef uint16_t *PUSHORT; +typedef uint16_t WORD; +typedef int32_t INT; +typedef uint32_t UINT; +typedef uint32_t DWORD, *PDWORD, *LPDWORD; +typedef DWORD *DWORD_PTR; +typedef int32_t LONG; +typedef uint32_t ULONG; +typedef uint32_t *PULONG; +typedef int64_t LONGLONG, DWORD64, *PDWORD64; +typedef uint64_t ULONGLONG, *PULONGLONG; +typedef ULONGLONG DWORDLONG; +typedef uint64_t ULONGULONG; +typedef uint64_t ULONG64, *PULONG64; +typedef uint64_t QWORD, *PQWORD; +typedef HANDLE *PHANDLE; +typedef LONG HRESULT; typedef CHAR CCHAR; typedef SHORT CSHORT; @@ -197,110 +206,114 @@ typedef ULONG SECURITY_INFORMATION; #define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0) typedef struct _FILETIME { - DWORD dwLowDateTime; - DWORD dwHighDateTime; + DWORD dwLowDateTime; + DWORD dwHighDateTime; } FILETIME, *PFILETIME; typedef struct ansi_string { - USHORT length; - USHORT max_length; - char *buf; + USHORT length; + USHORT max_length; + char *buf; } ANSI_STRING, *PANSI_STRING; typedef struct unicode_string { - USHORT Length; - USHORT MaximumLength; - wchar_t *Buffer; + USHORT Length; + USHORT MaximumLength; + wchar_t *Buffer; } UNICODE_STRING, *PUNICODE_STRING; struct nt_slist { - struct nt_slist *next; + struct nt_slist *next; }; union nt_slist_head { - ULONGLONG align; - struct { - struct nt_slist *next; - USHORT depth; - USHORT sequence; - }; + ULONGLONG align; + struct { + struct nt_slist *next; + USHORT depth; + USHORT sequence; + }; }; typedef union nt_slist_head nt_slist_header; struct nt_list { - struct nt_list *next; - struct nt_list *prev; + struct nt_list *next; + struct nt_list *prev; }; typedef ULONG_PTR NT_SPIN_LOCK; -enum kdpc_importance {LowImportance, MediumImportance, HighImportance}; +enum kdpc_importance { + LowImportance, MediumImportance, HighImportance +}; struct kdpc; + typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2) wstdcall; + struct kdpc { - SHORT type; - UCHAR nr_cpu; - UCHAR importance; - struct nt_list list; - DPC func; - void *ctx; - void *arg1; - void *arg2; - union { - NT_SPIN_LOCK *lock; - /* 'lock' is not used; 'queued' represents whether - * kdpc is queued or not */ - int queued; - }; + SHORT type; + UCHAR nr_cpu; + UCHAR importance; + struct nt_list list; + DPC func; + void *ctx; + void *arg1; + void *arg2; + union { + NT_SPIN_LOCK *lock; + /* 'lock' is not used; 'queued' represents whether + * kdpc is queued or not */ + int queued; + }; }; enum pool_type { - NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, - NonPagedPoolCacheAligned, PagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS, MaxPoolType, - NonPagedPoolSession = 32, - PagedPoolSession = NonPagedPoolSession + 1, - NonPagedPoolMustSucceedSession = PagedPoolSession + 1, - DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, - NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, - PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, - NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 + NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, + NonPagedPoolCacheAligned, PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, MaxPoolType, + NonPagedPoolSession = 32, + PagedPoolSession = NonPagedPoolSession + 1, + NonPagedPoolMustSucceedSession = PagedPoolSession + 1, + DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, + NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, + PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, + NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 }; enum memory_caching_type_orig { - MmFrameBufferCached = 2 + MmFrameBufferCached = 2 }; enum memory_caching_type { - MmNonCached = FALSE, MmCached = TRUE, - MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, - MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType + MmNonCached = FALSE, MmCached = TRUE, + MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, + MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType }; enum lock_operation { - IoReadAccess, IoWriteAccess, IoModifyAccess + IoReadAccess, IoWriteAccess, IoModifyAccess }; enum mode { - KernelMode, UserMode, MaximumMode + KernelMode, UserMode, MaximumMode }; struct mdl { - struct mdl *next; - CSHORT size; - CSHORT flags; - /* NdisFreeBuffer doesn't pass pool, so we store pool in - * unused field 'process' */ - union { - void *process; - void *pool; - }; - void *mappedsystemva; - void *startva; - ULONG bytecount; - ULONG byteoffset; + struct mdl *next; + CSHORT size; + CSHORT flags; + /* NdisFreeBuffer doesn't pass pool, so we store pool in + * unused field 'process' */ + union { + void *process; + void *pool; + }; + void *mappedsystemva; + void *startva; + ULONG bytecount; + ULONG byteoffset; }; #define MDL_MAPPED_TO_SYSTEM_VA 0x0001 @@ -344,74 +357,74 @@ do { \ } while (0) struct kdevice_queue_entry { - struct nt_list list; - ULONG sort_key; - BOOLEAN inserted; + struct nt_list list; + ULONG sort_key; + BOOLEAN inserted; }; struct kdevice_queue { - USHORT type; - USHORT size; - struct nt_list list; - NT_SPIN_LOCK lock; - BOOLEAN busy; + USHORT type; + USHORT size; + struct nt_list list; + NT_SPIN_LOCK lock; + BOOLEAN busy; }; struct wait_context_block { - struct kdevice_queue_entry wait_queue_entry; - void *device_routine; - void *device_context; - ULONG num_regs; - void *device_object; - void *current_irp; - void *buffer_chaining_dpc; + struct kdevice_queue_entry wait_queue_entry; + void *device_routine; + void *device_context; + ULONG num_regs; + void *device_object; + void *current_irp; + void *buffer_chaining_dpc; }; struct wait_block { - struct nt_list list; - struct task_struct *thread; - void *object; - int *wait_done; - USHORT wait_key; - USHORT wait_type; + struct nt_list list; + struct task_struct *thread; + void *object; + int *wait_done; + USHORT wait_key; + USHORT wait_type; }; struct dispatcher_header { - UCHAR type; - UCHAR absolute; - UCHAR size; - UCHAR inserted; - LONG signal_state; - struct nt_list wait_blocks; + UCHAR type; + UCHAR absolute; + UCHAR size; + UCHAR inserted; + LONG signal_state; + struct nt_list wait_blocks; }; enum event_type { - NotificationEvent, - SynchronizationEvent, + NotificationEvent, + SynchronizationEvent, }; enum timer_type { - NotificationTimer = NotificationEvent, - SynchronizationTimer = SynchronizationEvent, + NotificationTimer = NotificationEvent, + SynchronizationTimer = SynchronizationEvent, }; enum dh_type { - NotificationObject = NotificationEvent, - SynchronizationObject = SynchronizationEvent, - MutexObject, - SemaphoreObject, - ThreadObject, + NotificationObject = NotificationEvent, + SynchronizationObject = SynchronizationEvent, + MutexObject, + SemaphoreObject, + ThreadObject, }; enum wait_type { - WaitAll, WaitAny + WaitAll, WaitAny }; /* objects that use dispatcher_header have it as the first field, so * whenever we need to initialize dispatcher_header, we can convert * that object into a nt_event and access dispatcher_header */ struct nt_event { - struct dispatcher_header dh; + struct dispatcher_header dh; }; struct wrap_timer; @@ -419,47 +432,47 @@ struct wrap_timer; #define WRAP_TIMER_MAGIC 47697249 struct nt_timer { - struct dispatcher_header dh; - /* We can't fit Linux timer in this structure. Instead of - * padding the nt_timer structure, we replace due_time field - * with *wrap_timer and allocate memory for it when nt_timer is - * initialized */ - union { - ULONGLONG due_time; - struct wrap_timer *wrap_timer; - }; - struct nt_list nt_timer_list; - struct kdpc *kdpc; - union { - LONG period; - LONG wrap_timer_magic; - }; + struct dispatcher_header dh; + /* We can't fit Linux timer in this structure. Instead of + * padding the nt_timer structure, we replace due_time field + * with *wrap_timer and allocate memory for it when nt_timer is + * initialized */ + union { + ULONGLONG due_time; + struct wrap_timer *wrap_timer; + }; + struct nt_list nt_timer_list; + struct kdpc *kdpc; + union { + LONG period; + LONG wrap_timer_magic; + }; }; struct nt_mutex { - struct dispatcher_header dh; - struct nt_list list; - struct task_struct *owner_thread; - BOOLEAN abandoned; - BOOLEAN apc_disable; + struct dispatcher_header dh; + struct nt_list list; + struct task_struct *owner_thread; + BOOLEAN abandoned; + BOOLEAN apc_disable; }; struct nt_semaphore { - struct dispatcher_header dh; - LONG limit; + struct dispatcher_header dh; + LONG limit; }; struct nt_thread { - struct dispatcher_header dh; - /* the rest in Windows is a long structure; since this - * structure is opaque to drivers, we just define what we - * need */ - int pid; - NTSTATUS status; - struct task_struct *task; - struct nt_list irps; - NT_SPIN_LOCK lock; - KPRIORITY prio; + struct dispatcher_header dh; + /* the rest in Windows is a long structure; since this + * structure is opaque to drivers, we just define what we + * need */ + int pid; + NTSTATUS status; + struct task_struct *task; + struct nt_list irps; + NT_SPIN_LOCK lock; + KPRIORITY prio; }; #define set_object_type(dh, type) ((dh)->type = (type)) @@ -482,48 +495,48 @@ struct dev_obj_ext; struct driver_object; struct device_object { - CSHORT type; - USHORT size; - LONG ref_count; - struct driver_object *drv_obj; - struct device_object *next; - struct device_object *attached; - struct irp *current_irp; - void *io_timer; - ULONG flags; - ULONG characteristics; - void *vpb; - void *dev_ext; - CCHAR stack_count; - union { - struct nt_list queue_list; - struct wait_context_block wcb; - } queue; - ULONG align_req; - struct kdevice_queue dev_queue; - struct kdpc dpc; - ULONG active_threads; - void *security_desc; - struct nt_event lock; - USHORT sector_size; - USHORT spare1; - struct dev_obj_ext *dev_obj_ext; - void *reserved; + CSHORT type; + USHORT size; + LONG ref_count; + struct driver_object *drv_obj; + struct device_object *next; + struct device_object *attached; + struct irp *current_irp; + void *io_timer; + ULONG flags; + ULONG characteristics; + void *vpb; + void *dev_ext; + CCHAR stack_count; + union { + struct nt_list queue_list; + struct wait_context_block wcb; + } queue; + ULONG align_req; + struct kdevice_queue dev_queue; + struct kdpc dpc; + ULONG active_threads; + void *security_desc; + struct nt_event lock; + USHORT sector_size; + USHORT spare1; + struct dev_obj_ext *dev_obj_ext; + void *reserved; }; struct dev_obj_ext { - CSHORT type; - CSHORT size; - struct device_object *dev_obj; - struct device_object *attached_to; + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + struct device_object *attached_to; }; struct io_status_block { - union { - NTSTATUS status; - void *pointer; - }; - ULONG_PTR info; + union { + NTSTATUS status; + void *pointer; + }; + ULONG_PTR info; }; @@ -535,70 +548,74 @@ typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj, struct irp *irp) wstdcall; struct driver_object { - CSHORT type; - CSHORT size; - struct device_object *dev_obj; - ULONG flags; - void *start; - ULONG driver_size; - void *section; - struct driver_extension *drv_ext; - struct unicode_string name; - struct unicode_string *hardware_database; - void *fast_io_dispatch; - void *init; - void *start_io; - void (*unload)(struct driver_object *driver) wstdcall; - driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + ULONG flags; + void *start; + ULONG driver_size; + void *section; + struct driver_extension *drv_ext; + struct unicode_string name; + struct unicode_string *hardware_database; + void *fast_io_dispatch; + void *init; + void *start_io; + + void (*unload)(struct driver_object *driver) wstdcall; + + driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; }; struct driver_extension { - struct driver_object *drv_obj; - NTSTATUS (*add_device)(struct driver_object *drv_obj, - struct device_object *dev_obj); - ULONG count; - struct unicode_string service_key_name; - struct nt_list custom_ext; + struct driver_object *drv_obj; + + NTSTATUS (*add_device)(struct driver_object *drv_obj, + struct device_object *dev_obj); + + ULONG count; + struct unicode_string service_key_name; + struct nt_list custom_ext; }; struct custom_ext { - struct nt_list list; - void *client_id; + struct nt_list list; + void *client_id; }; struct wrap_bin_file; struct file_object { - CSHORT type; - CSHORT size; - struct device_object *dev_obj; - void *volume_parameter_block; - void *fs_context; - void *fs_context2; - void *section_object_pointer; - void *private_cache_map; - NTSTATUS final_status; - union { - struct file_object *related_file_object; - struct wrap_bin_file *wrap_bin_file; - }; - BOOLEAN lock_operation; - BOOLEAN delete_pending; - BOOLEAN read_access; - BOOLEAN write_access; - BOOLEAN delete_access; - BOOLEAN shared_read; - BOOLEAN shared_write; - BOOLEAN shared_delete; - ULONG flags; - struct unicode_string _name_; - LARGE_INTEGER current_byte_offset; - ULONG waiters; - ULONG busy; - void *last_lock; - struct nt_event lock; - struct nt_event event; - void *completion_context; + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + void *volume_parameter_block; + void *fs_context; + void *fs_context2; + void *section_object_pointer; + void *private_cache_map; + NTSTATUS final_status; + union { + struct file_object *related_file_object; + struct wrap_bin_file *wrap_bin_file; + }; + BOOLEAN lock_operation; + BOOLEAN delete_pending; + BOOLEAN read_access; + BOOLEAN write_access; + BOOLEAN delete_access; + BOOLEAN shared_read; + BOOLEAN shared_write; + BOOLEAN shared_delete; + ULONG flags; + struct unicode_string _name_; + LARGE_INTEGER current_byte_offset; + ULONG waiters; + ULONG busy; + void *last_lock; + struct nt_event lock; + struct nt_event event; + void *completion_context; }; #define POINTER_ALIGN @@ -606,54 +623,56 @@ struct file_object { #define CACHE_ALIGN __attribute__((aligned(128))) enum system_power_state { - PowerSystemUnspecified = 0, - PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, - PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, - PowerSystemMaximum, + PowerSystemUnspecified = 0, + PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, + PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, + PowerSystemMaximum, }; enum device_power_state { - PowerDeviceUnspecified = 0, - PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, - PowerDeviceMaximum, + PowerDeviceUnspecified = 0, + PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, + PowerDeviceMaximum, }; union power_state { - enum system_power_state system_state; - enum device_power_state device_state; + enum system_power_state system_state; + enum device_power_state device_state; }; enum power_state_type { - SystemPowerState = 0, DevicePowerState, + SystemPowerState = 0, DevicePowerState, }; enum power_action { - PowerActionNone = 0, - PowerActionReserved, PowerActionSleep, PowerActionHibernate, - PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, - PowerActionWarmEject, + PowerActionNone = 0, + PowerActionReserved, PowerActionSleep, PowerActionHibernate, + PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, + PowerActionWarmEject, }; typedef struct guid { - ULONG data1; - USHORT data2; - USHORT data3; - UCHAR data4[8]; + ULONG data1; + USHORT data2; + USHORT data3; + UCHAR data4[8]; } GUID, *PGUID, *LPGUID; struct nt_interface { - USHORT size; - USHORT version; - void *context; - void (*reference)(void *context) wstdcall; - void (*dereference)(void *context) wstdcall; + USHORT size; + USHORT version; + void *context; + + void (*reference)(void *context) wstdcall; + + void (*dereference)(void *context) wstdcall; }; enum interface_type { - InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, - TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, - MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, - PNPBus, MaximumInterfaceType, + InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, + TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, + MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, + PNPBus, MaximumInterfaceType, }; #define CmResourceTypeNull 0 @@ -672,8 +691,8 @@ enum interface_type { #define CmResourceTypeMfCardConfig 131 enum cm_share_disposition { - CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, - CmResourceShareDriverExclusive, CmResourceShareShared + CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, CmResourceShareShared }; #define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0 @@ -707,105 +726,105 @@ enum cm_share_disposition { #define MAX_RESOURCES 20 -#pragma pack(push,4) +#pragma pack(push, 4) struct cm_partial_resource_descriptor { - UCHAR type; - UCHAR share; - USHORT flags; - union { - struct { - PHYSICAL_ADDRESS start; - ULONG length; - } generic; - struct { - PHYSICAL_ADDRESS start; - ULONG length; - } port; - struct { - ULONG level; - ULONG vector; - KAFFINITY affinity; - } interrupt; - struct { - PHYSICAL_ADDRESS start; - ULONG length; - } memory; - struct { - ULONG channel; - ULONG port; - ULONG reserved1; - } dma; - struct { - ULONG data[3]; - } device_private; - struct { - ULONG start; - ULONG length; - ULONG reserved; - } bus_number; - struct { - ULONG data_size; - ULONG reserved1; - ULONG reserved2; - } device_specific_data; - } u; + UCHAR type; + UCHAR share; + USHORT flags; + union { + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } generic; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } port; + struct { + ULONG level; + ULONG vector; + KAFFINITY affinity; + } interrupt; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } memory; + struct { + ULONG channel; + ULONG port; + ULONG reserved1; + } dma; + struct { + ULONG data[3]; + } device_private; + struct { + ULONG start; + ULONG length; + ULONG reserved; + } bus_number; + struct { + ULONG data_size; + ULONG reserved1; + ULONG reserved2; + } device_specific_data; + } u; }; #pragma pack(pop) struct cm_partial_resource_list { - USHORT version; - USHORT revision; - ULONG count; - struct cm_partial_resource_descriptor partial_descriptors[1]; + USHORT version; + USHORT revision; + ULONG count; + struct cm_partial_resource_descriptor partial_descriptors[1]; }; struct cm_full_resource_descriptor { - enum interface_type interface_type; - ULONG bus_number; - struct cm_partial_resource_list partial_resource_list; + enum interface_type interface_type; + ULONG bus_number; + struct cm_partial_resource_list partial_resource_list; }; struct cm_resource_list { - ULONG count; - struct cm_full_resource_descriptor list[1]; + ULONG count; + struct cm_full_resource_descriptor list[1]; }; enum file_info_class { - FileDirectoryInformation = 1, - FileBasicInformation = 4, - FileStandardInformation = 5, - FileNameInformation = 9, - FilePositionInformation = 14, - FileAlignmentInformation = 17, - FileNetworkOpenInformation = 34, - FileAttributeTagInformation = 35, - FileMaximumInformation = 41, + FileDirectoryInformation = 1, + FileBasicInformation = 4, + FileStandardInformation = 5, + FileNameInformation = 9, + FilePositionInformation = 14, + FileAlignmentInformation = 17, + FileNetworkOpenInformation = 34, + FileAttributeTagInformation = 35, + FileMaximumInformation = 41, }; enum fs_info_class { - FileFsVolumeInformation = 1, - /* ... */ - FileFsMaximumInformation = 9, + FileFsVolumeInformation = 1, + /* ... */ + FileFsMaximumInformation = 9, }; enum device_relation_type { - BusRelations, EjectionRelations, PowerRelations, RemovalRelations, - TargetDeviceRelation, SingleBusRelations, + BusRelations, EjectionRelations, PowerRelations, RemovalRelations, + TargetDeviceRelation, SingleBusRelations, }; enum bus_query_id_type { - BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, - BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, - BusQueryDeviceSerialNumber = 4, + BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, + BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, + BusQueryDeviceSerialNumber = 4, }; enum device_text_type { - DeviceTextDescription = 0, DeviceTextLocationInformation = 1, + DeviceTextDescription = 0, DeviceTextLocationInformation = 1, }; enum device_usage_notification_type { - DeviceUsageTypeUndefined, DeviceUsageTypePaging, - DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, + DeviceUsageTypeUndefined, DeviceUsageTypePaging, + DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, }; #define METHOD_BUFFERED 0 @@ -819,162 +838,164 @@ enum device_usage_notification_type { #define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3) struct io_stack_location { - UCHAR major_fn; - UCHAR minor_fn; - UCHAR flags; - UCHAR control; - union { - struct { - void *security_context; - ULONG options; - USHORT POINTER_ALIGN file_attributes; - USHORT share_access; - ULONG POINTER_ALIGN ea_length; - } create; - struct { - ULONG length; - ULONG POINTER_ALIGN key; - LARGE_INTEGER byte_offset; - } read; - struct { - ULONG length; - ULONG POINTER_ALIGN key; - LARGE_INTEGER byte_offset; - } write; - struct { - ULONG length; - enum file_info_class POINTER_ALIGN file_info_class; - } query_file; - struct { - ULONG length; - enum file_info_class POINTER_ALIGN file_info_class; - struct file_object *file_object; - union { - struct { - BOOLEAN replace_if_exists; - BOOLEAN advance_only; - }; - ULONG cluster_count; - void *delete_handle; - }; - } set_file; - struct { - ULONG length; - enum fs_info_class POINTER_ALIGN fs_info_class; - } query_volume; - struct { - ULONG output_buf_len; - ULONG POINTER_ALIGN input_buf_len; - ULONG POINTER_ALIGN code; - void *type3_input_buf; - } dev_ioctl; - struct { - SECURITY_INFORMATION security_info; - ULONG POINTER_ALIGN length; - } query_security; - struct { - SECURITY_INFORMATION security_info; - void *security_descriptor; - } set_security; - struct { - void *vpb; - struct device_object *device_object; - } mount_volume; - struct { - void *vpb; - struct device_object *device_object; - } verify_volume; - struct { - void *srb; - } scsi; - struct { - enum device_relation_type type; - } query_device_relations; - struct { - const struct guid *type; - USHORT size; - USHORT version; - struct nt_interface *intf; - void *intf_data; - } query_intf; - struct { - void *capabilities; - } device_capabilities; - struct { - void *io_resource_requirement_list; - } filter_resource_requirements; - struct { - ULONG which_space; - void *buffer; - ULONG offset; - ULONG POINTER_ALIGN length; - } read_write_config; - struct { - BOOLEAN lock; - } set_lock; - struct { - enum bus_query_id_type id_type; - } query_id; - struct { - enum device_text_type device_text_type; - ULONG POINTER_ALIGN locale_id; - } query_device_text; - struct { - BOOLEAN in_path; - BOOLEAN reserved[3]; - enum device_usage_notification_type POINTER_ALIGN type; - } usage_notification; - struct { - enum system_power_state power_state; - } wait_wake; - struct { - void *power_sequence; - } power_sequence; - struct { - ULONG sys_context; - enum power_state_type POINTER_ALIGN type; - union power_state POINTER_ALIGN state; - enum power_action POINTER_ALIGN shutdown_type; - } power; - struct { - struct cm_resource_list *allocated_resources; - struct cm_resource_list *allocated_resources_translated; - } start_device; - struct { - ULONG_PTR provider_id; - void *data_path; - ULONG buf_len; - void *buf; - } wmi; + UCHAR major_fn; + UCHAR minor_fn; + UCHAR flags; + UCHAR control; + union { + struct { + void *security_context; + ULONG options; + USHORT POINTER_ALIGN file_attributes; + USHORT share_access; + ULONG POINTER_ALIGN ea_length; + } create; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } read; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } write; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + } query_file; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + struct file_object *file_object; + union { struct { - void *arg1; - void *arg2; - void *arg3; - void *arg4; - } others; - } params; - struct device_object *dev_obj; - struct file_object *file_obj; - NTSTATUS (*completion_routine)(struct device_object *, - struct irp *, void *) wstdcall; - void *context; + BOOLEAN replace_if_exists; + BOOLEAN advance_only; + }; + ULONG cluster_count; + void *delete_handle; + }; + } set_file; + struct { + ULONG length; + enum fs_info_class POINTER_ALIGN fs_info_class; + } query_volume; + struct { + ULONG output_buf_len; + ULONG POINTER_ALIGN input_buf_len; + ULONG POINTER_ALIGN code; + void *type3_input_buf; + } dev_ioctl; + struct { + SECURITY_INFORMATION security_info; + ULONG POINTER_ALIGN length; + } query_security; + struct { + SECURITY_INFORMATION security_info; + void *security_descriptor; + } set_security; + struct { + void *vpb; + struct device_object *device_object; + } mount_volume; + struct { + void *vpb; + struct device_object *device_object; + } verify_volume; + struct { + void *srb; + } scsi; + struct { + enum device_relation_type type; + } query_device_relations; + struct { + const struct guid *type; + USHORT size; + USHORT version; + struct nt_interface *intf; + void *intf_data; + } query_intf; + struct { + void *capabilities; + } device_capabilities; + struct { + void *io_resource_requirement_list; + } filter_resource_requirements; + struct { + ULONG which_space; + void *buffer; + ULONG offset; + ULONG POINTER_ALIGN length; + } read_write_config; + struct { + BOOLEAN lock; + } set_lock; + struct { + enum bus_query_id_type id_type; + } query_id; + struct { + enum device_text_type device_text_type; + ULONG POINTER_ALIGN locale_id; + } query_device_text; + struct { + BOOLEAN in_path; + BOOLEAN reserved[3]; + enum device_usage_notification_type POINTER_ALIGN type; + } usage_notification; + struct { + enum system_power_state power_state; + } wait_wake; + struct { + void *power_sequence; + } power_sequence; + struct { + ULONG sys_context; + enum power_state_type POINTER_ALIGN type; + union power_state POINTER_ALIGN state; + enum power_action POINTER_ALIGN shutdown_type; + } power; + struct { + struct cm_resource_list *allocated_resources; + struct cm_resource_list *allocated_resources_translated; + } start_device; + struct { + ULONG_PTR provider_id; + void *data_path; + ULONG buf_len; + void *buf; + } wmi; + struct { + void *arg1; + void *arg2; + void *arg3; + void *arg4; + } others; + } params; + struct device_object *dev_obj; + struct file_object *file_obj; + + NTSTATUS (*completion_routine)(struct device_object *, + struct irp *, void *) wstdcall; + + void *context; }; struct kapc { - CSHORT type; - CSHORT size; - ULONG spare0; - struct nt_thread *thread; - struct nt_list list; - void *kernele_routine; - void *rundown_routine; - void *normal_routine; - void *normal_context; - void *sys_arg1; - void *sys_arg2; - CCHAR apc_state_index; - KPROCESSOR_MODE apc_mode; - BOOLEAN inserted; + CSHORT type; + CSHORT size; + ULONG spare0; + struct nt_thread *thread; + struct nt_list list; + void *kernele_routine; + void *rundown_routine; + void *normal_routine; + void *normal_context; + void *sys_arg1; + void *sys_arg2; + CCHAR apc_state_index; + KPROCESSOR_MODE apc_mode; + BOOLEAN inserted; }; #define IRP_NOCACHE 0x00000001 @@ -982,82 +1003,85 @@ struct kapc { #define IRP_ASSOCIATED_IRP 0x00000008 enum urb_state { - URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, - URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED }; + URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, + URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED +}; struct wrap_urb { - struct nt_list list; - enum urb_state state; - struct nt_list complete_list; - unsigned int flags; - struct urb *urb; - struct irp *irp; + struct nt_list list; + enum urb_state state; + struct nt_list complete_list; + unsigned int flags; + struct urb *urb; + struct irp *irp; #ifdef USB_DEBUG - unsigned int id; + unsigned int id; #endif }; struct irp { - SHORT type; - USHORT size; - struct mdl *mdl; - ULONG flags; - union { - struct irp *master_irp; - LONG irp_count; - void *system_buffer; - } associated_irp; - struct nt_list thread_list; - struct io_status_block io_status; - KPROCESSOR_MODE requestor_mode; - BOOLEAN pending_returned; - CHAR stack_count; - CHAR current_location; - BOOLEAN cancel; - KIRQL cancel_irql; - CCHAR apc_env; - UCHAR alloc_flags; - struct io_status_block *user_status; - struct nt_event *user_event; - union { - struct { - void *user_apc_routine; - void *user_apc_context; - } async_params; - LARGE_INTEGER alloc_size; - } overlay; - void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; - void *user_buf; - union { + SHORT type; + USHORT size; + struct mdl *mdl; + ULONG flags; + union { + struct irp *master_irp; + LONG irp_count; + void *system_buffer; + } associated_irp; + struct nt_list thread_list; + struct io_status_block io_status; + KPROCESSOR_MODE requestor_mode; + BOOLEAN pending_returned; + CHAR stack_count; + CHAR current_location; + BOOLEAN cancel; + KIRQL cancel_irql; + CCHAR apc_env; + UCHAR alloc_flags; + struct io_status_block *user_status; + struct nt_event *user_event; + union { + struct { + void *user_apc_routine; + void *user_apc_context; + } async_params; + LARGE_INTEGER alloc_size; + } overlay; + + void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; + + void *user_buf; + union { + struct { + union { + struct kdevice_queue_entry dev_q_entry; struct { - union { - struct kdevice_queue_entry dev_q_entry; - struct { - void *driver_context[4]; - }; - }; - void *thread; - char *aux_buf; - struct { - struct nt_list list; - union { - struct io_stack_location *csl; - ULONG packet_type; - }; - }; - struct file_object *file_object; - } overlay; + void *driver_context[4]; + }; + }; + void *thread; + char *aux_buf; + struct { + struct nt_list list; union { - struct kapc apc; - /* space for apc is used for ndiswrapper - * specific fields */ - struct { - struct wrap_urb *wrap_urb; - struct wrap_device *wrap_device; - }; + struct io_stack_location *csl; + ULONG packet_type; }; - void *completion_key; - } tail; + }; + struct file_object *file_object; + } overlay; + union { + struct kapc apc; + /* space for apc is used for ndiswrapper + * specific fields */ + struct { + struct wrap_urb *wrap_urb; + struct wrap_device *wrap_device; + }; + }; + void *completion_key; + } tail; }; #define IoSizeOfIrp(stack_count) \ @@ -1089,29 +1113,27 @@ do { \ } while (0) static inline void -IoCopyCurrentIrpStackLocationToNext(struct irp *irp) -{ - struct io_stack_location *next; - next = IoGetNextIrpStackLocation(irp); - memcpy(next, IoGetCurrentIrpStackLocation(irp), - offsetof(struct io_stack_location, completion_routine)); - next->control = 0; +IoCopyCurrentIrpStackLocationToNext(struct irp *irp) { + struct io_stack_location *next; + next = IoGetNextIrpStackLocation(irp); + memcpy(next, IoGetCurrentIrpStackLocation(irp), + offsetof(struct io_stack_location, completion_routine)); + next->control = 0; } static inline void IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, - BOOLEAN success, BOOLEAN error, BOOLEAN cancel) -{ - struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); - irp_sl->completion_routine = routine; - irp_sl->context = context; - irp_sl->control = 0; - if (success) - irp_sl->control |= SL_INVOKE_ON_SUCCESS; - if (error) - irp_sl->control |= SL_INVOKE_ON_ERROR; - if (cancel) - irp_sl->control |= SL_INVOKE_ON_CANCEL; + BOOLEAN success, BOOLEAN error, BOOLEAN cancel) { + struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->completion_routine = routine; + irp_sl->context = context; + irp_sl->control = 0; + if (success) + irp_sl->control |= SL_INVOKE_ON_SUCCESS; + if (error) + irp_sl->control |= SL_INVOKE_ON_ERROR; + if (cancel) + irp_sl->control |= SL_INVOKE_ON_CANCEL; } #define IoMarkIrpPending(irp) \ @@ -1130,59 +1152,59 @@ IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, #define IRP_WRAP_URB(irp) (irp)->tail.wrap_urb struct wmi_guid_reg_info { - struct guid *guid; - ULONG instance_count; - ULONG flags; + struct guid *guid; + ULONG instance_count; + ULONG flags; }; struct wmilib_context { - ULONG guid_count; - struct wmi_guid_reg_info *guid_list; - void *query_wmi_reg_info; - void *query_wmi_data_block; - void *set_wmi_data_block; - void *set_wmi_data_item; - void *execute_wmi_method; - void *wmi_function_control; + ULONG guid_count; + struct wmi_guid_reg_info *guid_list; + void *query_wmi_reg_info; + void *query_wmi_data_block; + void *set_wmi_data_block; + void *set_wmi_data_item; + void *execute_wmi_method; + void *wmi_function_control; }; enum key_value_information_class { - KeyValueBasicInformation, KeyValueFullInformation, - KeyValuePartialInformation, KeyValueFullInformationAlign64, - KeyValuePartialInformationAlign64 + KeyValueBasicInformation, KeyValueFullInformation, + KeyValuePartialInformation, KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64 }; struct file_name_info { - ULONG length; - wchar_t *name; + ULONG length; + wchar_t *name; }; struct file_std_info { - LARGE_INTEGER alloc_size; - LARGE_INTEGER eof; - ULONG num_links; - BOOLEAN delete_pending; - BOOLEAN dir; + LARGE_INTEGER alloc_size; + LARGE_INTEGER eof; + ULONG num_links; + BOOLEAN delete_pending; + BOOLEAN dir; }; enum nt_obj_type { - NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, - NT_OBJ_SEMAPHORE, + NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, + NT_OBJ_SEMAPHORE, }; enum common_object_type { - OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, - OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, + OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, + OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, }; struct common_object_header { - struct nt_list list; - enum common_object_type type; - UINT size; - UINT ref_count; - BOOLEAN close_in_process; - BOOLEAN permanent; - struct unicode_string name; + struct nt_list list; + enum common_object_type type; + UINT size; + UINT ref_count; + BOOLEAN close_in_process; + BOOLEAN permanent; + struct unicode_string name; }; #define OBJECT_TO_HEADER(object) \ @@ -1196,140 +1218,142 @@ struct common_object_header { #define HANDLE_TO_HEADER(handle) (handle) enum work_queue_type { - CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, - MaximumWorkQueue + CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, + MaximumWorkQueue }; typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall; struct io_workitem { - enum work_queue_type type; - struct device_object *dev_obj; - NTOS_WORK_FUNC worker_routine; - void *context; + enum work_queue_type type; + struct device_object *dev_obj; + NTOS_WORK_FUNC worker_routine; + void *context; }; struct io_workitem_entry { - struct nt_list list; - struct io_workitem *io_workitem; + struct nt_list list; + struct io_workitem *io_workitem; }; enum mm_page_priority { - LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 + LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 }; enum kinterrupt_mode { - LevelSensitive, Latched + LevelSensitive, Latched }; enum ntos_wait_reason { - Executive, FreePage, PageIn, PoolAllocation, DelayExecution, - Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, - WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, - WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, - WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, - WrKernel, MaximumWaitReason + Executive, FreePage, PageIn, PoolAllocation, DelayExecution, + Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, + WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, + WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, + WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, + WrKernel, MaximumWaitReason }; typedef enum ntos_wait_reason KWAIT_REASON; typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type, SIZE_T size, ULONG tag) wstdcall; + typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall; struct npaged_lookaside_list { - nt_slist_header head; - USHORT depth; - USHORT maxdepth; - ULONG totalallocs; - union { - ULONG allocmisses; - ULONG allochits; - } u1; - ULONG totalfrees; - union { - ULONG freemisses; - ULONG freehits; - } u2; - enum pool_type pool_type; - ULONG tag; - ULONG size; - LOOKASIDE_ALLOC_FUNC *alloc_func; - LOOKASIDE_FREE_FUNC *free_func; - struct nt_list list; - ULONG lasttotallocs; - union { - ULONG lastallocmisses; - ULONG lastallochits; - } u3; - ULONG pad[2]; -} -; + nt_slist_header head; + USHORT depth; + USHORT maxdepth; + ULONG totalallocs; + union { + ULONG allocmisses; + ULONG allochits; + } u1; + ULONG totalfrees; + union { + ULONG freemisses; + ULONG freehits; + } u2; + enum pool_type pool_type; + ULONG tag; + ULONG size; + LOOKASIDE_ALLOC_FUNC *alloc_func; + LOOKASIDE_FREE_FUNC *free_func; + struct nt_list list; + ULONG lasttotallocs; + union { + ULONG lastallocmisses; + ULONG lastallochits; + } u3; + ULONG pad[2]; +}; enum device_registry_property { - DevicePropertyDeviceDescription, DevicePropertyHardwareID, - DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, - DevicePropertyBootConfigurationTranslated, - DevicePropertyClassName, DevicePropertyClassGuid, - DevicePropertyDriverKeyName, DevicePropertyManufacturer, - DevicePropertyFriendlyName, DevicePropertyLocationInformation, - DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, - DevicePropertyLegacyBusType, DevicePropertyBusNumber, - DevicePropertyEnumeratorName, DevicePropertyAddress, - DevicePropertyUINumber, DevicePropertyInstallState, - DevicePropertyRemovalPolicy + DevicePropertyDeviceDescription, DevicePropertyHardwareID, + DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, + DevicePropertyBootConfigurationTranslated, + DevicePropertyClassName, DevicePropertyClassGuid, + DevicePropertyDriverKeyName, DevicePropertyManufacturer, + DevicePropertyFriendlyName, DevicePropertyLocationInformation, + DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, + DevicePropertyLegacyBusType, DevicePropertyBusNumber, + DevicePropertyEnumeratorName, DevicePropertyAddress, + DevicePropertyUINumber, DevicePropertyInstallState, + DevicePropertyRemovalPolicy }; enum trace_information_class { - TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, - TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, - AllLoggerHandlesClass, TraceHandleByNameClass + TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, + TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, + AllLoggerHandlesClass, TraceHandleByNameClass }; struct kinterrupt; + typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt, void *context) wstdcall; + typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall; struct kinterrupt { - ULONG vector; - KAFFINITY cpu_mask; - NT_SPIN_LOCK lock; - NT_SPIN_LOCK *actual_lock; - BOOLEAN shared; - BOOLEAN save_fp; - union { - CHAR processor_number; + ULONG vector; + KAFFINITY cpu_mask; + NT_SPIN_LOCK lock; + NT_SPIN_LOCK *actual_lock; + BOOLEAN shared; + BOOLEAN save_fp; + union { + CHAR processor_number; #ifdef CONFIG_DEBUG_SHIRQ - CHAR enabled; + CHAR enabled; #endif - } u; - PKSERVICE_ROUTINE isr; - void *isr_ctx; - struct nt_list list; - KIRQL irql; - KIRQL synch_irql; - enum kinterrupt_mode mode; + } u; + PKSERVICE_ROUTINE isr; + void *isr_ctx; + struct nt_list list; + KIRQL irql; + KIRQL synch_irql; + enum kinterrupt_mode mode; }; struct time_fields { - CSHORT year; - CSHORT month; - CSHORT day; - CSHORT hour; - CSHORT minute; - CSHORT second; - CSHORT milliseconds; - CSHORT weekday; + CSHORT year; + CSHORT month; + CSHORT day; + CSHORT hour; + CSHORT minute; + CSHORT second; + CSHORT milliseconds; + CSHORT weekday; }; struct object_attributes { - ULONG length; - void *root_dir; - struct unicode_string *name; - ULONG attributes; - void *security_descr; - void *security_qos; + ULONG length; + void *root_dir; + struct unicode_string *name; + ULONG attributes; + void *security_descr; + void *security_qos; }; typedef void (*PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData) wstdcall; @@ -1339,75 +1363,232 @@ typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1, struct callback_object; struct callback_func { - PCALLBACK_FUNCTION func; - void *context; - struct nt_list list; - struct callback_object *object; + PCALLBACK_FUNCTION func; + void *context; + struct nt_list list; + struct callback_object *object; }; struct callback_object { - NT_SPIN_LOCK lock; - struct nt_list list; - struct nt_list callback_funcs; - BOOLEAN allow_multiple_callbacks; - struct object_attributes *attributes; + NT_SPIN_LOCK lock; + struct nt_list list; + struct nt_list callback_funcs; + BOOLEAN allow_multiple_callbacks; + struct object_attributes *attributes; }; enum section_inherit { - ViewShare = 1, ViewUnmap = 2 + ViewShare = 1, ViewUnmap = 2 }; struct ksystem_time { - ULONG low_part; - LONG high1_time; - LONG high2_time; + ULONG low_part; + LONG high1_time; + LONG high2_time; }; enum nt_product_type { - nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server + nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server }; enum alt_arch_type { - arch_type_standard, arch_type_nex98x86, end_alternatives + arch_type_standard, arch_type_nex98x86, end_alternatives }; #define EXCEPTION_MAXIMUM_PARAMETERS 15 #define MAXIMUM_SUPPORTED_EXTENSION 512 #define SIZE_OF_80387_REGISTERS 80 -typedef enum -{ - ExceptionContinueExecution = 0, - ExceptionContinueSearch = 1, - ExceptionNestedException = 2, - ExceptionCollidedUnwind = 3 +typedef enum { + ExceptionContinueExecution = 0, + ExceptionContinueSearch = 1, + ExceptionNestedException = 2, + ExceptionCollidedUnwind = 3 } EXCEPTION_DISPOSITION; typedef struct _EXCEPTION_RECORD { - DWORD ExceptionCode; - DWORD ExceptionFlags; - struct _EXCEPTION_RECORD *ExceptionRecord; - PVOID ExceptionAddress; - DWORD NumberParameters; - ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct _EXCEPTION_RECORD *ExceptionRecord; + PVOID ExceptionAddress; + long NumberParameters; + ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD, *PEXCEPTION_RECORD; typedef struct _FLOATING_SAVE_AREA { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; - DWORD Cr0NpxState; + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; + DWORD Cr0NpxState; } FLOATING_SAVE_AREA; +#ifdef __x86_64__ +typedef struct _M128A { + ULONGLONG Low; + LONGLONG High; +} M128A, *PM128A; + +typedef struct _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + +#if defined(_WIN64) + + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + +#else + + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + +#endif + +} XSAVE_FORMAT, *PXSAVE_FORMAT; + +typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + +typedef struct _CONTEXT { + + // + // Register parameter home addresses. + // + // N.B. These fields are for convience - they could be used to extend the + // context record in the future. + // + + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + + // + // Control flags. + // + + DWORD ContextFlags; + DWORD MxCsr; + + // + // Segment Registers and processor flags. + // + + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + + // + // Debug registers + // + + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + + // + // Integer registers. + // + + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + + // + // Program counter. + // + + DWORD64 Rip; + + // + // Floating point state. + // + + union { + XMM_SAVE_AREA32 FltSave; + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + // + // Vector registers. + // + + M128A VectorRegister[26]; + DWORD64 VectorControl; + + // + // Special debug control registers. + // + + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; +} CONTEXT, *PCONTEXT; + +#else typedef struct _CONTEXT { DWORD ContextFlags; - DWORD Dr0; + DWORD Drct0; DWORD Dr1; DWORD Dr2; DWORD Dr3; @@ -1437,22 +1618,23 @@ typedef struct _CONTEXT { BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; } CONTEXT; +#endif struct _EXCEPTION_FRAME; typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER)( - struct _EXCEPTION_RECORD *ExceptionRecord, - struct _EXCEPTION_FRAME *EstablisherFrame, - struct _CONTEXT *ContextRecord, - struct _EXCEPTION_FRAME **DispatcherContext); + struct _EXCEPTION_RECORD *ExceptionRecord, + struct _EXCEPTION_FRAME *EstablisherFrame, + PVOID *ContextRecord, + struct _EXCEPTION_FRAME **DispatcherContext); typedef struct _EXCEPTION_FRAME { - struct _EXCEPTION_FRAME *prev; - PEXCEPTION_HANDLER handler; + struct _EXCEPTION_FRAME *prev; + PEXCEPTION_HANDLER handler; } EXCEPTION_FRAME, *PEXCEPTION_FRAME; typedef struct _RTL_BITMAP { - ULONG SizeOfBitMap; + ULONG SizeOfBitMap; LPBYTE Buffer; } RTL_BITMAP, *PRTL_BITMAP; @@ -1466,44 +1648,44 @@ typedef struct _RTL_BITMAP_RUN { typedef const RTL_BITMAP_RUN *PCRTL_BITMAP_RUN; typedef struct _KUSER_SHARED_DATA { - ULONG tick_count; - ULONG tick_count_multiplier; - volatile struct ksystem_time interrupt_time; - volatile struct ksystem_time system_time; - volatile struct ksystem_time time_zone_bias; - USHORT image_number_low; - USHORT image_number_high; - wchar_t nt_system_root[260]; - ULONG max_stack_trace_depth; - ULONG crypto_exponent; - ULONG time_zone_id; - ULONG large_page_min; - ULONG reserved2[7]; - enum nt_product_type nt_product_type; - BOOLEAN product_type_is_valid; - ULONG nt_major_version; - ULONG nt_minor_version; - BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; - ULONG reserved1; - ULONG reserved3; - volatile LONG time_slip; - enum alt_arch_type alt_arch_type; - LARGE_INTEGER system_expiration_date; - ULONG suite_mask; - BOOLEAN kdbg_enabled; - volatile ULONG active_console; - volatile ULONG dismount_count; - ULONG com_plus_package; - ULONG last_system_rite_event_tick_count; - ULONG num_phys_pages; - BOOLEAN safe_boot_mode; - ULONG trace_log; - ULONGLONG fill0; - ULONGLONG sys_call[4]; - union { - volatile struct ksystem_time tick_count; - volatile ULONG64 tick_count_quad; - } tick; + ULONG tick_count; + ULONG tick_count_multiplier; + volatile struct ksystem_time interrupt_time; + volatile struct ksystem_time system_time; + volatile struct ksystem_time time_zone_bias; + USHORT image_number_low; + USHORT image_number_high; + wchar_t nt_system_root[260]; + ULONG max_stack_trace_depth; + ULONG crypto_exponent; + ULONG time_zone_id; + ULONG large_page_min; + ULONG reserved2[7]; + enum nt_product_type nt_product_type; + BOOLEAN product_type_is_valid; + ULONG nt_major_version; + ULONG nt_minor_version; + BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; + ULONG reserved1; + ULONG reserved3; + volatile LONG time_slip; + enum alt_arch_type alt_arch_type; + LARGE_INTEGER system_expiration_date; + ULONG suite_mask; + BOOLEAN kdbg_enabled; + volatile ULONG active_console; + volatile ULONG dismount_count; + ULONG com_plus_package; + ULONG last_system_rite_event_tick_count; + ULONG num_phys_pages; + BOOLEAN safe_boot_mode; + ULONG trace_log; + ULONGLONG fill0; + ULONGLONG sys_call[4]; + union { + volatile struct ksystem_time tick_count; + volatile ULONG64 tick_count_quad; + } tick; } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA; #define REG_NONE (0) @@ -1536,36 +1718,36 @@ typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type, void *entry) wstdcall; struct rtl_query_registry_table { - PRTL_QUERY_REGISTRY_ROUTINE query_func; - ULONG flags; - wchar_t *name; - void *context; - ULONG def_type; - void *def_data; - ULONG def_length; + PRTL_QUERY_REGISTRY_ROUTINE query_func; + ULONG flags; + wchar_t *name; + void *context; + ULONG def_type; + void *def_data; + ULONG def_length; }; struct io_remove_lock { - BOOLEAN removed; - BOOLEAN reserved[3]; - LONG io_count; - struct nt_event remove_event; + BOOLEAN removed; + BOOLEAN reserved[3]; + LONG io_count; + struct nt_event remove_event; }; struct io_error_log_packet { - UCHAR major_fn_code; - UCHAR retry_count; - USHORT dump_data_size; - USHORT nr_of_strings; - USHORT string_offset; - USHORT event_category; - NTSTATUS error_code; - ULONG unique_error_value; - NTSTATUS final_status; - ULONG sequence_number; - ULONG io_control_code; - LARGE_INTEGER device_offset; - ULONG dump_data[1]; + UCHAR major_fn_code; + UCHAR retry_count; + USHORT dump_data_size; + USHORT nr_of_strings; + USHORT string_offset; + USHORT event_category; + NTSTATUS error_code; + ULONG unique_error_value; + NTSTATUS final_status; + ULONG sequence_number; + ULONG io_control_code; + LARGE_INTEGER device_offset; + ULONG dump_data[1]; }; /* some of the functions below are slightly different from DDK's @@ -1577,86 +1759,78 @@ struct io_error_log_packet { * worry about Linux's list being different from nt_list (right now * they are same, but in future they could be different) */ -static inline void InitializeListHead(struct nt_list *head) -{ - head->next = head->prev = head; +static inline void InitializeListHead(struct nt_list *head) { + head->next = head->prev = head; } -static inline BOOLEAN IsListEmpty(struct nt_list *head) -{ - if (head == head->next) - return TRUE; - else - return FALSE; +static inline BOOLEAN IsListEmpty(struct nt_list *head) { + if (head == head->next) + return TRUE; + else + return FALSE; } -static inline void RemoveEntryList(struct nt_list *entry) -{ - entry->prev->next = entry->next; - entry->next->prev = entry->prev; +static inline void RemoveEntryList(struct nt_list *entry) { + entry->prev->next = entry->next; + entry->next->prev = entry->prev; } -static inline struct nt_list *RemoveHeadList(struct nt_list *head) -{ - struct nt_list *entry; - - entry = head->next; - if (entry == head) - return NULL; - else { - RemoveEntryList(entry); - return entry; - } +static inline struct nt_list *RemoveHeadList(struct nt_list *head) { + struct nt_list *entry; + + entry = head->next; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } } -static inline struct nt_list *RemoveTailList(struct nt_list *head) -{ - struct nt_list *entry; - - entry = head->prev; - if (entry == head) - return NULL; - else { - RemoveEntryList(entry); - return entry; - } +static inline struct nt_list *RemoveTailList(struct nt_list *head) { + struct nt_list *entry; + + entry = head->prev; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } } static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev, - struct nt_list *next) -{ - next->prev = entry; - entry->next = next; - entry->prev = prev; - prev->next = entry; + struct nt_list *next) { + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; } static inline struct nt_list *InsertHeadList(struct nt_list *head, - struct nt_list *entry) -{ - struct nt_list *ret; + struct nt_list *entry) { + struct nt_list *ret; - if (IsListEmpty(head)) - ret = NULL; - else - ret = head->next; + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->next; - InsertListEntry(entry, head, head->next); - return ret; + InsertListEntry(entry, head, head->next); + return ret; } static inline struct nt_list *InsertTailList(struct nt_list *head, - struct nt_list *entry) -{ - struct nt_list *ret; + struct nt_list *entry) { + struct nt_list *ret; - if (IsListEmpty(head)) - ret = NULL; - else - ret = head->prev; + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->prev; - InsertListEntry(entry, head->prev, head); - return ret; + InsertListEntry(entry, head->prev, head); + return ret; } #define nt_list_for_each(pos, head) \ @@ -1830,4 +2004,264 @@ typedef enum _HEAP_INFORMATION_CLASS { HeapEnableTerminationOnCorruption } HEAP_INFORMATION_CLASS; +typedef enum _EVENT_INFO_CLASS { + EventProviderBinaryTrackInfo, + EventProviderSetReserved1, + EventProviderSetTraits, + EventProviderUseDescriptorType, + MaxEventInfo +} EVENT_INFO_CLASS; + +typedef enum _PROCESS_MITIGATION_POLICY { + ProcessDEPPolicy, + ProcessASLRPolicy, + ProcessDynamicCodePolicy, + ProcessStrictHandleCheckPolicy, + ProcessSystemCallDisablePolicy, + ProcessMitigationOptionsMask, + ProcessExtensionPointDisablePolicy, + ProcessControlFlowGuardPolicy, + ProcessSignaturePolicy, + ProcessFontDisablePolicy, + ProcessImageLoadPolicy, + ProcessSystemCallFilterPolicy, + ProcessPayloadRestrictionPolicy, + ProcessChildProcessPolicy, + ProcessSideChannelIsolationPolicy, + ProcessUserShadowStackPolicy, + MaxProcessMitigationPolicy +} PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY; + +typedef enum _FILE_INFO_BY_HANDLE_CLASS { + FileBasicInfo, + FileStandardInfo, + FileNameInfo, + FileRenameInfo, + FileDispositionInfo, + FileAllocationInfo, + FileEndOfFileInfo, + FileStreamInfo, + FileCompressionInfo, + FileAttributeTagInfo, + FileIdBothDirectoryInfo, + FileIdBothDirectoryRestartInfo, + FileIoPriorityHintInfo, + FileRemoteProtocolInfo, + FileFullDirectoryInfo, + FileFullDirectoryRestartInfo, + FileStorageInfo, + FileAlignmentInfo, + FileIdInfo, + FileIdExtdDirectoryInfo, + FileIdExtdDirectoryRestartInfo, + FileDispositionInfoEx, + FileRenameInfoEx, + FileCaseSensitiveInfo, + FileNormalizedNameInfo, + MaximumFileInfoByHandleClass +} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS; + +#define CSTR_LESS_THAN 0 +#define CSTR_EQUAL 1 +#define CSTR_GREATER_THAN 2 + +typedef union _RTL_RUN_ONCE { + PVOID Ptr; +} RTL_RUN_ONCE, *PRTL_RUN_ONCE; + +typedef union _UNWIND_CODE { + struct { + UBYTE CodeOffset; + UBYTE UnwindOp: 4; + UBYTE OpInfo: 4; + }; + USHORT FrameOffset; +} UNWIND_CODE, *PUNWIND_CODE; + +#define STATUS_INVALID_DISPOSITION ((DWORD) 0xC0000026L) + +#define UWOP_PUSH_NONVOL 0 // info == register number +#define UWOP_ALLOC_LARGE 1 // no info, alloc size in next 2 slots +#define UWOP_ALLOC_SMALL 2 // info == size of allocation / 8 - 1 +#define UWOP_SET_FPREG 3 // no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 +#define UWOP_SAVE_NONVOL 4 // info == register number, offset in next slot +#define UWOP_SAVE_NONVOL_FAR 5 // info == register number, offset in next 2 slots +#define UWOP_SAVE_XMM 6 // Version 1; undocumented +#define UWOP_EPILOG 6 // Version 2; undocumented +#define UWOP_SAVE_XMM_FAR 7 // Version 1; undocumented +#define UWOP_SPARE_CODE 7 // Version 2; undocumented +#define UWOP_SAVE_XMM128 8 // info == XMM reg number, offset in next slot +#define UWOP_SAVE_XMM128_FAR 9 // info == XMM reg number, offset in next 2 slots +#define UWOP_PUSH_MACHFRAME 10 // info == 0: no error-code, 1: error-code + +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + +enum +{ + UNW_FLAG_NHANDLER = 0x00, + UNW_FLAG_EHANDLER = 0x01, + UNW_FLAG_UHANDLER = 0x02, + UNW_FLAG_CHAININFO = 0x04, +}; + +typedef struct _UNWIND_INFO { + UBYTE Version: 3; + UBYTE Flags: 5; + UBYTE SizeOfProlog; + UBYTE CountOfCodes; //so the beginning of ExceptionData is known as they're both FAMs + UBYTE FrameRegister: 4; + UBYTE FrameOffset: 4; + UNWIND_CODE UnwindCode[1]; + union { + // + // If (Flags & UNW_FLAG_EHANDLER) + // + ULONG ExceptionHandler; + // + // Else if (Flags & UNW_FLAG_CHAININFO) + // + ULONG FunctionEntry; + }; + // + // If (Flags & UNW_FLAG_EHANDLER) + // + ULONG ExceptionData[]; +} UNWIND_INFO, *PUNWIND_INFO; + +typedef struct _RUNTIME_FUNCTION { + DWORD BeginAddress; + DWORD EndAddress; + DWORD UnwindData; +} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; + +#define UNWIND_HISTORY_TABLE_SIZE 12 + +typedef struct _UNWIND_HISTORY_TABLE_ENTRY { + DWORD64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; +} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY; + +typedef struct _UNWIND_HISTORY_TABLE { + DWORD Count; + BYTE LocalHint; + BYTE GlobalHint; + BYTE Search; + BYTE Once; + DWORD64 LowAddress; + DWORD64 HighAddress; + UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE]; +} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE; + +typedef struct _FRAME_POINTERS { + ULONGLONG MemoryStackFp; + ULONGLONG BackingStoreFp; +} FRAME_POINTERS, *PFRAME_POINTERS; + +typedef EXCEPTION_DISPOSITION +WINAPI EXCEPTION_ROUTINE( + struct _EXCEPTION_RECORD *ExceptionRecord, + PVOID EstablisherFrame, + struct _CONTEXT *ContextRecord, + PVOID DispatcherContext); + +typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE; + +typedef struct _DISPATCHER_CONTEXT +{ + ULONG64 ControlPc; + ULONG64 ImageBase; + struct _RUNTIME_FUNCTION *FunctionEntry; + ULONG64 EstablisherFrame; + ULONG64 TargetIp; + CONTEXT *ContextRecord; + PEXCEPTION_ROUTINE LanguageHandler; + PVOID HandlerData; + struct _UNWIND_HISTORY_TABLE *HistoryTable; + ULONG ScopeIndex; + ULONG Fill0; +} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; + +#ifdef __x86_64__ +typedef struct _KNONVOLATILE_CONTEXT_POINTERS { + union { + PM128A FloatingContext[16]; + struct { + PM128A Xmm0; + PM128A Xmm1; + PM128A Xmm2; + PM128A Xmm3; + PM128A Xmm4; + PM128A Xmm5; + PM128A Xmm6; + PM128A Xmm7; + PM128A Xmm8; + PM128A Xmm9; + PM128A Xmm10; + PM128A Xmm11; + PM128A Xmm12; + PM128A Xmm13; + PM128A Xmm14; + PM128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + union { + PDWORD64 IntegerContext[16]; + struct { + PDWORD64 Rax; + PDWORD64 Rcx; + PDWORD64 Rdx; + PDWORD64 Rbx; + PDWORD64 Rsp; + PDWORD64 Rbp; + PDWORD64 Rsi; + PDWORD64 Rdi; + PDWORD64 R8; + PDWORD64 R9; + PDWORD64 R10; + PDWORD64 R11; + PDWORD64 R12; + PDWORD64 R13; + PDWORD64 R14; + PDWORD64 R15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME2; + +} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; +#endif + +typedef struct _MEMORYSTATUSEX { + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; +} MEMORYSTATUSEX, *LPMEMORYSTATUSEX; + + +#define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception +#define EXCEPTION_UNWINDING 0x2 // Unwind is in progress +#define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress +#define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned +#define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call +#define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress +#define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call + +#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \ + EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND) + +#define IS_UNWINDING(Flag) ((Flag & EXCEPTION_UNWIND) != 0) +#define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0) +#define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND) + +#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters + #endif /* WINNT_TYPES_H */