diff --git a/configure.ac b/configure.ac index 1d5b927..f63fc9e 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,7 @@ esac], ) AC_MSG_RESULT($mariadb_visibility) AM_CONDITIONAL([ENABLE_MARIADB_SYMBOLS], [test "x$mariadb_visibility" = "xyes"]) +AM_CONDITIONAL(TARGET_WINDOWS, test "$TARGET_OS" = windows) #mariadb-visibility section end AC_CONFIG_FILES([Makefile diff --git a/include/mysql_inc.h b/include/mysql_inc.h index 8d4173b..aab186c 100644 --- a/include/mysql_inc.h +++ b/include/mysql_inc.h @@ -17,6 +17,9 @@ #include #include +#if MYSQL_VERSION_ID >= 80032 +#define TABLE_LIST Table_ref +#endif // These two are not present in 5.7.9 #if MYSQL_VERSION_ID < 50709 @@ -210,7 +213,9 @@ static inline bool init_str_session() if (!handle) return false; _command_name = (decltype(_command_name))dlsym(handle, "command_name"); - _str_session_80026 = (decltype(_str_session_80026))dlsym(handle, "_ZN13Command_names11str_sessionE19enum_server_command"); + _str_session_80026 = ((decltype(_str_session_80026))dlsym(handle, "_ZN13Command_names11str_sessionE19enum_server_command") != NULL) + ? (decltype(_str_session_80026))dlsym(handle, "_ZN13Command_names11str_sessionE19enum_server_command") : + (decltype(_str_session_80026))dlsym(handle, "_ZN13Command_names11str_sessionB5cxx11E19enum_server_command"); dlclose(handle); return _command_name || _str_session_80026; } diff --git a/offset-extract/offset-extract.sh b/offset-extract/offset-extract.sh index 847ffdb..7dc1084 100644 --- a/offset-extract/offset-extract.sh +++ b/offset-extract/offset-extract.sh @@ -135,7 +135,9 @@ VIEW_TABLES="" if echo $MYVER | grep -P '^(8\.0)' > /dev/null then LEX_COMMENT='printf ", 0"' - VIEW_TABLES="print_offset TABLE_LIST view_tables" + # TABLE_LIST struct was used in older versions of mysql, its replacement is Table_ref class + # VIEW_TABLES="print_offset TABLE_LIST view_tables" + VIEW_TABLES="print_offset Table_ref view_tables" else LEX_COMMENT="print_offset LEX comment" VIEW_TABLES='printf ", 0"' diff --git a/src/audit_handler.cc b/src/audit_handler.cc index 3eb2759..47feb7f 100644 --- a/src/audit_handler.cc +++ b/src/audit_handler.cc @@ -841,7 +841,7 @@ static bool parse_length_encoded_string( const char *well_formed_error_pos = NULL, *cannot_convert_error_pos = NULL, *from_end_pos = NULL; copy_length = well_formed_copy_nchars( - &my_charset_utf8_bin + &my_charset_utf8mb4_bin //migrated to utf8mb4 character encoding which is modern version , dest , dest_size , from_cs @@ -1089,7 +1089,7 @@ ssize_t Audit_json_formatter::event_format(ThdSesData *pThdData, IWriter *writer #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100504 &my_charset_utf8mb3_general_ci, #else - &my_charset_utf8_general_ci, + &my_charset_utf8mb4_general_ci, //migrated to utf8mb4 character encoding which is modern version #endif query, qlen, col_connection, & errors); diff --git a/src/audit_offsets.cc b/src/audit_offsets.cc index 6001ada..0ada88e 100644 --- a/src/audit_offsets.cc +++ b/src/audit_offsets.cc @@ -25,6 +25,12 @@ const ThdOffsets thd_offsets_arr[] = { /* +++ PERCONA 64 OFFSETS GO HERE +++ */ + //offsets for: /perconarpm/usr/sbin/mysqld (5.7.39-42) + {"5.7.39-42","732e09958d6ff8ff2cc15dd650780a4a", 8368, 8432, 3936, 5096, 456, 360, 0, 32, 64, 160, 544, 8564, 4664, 3648, 3656, 3660, 6568, 2088, 8, 7600, 7640, 7624, 14336, 148, 672, 0}, + //offsets for: /perconarpm/usr/sbin/mysqld (5.7.38-41) + {"5.7.38-41","b250cad1c7d8a102f21bd11ec2e13f5c", 8368, 8432, 3936, 5096, 456, 360, 0, 32, 64, 160, 544, 8564, 4664, 3648, 3656, 3660, 6568, 2088, 8, 7600, 7640, 7624, 14336, 148, 672, 0}, + //offsets for: /perconarpm/usr/sbin/mysqld (5.7.37-40) + {"5.7.37-40","9c01fa6a46b89ba25c836b331026c1d1", 8368, 8432, 3936, 5096, 456, 360, 0, 32, 64, 160, 544, 8564, 4664, 3648, 3656, 3660, 6568, 2088, 8, 7600, 7640, 7624, 14336, 148, 672, 0}, //offsets for: /perconarpm/usr/sbin/mysqld (5.7.36-39) {"5.7.36-39","b7e514d8c2f29ee43540213665d8ff89", 8368, 8432, 3936, 5096, 456, 360, 0, 32, 64, 160, 544, 8564, 4664, 3648, 3656, 3660, 6568, 2088, 8, 7600, 7640, 7624, 14336, 148, 672, 0}, //offsets for: /perconarpm/usr/sbin/mysqld (5.7.35-38) @@ -75,6 +81,18 @@ const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] = { /* +++ MYSQL 64 OFFSETS GO HERE +++ */ + //offsets for: /usr/sbin/mysqld (8.0.36) + {"8.0.36","9ba2568aeceed956bc047f4913f8285a", 9448, 9488, 4952, 6388, 1288, 0, 0, 32, 64, 160, 1376, 9588, 6008, 4248, 4256, 4260, 7672, 1576, 32, 8632, 8672, 8656, 12832, 140, 668, 320}, + //offsets for: /usr/sbin/mysqld (8.0.35) + {"8.0.35","465a40519e83cab54735ba515ba596bc", 9496, 9536, 4952, 6436, 1288, 0, 0, 32, 64, 160, 1376, 9636, 6056, 4248, 4256, 4260, 7720, 1576, 32, 8680, 8720, 8704, 12880, 140, 664, 320}, + //offsets for: /usr/sbin/mysqld (8.0.34) + {"8.0.34","2bf7588f074ff87a28dcc5fdc781d6e4", 9496, 9536, 4952, 6436, 1288, 0, 0, 32, 64, 160, 1376, 9636, 6056, 4248, 4256, 4260, 7720, 1576, 32, 8680, 8720, 8704, 12880, 140, 664, 320}, + //offsets for: /usr/sbin/mysqld (8.0.33) + {"8.0.33","5ef11079d4a42b8d9e23ddd8af825ea3", 9504, 9544, 4960, 6444, 1288, 0, 0, 32, 64, 160, 1376, 9644, 6064, 4248, 4256, 4260, 7728, 1576, 32, 8688, 8728, 8712, 12568, 140, 664, 320}, + //offsets for: /usr/sbin/mysqld (8.0.32) + {"8.0.32","3b5842405ac248629bacc97365bd3689", 9464, 9504, 4960, 6444, 1288, 0, 0, 32, 64, 160, 1376, 9604, 6064, 4248, 4256, 4260, 7728, 1576, 32, 8688, 8728, 8712, 12536, 140, 664, 320}, + //offsets for: /usr/sbin/mysqld (8.0.31) + {"8.0.31","82d74d745fa4864a9a7e47c94b343234", 9440, 9480, 4944, 6424, 1288, 0, 0, 32, 64, 160, 1376, 9580, 6048, 4248, 4256, 4260, 7704, 1576, 32, 8664, 8704, 8688, 12488, 140, 664, 328}, //offsets for: /mysqlrpm/8.0.30/usr/sbin/mysqld (8.0.30) {"8.0.30","3ddc67dbe6ae09a6bd0ff936341399b0", 9400, 9440, 4936, 6416, 1288, 0, 0, 32, 64, 160, 1376, 9540, 6040, 4248, 4256, 4260, 7696, 1576, 32, 8656, 8696, 8680, 12424, 140, 664, 328}, //offsets for: /mysqlrpm/5.7.39/usr/sbin/mysqld (5.7.39) @@ -450,20 +468,100 @@ const ThdOffsets thd_offsets_arr[] = const ThdOffsets thd_offsets_arr[] = { /* +++ MARIADB 64 OFFSETS GO HERE +++ */ + //offsets for: /mariadb/10.6.11/bin/mysqld (10.6.11-MariaDB) + {"10.6.11-MariaDB","fcd5e6c4637f2cbfc69449d0ea81f050", 15704, 15864, 7784, 9944, 88, 3552, 8, 0, 16, 24, 160, 15980, 9576, 5680, 5688, 5692, 696, 0, 0, 14960, 14984, 14968, 24560, 564, 8, 0}, + //offsets for: /mariadb/10.7.7/bin/mysqld (10.7.7-MariaDB) + {"10.7.7-MariaDB","52e002aa9ea7c3e792eb9a6da9ca88ce", 15800, 15976, 7816, 10024, 88, 3568, 8, 0, 16, 24, 160, 16108, 9608, 5672, 5680, 5684, 696, 0, 0, 15056, 15080, 15064, 24792, 564, 8, 0}, + //offsets for: /mariadb/10.9.4/bin/mysqld (10.9.4-MariaDB) + {"10.9.4-MariaDB","0632c6ad7cfebb3ee580ae5c2abe56bb", 15824, 16000, 7840, 10048, 88, 3568, 8, 0, 16, 24, 160, 16132, 9632, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadbrpm/10.5.18/usr/sbin/mariadbd (10.5.18-MariaDB) + {"10.5.18-MariaDB","3d904876b77dcaf6afa4ffcfeb9138c9", 15256, 15416, 7744, 9512, 88, 3592, 8, 0, 16, 24, 160, 15532, 9144, 5488, 5496, 5500, 680, 0, 0, 14512, 14536, 14520, 24120, 564, 8, 0}, + //offsets for: /mariadbrpm/10.6.11/usr/sbin/mariadbd (10.6.11-MariaDB) + {"10.6.11-MariaDB","3f70429564bfab1fefdef526865e4307", 15704, 15864, 7784, 9944, 88, 3552, 8, 0, 16, 24, 160, 15980, 9576, 5680, 5688, 5692, 696, 0, 0, 14960, 14984, 14968, 24560, 564, 8, 0}, + //offsets for: /mariadbrpm/10.7.7/usr/sbin/mariadbd (10.7.7-MariaDB) + {"10.7.7-MariaDB","2ea3e576b259784525259f5852bd934b", 15800, 15976, 7816, 10024, 88, 3568, 8, 0, 16, 24, 160, 16108, 9608, 5672, 5680, 5684, 696, 0, 0, 15056, 15080, 15064, 24792, 564, 8, 0}, + //offsets for: /mariadbrpm/10.9.4/usr/sbin/mariadbd (10.9.4-MariaDB) + {"10.9.4-MariaDB","293ab1a0f49b1fe6b5bfaeb97a695f41", 15824, 16000, 7840, 10048, 88, 3568, 8, 0, 16, 24, 160, 16132, 9632, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadb/10.4.27/bin/mysqld (10.4.27-MariaDB) + {"10.4.27-MariaDB","506b4e0053605687b9b7ea080bf8d4fd", 14656, 14808, 7312, 9048, 88, 3576, 8, 0, 16, 24, 160, 14916, 8704, 2984, 2992, 2996, 680, 0, 0, 14032, 14056, 14040, 23456, 564, 8, 0}, + //offsets for: /mariadb/10.5.18/bin/mysqld (10.5.18-MariaDB) + {"10.5.18-MariaDB","4abd25139214fdc198ce578a3fdf591e", 15256, 15416, 7744, 9512, 88, 3592, 8, 0, 16, 24, 160, 15532, 9144, 5488, 5496, 5500, 680, 0, 0, 14512, 14536, 14520, 24120, 564, 8, 0}, + //offsets for: /mariadb/10.8.6/bin/mysqld (10.8.6-MariaDB) + {"10.8.6-MariaDB","ec615b484365d46dcbd79b43f0fbec91", 15808, 15984, 7824, 10032, 88, 3568, 8, 0, 16, 24, 160, 16116, 9616, 5672, 5680, 5684, 696, 0, 0, 15064, 15088, 15072, 24800, 564, 8, 0}, + //offsets for: /mariadbrpm/10.4.27/usr/sbin/mariadbd (10.4.27-MariaDB) + {"10.4.27-MariaDB","56d7473f11fb82b227af31f39eaf0cb7", 14656, 14808, 7312, 9048, 88, 3576, 8, 0, 16, 24, 160, 14916, 8704, 2984, 2992, 2996, 680, 0, 0, 14032, 14056, 14040, 23456, 564, 8, 0}, + //offsets for: /mariadbrpm/10.8.6/usr/sbin/mariadbd (10.8.6-MariaDB) + {"10.8.6-MariaDB","86083b4c7ab1d03f45f62ba558ea5b3f", 15808, 15984, 7824, 10032, 88, 3568, 8, 0, 16, 24, 160, 16116, 9616, 5672, 5680, 5684, 696, 0, 0, 15064, 15088, 15072, 24800, 564, 8, 0}, + //offsets for: /mariadb/10.9.2/bin/mysqld (10.9.2-MariaDB) + {"10.9.2-MariaDB","019ab09000aa62762eb2cb7631d8b97d", 15816, 15992, 7832, 10040, 88, 3528, 8, 0, 16, 24, 152, 16124, 9624, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadb/10.9.3/bin/mysqld (10.9.3-MariaDB) + {"10.9.3-MariaDB","d52836989b0857cd5f6c122e5cbf2bf0", 15816, 15992, 7832, 10040, 88, 3528, 8, 0, 16, 24, 152, 16124, 9624, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadbrpm/10.9.2/usr/sbin/mariadbd (10.9.2-MariaDB) + {"10.9.2-MariaDB","7c772616443f29c4bb134b17d9b994e6", 15816, 15992, 7832, 10040, 88, 3528, 8, 0, 16, 24, 152, 16124, 9624, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadbrpm/10.9.3/usr/sbin/mariadbd (10.9.3-MariaDB) + {"10.9.3-MariaDB","7094d4cb6a8ab299ea8d80e272ac9c6c", 15816, 15992, 7832, 10040, 88, 3528, 8, 0, 16, 24, 152, 16124, 9624, 5680, 5688offsets.gdb:22: Error in sourced command file: + //offsets for: /mariadb/10.6.10/bin/mysqld (10.6.10-MariaDB) + {"10.6.10-MariaDB","89c1b2f6a4de72a78255604f735d3bb0", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5680, 5688, 5692, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, + //offsets for: /mariadb/10.7.6/bin/mysqld (10.7.6-MariaDB) + {"10.7.6-MariaDB","9c89d1d9665e419fc9c294e65fc51606", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5672, 5680, 5684, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, + //offsets for: /mariadb/10.8.5/bin/mysqld (10.8.5-MariaDB) + {"10.8.5-MariaDB","851bb7fd13740a8940da6622499a5f5f", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5672, 5680, 5684, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, + //offsets for: /mariadbrpm/10.6.10/usr/sbin/mariadbd (10.6.10-MariaDB) + {"10.6.10-MariaDB","d7586e4afa8a685c46704d470712c541", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5680, 5688, 5692, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, + //offsets for: /mariadbrpm/10.7.6/usr/sbin/mariadbd (10.7.6-MariaDB) + {"10.7.6-MariaDB","c3307cce4bfbc55ee3703674c32d6697", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5672, 5680, 5684, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, + //offsets for: /mariadbrpm/10.8.5/usr/sbin/mariadbd (10.8.5-MariaDB) + {"10.8.5-MariaDB","d1c95c5f34a6473bdd4aff7f6ce1390f", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5672, 5680, 5684, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, + //offsets for: /mariadb/10.4.25/bin/mysqld (10.4.25-MariaDB) + {"10.4.25-MariaDB","31cc385a8b4455e1f283b8681059074a", 14648, 14800, 7304, 9040, 88, 3536, 8, 0, 16, 24, 152, 14908, 8696, 2984, 2992, 2996, 672, 0, 0, 14024, 14048, 14032, 23408, 564, 8, 0}, + //offsets for: /mariadbrpm/10.4.25/usr/sbin/mariadbd (10.4.25-MariaDB) + {"10.4.25-MariaDB","82458dc7be142af61845c501d47d5868", 14648, 14800, 7304, 9040, 88, 3536, 8, 0, 16, 24, 152, 14908, 8696, 2984, 2992, 2996, 672, 0, 0, 14024, 14048, 14032, 23408, 564, 8, 0}, //offsets for: /mariadb/10.5.16/bin/mysqld (10.5.16-MariaDB) {"10.5.16-MariaDB","a99e23ae8a2a5d1cd2fa802503b68c84", 15248, 15408, 7736, 9504, 88, 3552, 8, 0, 16, 24, 152, 15524, 9136, 5480, 5488, 5492, 672, 0, 0, 14504, 14528, 14512, 24072, 564, 8, 0}, + //offsets for: /mariadb/10.6.8/bin/mysqld (10.6.8-MariaDB) + {"10.6.8-MariaDB","9266509a305c9f55988dbfd62b0fbf68", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5672, 5680, 5684, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, //offsets for: /mariadb/10.7.4/bin/mysqld (10.7.4-MariaDB) {"10.7.4-MariaDB","f3864f78ec91ecb1316ed3cab08a39aa", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5664, 5672, 5676, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, //offsets for: /mariadbrpm/10.5.16/usr/sbin/mariadbd (10.5.16-MariaDB) {"10.5.16-MariaDB","fce7d428095be987c56537bfac9e9257", 15248, 15408, 7736, 9504, 88, 3552, 8, 0, 16, 24, 152, 15524, 9136, 5480, 5488, 5492, 672, 0, 0, 14504, 14528, 14512, 24072, 564, 8, 0}, + //offsets for: /mariadbrpm/10.6.8/usr/sbin/mariadbd (10.6.8-MariaDB) + {"10.6.8-MariaDB","cd9f2822479dbf317b251feacaf9a9da", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5672, 5680, 5684, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, //offsets for: /mariadbrpm/10.7.4/usr/sbin/mariadbd (10.7.4-MariaDB) {"10.7.4-MariaDB","5113cb3cb21ea378193d795815ca3da4", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5664, 5672, 5676, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, + //offsets for: /mariadb/10.3.36/bin/mysqld (10.3.36-MariaDB) + {"10.3.36-MariaDB","6d9ec518cd13af346bf77d337b9e9d45", 14512, 14616, 7160, 8888, 88, 3376, 8, 0, 16, 24, 152, 14716, 8544, 2984, 2992, 2996, 640, 0, 0, 13888, 13912, 13896, 22272, 564, 8, 0}, + //offsets for: /mariadb/10.4.26/bin/mysqld (10.4.26-MariaDB) + {"10.4.26-MariaDB","1e4838ce4a15b9db5dc8a4de1d4a19c3", 14648, 14800, 7304, 9040, 88, 3536, 8, 0, 16, 24, 152, 14908, 8696, 2984, 2992, 2996, 672, 0, 0, 14024, 14048, 14032, 23408, 564, 8, 0}, + //offsets for: /mariadb/10.5.17/bin/mysqld (10.5.17-MariaDB) + {"10.5.17-MariaDB","dd87263d874e12b10911552bebf237a3", 15248, 15408, 7736, 9504, 88, 3552, 8, 0, 16, 24, 152, 15524, 9136, 5488, 5496, 5500, 672, 0, 0, 14504, 14528, 14512, 24072, 564, 8, 0}, + //offsets for: /mariadb/10.6.9/bin/mysqld (10.6.9-MariaDB) + {"10.6.9-MariaDB","8ee4269d8d64ed4aea9ec6ac4cbbc084", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5680, 5688, 5692, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, //offsets for: /mariadb/10.7.5/bin/mysqld (10.7.5-MariaDB) {"10.7.5-MariaDB","6d5ca6eb4257ce6f3b176db4f0216f0c", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5672, 5680, 5684, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, + //offsets for: /mariadb/10.8.4/bin/mysqld (10.8.4-MariaDB) + {"10.8.4-MariaDB","34d9e5e20f6a2e9188f60d395c00f8ba", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5672, 5680, 5684, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, + //offsets for: /mariadbrpm/10.3.36/usr/sbin/mysqld (10.3.36-MariaDB) + {"10.3.36-MariaDB","deed5e82e5f6b7478843e9af95dbd201", 14512, 14616, 7160, 8888, 88, 3376, 8, 0, 16, 24, 152, 14716, 8544, 2984, 2992, 2996, 640, 0, 0, 13888, 13912, 13896, 22272, 564, 8, 0}, + //offsets for: /mariadbrpm/10.4.26/usr/sbin/mariadbd (10.4.26-MariaDB) + {"10.4.26-MariaDB","9e729d19a69e76f09d3f56e240a7c273", 14648, 14800, 7304, 9040, 88, 3536, 8, 0, 16, 24, 152, 14908, 8696, 2984, 2992, 2996, 672, 0, 0, 14024, 14048, 14032, 23408, 564, 8, 0}, + //offsets for: /mariadbrpm/10.5.17/usr/sbin/mariadbd (10.5.17-MariaDB) + {"10.5.17-MariaDB","38937279a57aedc962dc703842d9c461", 15248, 15408, 7736, 9504, 88, 3552, 8, 0, 16, 24, 152, 15524, 9136, 5488, 5496, 5500, 672, 0, 0, 14504, 14528, 14512, 24072, 564, 8, 0}, + //offsets for: /mariadbrpm/10.6.9/usr/sbin/mariadbd (10.6.9-MariaDB) + {"10.6.9-MariaDB","852e3e0b390a2d1211678b5f97c3c419", 15696, 15856, 7776, 9936, 88, 3512, 8, 0, 16, 24, 152, 15972, 9568, 5680, 5688, 5692, 688, 0, 0, 14952, 14976, 14960, 24512, 564, 8, 0}, //offsets for: /mariadbrpm/10.7.5/usr/sbin/mariadbd (10.7.5-MariaDB) {"10.7.5-MariaDB","a033181397444805631c860f72f6ff19", 15792, 15968, 7808, 10016, 88, 3528, 8, 0, 16, 24, 152, 16100, 9600, 5672, 5680, 5684, 688, 0, 0, 15048, 15072, 15056, 24744, 564, 8, 0}, + //offsets for: /mariadbrpm/10.8.4/usr/sbin/mariadbd (10.8.4-MariaDB) + {"10.8.4-MariaDB","3bdf6f6f3283b0c3ee01219c91a6a259", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5672, 5680, 5684, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, + //offsets for: /mariadb/10.8.3/bin/mysqld (10.8.3-MariaDB) + {"10.8.3-MariaDB","a86553fc21f310c7d5daadf3fdf08acf", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5664, 5672, 5676, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, + //offsets for: /mariadbrpm/10.8.3/usr/sbin/mariadbd (10.8.3-MariaDB) + {"10.8.3-MariaDB","d51812ed7d3b9fdf905ecb53d53a3280", 15800, 15976, 7816, 10024, 88, 3528, 8, 0, 16, 24, 152, 16108, 9608, 5664, 5672, 5676, 688, 0, 0, 15056, 15080, 15064, 24752, 564, 8, 0}, //offsets for: /mariadb/10.2.44/bin/mysqld (10.2.44-MariaDB) {"10.2.44-MariaDB","9e7388a2050aca7c590e6844f5dd10d1", 13896, 13960, 6688, 8304, 88, 3224, 8, 0, 16, 24, 152, 14060, 8064, 2984, 2992, 2996, 624, 0, 0, 13272, 13296, 13280, 21232, 548, 516, 0}, + //offsets for: /mariadb/10.4.7/bin/mysqld (10.4.7-MariaDB) + {"10.4.7-MariaDB","e321670955bc21af9758ba1e40c66376", 14616, 14768, 7272, 9008, 88, 3480, 8, 0, 16, 24, 152, 14868, 8664, 2984, 2992, 2996, 624, 0, 0, 13992, 14016, 14000, 23320, 564, 8, 0}, + //offsets for: /mariadb/10.4.8/bin/mysqld (10.4.8-MariaDB) + {"10.4.8-MariaDB","a55b1558227a9f3c91c279fb8045efb8", 14616, 14768, 7272, 9008, 88, 3480, 8, 0, 16, 24, 152, 14868, 8664, 2984, 2992, 2996, 624, 0, 0, 13992, 14016, 14000, 23320, 564, 8, 0}, //offsets for: /mariadb/10.7.3/bin/mysqld (10.7.3-MariaDB) {"10.7.3-MariaDB","252cfb62266a7b2af0ff4b1c8f8ec2b2", 15760, 15936, 7776, 9984, 88, 3528, 8, 0, 16, 24, 152, 16068, 9568, 5664, 5672, 5676, 656, 0, 0, 15016, 15040, 15024, 24744, 564, 8, 0}, //offsets for: /mariadbrpm/10.7.3/usr/sbin/mariadbd (10.7.3-MariaDB) @@ -484,10 +582,14 @@ const ThdOffsets thd_offsets_arr[] = {"10.6.5-MariaDB","90cfc8ff0ed2aef04154b503bbd5f2f2", 15664, 15824, 7744, 9904, 88, 3512, 8, 0, 16, 24, 152, 15940, 9536, 5672, 5680, 5684, 656, 0, 0, 14920, 14944, 14928, 24512, 564, 8, 0}, //offsets for: /mariadbrpm/10.6.7/usr/sbin/mariadbd (10.6.7-MariaDB) {"10.6.7-MariaDB","9163361e728a4cfcd20d1d18928fda63", 15664, 15824, 7744, 9904, 88, 3512, 8, 0, 16, 24, 152, 15940, 9536, 5672, 5680, 5684, 656, 0, 0, 14920, 14944, 14928, 24512, 564, 8, 0}, + //offsets for: /mariadb/10.3.34/bin/mysqld (10.3.34-MariaDB) + {"10.3.34-MariaDB","2826df940b45af60307f34a9fbb2993f", 14480, 14584, 7128, 8856, 88, 3376, 8, 0, 16, 24, 152, 14684, 8512, 2984, 2992, 2996, 608, 0, 0, 13856, 13880, 13864, 22272, 564, 8, 0}, //offsets for: /mariadb/10.4.24/bin/mysqld (10.4.24-MariaDB) {"10.4.24-MariaDB","d0709b66f85f1d6dbd97f49eec72a30d", 14616, 14768, 7272, 9008, 88, 3536, 8, 0, 16, 24, 152, 14876, 8664, 2984, 2992, 2996, 640, 0, 0, 13992, 14016, 14000, 23408, 564, 8, 0}, //offsets for: /mariadb/10.5.15/bin/mysqld (10.5.15-MariaDB) {"10.5.15-MariaDB","6cf2a099ba5a317561f42ae66aa9c9f2", 15216, 15376, 7704, 9472, 88, 3552, 8, 0, 16, 24, 152, 15492, 9104, 5480, 5488, 5492, 640, 0, 0, 14472, 14496, 14480, 24072, 564, 8, 0}, + //offsets for: /mariadbrpm/10.3.34/usr/sbin/mysqld (10.3.34-MariaDB) + {"10.3.34-MariaDB","ef2dcfd91cbd396c5699d59db7348740", 14480, 14584, 7128, 8856, 88, 3376, 8, 0, 16, 24, 152, 14684, 8512, 2984, 2992, 2996, 608, 0, 0, 13856, 13880, 13864, 22272, 564, 8, 0}, //offsets for: /mariadbrpm/10.4.24/usr/sbin/mariadbd (10.4.24-MariaDB) {"10.4.24-MariaDB","6625d0e2ff924708b83edeb4f2ddd338", 14616, 14768, 7272, 9008, 88, 3536, 8, 0, 16, 24, 152, 14876, 8664, 2984, 2992, 2996, 640, 0, 0, 13992, 14016, 14000, 23408, 564, 8, 0}, //offsets for: /mariadbrpm/10.5.15/usr/sbin/mariadbd (10.5.15-MariaDB) diff --git a/udis86/BUILD-WINDOWS b/udis86/BUILD-WINDOWS new file mode 100644 index 0000000..42b6f58 --- /dev/null +++ b/udis86/BUILD-WINDOWS @@ -0,0 +1,90 @@ +Build Instructions for Visual Studio +************************************ + +Note: it is important to perform the build at least once before +attempting to open the solution in Visual Studio so that the build +process can generate the itab.c/itab.h files from the itab.py Python +script. + +Prerequisites +============= + +The buildVS2010.bat and build.proj MSBuild project have the following +prerequisites: + + 1. Visual Studio 2010 with VC++ (full edition is required to compile + for x64). A later compiler can be used however the build batch file + will need to be changed to run the correct vcvarsall.bat. + + 2. Python 2.7 - although a later version should work, the build script + has been configured to expect "python.exe" to be installed in + "c:\python27\". + +How to Build +============ + +Ensure all prerequisites are in place and then run "buildVS2010.bat". +MSBuild will run the "Clean" target for the "udis86.sln" solution and +then build the following targets for "build.proj" MSBuild project: + + 1. Clean - (remove the "./Build" directory) + 2. BuildRelease_x86 - build the release configuration for x86 + 3. BuildRelease_x64 - build the release configuration for x64 + 4. PostBuild - copy license and headers to build directory + +If a debug version is required, the batch file can be modified to also +build the BuildDebug_x86 and BuildDebug_x64 targets. + +If Visual Studio Express is being used you will need to comment out the +x64 target(s). + +Build Output +============ + +The Build directory has the following structure (if building all +Release and Debug targets): + +. ++-- Bin +¦   +-- Debug +¦   ¦   +-- x64 +¦   ¦   ¦   +-- libudis86.dll +¦   ¦   ¦   +-- libudis86.ilk +¦   ¦   ¦   +-- libudis86.pdb +¦   ¦   ¦   +-- udcli.exe +¦   ¦   ¦   +-- udcli.ilk +¦   ¦   ¦   +-- udcli.pdb +¦   ¦   +-- x86 +¦   ¦   +-- libudis86.dll +¦   ¦   +-- libudis86.ilk +¦   ¦   +-- libudis86.pdb +¦   ¦   +-- udcli.exe +¦   ¦   +-- udcli.ilk +¦   ¦   +-- udcli.pdb +¦   +-- x64 +¦   ¦   +-- libudis86.dll +¦   ¦   +-- libudis86.pdb +¦   ¦   +-- udcli.exe +¦   ¦   +-- udcli.pdb +¦   +-- x86 +¦   +-- libudis86.dll +¦   +-- libudis86.pdb +¦   +-- udcli.exe +¦   +-- udcli.pdb ++-- Include +¦   +-- libudis86 +¦   ¦   +-- itab.h +¦   ¦   +-- types.h +¦   +-- udis86.h ++-- Lib +¦   +-- Debug +¦   ¦   +-- x64 +¦   ¦   ¦   +-- libudis86.lib +¦   ¦   +-- x86 +¦   ¦   +-- libudis86.lib +¦   +-- x64 +¦   ¦   +-- libudis86.lib +¦   +-- x86 +¦   +-- libudis86.lib ++-- LICENSE ++-- README diff --git a/udis86/BuildVS2010/README.txt b/udis86/BuildVS2010/README.txt new file mode 100644 index 0000000..209d554 --- /dev/null +++ b/udis86/BuildVS2010/README.txt @@ -0,0 +1,8 @@ +Build notes for Windows: +- If you don't have python installed at C:\Python27, edit build.proj accordingly +- Execute buildVS2010.bat + - If you got VS2012, this will fail. + - Edit/Copy the build script, so that it finds vcvars32.bat (just needed to replace 10.0 with 11.0). + - Open the solution and update the toolset. + - Compile with the build script and ignore an error regarding ./Win32 not deletable. +- Be done with it :) \ No newline at end of file diff --git a/udis86/BuildVS2010/build.proj b/udis86/BuildVS2010/build.proj new file mode 100644 index 0000000..1de4306 --- /dev/null +++ b/udis86/BuildVS2010/build.proj @@ -0,0 +1,60 @@ + + + + .\Deploy + .\Build + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/udis86/BuildVS2010/buildVS2010.bat b/udis86/BuildVS2010/buildVS2010.bat new file mode 100644 index 0000000..de02265 --- /dev/null +++ b/udis86/BuildVS2010/buildVS2010.bat @@ -0,0 +1,7 @@ +echo off +call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86_amd64 + +msbuild.exe udis86.sln /t:Clean +msbuild.exe build.proj /t:Clean,BuildRelease_x86,BuildRelease_x64,PostBuild +REM msbuild.exe build.proj /t:Clean,BuildRelease_x86,BuildRelease_x64,BuildDebug_x86,BuildDebug_x64,PostBuild +pause \ No newline at end of file diff --git a/udis86/BuildVS2010/libudis86.vcxproj b/udis86/BuildVS2010/libudis86.vcxproj new file mode 100644 index 0000000..a8dbd3f --- /dev/null +++ b/udis86/BuildVS2010/libudis86.vcxproj @@ -0,0 +1,294 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {D5C34A21-7218-4A08-9578-1EBB35280A42} + Win32Proj + libudis86 + + + + StaticLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)Build\Lib\Debug\x86\ + $(Platform)\$(Configuration)\ + + + true + $(SolutionDir)Build\Bin\Debug\x86\ + $(Platform)\$(Configuration)\ + + + true + $(SolutionDir)Build\Lib\Debug\x64\ + + + true + $(SolutionDir)Build\Bin\Debug\x64\ + + + false + $(SolutionDir)Build\Lib\x86\ + $(Platform)\$(Configuration)\ + + + false + $(SolutionDir)Build\Bin\x86\ + $(Platform)\$(Configuration)\ + + + false + $(SolutionDir)Build\Lib\x64\ + + + false + $(SolutionDir)Build\Bin\x64\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + /c %(AdditionalOptions) + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + /c %(AdditionalOptions) + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + /c %(AdditionalOptions) + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + /c %(AdditionalOptions) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBUDIS86_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/udis86/BuildVS2010/libudis86.vcxproj.filters b/udis86/BuildVS2010/libudis86.vcxproj.filters new file mode 100644 index 0000000..dfb4cc8 --- /dev/null +++ b/udis86/BuildVS2010/libudis86.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {67a7943a-ad63-4da1-be6b-daf8a3fef1d6} + + + {a0eee912-4b82-493a-8c43-3b712061afb1} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\Generated + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Generated + + + diff --git a/udis86/BuildVS2010/udcli.vcxproj b/udis86/BuildVS2010/udcli.vcxproj new file mode 100644 index 0000000..450f821 --- /dev/null +++ b/udis86/BuildVS2010/udcli.vcxproj @@ -0,0 +1,292 @@ + + + + + Debug-DLL + Win32 + + + Debug-DLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release-DLL + Win32 + + + Release-DLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {620E885C-DA4A-4296-AFEB-AFB0077EFA14} + Win32Proj + udcli + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(IncludePath) + $(SolutionDir)Build\Bin\Debug\x86\ + $(Platform)\$(Configuration)\ + $(SolutionDir)Build\Lib\Debug\x86;$(LibraryPath) + + + true + $(IncludePath) + $(SolutionDir)Build\Bin\$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + true + $(IncludePath) + $(SolutionDir)Build\Bin\Debug\x64\ + $(SolutionDir)Build\Lib\Debug\x64;$(LibraryPath) + + + true + $(IncludePath) + $(SolutionDir)Build\Bin\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)Build\Bin\x86\ + $(Platform)\$(Configuration)\ + $(SolutionDir)Build\lib\x86;$(LibraryPath) + + + false + $(SolutionDir)Build\Bin\$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + + + false + $(SolutionDir)Build\Bin\x64\ + $(SolutionDir)Build\lib\x64;$(LibraryPath) + + + false + $(SolutionDir)Build\Bin\$(Platform)\$(Configuration)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + libudis86.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + libudis86.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + libudis86.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + libudis86.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/udis86/BuildVS2010/udcli.vcxproj.filters b/udis86/BuildVS2010/udcli.vcxproj.filters new file mode 100644 index 0000000..d5b9fee --- /dev/null +++ b/udis86/BuildVS2010/udcli.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/udis86/BuildVS2010/udis86.sln b/udis86/BuildVS2010/udis86.sln new file mode 100644 index 0000000..b84e29c --- /dev/null +++ b/udis86/BuildVS2010/udis86.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libudis86", "libudis86.vcxproj", "{D5C34A21-7218-4A08-9578-1EBB35280A42}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "udcli", "udcli.vcxproj", "{620E885C-DA4A-4296-AFEB-AFB0077EFA14}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug-DLL|Win32 = Debug-DLL|Win32 + Debug-DLL|x64 = Debug-DLL|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release-DLL|Win32 = Release-DLL|Win32 + Release-DLL|x64 = Release-DLL|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug|Win32.ActiveCfg = Debug|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug|Win32.Build.0 = Debug|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug|x64.ActiveCfg = Debug|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug|x64.Build.0 = Debug|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Debug-DLL|x64.Build.0 = Debug-DLL|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release|Win32.ActiveCfg = Release|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release|Win32.Build.0 = Release|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release|x64.ActiveCfg = Release|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release|x64.Build.0 = Release|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release-DLL|Win32.Build.0 = Release-DLL|Win32 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + {D5C34A21-7218-4A08-9578-1EBB35280A42}.Release-DLL|x64.Build.0 = Release-DLL|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug|Win32.ActiveCfg = Debug|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug|Win32.Build.0 = Debug|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug|x64.ActiveCfg = Debug|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug|x64.Build.0 = Debug|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release|Win32.ActiveCfg = Release|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release|Win32.Build.0 = Release|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release|x64.ActiveCfg = Release|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release|x64.Build.0 = Release|x64 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32 + {620E885C-DA4A-4296-AFEB-AFB0077EFA14}.Release-DLL|x64.ActiveCfg = Release-DLL|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/udis86/CHANGES b/udis86/CHANGES new file mode 100644 index 0000000..34c4c05 --- /dev/null +++ b/udis86/CHANGES @@ -0,0 +1,47 @@ +v1.7.2 + + * Clean up input handling, removing unnecessary caching + of input, which should speed up things. + * Add the missing ud_insn_mnemonic api function. + * Rename ud_opr_isgpr to ud_opr_is_gpr. + * Fix decoding of relative jumps. + * Fix build with automake-1.14 + * Minor fix to AT&T syntax (missing "$" prefix for immedaites) + * Add a new api checker (tests/libcheck.c). + * Add a standalone script for diff-testing (tests/difftest.sh) + * Refinements to the documentation. + + Acknowledgements: + + Brendan Long (https://github.com/brendanlong) + radare (https://github.com/radare) + Sergey Basalaev (https://github.com/SBasalaev) + ebfe (https://github.com/ebfe) + +v1.7.1 + + * Full support for SSSE3, SSE4.1, SSE4.2, SMX, AES. + * New Sphinx-doc/RST based documentation. + * New api for client size symbol resolver. + * Visual Studio 2010 Build Support. + * Added an operand tester. + * Python 3.0 compatibility changes. + * Minor fixes to AT&T syntax. + * Fix install directory for data files. + * Many bug fixes, and optable updates. + * Add Texinfo document (make install-info). + + Acknowledgements: + + L Peter Deutsch (https://github.com/ghghost) + Bjoern Doebel (https://github.com/bjoernd) + Justin Stenning (http://github.com/spazzarama) + Jamie Iles (https://github.com/jamieiles) + Stephen Fewer (https://github.com/stephenfewer) + Piotr Gaczkowski (https://github.com/DoomHammer) + Evan Pheonix + mbarbu (https://github.com/mbarbu) + + + +Please see the commit logs for change information for older releases diff --git a/udis86/LICENSE b/udis86/LICENSE index 5d7bf4d..580f359 100644 --- a/udis86/LICENSE +++ b/udis86/LICENSE @@ -1,14 +1,14 @@ -Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 +Copyright (c) 2002-2012, Vivek Thampi All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED diff --git a/udis86/Makefile.am b/udis86/Makefile.am index 28ab51b..7ad647f 100644 --- a/udis86/Makefile.am +++ b/udis86/Makefile.am @@ -1,2 +1,38 @@ -SUBDIRS = libudis86 +ACLOCAL_AMFLAGS = -I build/m4 +SUBDIRS = scripts libudis86 udcli docs tests + +MAINTAINERCLEANFILES = \ + Makefile.in \ + configure \ + config.h.in \ + config.h.in~ \ + missing \ + aclocal.m4 \ + build/config.guess \ + build/config.sub \ + build/compile \ + build/config.guess \ + build/config.sub \ + build/depcomp \ + build/install-sh \ + build/ltmain.sh \ + build/missing + +include_ladir = ${includedir} +include_la_HEADERS = udis86.h + +.PHONY: libudis86 udcli tests docs + +libudis86: + $(MAKE) -C $@ + +udcli: libudis86 + $(MAKE) -C $@ + +tests: check + +maintainer-clean-local: + -rm -rf build/m4 + -rm -rf build + -rm -rf autom4te.cache diff --git a/udis86/README b/udis86/README index 70757cb..03eaee5 100644 --- a/udis86/README +++ b/udis86/README @@ -1 +1,91 @@ -See docs/udis86.pdf +Udis86 +====== + +Udis86 is a disassembler for the x86 and x86-64 class of instruction set +architectures. It consists of a C library called libudis86 which +provides a clean and simple interface to decode a stream of raw binary +data, and to inspect the disassembled instructions in a structured +manner. + + +LICENSE +------- + +Udis86 is distributed under the terms of the 2-clause "Simplified BSD +License". A copy of the license is included with the source in LICENSE. + + +libudis86 +--------- + + o Supports all x86 and x86-64 (AMD64) General purpose and + System instructions. + o Supported ISA extensions: + - MMX, FPU (x87), AMD 3DNow + - SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES, + - AMD-V, INTEL-VMX, SMX + o Instructions are defined in an XML document, with opcode + tables generated for performance. + o Supports output in both INTEL (NASM) as well as AT&T (GNU as) style + assembly language syntax. + o Supports a variety of input methods: Files, Memory Buffers, and + Function Callback hooks. + o Re-entrant, no dynamic memory allocation. + o Fully documented API + + + -- EXAMPLE ----------------------------------------------------------- + + ud_t u; + + ud_init(&u); + ud_set_input_file(&u, stdin); + ud_set_mode(&u, 64); + ud_set_syntax(&u, UD_SYN_INTEL); + + while (ud_disassemble(&u)) { + printf("\t%s\n", ud_insn_asm(&ud_obj)); + } + + ---------------------------------------------------------------------- + + +udcli +----- + +udcli is a small command-line tool for your quick disassembly needs. + + -- EXAMPLE ----------------------------------------------------------- + + $ echo "65 67 89 87 76 65 54 56 78 89 09 00 90" | udcli -32 -x + 0000000080000800 656789877665 mov [gs:bx+0x6576], eax + 0000000080000806 54 push esp + 0000000080000807 56 push esi + 0000000080000808 7889 js 0x80000793 + 000000008000080a 0900 or [eax], eax + 000000008000080c 90 nop + + ---------------------------------------------------------------------- + + +Documentation +------------- + +The libudis86 api is fully documented. The package distribution contains +a Texinfo file which can be installed by invoking "make install-info". +You can also find an online html version of the documentation available +at http://udis86.sourceforge.net/. + + +Autotools Build +--------------- + +You need autotools if building from sources cloned form version control +system, or if you need to regenerate the build system. The wrapper +script 'autogen.sh' is provided that'll generate the build system. + + +AUTHOR +------ + +Udis86 is written and maintained by Vivek Thampi (vivek.mt@gmail.com). diff --git a/udis86/autogen.sh b/udis86/autogen.sh new file mode 100644 index 0000000..91fe816 --- /dev/null +++ b/udis86/autogen.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# +if [ ! -e build/m4 ]; then mkdir -p build/m4; fi +autoreconf --force -v --install || ( echo "autogen: autoreconf -i failed." && false ) +CFLAGS=-fPIC ./configure --with-python=/usr/bin/python2 --enable-utf --disable-cpp --disable-shared --enable-static diff --git a/udis86/configure.ac b/udis86/configure.ac new file mode 100644 index 0000000..d62db16 --- /dev/null +++ b/udis86/configure.ac @@ -0,0 +1,83 @@ +# +# udis86 autoconf +# +AC_PREREQ(2.60) +AC_INIT([udis86], [1.7.2], [vivek.mt@gmail.com]) +AC_CONFIG_HEADERS(config.h) +AC_CONFIG_AUX_DIR(build) +AC_CONFIG_MACRO_DIR([build/m4]) + +m4_include([m4/ax_compare_version.m4]) +m4_include([m4/ax_prog_sphinx_version.m4]) +m4_include([m4/ax_prog_yasm_version.m4]) +m4_include([m4/ax_with_prog.m4]) +m4_include([m4/ax_with_python.m4]) + +# Make sure $ACLOCAL_FLAGS are used during a rebuild. +AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \${ACLOCAL_FLAGS}"]) + +# +# Determine the build host; we notify automake of Windows +# builds, so it can pass proper parameters for building +# DLLs to the linker. +# +AC_CANONICAL_HOST + +case "$host_os" in + mingw32* ) + TARGET_OS=windows + AC_LIBTOOL_WIN32_DLL + ;; +esac + +# Initialize the automake subsystem. +AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability -Wno-extra-portability -Werror foreign]) +AM_SILENT_RULES([yes]) + +# +# In case we have a Windows build, we pass a +# TARGET_WINDOWS conditional to automake. +# +AM_CONDITIONAL(TARGET_WINDOWS, test "$TARGET_OS" = windows) + +AC_PROG_CC +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AM_PROG_CC_C_O + +# If this is a gnu compiler, pass -Wall +if test "$ac_cv_c_compiler_gnu" = "yes"; then + CFLAGS="$CFLAGS -Wall" +fi + +# Look for python +AX_WITH_PYTHON +if test "x$PYTHON" = "x"; then + AC_MSG_ERROR([Python not found. Use --with-python to specify path to python binary]) +fi + +# Yasm (>= 1.2.0) for testing +AX_WITH_PROG(YASM,yasm) +AX_PROG_YASM_VERSION([1.2.0],[ac_have_yasm_version=1],[]) +AM_CONDITIONAL(HAVE_YASM, [test -n "$ac_have_yasm_version"]) + +# Sphinx (>= 1.1.3) for documentation +AX_WITH_PROG(SPHINX_BUILD,sphinx-build) +AX_PROG_SPHINX([1.1.3],[ac_have_sphinx_version=1],[]) +AM_CONDITIONAL(HAVE_SPHINX_DOC, [test -n "$ac_have_sphinx_version"]) + +AC_CHECK_HEADERS([assert.h stdio.h]) + +AC_CONFIG_FILES([ + Makefile + scripts/Makefile + libudis86/Makefile + udcli/Makefile + tests/Makefile + docs/Makefile + docs/manual/Makefile + docs/x86/Makefile + tests/difftest.sh +]) + +AC_OUTPUT diff --git a/udis86/docs/Makefile.am b/udis86/docs/Makefile.am index 8ed694e..7d8b0da 100644 --- a/udis86/docs/Makefile.am +++ b/udis86/docs/Makefile.am @@ -1 +1,2 @@ -dist_doc_DATA = udis86.odt udis86.pdf index.html style.css ss.jpg x86optable.xml x86optable.xsl +SUBDIRS = x86 manual +MAINTAINERCLEANFILES = Makefile.in diff --git a/udis86/docs/manual/Makefile.am b/udis86/docs/manual/Makefile.am new file mode 100644 index 0000000..7eee652 --- /dev/null +++ b/udis86/docs/manual/Makefile.am @@ -0,0 +1,56 @@ +manualdir = ${docdir}/manual + +rst_sources = \ + index.rst \ + getstarted.rst \ + libudis86.rst + +# +# The official distribution only contains the rst files. So users +# may generate documentation using Sphinx if they wish to. +# +EXTRA_DIST = \ + $(rst_sources) \ + udis86.info \ + conf.py \ + static + +MAINTAINERCLEANFILES = \ + Makefile.in \ + udis86.info + +if HAVE_SPHINX_DOC + +html-local: + $(SPHINX_BUILD) -c $(srcdir) -b html $(srcdir) $(builddir)/html + +udis86.info: $(rst_sources) + $(SPHINX_BUILD) -E -c $(srcdir) -b texinfo $(srcdir) $(builddir)/texinfo + $(MAKEINFO) --no-split $(builddir)/texinfo/udis86.texi + +check-local: html-local + +else + +udis86.info: $(rst_sources) +html-local udis86.info: + @echo "" + @echo "------------------------------------------------------------------" + @echo "" + @echo " Please make sure you have Sphinx (sphinx-doc.org) version 1.1.3" + @echo " or above, to be able to build documentation." + @echo "" + @echo " You can also find documentation at http://udis86.sourceforge.net/" + @echo "" + @echo "------------------------------------------------------------------" + @echo "" + @exit 1 + +endif + +install-info-local: udis86.info + install-info --info-dir=$(infodir) $< + +clean-local: + -rm -rf $(builddir)/html + -rm -rf $(builddir)/texinfo $(builddir)/udis86.info diff --git a/udis86/docs/manual/conf.py b/udis86/docs/manual/conf.py new file mode 100644 index 0000000..654fed6 --- /dev/null +++ b/udis86/docs/manual/conf.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +import sys, os + +source_suffix = '.rst' +master_doc = 'index' +project = u'udis86' +copyright = u'2013, Vivek Thampi' +version = '1.7' +release = '1.7.2' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +pygments_style = 'sphinx' +html_theme = 'pyramid' +html_theme_options = { "nosidebar" : True } +html_static_path = ['static'] +html_style = "udis86.css" +htmlhelp_basename = 'udis86doc' + +latex_documents = [ + ('index', 'udis86.tex', u'udis86 Documentation', + u'Vivek Thampi', 'manual'), +] + +man_pages = [ + ('index', 'udis86', u'udis86 Documentation', + [u'Vivek Thampi'], 1) +] + +texinfo_documents = [ + ('index', 'udis86', u'udis86 Documentation', + u'Vivek Thampi', 'udis86', 'Disassembler library for x86.', + 'Miscellaneous', True), +] diff --git a/udis86/docs/manual/getstarted.rst b/udis86/docs/manual/getstarted.rst new file mode 100644 index 0000000..54b4c5e --- /dev/null +++ b/udis86/docs/manual/getstarted.rst @@ -0,0 +1,57 @@ +Getting Started +=============== + + +Building and Installing udis86 +------------------------------ + +udis86 is developed for unix-like environments, and like most software, +the basic steps towards building and installing it are as follows. + +.. code:: + + $ ./configure + $ make + $ make install + +Depending on your choice of install location, you may need to have root +privileges to do an install. The install scripts copy the necessary header +and library files to appropriate locations in your system. + + +Interfacing with libudis86: A Quick Example +------------------------------------------- + +The following is an example of a program that interfaces with libudis86 +and uses the API to generate assembly language output for 64-bit code, +input from STDIN. + +.. code-block:: c + + #include + #include + + int main() + { + ud_t ud_obj; + + ud_init(&ud_obj); + ud_set_input_file(&ud_obj, stdin); + ud_set_mode(&ud_obj, 64); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + + while (ud_disassemble(&ud_obj)) { + printf("\t%s\n", ud_insn_asm(&ud_obj)); + } + + return 0; + } + +To compile the program (using gcc): + +.. code:: + + $ gcc -ludis86 example.c -o example + +This example should give you an idea of how this library can be used. The +following sections describe, in detail, the complete API of libudis86. diff --git a/udis86/docs/manual/index.rst b/udis86/docs/manual/index.rst new file mode 100644 index 0000000..1e5db0f --- /dev/null +++ b/udis86/docs/manual/index.rst @@ -0,0 +1,27 @@ +.. udis86 documentation master file + +Welcome to udis86's documentation! +================================== + +Udis86 is a disassembler engine that decodes a stream of binary +machine code bytes as opcodes defined in the x86 and x86-64 class +of Instruction Set Archictures. The core component of this project +is libudis86 which provides a clean and simple interface to +disassemble binary code, and to inspect the disassembly to various +degrees of detail. The library is designed to aid software +projects that entail analysis and manipulation of all flavors of +x86 binary code. + + +.. toctree:: + :maxdepth: 3 + + getstarted + libudis86 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` + diff --git a/udis86/docs/manual/libudis86.rst b/udis86/docs/manual/libudis86.rst new file mode 100644 index 0000000..67e1085 --- /dev/null +++ b/udis86/docs/manual/libudis86.rst @@ -0,0 +1,531 @@ +libudis86 +========= + +libudis86 is a disassembler library for the x86 architecture, including support +for the newer 64bit variants (IA32e, amd64, etc.) It provides you the ability +to decode a stream of bytes as x86 instructions, inspect various bits +of information about those instructions and even translate to human readable +assembly language format. + +.. default-domain:: c + +.. contents:: + + +ud_t: udis86 object +------------------- + +libudis86 is reentrant, and to maintain that property it does not use static +data. All data related to the disassembly are stored in a single object, called +the udis86 object :type:`ud_t`. + +.. c:type:: ud_t + + A structure encapsulating udis86 disassembler state. + +To use libudis86 you must create an instance of this object, + +.. code-block:: c + + ud_t ud_obj; + +and initialize it, + +.. code-block:: c + + ud_init(&ud_obj); + +You can create multiple such objects and use with the library, each one +an independent disassembler. + + +Setup Machine State +------------------- + +The decode semantics of a sequence of bytes depends on the target machine state +for which they are being disassembled. In x86, this means the current effective +processor mode (16, 32 or 64bits), the current program counter (ip/eip/rip), and +sometimes, the processor vendor. By default, libudis86 is initialized to be in +32 bit disassembly mode, program counter at 0, and vendor being :code:`UD_VENDOR_ANY`. +The following functions allow you to override these default to suit your needs. + +.. c:function:: void ud_set_mode(ud_t*, uint8_t mode_bits) + + Sets the mode of disassembly. Possible values are 16, 32, and 64. By + default, the library works in 32bit mode. + +.. c:function:: void ud_set_pc(ud_t*, uint64_t pc) + + Sets the program counter (IP/EIP/RIP). This changes the offset of the + assembly output generated, with direct effect on branch instructions. + +.. c:function:: void ud_set_vendor(ud_t*, unsigned vendor) + + Sets the vendor of whose instruction to choose from. This is only useful + for selecting the VMX or SVM instruction sets at which point INTEL and AMD + have diverged significantly. At a later stage, support for a more granular + selection of instruction sets maybe added. + + * :code:`UD_VENDOR_INTEL` - for INTEL instruction set. + * :code:`UD_VENDOR_ATT` - for AMD instruction set. + * :code:`UD_VENDOR_ANY` - for any valid instruction in either INTEL or AMD. + + +Setup Input +----------- + +libudis86 provides three ways in which you can input binary data: as a fixed +sized memory buffer, a standard library FILE object, or as a callback function. +By default, a :type:`ud_t` object is initialized to read input from :code:`STDIN`. + +.. c:function:: void ud_set_input_buffer(ud_t*, unsigned char* buffer, size_t size) + + Sets the input source for the library to a `buffer` of `size` bytes. + +.. c:function:: void ud_set_input_file(ud_t*, FILE* filep) + + Sets the input source to a file pointed to by a given standard library + :code:`FILE` pointer. Note that libudis86 does not perform any checks, + and assumes that the file pointer is properly initialized and open for + reading. + +.. c:function:: void ud_set_input_hook(ud_t* ud_obj, int (*hook)(ud_t *ud_obj)) + + Sets a pointer to a function, to callback for input. The callback is invoked + each time libudis86 needs the next byte in the input stream. To single + end-of-input, this callback must return the constant :code:`UD_EOI`. + + .. seealso:: :func:`ud_set_user_opaque_data`, :func:`ud_set_user_opaque_data` + +.. c:function:: void ud_input_skip(ud_t*, size_t n); + + Skips ahead `n` number of bytes in the input stream. + + +.. c:function:: int ud_input_end(const ud_t*); + + Test for end of input. You can use this function to test if udis86 + has exhausted the input. + +At the end of input, udis86 stops disassembly. If you want to restart or +reset the source of input, you must again invoke one of the above functions. + +Sometimes you may want to associate custom data with a udis86 object, that you +can use with the input callback function, or even in different parts of your +own project as you pass the object around. You can use the following two +functions to achieve this. + +.. c:function:: void ud_set_user_opaque_data(ud_t* ud_obj, void* opaque) + + Associates a pointer with the udis86 object to be retrieved and used in + client functions, such as the input hook callback function. + +.. c:function:: void* ud_get_user_opaque_data(const ud_t* ud_obj) + + Returns any pointer associated with the udis86 object, using the + :func:`ud_set_user_opaque_data` function. + + +Setup Translation +----------------- + +libudis86 can translate the decoded instruction into one of two assembly +language dialects: the INTEL syntax (such as those found in NASM and YASM) and +the other which resembles GNU Assembler (AT&T style) syntax. By default, this +is set to INTEL like syntax. You can override the default or specify your own +translator using the following function. + +.. c:function:: void ud_set_syntax(ud_t*, void (*translator)(ud_t*)) + + Sets the function that translates the intermediate decode information to + a human readable form. There are two inbuilt translators, + + - :code:`UD_SYN_INTEL` for INTEL (NASM-like) syntax. (default) + - :code:`UD_SYN_ATT` for AT&T (GAS-like) syntax. + + If you do not want libudis86 to translate, you can pass :code:`NULL` to the + function, with no more translations thereafter. This is useful when you + only want to identify chunks of code and then create the assembly output if + needed, or when you are only interested in examining the instructions and + do not want to waste cycles generating the assembly language output. + + If you want to create your own translator, you can specify a pointer to your + own function. This function must accept a single parameter, the udis86 object + :type:`ud_t`, and it will be invoked everytime an instruction is decoded. + + +Disassemble +----------- + +With target state and input source set up, you can now disassemble. At the core +of libudis86 api is the function :c:func:`ud_disassemble` which does this. +libudis86 exposes decoded instructions in an intermediate form meant to be +useful for programs that want to examine them. This intermediate form is +available using functions and fields of :type:`ud_t` as described below. + + +.. c:function:: unsigned int ud_disassemble(ud_t*) + + Disassembles the next instruction in the input stream. + + :returns: the number of bytes disassembled. A 0 indicates end of input. + + Note, to restart disassembly after the end of input, you must call one of + the input setting functions with a new source of input. + + A common use-case pattern for this function is in a loop:: + + while (ud_disassemble(&ud_obj)) { + /* + * use or print decode info. + */ + } + +For each successful invocation of :c:func:`ud_disassemble`, you can use the +following functions to get information about the disassembled instruction. + + +.. c:function:: unsigned int ud_insn_len(const ud_t* u) + + Returns the number of bytes disassembled. + +.. c:function:: uint64_t ud_insn_off(const ud_t*) + + Returns the offset of the disassembled instruction in terms of the + program counter value specified initially. + + .. seealso:: :func:`ud_set_pc` + +.. c:function:: const char* ud_insn_hex(ud_t*) + + Returns pointer to a character string holding the hexadecimal + representation of the disassembled bytes. + +.. c:function:: const uint8_t* ud_insn_ptr(const ud_t* u) + + Returns pointer to the buffer holding the instruction bytes. Use + :func:`ud_insn_len` to determine the size of this buffer. + +.. c:function:: const char* ud_insn_asm(const ud_t* u) + + If the syntax is specified, returns pointer to the character string holding + assembly language representation of the disassembled instruction. + +.. c:function:: const ud_operand_t* ud_insn_opr(const ud_t* u, unsigned int n) + + Returns a reference (:type:`ud_operand_t`) to the nth (starting with 0) + operand of the instruction. If the instruction does not have such an + operand, the function returns :code:`NULL`. + +.. c:function:: enum ud_mnemonic_code ud_insn_mnemonic(const ud_t *u) + + .. versionadded:: 1.7.2 + + Returns the instruction mnemonic in the form of an enumerated constant + (:code:`enum ud_mnemonic_code`). As a convention all mnemonic constants + are composed by prefixing standard instruction mnemonics with :code:`UD_I`. + For example, the enumerations for :code:`mov`, :code:`xor` and :code:`jmp` + are :code:`UD_Imov`, :code:`UD_Ixor`, and :code:`UD_Ijmp`, respectively.:: + + ud_disassemble(&ud_obj); + + switch (ud_insn_mnemonic(ud_obj)) { + case UD_Imov: printf("mov!"); break; + case UD_Ixor: printf("xor!"); break; + case UD_Ijmp: printf("jmp!"); break; + /*...*/ + } + + Prior to version 1.7.2, the way to access the mnemonic was by a field of + :code:`ud_t`, :c:member:`ud_t.mnemonc`. This field is now deprecated and + may not be supported in the future. + + .. seealso:: :func:`ud_lookup_mnemonic` + +.. c:function:: const char* ud_const lookup_mnemonic(enum ud_mnemonic_code) + + Returns a pointer to a character string corresponding to the given + mnemonic code. Returns a :code:`NULL` if the code is invalid. + +Inspect Operands +---------------- + +An intermediate representation of instruction operands is available in the +form of :type:`ud_operand_t`. You can retrieve the nth operand of a +disassembled instruction using the function :func:`ud_insn_opr`. + +.. c:type:: ud_operand_t + + The operand type, represents a single operand of an instruction. It + contains the following fields. + + - :c:member:`size ` + - :c:member:`type ` + - :c:member:`base ` + - :c:member:`index ` + - :c:member:`scale ` + - :c:member:`offset ` + - :c:member:`lval ` + +.. c:member:: unsigned ud_operand_t.size + + Size of the operand in number of bits. + +.. c:member:: enum ud_operand_type ud_operand_t.type + + Type of the operand. Possible values are, + + .. c:var:: UD_OP_MEM + + A memory operand. The intermediate form normalizes all memory address + equations to the scale-index-base form. The address equation is + available in, + + - :member:`base ` - base register as an enumerated + constant of type :type:`enum ud_type`. Maybe :code:`UD_NONE`, in which + case the memory addressing form does not include a base register. + - :member:`index ` - index register as an enumerated + constant of type :type:`enum ud_type`. Maybe :code:`UD_NONE`, in which + case the memory addressing form does not include an index register. + - :member:`scale ` - an integer value by which + the index register must be scaled. Maybe 0, denoting the absence of + a scale component in the address. + - :member:`offset ` - An integer value, which if + non-zero represents the size of the displacement offset, and is one + of 8, 16, 32, and 64. The value is available in + :member:`lval `. + + .. c:var:: UD_OP_PTR + + A segment:offset pointer operand. The :member:`size ` + field can have two values, 32 (for 16:16 seg:off) and 48 (for 16:32 seg:off). + The pointer value is available in :member:`lval ` + (as :member:`lval.ptr.seg` and :member:`lval.ptr.off`) + + .. c:var:: UD_OP_IMM + + An Immediate operand. Value available in :member:`lval `. + + .. c:var:: UD_OP_JIMM + + An Immediate operand to a branch instruction (relative offsets). Value + available in :member:`lval `. + + .. c:var:: UD_OP_CONST + + Implicit constant operand. Value available in :member:`lval `. + + .. c:var:: UD_OP_REG + + A register operand. The specific register is available in the + :member:`base ` field as an enumerated constant of type + :type:`enum ud_type`. + + +.. c:member:: enum ud_register ud_operand_t.base + + Contains an enumerated constant of type :type:`enum ud_type` representing + a :data:`register ` operand or the base of a :data:`memory ` + operand. + +.. c:member:: enum ud_register ud_operand_t.index + + Contains an enumerated constant of type :type:`enum ud_type` representing + the index register of a :data:`memory ` operand. + +.. c:member:: unsigned ud_operand_t.scale + + Contains the scale component of a :data:`memory ` address operand. + +.. c:member:: unsigned ud_operand_t.offset + + Contains the size of the displacement component of a :data:`memory + ` address operand. The displacement itself is given by + :member:`lval `. + +.. c:member:: ud_lval_t ud_operand_t.lval + + A union data structure that aggregates integer fields of different sizes, + storing values depending on the :member:`type ` and + :member:`size ` of the operand. + + .. c:member:: lval.sbyte + + Signed Byte + + .. c:member:: lval.ubyte + + Unsigned Byte + + .. c:member:: lval.sword + + Signed Word + + .. c:member:: lval.uword + + Unsigned Word + + .. c:member:: lval.sdword + + Signed Double Word + + .. c:member:: lval.udword + + Unsigned Double Word + + .. c:member:: lval.sqword + + Signed Quad Word + + .. c:member:: lval.uqword + + Unsigned Quad Word + + .. c:member:: lval.ptr.seg + + Pointer Segment in Segment:Offset + + .. c:member:: lval.ptr.off + + Pointer Offset in Segment:Offset + +.. c:type:: enum ud_type + + Instruction Pointer + + .. code-block:: c + + UD_R_RIP + + 8-Bit Registers + + .. code-block:: c + + UD_NONE, + + UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, + UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, + UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, + UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, + UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, + + 16-Bit General Purporse Registers + + .. code-block:: c + + UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, + UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, + UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, + UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, + + 32-Bit General Purporse Registers: + + .. code-block:: c + + UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, + UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, + UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, + UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, + + 64-Bit General Purporse Registers: + + .. code-block:: c + + UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, + UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, + UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, + UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, + + Segment Registers: + + .. code-block:: c + + UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, + UD_R_FS, UD_R_GS, + + Control Registers: + + .. code-block:: c + + UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, + UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, + UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, + UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, + + Debug Registers: + + .. code-block:: c + + UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, + UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, + UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, + UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, + + MMX Registers: + + .. code-block:: c + + UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, + UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, + + FPU Registers: + + .. code-block:: c + + UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, + UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, + + SSE Registers: + + .. code-block:: c + + UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, + UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, + UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, + UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, + + +Inspect Prefixes +---------------- + +Prefix bytes that affect the disassembly of the instruction are availabe in the +following fields, each of which corressponds to a particular type or class of +prefixes. + +.. c:member:: uint8_t ud_t.pfx_rex + + 64-bit mode REX prefix + +.. c:member:: uint8_t ud_t.pfx_rex + + 64-bit mode REX prefix + +.. c:member:: uint8_t ud_t.pfx_seg + + Segment register prefix + +.. c:member:: uint8_t ud_t.pfx_opr + + Operand-size prefix (66h) + +.. c:member:: uint8_t ud_t.pfx_adr + + Address-size prefix (67h) + +.. c:member:: uint8_t ud_t.pfx_lock + + Lock prefix + +.. c:member:: uint8_t ud_t.pfx_rep + + Rep prefix + +.. c:member:: uint8_t ud_t.pfx_repe + + Repe prefix + +.. c:member:: uint8_t ud_t.pfx_repne + + Repne prefix + +These fields default to :code:`UD_NONE` if the respective prefixes were not found. diff --git a/udis86/docs/manual/static/udis86.css b/udis86/docs/manual/static/udis86.css new file mode 100644 index 0000000..d0dc128 --- /dev/null +++ b/udis86/docs/manual/static/udis86.css @@ -0,0 +1,115 @@ +/* override pyramid */ + +@import url("pyramid.css"); + +body { + background-color: #eee; + background-color: #e8ecef; +} + +pre { + background-color: #e8ecef; + border: 1px solid #bbb; + border-radius: 5px; + -moz-border-radius: 5px; +} + +div.body { + border: 1px solid #bbb; + border-radius: 5px; + -moz-border-radius: 5px; + color: black; +} + +div.related, +div.document { + width: 840px; + margin-left: auto; + margin-right: auto; +} + +div.related ul { + padding-left: 8px; +} + +div.footer a, +div.footer { + color: #000; + font-weight: bold; +} + +div.footer { + margin-top: 40px; + background-color: #ddd; +} + +/* +div.body { + margin-left: auto; + margin-right: auto; + width: 720px; +}*/ + +body, +div.body, +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Arial, "Helvetica Neue", Arial, Helvetica, "sans-serif"; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-weight: bold; +} + +code, +.function dt, +.member dt, +.type dt, +.var dt, +.function tt.descname, +.member tt.descname, +.var tt.descname, +.type tt.descname, +pre { + font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 1em; + padding-bottom: 6px; +} + +.function dt +{ + font-size: 1em; + padding-bottom: 6px; +} + +.function tt.descname { + font-size: 1em; +} + +a .pre, +div.related a, +a { + text-decoration: none; + color: #444; + border-bottom: 1px solid #eee; +} + +a .pre { + font-weight: bold; +} + +a:hover .pre, +a:hover, div.toctree-wrapper a:hover, .indextable a:hover, #indices-and-tables a:hover { + text-decoration: none; + color: #111; + border-bottom: 1px solid #111; +} diff --git a/udis86/docs/x86/Makefile.am b/udis86/docs/x86/Makefile.am new file mode 100644 index 0000000..3c1fe6c --- /dev/null +++ b/udis86/docs/x86/Makefile.am @@ -0,0 +1,4 @@ +x86dir = ${docdir}/x86 +dist_x86_DATA = optable.xml optable.xsl + +MAINTAINERCLEANFILES = Makefile.in diff --git a/udis86/docs/x86/README b/udis86/docs/x86/README new file mode 100644 index 0000000..1137936 --- /dev/null +++ b/udis86/docs/x86/README @@ -0,0 +1,34 @@ +x86 optable reference +--------------------- +(incomplete) + + P - modrm (reg mmx) + PR - modrm (rm mmx, mod must be 11b) + Q - modrm (rm mmx if mod=11b else mem) + + V - modrm (reg - xmm) + VR - modrm (rm xmm, mod must be 11b) + W - modrm (rm xmm if mod=11b else mem) + + G - modrm (reg - gpr) + S - modrm (reg - seg) + VR - modrm (rm gpr, mod must be 11b) + E - modrm (rm gpr if mod=11b else mem) + M - modrm (mem), mod!=11b + + I - immediate + J - relative immediate + O - memory offset + + C - control reg + D - debug reg + + + opc <> + + /n - modrm reg field extends opcode + /Mnn - disassembly mode extends opcode + /Onn - operand mode extends opcode + /mod=!11 - modrm mod field extends opcode + + diff --git a/udis86/docs/x86/avx.xml b/udis86/docs/x86/avx.xml new file mode 100644 index 0000000..9b7b12c --- /dev/null +++ b/udis86/docs/x86/avx.xml @@ -0,0 +1,3023 @@ + + vaddpd + vex.L + vex.660f 58 + V H W + avx + + + + vaddps + vex.L + vex.0f 58 + V H W + avx + + + + vaddsd + + vex.f20f 58 + V H W + avx + + + + vaddss + + vex.f30f 58 + V H W + avx + + + + vandpd + vex.L + vex.660f 54 + V H W + avx + + + + vandps + vex.L + vex.0f 54 + V H W + avx + + + + vandnpd + vex.L + vex.660f 55 + V H W + avx + + + + vandnps + vex.L + vex.0f 55 + V H W + avx + + + + vcmppd + vex.L + vex.660f c2 + V W Ib + avx + + + + vcmpps + vex.L + vex.0f c2 + V W Ib + avx + + + + vcmpsd + + vex.f20f c2 + V W Ib + avx + + + + vcmpss + + vex.f30f c2 + V W Ib + avx + + + + vcomisd + + vex.660f 2f + V H W + avx + + + + vcomiss + + vex.0f 2f + V H W + avx + + + + vcvtdq2pd + vex.L + vex.f30f e6 + V H W + avx + + + + vcvtdq2ps + vex.L + vex.0f 5b + V H W + avx + + + + vcvtpd2dq + vex.L + vex.f20f e6 + V H W + avx + + + + vcvtpd2pi + vex.L + vex.660f 2d + P W + avx + + + + vcvtpd2ps + vex.L + vex.660f 5a + V H W + avx + + + + vcvtpi2ps + vex.L + vex.0f 2a + V Q + avx + + + + vcvtpi2pd + vex.L + vex.660f 2a + V Q + avx + + + + vcvtps2dq + vex.L + vex.660f 5b + V H W + avx + + + + vcvtps2pi + vex.L + vex.0f 2d + P W + avx + + + + vcvtps2pd + vex.L + vex.0f 5a + V H W + avx + + + + vcvtsd2si + vex.W vex.L + vex.f20f 2d + Gy W + avx + + + + vcvtsd2ss + + vex.f20f 5a + V H W + avx + + + + vcvtsi2ss + aso + vex.f30f 2a + V Ey + avx + + + + vcvtss2si + vex.W vex.L + vex.f30f 2d + Gy W + avx + + + + vcvtss2sd + + vex.f30f 5a + V H W + avx + + + + vcvttpd2pi + vex.L + vex.660f 2c + P W + avx + + + + vcvttpd2dq + vex.L + vex.660f e6 + V H W + avx + + + + vcvttps2dq + vex.L + vex.f30f 5b + V H W + avx + + + + vcvttps2pi + vex.L + vex.0f 2c + P W + avx + + + + vcvttsd2si + vex.W vex.L + vex.f20f 2c + Gy W + avx + + + + vcvtsi2sd + aso + vex.f20f 2a + V Ey + avx + + + + vcvttss2si + vex.W vex.L + vex.f30f 2c + Gy W + avx + + + + vdivpd + vex.L + vex.660f 5e + V H W + avx + + + + vdivps + vex.L + vex.0f 5e + V H W + avx + + + + vdivsd + + vex.f20f 5e + V H W + avx + + + + vdivss + + vex.f30f 5e + V H W + avx + + + + vmaskmovq + vex.L + vex.0f f7 + V U + avx + + + + vmaxpd + vex.L + vex.660f 5f + V H W + avx + + + + vmaxps + vex.L + vex.0f 5f + V H W + avx + + + + vmaxsd + + vex.f20f 5f + V H W + avx + + + + vmaxss + + vex.f30f 5f + V H W + avx + + + + vminpd + vex.L + vex.660f 5d + V H W + avx + + + + vminps + vex.L + vex.0f 5d + V H W + avx + + + + vminsd + + vex.f20f 5d + V H W + avx + + + + vminss + + vex.f30f 5d + V H W + avx + + + + vmovapd + vex.L + vex.660f 28 + V H W + avx + + + + vmovapd + vex.L + vex.660f 29 + W H V + avx + + + + vmovaps + vex.L + vex.0f 28 + V H W + avx + + + + vmovaps + vex.L + vex.0f 29 + W H V + avx + + + + vmovd + aso vex.L + vex.660f 6e + V Ey + avx + + + + vmovd + aso vex.L + vex.0f 6e + P Ey + avx + + + + vmovd + aso vex.L + vex.660f 7e + Ey V + avx + + + + vmovd + aso vex.L + vex.0f 7e + Ey P + avx + + + + vmovhpd + aso vex.L + vex.660f 16 /mod=!11 + V M + avx + + + + vmovhpd + aso vex.L + vex.660f 17 + M V + avx + + + + vmovhps + aso vex.L + vex.0f 16 /mod=!11 + V M + avx + + + + vmovhps + aso vex.L + vex.0f 17 + M V + avx + + + + vmovlhps + vex.L + vex.0f 16 /mod=11 + V U + avx + + + + vmovlpd + aso vex.L + vex.660f 12 /mod=!11 + V M + avx + + + + vmovlpd + aso vex.L + vex.660f 13 + M V + avx + + + + vmovlps + aso vex.L + vex.0f 12 /mod=!11 + V M + avx + + + + vmovlps + aso vex.L + vex.0f 13 + M V + avx + + + + vmovhlps + vex.L + vex.0f 12 /mod=11 + V U + avx + + + + vmovmskpd + vex.W vex.L + vex.660f 50 + Gd U + avx + + + + vmovmskps + vex.W vex.L + vex.0f 50 + Gd U + avx + + + + vmovntdq + aso vex.L + vex.660f e7 + M V + avx + + + + vmovnti + aso vex.W vex.L + vex.0f c3 + M Gy + avx + + + + vmovntpd + aso vex.L + vex.660f 2b + M V + avx + + + + vmovntps + aso vex.L + vex.0f 2b + M V + avx + + + + vmovntq + aso vex.L + vex.0f e7 + M V + avx + + + + vmovq + vex.L + vex.0f 6f + V W + avx + + + + vmovq + vex.L + vex.660f d6 + W H V + avx + + + + vmovq + vex.L + vex.f30f 7e + V H W + avx + + + + vmovq + vex.L + vex.0f 7f + W V + avx + + + + vmovsd + + vex.f20f 10 + V H W + avx + + + + vmovsd + + vex.f20f 11 + W H V + avx + + + + vmovss + + vex.f30f 10 + V H W + avx + + + + vmovss + + vex.f30f 11 + W H V + avx + + + + vmovsx + aso vex.W vex.L + vex.0f be + Gv Eb + avx + + + + vmovsx + aso vex.W vex.L + vex.0f bf + Gy Ew + avx + + + + vmovupd + vex.L + vex.660f 10 + V H W + avx + + + + vmovupd + vex.L + vex.660f 11 + W H V + avx + + + + vmovups + vex.L + vex.0f 10 + V H W + avx + + + + vmovups + vex.L + vex.0f 11 + W H V + avx + + + + vmovzx + aso vex.W vex.L + vex.0f b6 + Gv Eb + avx + + + + vmovzx + aso vex.W vex.L + vex.0f b7 + Gy Ew + avx + + + + vmulpd + vex.L + vex.660f 59 + V H W + avx + + + + vmulps + vex.L + vex.0f 59 + V H W + avx + + + + vmulsd + + vex.f20f 59 + V H W + avx + + + + vmulss + + vex.f30f 59 + V H W + avx + + + + vorps + vex.L + vex.0f 56 + V H W + avx + + + + vpacksswb + vex.L + vex.660f 63 + V H W + avx + + + + vpacksswb + vex.L + vex.0f 63 + V W + avx + + + + vpackssdw + vex.L + vex.660f 6b + V H W + avx + + + + vpackssdw + vex.L + vex.0f 6b + V W + avx + + + + vpackuswb + vex.L + vex.660f 67 + V H W + avx + + + + vpackuswb + vex.L + vex.0f 67 + V W + avx + + + + vpaddb + vex.L + vex.660f fc + V H W + avx + + + + vpaddb + vex.L + vex.0f fc + V W + avx + + + + vpaddw + vex.L + vex.0f fd + V W + avx + + + + vpaddw + vex.L + vex.660f fd + V H W + avx + + + + vpaddd + vex.L + vex.0f fe + V W + avx + + + + vpaddd + vex.L + vex.660f fe + V H W + avx + + + + vpaddsb + vex.L + vex.0f ec + V W + avx + + + + vpaddsb + vex.L + vex.660f ec + V H W + avx + + + + vpaddsw + vex.L + vex.0f ed + V W + avx + + + + vpaddsw + vex.L + vex.660f ed + V H W + avx + + + + vpaddusb + vex.L + vex.0f dc + V W + avx + + + + vpaddusb + vex.L + vex.660f dc + V H W + avx + + + + vpaddusw + vex.L + vex.0f dd + V W + avx + + + + vpaddusw + vex.L + vex.660f dd + V H W + avx + + + + vpand + vex.L + vex.660f db + V H W + avx + + + + vpand + vex.L + vex.0f db + V W + avx + + + + vpandn + vex.L + vex.660f df + V H W + avx + + + + vpandn + vex.L + vex.0f df + V W + avx + + + + vpavgb + vex.L + vex.660f e0 + V H W + avx + + + + vpavgb + vex.L + vex.0f e0 + V W + avx + + + + vpavgw + vex.L + vex.660f e3 + V H W + avx + + + + vpavgw + vex.L + vex.0f e3 + V W + avx + + + + vpcmpeqb + vex.L + vex.0f 74 + V W + avx + + + + vpcmpeqb + vex.L + vex.660f 74 + V H W + avx + + + + vpcmpeqw + vex.L + vex.0f 75 + V W + avx + + + + vpcmpeqw + vex.L + vex.660f 75 + V H W + avx + + + + vpcmpeqd + vex.L + vex.0f 76 + V W + avx + + + + vpcmpeqd + vex.L + vex.660f 76 + V H W + avx + + + + vpcmpgtb + vex.L + vex.660f 64 + V H W + avx + + + + vpcmpgtb + vex.L + vex.0f 64 + V W + avx + + + + vpcmpgtw + vex.L + vex.660f 65 + V H W + avx + + + + vpcmpgtw + vex.L + vex.0f 65 + V W + avx + + + + vpcmpgtd + vex.L + vex.660f 66 + V H W + avx + + + + vpcmpgtd + vex.L + vex.0f 66 + V W + avx + + + + vpextrb + aso vex.W vex.L + vex.660f3a 14 + MbRv V Ib + avx + + + + vpextrd + aso vex.L + vex.660f3a 16 /o=16 + Ed V Ib + avx + + + + vpextrd + aso vex.L + vex.660f3a 16 /o=32 + Ed V Ib + avx + + + + vpextrq + aso vex.L + vex.660f3a 16 /o=64 + Eq V Ib + avx + + + + vpextrw + vex.W vex.L + vex.660f c5 + Gd U Ib + avx + + + + vpextrw + vex.W vex.L + vex.0f c5 + Gd N Ib + avx + + + + vpinsrb + aso vex.W vex.L + vex.660f3a 20 + V MbRd Ib + avx + + + + vpinsrw + aso vex.W vex.L + vex.0f c4 + P MwRy Ib + avx + + + + vpinsrw + aso vex.W vex.L + vex.660f c4 + V MwRy Ib + avx + + + + vpinsrd + aso vex.L + vex.660f3a 22 /o=16 + V Ed Ib + avx + + + + vpinsrd + aso vex.L + vex.660f3a 22 /o=32 + V Ed Ib + avx + + + + vpinsrq + aso vex.L + vex.660f3a 22 /o=64 + V Eq Ib + avx + + + + vpmaddwd + vex.L + vex.0f f5 + V W + avx + + + + vpmaddwd + vex.L + vex.660f f5 + V H W + avx + + + + vpmaxsw + vex.L + vex.660f ee + V H W + avx + + + + vpmaxsw + vex.L + vex.0f ee + V W + avx + + + + vpmaxub + vex.L + vex.0f de + V W + avx + + + + vpmaxub + vex.L + vex.660f de + V H W + avx + + + + vpminsw + vex.L + vex.660f ea + V H W + avx + + + + vpminsw + vex.L + vex.0f ea + V W + avx + + + + vpminub + vex.L + vex.660f da + V H W + avx + + + + vpminub + vex.L + vex.0f da + V W + avx + + + + vpmovmskb + vex.W vex.L + vex.660f d7 + Gd U + avx + + + + vpmovmskb + vex.W vex.L + vex.0f d7 + Gd N + avx + + + + vpmulhuw + vex.L + vex.0f e4 + V W + avx + + + + vpmulhuw + vex.L + vex.660f e4 + V H W + avx + + + + vpmulhw + vex.L + vex.660f e5 + V H W + avx + + + + vpmulhw + vex.L + vex.0f e5 + V W + avx + + + + vpmullw + vex.L + vex.0f d5 + V W + avx + + + + vpmullw + vex.L + vex.660f d5 + V H W + avx + + + + vpop + vex.W vex.L + vex.0f a9 + GS + avx + + + + vpop + vex.L + vex.0f a1 + FS + avx + + + + vpor + vex.L + vex.660f eb + V H W + avx + + + + vpor + vex.L + vex.0f eb + V W + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=0 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=1 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=2 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=3 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=4 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=5 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=6 + M + avx + + + + vprefetch + aso vex.L + vex.0f 0d /reg=7 + M + avx + + + + vprefetchnta + aso vex.L + vex.0f 18 /reg=0 + M + avx + + + + vprefetcht0 + aso vex.L + vex.0f 18 /reg=1 + M + avx + + + + vprefetcht1 + aso vex.L + vex.0f 18 /reg=2 + M + avx + + + + vprefetcht2 + aso vex.L + vex.0f 18 /reg=3 + M + avx + + + + vpsadbw + vex.L + vex.660f f6 + V H W + avx + + + + vpsadbw + vex.L + vex.0f f6 + V W + avx + + + + vpshufw + vex.L + vex.0f 70 + P Q Ib + avx + + + + vpsllw + vex.L + vex.660f f1 + V H W + avx + + + + vpsllw + vex.L + vex.0f f1 + V W + avx + + + + vpsllw + vex.L + vex.660f 71 /reg=6 + U Ib + avx + + + + vpsllw + vex.L + vex.0f 71 /reg=6 + N Ib + avx + + + + vpslld + vex.L + vex.660f f2 + V H W + avx + + + + vpslld + vex.L + vex.0f f2 + V W + avx + + + + vpslld + vex.L + vex.660f 72 /reg=6 + U Ib + avx + + + + vpslld + vex.L + vex.0f 72 /reg=6 + N Ib + avx + + + + vpsllq + vex.L + vex.660f f3 + V H W + avx + + + + vpsllq + vex.L + vex.0f f3 + V W + avx + + + + vpsllq + vex.L + vex.660f 73 /reg=6 + U Ib + avx + + + + vpsllq + vex.L + vex.0f 73 /reg=6 + N Ib + avx + + + + vpsraw + vex.L + vex.0f e1 + V W + avx + + + + vpsraw + vex.L + vex.660f e1 + V H W + avx + + + + vpsraw + vex.L + vex.660f 71 /reg=4 + U Ib + avx + + + + vpsraw + vex.L + vex.0f 71 /reg=4 + N Ib + avx + + + + vpsrad + vex.L + vex.0f 72 /reg=4 + N Ib + avx + + + + vpsrad + vex.L + vex.660f e2 + V H W + avx + + + + vpsrad + vex.L + vex.0f e2 + V W + avx + + + + vpsrad + vex.L + vex.660f 72 /reg=4 + U Ib + avx + + + + vpsrlw + vex.L + vex.0f 71 /reg=2 + N Ib + avx + + + + vpsrlw + vex.L + vex.0f d1 + V W + avx + + + + vpsrlw + vex.L + vex.660f d1 + V H W + avx + + + + vpsrlw + vex.L + vex.660f 71 /reg=2 + U Ib + avx + + + + vpsrld + vex.L + vex.0f 72 /reg=2 + N Ib + avx + + + + vpsrld + vex.L + vex.0f d2 + V W + avx + + + + vpsrld + vex.L + vex.660f d2 + V H W + avx + + + + vpsrld + vex.L + vex.660f 72 /reg=2 + U Ib + avx + + + + vpsrlq + vex.L + vex.0f 73 /reg=2 + N Ib + avx + + + + vpsrlq + vex.L + vex.0f d3 + V W + avx + + + + vpsrlq + vex.L + vex.660f d3 + V H W + avx + + + + vpsrlq + vex.L + vex.660f 73 /reg=2 + U Ib + avx + + + + vpsubb + vex.L + vex.660f f8 + V H W + avx + + + + vpsubb + vex.L + vex.0f f8 + V W + avx + + + + vpsubw + vex.L + vex.660f f9 + V H W + avx + + + + vpsubw + vex.L + vex.0f f9 + V W + avx + + + + vpsubd + vex.L + vex.0f fa + V W + avx + + + + vpsubd + vex.L + vex.660f fa + V H W + avx + + + + vpsubsb + vex.L + vex.0f e8 + V W + avx + + + + vpsubsb + vex.L + vex.660f e8 + V H W + avx + + + + vpsubsw + vex.L + vex.0f e9 + V W + avx + + + + vpsubsw + vex.L + vex.660f e9 + V H W + avx + + + + vpsubusb + vex.L + vex.0f d8 + V W + avx + + + + vpsubusb + vex.L + vex.660f d8 + V H W + avx + + + + vpsubusw + vex.L + vex.0f d9 + V W + avx + + + + vpsubusw + vex.L + vex.660f d9 + V H W + avx + + + + vpunpckhbw + vex.L + vex.660f 68 + V H W + avx + + + + vpunpckhbw + vex.L + vex.0f 68 + V W + avx + + + + vpunpckhwd + vex.L + vex.660f 69 + V H W + avx + + + + vpunpckhwd + vex.L + vex.0f 69 + V W + avx + + + + vpunpckhdq + vex.L + vex.660f 6a + V H W + avx + + + + vpunpckhdq + vex.L + vex.0f 6a + V W + avx + + + + vpunpcklbw + vex.L + vex.660f 60 + V H W + avx + + + + vpunpcklbw + vex.L + vex.0f 60 + V W + avx + + + + vpunpcklwd + vex.L + vex.660f 61 + V H W + avx + + + + vpunpcklwd + vex.L + vex.0f 61 + V W + avx + + + + vpunpckldq + vex.L + vex.660f 62 + V H W + avx + + + + vpunpckldq + vex.L + vex.0f 62 + V W + avx + + + + vpush + vex.W vex.L + vex.0f a8 + GS + avx + + + + vpush + vex.L + vex.0f a0 + FS + avx + + + + vpxor + vex.L + vex.660f ef + V H W + avx + + + + vpxor + vex.L + vex.0f ef + V W + avx + + + + vrcpps + vex.L + vex.0f 53 + V H W + avx + + + + vrcpss + + vex.f30f 53 + V H W + avx + + + + vrsqrtps + vex.L + vex.0f 52 + V H W + avx + + + + vrsqrtss + + vex.f30f 52 + V H W + avx + + + + vshufpd + vex.L + vex.660f c6 + V W Ib + avx + + + + vshufps + vex.L + vex.0f c6 + V W Ib + avx + + + + vsqrtps + vex.L + vex.0f 51 + V H W + avx + + + + vsqrtpd + vex.L + vex.660f 51 + V H W + avx + + + + vsqrtsd + + vex.f20f 51 + V H W + avx + + + + vsqrtss + + vex.f30f 51 + V H W + avx + + + + vsubpd + vex.L + vex.660f 5c + V H W + avx + + + + vsubps + vex.L + vex.0f 5c + V H W + avx + + + + vsubsd + + vex.f20f 5c + V H W + avx + + + + vsubss + + vex.f30f 5c + V H W + avx + + + + vucomisd + + vex.660f 2e + V H W + avx + + + + vucomiss + + vex.0f 2e + V H W + avx + + + + vunpckhpd + vex.L + vex.660f 15 + V H W + avx + + + + vunpckhps + vex.L + vex.0f 15 + V H W + avx + + + + vunpcklps + vex.L + vex.0f 14 + V H W + avx + + + + vunpcklpd + vex.L + vex.660f 14 + V H W + avx + + + + vxorpd + vex.L + vex.660f 57 + V H W + avx + + + + vxorps + vex.L + vex.0f 57 + V H W + avx + + + + vmovdqa + vex.L + vex.660f 7f + W H V + avx + + + + vmovdqa + vex.L + vex.660f 6f + V H W + avx + + + + vmovdq2q + vex.L + vex.f20f d6 + P U + avx + + + + vmovdqu + vex.L + vex.f30f 6f + V H W + avx + + + + vmovdqu + vex.L + vex.f30f 7f + W H V + avx + + + + vmovq2dq + vex.L + vex.f30f d6 + V N + avx + + + + vpaddq + vex.L + vex.0f d4 + V W + avx + + + + vpaddq + vex.L + vex.660f d4 + V H W + avx + + + + vpsubq + vex.L + vex.660f fb + V H W + avx + + + + vpsubq + vex.L + vex.0f fb + V W + avx + + + + vpmuludq + vex.L + vex.0f f4 + V W + avx + + + + vpmuludq + vex.L + vex.660f f4 + V H W + avx + + + + vpshufhw + vex.L + vex.f30f 70 + V W Ib + avx + + + + vpshuflw + vex.L + vex.f20f 70 + V W Ib + avx + + + + vpshufd + vex.L + vex.660f 70 + V W Ib + avx + + + + vpslldq + vex.L + vex.660f 73 /reg=7 + U Ib + avx + + + + vpsrldq + vex.L + vex.660f 73 /reg=3 + U Ib + avx + + + + vpunpckhqdq + vex.L + vex.660f 6d + V H W + avx + + + + vpunpcklqdq + vex.L + vex.660f 6c + V H W + avx + + + + vaddsubpd + vex.L + vex.660f d0 + V H W + avx + + + + vaddsubps + vex.L + vex.f20f d0 + V H W + avx + + + + vhaddpd + vex.L + vex.660f 7c + V H W + avx + + + + vhaddps + vex.L + vex.f20f 7c + V H W + avx + + + + vhsubpd + vex.L + vex.660f 7d + V H W + avx + + + + vhsubps + vex.L + vex.f20f 7d + V H W + avx + + + + vmovddup + vex.L + vex.f20f 12 /mod=11 + V H W + avx + + + + vmovddup + vex.L + vex.f20f 12 /mod=!11 + V H W + avx + + + + vmovshdup + vex.L + vex.f30f 16 /mod=11 + V H W + avx + + + + vmovshdup + vex.L + vex.f30f 16 /mod=!11 + V H W + avx + + + + vmovsldup + vex.L + vex.f30f 12 /mod=11 + V H W + avx + + + + vmovsldup + vex.L + vex.f30f 12 /mod=!11 + V H W + avx + + + + vpabsb + vex.L + vex.0f38 1c + V W + avx + + + + vpabsb + vex.L + vex.660f38 1c + V H W + avx + + + + vpabsw + vex.L + vex.0f38 1d + V W + avx + + + + vpabsw + vex.L + vex.660f38 1d + V H W + avx + + + + vpabsd + + vex.0f38 1e + V W + avx + + + + vpabsd + + vex.660f38 1e + V H W + avx + + + + vpsignb + vex.L + vex.0f38 00 + V W + avx + + + + vpsignb + vex.L + vex.660f38 00 + V H W + avx + + + + vphaddw + vex.L + vex.0f38 01 + V W + avx + + + + vphaddw + vex.L + vex.660f38 01 + V H W + avx + + + + vphaddd + vex.L + vex.0f38 02 + V W + avx + + + + vphaddd + vex.L + vex.660f38 02 + V H W + avx + + + + vphaddsw + vex.L + vex.0f38 03 + V W + avx + + + + vphaddsw + vex.L + vex.660f38 03 + V H W + avx + + + + vpmaddubsw + vex.L + vex.0f38 04 + V W + avx + + + + vpmaddubsw + vex.L + vex.660f38 04 + V H W + avx + + + + vphsubw + vex.L + vex.0f38 05 + V W + avx + + + + vphsubw + vex.L + vex.660f38 05 + V H W + avx + + + + vphsubd + vex.L + vex.0f38 06 + V W + avx + + + + vphsubd + vex.L + vex.660f38 06 + V H W + avx + + + + vphsubsw + vex.L + vex.0f38 07 + V W + avx + + + + vphsubsw + vex.L + vex.660f38 07 + V H W + avx + + + + vpsignb + vex.L + vex.0f38 08 + V W + avx + + + + vpsignb + vex.L + vex.660f38 08 + V H W + avx + + + + vpsignd + vex.L + vex.0f38 0a + V W + avx + + + + vpsignd + vex.L + vex.660f38 0a + V H W + avx + + + + vpsignw + vex.L + vex.0f38 09 + V W + avx + + + + vpsignw + vex.L + vex.660f38 09 + V H W + avx + + + + vpmulhrsw + vex.L + vex.0f38 0b + V W + avx + + + + vpmulhrsw + vex.L + vex.660f38 0b + V H W + avx + + + + vpalignr + vex.L + vex.0f3a 0f + P Q Ib + avx + + + + vpalignr + vex.L + vex.660f3a 0f + V W Ib + avx + + + + vpblendvb + vex.L + vex.660f38 10 + V H W + avx + + + + vpmuldq + vex.L + vex.660f38 28 + V H W + avx + + + + vpminsb + vex.L + vex.660f38 38 + V H W + avx + + + + vpminsd + + vex.660f38 39 + V H W + avx + + + + vpminuw + vex.L + vex.660f38 3a + V H W + avx + + + + vpminud + vex.L + vex.660f38 3b + V H W + avx + + + + vpmaxsb + vex.L + vex.660f38 3c + V H W + avx + + + + vpmaxsd + + vex.660f38 3d + V H W + avx + + + + vpmaxud + vex.L + vex.660f38 3f + V H W + avx + + + + vpmaxuw + vex.L + vex.660f38 3e + V H W + avx + + + + vpmulld + vex.L + vex.660f38 40 + V H W + avx + + + + vphminposuw + vex.L + vex.660f38 41 + V H W + avx + + + + vroundps + vex.L + vex.660f3a 08 + V W Ib + avx + + + + vroundpd + vex.L + vex.660f3a 09 + V W Ib + avx + + + + vroundss + + vex.660f3a 0a + V W Ib + avx + + + + vroundsd + + vex.660f3a 0b + V W Ib + avx + + + + vblendpd + vex.L + vex.660f3a 0d + V W Ib + avx + + + + vpblendw + vex.L + vex.660f3a 0e + V W Ib + avx + + + + vblendps + vex.L + vex.660f3a 0c + V W Ib + avx + + + + vblendvpd + vex.L + vex.660f38 15 + V H W + avx + + + + vblendvps + vex.L + vex.660f38 14 + V H W + avx + + + + vdpps + vex.L + vex.660f3a 40 + V W Ib + avx + + + + vdppd + vex.L + vex.660f3a 41 + V W Ib + avx + + + + vmpsadbw + vex.L + vex.660f3a 42 + V W Ib + avx + + + + vextractps + aso vex.W vex.L + vex.660f3a 17 + MdRy V Ib + avx + + + + vinsertps + aso vex.L + vex.660f3a 21 + V Md Ib + avx + + + + vmovntdqa + aso vex.L + vex.660f38 2a + V Mo + avx + + + + vpackusdw + vex.L + vex.660f38 2b + V H W + avx + + + + vpmovsxbw + aso vex.L + vex.660f38 20 + V MqU + avx + + + + vpmovsxbd + aso vex.L + vex.660f38 21 + V MdU + avx + + + + vpmovsxbq + aso vex.L + vex.660f38 22 + V MwU + avx + + + + vpmovsxwd + aso vex.L + vex.660f38 23 + V MqU + avx + + + + vpmovsxwq + aso vex.L + vex.660f38 24 + V MdU + avx + + + + vpmovsxdq + aso vex.L + vex.660f38 25 + V MqU + avx + + + + vpmovzxbw + aso vex.L + vex.660f38 30 + V MqU + avx + + + + vpmovzxbd + aso vex.L + vex.660f38 31 + V MdU + avx + + + + vpmovzxbq + aso vex.L + vex.660f38 32 + V MwU + avx + + + + vpmovzxwd + aso vex.L + vex.660f38 33 + V MqU + avx + + + + vpmovzxwq + aso vex.L + vex.660f38 34 + V MdU + avx + + + + vpmovzxdq + aso vex.L + vex.660f38 35 + V MqU + avx + + + + vpcmpeqq + vex.L + vex.660f38 29 + V H W + avx + + + + vptest + vex.L + vex.660f38 17 + V H W + avx + + + + vpcmpestri + vex.L + vex.660f3a 61 + V W Ib + avx + + + + vpcmpestrm + vex.L + vex.660f3a 60 + V W Ib + avx + + + + vpcmpgtq + vex.L + vex.660f38 37 + V H W + avx + + + + vpcmpistri + vex.L + vex.660f3a 63 + V W Ib + avx + + + + vpcmpistrm + vex.L + vex.660f3a 62 + V W Ib + avx + diff --git a/udis86/docs/x86/optable.xml b/udis86/docs/x86/optable.xml new file mode 100644 index 0000000..9c3ff67 --- /dev/null +++ b/udis86/docs/x86/optable.xml @@ -0,0 +1,10113 @@ + + + + + + + + aaa + + 37 /m=!64 + + + + + aad + + d5 /m=!64 + Ib + + + + + aam + + d4 /m=!64 + Ib + + + + + aas + + 3f /m=!64 + + + + + adc + + aso rexr rexx rexb + 10 + Eb Gb + + + aso oso rexw rexr rexx rexb + 11 + Ev Gv + + + aso rexr rexx rexb + 12 + Gb Eb + + + aso oso rexw rexr rexx rexb + 13 + Gv Ev + + + 14 + AL Ib + + + oso rexw + 15 + rAX sIz + + + aso rexr rexx rexb + 80 /reg=2 + Eb Ib + + + aso rexr rexx rexb + 82 /reg=2 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 81 /reg=2 + Ev sIz + + + aso oso rexw rexr rexx rexb + 83 /reg=2 + Ev sIb + + + + + add + + aso rexr rexx rexb + 00 + Eb Gb + + + aso oso rexw rexr rexx rexb + 01 + Ev Gv + + + aso rexr rexx rexb + 02 + Gb Eb + + + aso oso rexw rexr rexx rexb + 03 + Gv Ev + + + 04 + AL Ib + + + oso rexw + 05 + rAX sIz + + + aso rexr rexx rexb + 80 /reg=0 + Eb Ib + + + aso rexr rexx rexb + 82 /reg=0 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 81 /reg=0 + Ev sIz + + + aso oso rexw rexr rexx rexb + 83 /reg=0 + Ev sIb + + + + + addpd + + aso rexr rexx rexb vexl + /sse=66 0f 58 + V H W + sse2 avx + + + + + addps + + aso rexr rexx rexb vexl + 0f 58 + V H W + sse avx + + + + + addsd + + aso rexr rexx rexb + /sse=f2 0f 58 + V H W + sse2 avx + + + + + addss + + aso rexr rexx rexb + /sse=f3 0f 58 + V H W + sse avx + + + + + addsubpd + + aso rexr rexx rexb + /sse=66 0f d0 + V H W + sse3 avx + + + + + addsubps + + aso rexr rexx rexb + /sse=f2 0f d0 + V H W + sse3 avx + + + + + aesdec + + aso rexr rexx rexb + /sse=66 0f 38 de + V H W + aesni avx + + + + + aesdeclast + + aso rexr rexx rexb + /sse=66 0f 38 df + V W + aesni avx + + + + + aesenc + aesni + + aso rexr rexx rexb + /sse=66 0f 38 dc + V W + aesni avx + + + + + aesenclast + aesni avx + + aso rexr rexx rexb + /sse=66 0f 38 dd + V H W + + + + + aesimc + + aso rexr rexx rexb + /sse=66 0f 38 db + V W + aesni avx + + + + + aeskeygenassist + + aso rexr rexx rexb + /sse=66 0f 3a df + V W Ib + aesni avx + + + + + and + + aso rexr rexx rexb + 20 + Eb Gb + + + aso oso rexw rexr rexx rexb + 21 + Ev Gv + + + aso rexr rexx rexb + 22 + Gb Eb + + + aso oso rexw rexr rexx rexb + 23 + Gv Ev + + + 24 + AL Ib + + + oso rexw + 25 + rAX sIz + + + aso rexw rexr rexx rexb + 80 /reg=4 + Eb Ib + + + aso rexr rexx rexb + 82 /reg=4 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 81 /reg=4 + Ev sIz + + + aso oso rexw rexr rexx rexb + 83 /reg=4 + Ev sIb + + + + + andpd + + aso rexr rexx rexb vexl + /sse=66 0f 54 + V H W + sse2 avx + + + + + andps + + aso rexr rexx rexb + 0f 54 + V H W + sse avx + + + + + andnpd + + aso rexr rexx rexb + /sse=66 0f 55 + V H W + sse2 avx + + + + + andnps + + aso rexr rexx rexb + 0f 55 + V H W + sse2 avx + + + + + arpl + + aso + 63 /m=!64 + Ew Gw + + + + + movsxd + + aso oso rexw rexx rexr rexb + 63 /m=64 + Gq Ed + + + + + call + + aso oso rexw rexr rexx rexb + ff /reg=2 /m=!64 + Ev + + + aso oso rexw rexr rexx rexb + ff /reg=2 /m=64 + Eq + def64 + + + aso oso rexw rexr rexx rexb + ff /reg=3 + Fv + + + oso + e8 + Jz + def64 + + + oso + 9a /m=!64 + Av + + + + + cbw + + oso rexw + 98 /o=16 + + + + + cwde + + oso rexw + 98 /o=32 + + + + + cdqe + + oso rexw + 98 /o=64 + + + + + clc + + f8 + + + + + cld + + fc + + + + + clflush + + aso rexw rexr rexx rexb + 0f ae /reg=7 /mod=!11 + M + + + + + clgi + amd + + 0f 01 /reg=3 /mod=11 /rm=5 + + + + + cli + + fa + + + + + clts + + 0f 06 + + + + + cmc + + f5 + + + + + cmovo + + aso oso rexw rexr rexx rexb + 0f 40 + Gv Ev + + + + + cmovno + + aso oso rexw rexr rexx rexb + 0f 41 + Gv Ev + + + + + cmovb + + aso oso rexw rexr rexx rexb + 0f 42 + Gv Ev + + + + + cmovae + + aso oso rexw rexr rexx rexb + 0f 43 + Gv Ev + + + + + cmovz + + aso oso rexw rexr rexx rexb + 0f 44 + Gv Ev + + + + + cmovnz + + aso oso rexw rexr rexx rexb + 0f 45 + Gv Ev + + + + + cmovbe + + aso oso rexw rexr rexx rexb + 0f 46 + Gv Ev + + + + + cmova + + aso oso rexw rexr rexx rexb + 0f 47 + Gv Ev + + + + + cmovs + + aso oso rexw rexr rexx rexb + 0f 48 + Gv Ev + + + + + cmovns + + aso oso rexw rexr rexx rexb + 0f 49 + Gv Ev + + + + + cmovp + + aso oso rexw rexr rexx rexb + 0f 4a + Gv Ev + + + + + cmovnp + + aso oso rexw rexr rexx rexb + 0f 4b + Gv Ev + + + + + cmovl + + aso oso rexw rexr rexx rexb + 0f 4c + Gv Ev + + + + + cmovge + + aso oso rexw rexr rexx rexb + 0f 4d + Gv Ev + + + + + cmovle + + aso oso rexw rexr rexx rexb + 0f 4e + Gv Ev + + + + + cmovg + + aso oso rexw rexr rexx rexb + 0f 4f + Gv Ev + + + + + cmp + + aso rexr rexx rexb + 38 + Eb Gb + + + aso oso rexw rexr rexx rexb + 39 + Ev Gv + + + aso rexr rexx rexb + 3a + Gb Eb + + + aso oso rexw rexr rexx rexb + 3b + Gv Ev + + + 3c + AL Ib + + + oso rexw + 3d + rAX sIz + + + aso rexr rexx rexb + 80 /reg=7 + Eb Ib + + + aso rexr rexx rexb + 82 /reg=7 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 81 /reg=7 + Ev sIz + + + aso oso rexw rexr rexx rexb + 83 /reg=7 + Ev sIb + + + + + cmppd + + aso rexr rexx rexb vexl + /sse=66 0f c2 + V H W Ib + sse2 avx + + + + + cmpps + + aso rexr rexx rexb vexl + 0f c2 + V H W Ib + sse2 avx + + + + + cmpsb + + repz seg + a6 + + + + + cmpsw + + repz oso rexw seg + a7 /o=16 + + + + + cmpsd + + repz oso rexw seg + a7 /o=32 + + + aso rexr rexx rexb + /sse=f2 0f c2 + V H W Ib + sse2 avx + + + + + cmpsq + + repz oso rexw seg + a7 /o=64 + + + + + cmpss + + aso rexr rexx rexb + /sse=f3 0f c2 + V H W Ib + sse2 avx + + + + + cmpxchg + + aso rexr rexx rexb + 0f b0 + Eb Gb + + + aso oso rexw rexr rexx rexb + 0f b1 + Ev Gv + + + + + cmpxchg8b + + aso rexr rexx rexb + 0f c7 /mod=!11 /reg=1 /o=16 + M + + + aso rexr rexx rexb + 0f c7 /mod=!11 /reg=1 /o=32 + M + + + + + cmpxchg16b + + aso rexr rexx rexb + 0f c7 /mod=!11 /reg=1 /o=64 + M + + + + + comisd + + aso rexr rexx rexb + /sse=66 0f 2f + Vsd Wsd + sse2 avx + + + + + comiss + + aso rexr rexx rexb + 0f 2f + V W + sse2 avx + + + + + cpuid + + 0f a2 + + + + + cvtdq2pd + + aso rexr rexx rexb vexl + /sse=f3 0f e6 + V Wdq + sse2 avx + + + + + cvtdq2ps + + aso rexr rexx rexb + 0f 5b + V W + sse2 avx + + + + + cvtpd2dq + + aso rexr rexx rexb vexl + /sse=f2 0f e6 + Vdq W + sse2 avx + + + + + cvtpd2pi + + aso rexr rexx rexb + /sse=66 0f 2d + P W + + + + + cvtpd2ps + + aso rexr rexx rexb vexl + /sse=66 0f 5a + Vdq W + sse2 avx + + + + + cvtpi2ps + + aso rexr rexx rexb + 0f 2a + V Q + + + + + cvtpi2pd + + aso rexr rexx rexb + /sse=66 0f 2a + V Q + + + + + cvtps2dq + + aso rexr rexx rexb vexl + /sse=66 0f 5b + V W + sse2 avx + + + + + cvtps2pd + + aso rexr rexx rexb vexl + 0f 5a + V Wdq + sse2 avx + + + + + cvtps2pi + + aso rexr rexx rexb + 0f 2d + P MqU + + + + + cvtsd2si + + aso rexw rexr rexx rexb + /sse=f2 0f 2d + Gy MqU + sse2 avx + + + + + cvtsd2ss + + aso rexr rexx rexb + /sse=f2 0f 5a + V H W + sse2 avx + + + + + cvtsi2sd + + aso rexw rexr rexx rexb + /sse=f2 0f 2a + V H Ey + sse2 avx + + + + + cvtsi2ss + + aso rexw rexr rexx rexb + /sse=f3 0f 2a + V H Ey + sse avx + + + + + cvtss2sd + + aso rexr rexx rexb + /sse=f3 0f 5a + V H W + sse2 avx + + + + + cvtss2si + + aso rexw rexr rexx rexb + /sse=f3 0f 2d + Gy MdU + sse avx + + + + + cvttpd2dq + + aso rexr rexx rexb vexl + /sse=66 0f e6 + Vdq W + sse2 avx + + + + + cvttpd2pi + + aso rexr rexx rexb + /sse=66 0f 2c + P W + + + + + cvttps2dq + + aso rexr rexx rexb vexl + /sse=f3 0f 5b + V W + sse2 avx + + + + + cvttps2pi + + aso rexr rexx rexb + 0f 2c + P W + + + + + cvttsd2si + + aso rexw rexr rexx rexb + /sse=f2 0f 2c + Gy MqU + sse2 avx + + + + + cvttss2si + + aso rexw rexr rexx rexb + /sse=f3 0f 2c + Gy MdU + sse2 avx + + + + + cwd + + oso rexw + 99 /o=16 + + + + + cdq + + oso rexw + 99 /o=32 + + + + + cqo + + oso rexw + 99 /o=64 + + + + + daa + + 27 /m=!64 + inv64 + + + + + das + + 2f /m=!64 + inv64 + + + + + dec + + oso + 48 + R0z + + + oso + 49 + R1z + + + oso + 4a + R2z + + + oso + 4b + R3z + + + oso + 4c + R4z + + + oso + 4d + R5z + + + oso + 4e + R6z + + + oso + 4f + R7z + + + aso rexw rexr rexx rexb + fe /reg=1 + Eb + + + aso oso rexw rexr rexx rexb + ff /reg=1 + Ev + + + + + div + + aso oso rexw rexr rexx rexb + f7 /reg=6 + Ev + + + aso rexw rexr rexx rexb + f6 /reg=6 + Eb + + + + + divpd + + aso rexr rexx rexb vexl + /sse=66 0f 5e + V H W + sse2 avx + + + + + divps + + aso rexr rexx rexb + 0f 5e + V H W + sse avx + + + + + divsd + + aso rexr rexx rexb + /sse=f2 0f 5e + V H MqU + sse2 avx + + + + + divss + + aso rexr rexx rexb + /sse=f3 0f 5e + V H MdU + sse avx + + + + + dppd + + aso rexr rexx rexb + /sse=66 0f 3a 41 + V H W Ib + sse4.1 avx + + + + + dpps + + aso rexr rexx rexb vexl + /sse=66 0f 3a 40 + V H W Ib + sse4.1 avx + + + + + emms + + 0f 77 + + + + + endbr64 + + /sse=f3 0f 1e /mod=11 /reg=7 /rm=2 /m=64 + + + + + endbr32 + + /sse=f3 0f 1e /mod=11 /reg=7 /rm=3 /m=32 + + + + + enter + + c8 + Iw Ib + def64 + + + + + extractps + + aso rexr rexw rexx rexb + /sse=66 0f 3a 17 + MdRy V Ib + sse4.1 avx + + + + + f2xm1 + X87 + + d9 /mod=11 /x87=30 + + + + + fabs + X87 + + d9 /mod=11 /x87=21 + + + + + fadd + X87 + + aso rexr rexx rexb + dc /mod=!11 /reg=0 + Mq + + + aso rexr rexx rexb + d8 /mod=!11 /reg=0 + Md + + + dc /mod=11 /x87=00 + ST0 ST0 + + + dc /mod=11 /x87=01 + ST1 ST0 + + + dc /mod=11 /x87=02 + ST2 ST0 + + + dc /mod=11 /x87=03 + ST3 ST0 + + + dc /mod=11 /x87=04 + ST4 ST0 + + + dc /mod=11 /x87=05 + ST5 ST0 + + + dc /mod=11 /x87=06 + ST6 ST0 + + + dc /mod=11 /x87=07 + ST7 ST0 + + + d8 /mod=11 /x87=00 + ST0 ST0 + + + d8 /mod=11 /x87=01 + ST0 ST1 + + + d8 /mod=11 /x87=02 + ST0 ST2 + + + d8 /mod=11 /x87=03 + ST0 ST3 + + + d8 /mod=11 /x87=04 + ST0 ST4 + + + d8 /mod=11 /x87=05 + ST0 ST5 + + + d8 /mod=11 /x87=06 + ST0 ST6 + + + d8 /mod=11 /x87=07 + ST0 ST7 + + + + + faddp + X87 + + de /mod=11 /x87=00 + ST0 ST0 + + + de /mod=11 /x87=01 + ST1 ST0 + + + de /mod=11 /x87=02 + ST2 ST0 + + + de /mod=11 /x87=03 + ST3 ST0 + + + de /mod=11 /x87=04 + ST4 ST0 + + + de /mod=11 /x87=05 + ST5 ST0 + + + de /mod=11 /x87=06 + ST6 ST0 + + + de /mod=11 /x87=07 + ST7 ST0 + + + + + fbld + X87 + + aso rexr rexx rexb + df /mod=!11 /reg=4 + Mt + + + + + fbstp + X87 + + aso rexr rexx rexb + df /mod=!11 /reg=6 + Mt + + + + + fchs + X87 + + d9 /mod=11 /x87=20 + + + + + fclex + X87 + + db /mod=11 /x87=22 + + + + + fcmovb + X87 + + da /mod=11 /x87=00 + ST0 ST0 + + + da /mod=11 /x87=01 + ST0 ST1 + + + da /mod=11 /x87=02 + ST0 ST2 + + + da /mod=11 /x87=03 + ST0 ST3 + + + da /mod=11 /x87=04 + ST0 ST4 + + + da /mod=11 /x87=05 + ST0 ST5 + + + da /mod=11 /x87=06 + ST0 ST6 + + + da /mod=11 /x87=07 + ST0 ST7 + + + + + fcmove + X87 + + da /mod=11 /x87=08 + ST0 ST0 + + + da /mod=11 /x87=09 + ST0 ST1 + + + da /mod=11 /x87=0a + ST0 ST2 + + + da /mod=11 /x87=0b + ST0 ST3 + + + da /mod=11 /x87=0c + ST0 ST4 + + + da /mod=11 /x87=0d + ST0 ST5 + + + da /mod=11 /x87=0e + ST0 ST6 + + + da /mod=11 /x87=0f + ST0 ST7 + + + + + fcmovbe + X87 + + da /mod=11 /x87=10 + ST0 ST0 + + + da /mod=11 /x87=11 + ST0 ST1 + + + da /mod=11 /x87=12 + ST0 ST2 + + + da /mod=11 /x87=13 + ST0 ST3 + + + da /mod=11 /x87=14 + ST0 ST4 + + + da /mod=11 /x87=15 + ST0 ST5 + + + da /mod=11 /x87=16 + ST0 ST6 + + + da /mod=11 /x87=17 + ST0 ST7 + + + + + fcmovu + X87 + + da /mod=11 /x87=18 + ST0 ST0 + + + da /mod=11 /x87=19 + ST0 ST1 + + + da /mod=11 /x87=1a + ST0 ST2 + + + da /mod=11 /x87=1b + ST0 ST3 + + + da /mod=11 /x87=1c + ST0 ST4 + + + da /mod=11 /x87=1d + ST0 ST5 + + + da /mod=11 /x87=1e + ST0 ST6 + + + da /mod=11 /x87=1f + ST0 ST7 + + + + + fcmovnb + X87 + + db /mod=11 /x87=00 + ST0 ST0 + + + db /mod=11 /x87=01 + ST0 ST1 + + + db /mod=11 /x87=02 + ST0 ST2 + + + db /mod=11 /x87=03 + ST0 ST3 + + + db /mod=11 /x87=04 + ST0 ST4 + + + db /mod=11 /x87=05 + ST0 ST5 + + + db /mod=11 /x87=06 + ST0 ST6 + + + db /mod=11 /x87=07 + ST0 ST7 + + + + + fcmovne + X87 + + db /mod=11 /x87=08 + ST0 ST0 + + + db /mod=11 /x87=09 + ST0 ST1 + + + db /mod=11 /x87=0a + ST0 ST2 + + + db /mod=11 /x87=0b + ST0 ST3 + + + db /mod=11 /x87=0c + ST0 ST4 + + + db /mod=11 /x87=0d + ST0 ST5 + + + db /mod=11 /x87=0e + ST0 ST6 + + + db /mod=11 /x87=0f + ST0 ST7 + + + + + fcmovnbe + X87 + + db /mod=11 /x87=10 + ST0 ST0 + + + db /mod=11 /x87=11 + ST0 ST1 + + + db /mod=11 /x87=12 + ST0 ST2 + + + db /mod=11 /x87=13 + ST0 ST3 + + + db /mod=11 /x87=14 + ST0 ST4 + + + db /mod=11 /x87=15 + ST0 ST5 + + + db /mod=11 /x87=16 + ST0 ST6 + + + db /mod=11 /x87=17 + ST0 ST7 + + + + + fcmovnu + X87 + + db /mod=11 /x87=18 + ST0 ST0 + + + db /mod=11 /x87=19 + ST0 ST1 + + + db /mod=11 /x87=1a + ST0 ST2 + + + db /mod=11 /x87=1b + ST0 ST3 + + + db /mod=11 /x87=1c + ST0 ST4 + + + db /mod=11 /x87=1d + ST0 ST5 + + + db /mod=11 /x87=1e + ST0 ST6 + + + db /mod=11 /x87=1f + ST0 ST7 + + + + + fucomi + X87 + + db /mod=11 /x87=28 + ST0 ST0 + + + db /mod=11 /x87=29 + ST0 ST1 + + + db /mod=11 /x87=2a + ST0 ST2 + + + db /mod=11 /x87=2b + ST0 ST3 + + + db /mod=11 /x87=2c + ST0 ST4 + + + db /mod=11 /x87=2d + ST0 ST5 + + + db /mod=11 /x87=2e + ST0 ST6 + + + db /mod=11 /x87=2f + ST0 ST7 + + + + + fcom + X87 + + aso rexr rexx rexb + d8 /mod=!11 /reg=2 + Md + + + aso rexr rexx rexb + dc /mod=!11 /reg=2 + Mq + + + d8 /mod=11 /x87=10 + ST0 ST0 + + + d8 /mod=11 /x87=11 + ST0 ST1 + + + d8 /mod=11 /x87=12 + ST0 ST2 + + + d8 /mod=11 /x87=13 + ST0 ST3 + + + d8 /mod=11 /x87=14 + ST0 ST4 + + + d8 /mod=11 /x87=15 + ST0 ST5 + + + d8 /mod=11 /x87=16 + ST0 ST6 + + + d8 /mod=11 /x87=17 + ST0 ST7 + + + + + fcom2 + X87 UNDOC + + dc /mod=11 /x87=10 + ST0 + + + dc /mod=11 /x87=11 + ST1 + + + dc /mod=11 /x87=12 + ST2 + + + dc /mod=11 /x87=13 + ST3 + + + dc /mod=11 /x87=14 + ST4 + + + dc /mod=11 /x87=15 + ST5 + + + dc /mod=11 /x87=16 + ST6 + + + dc /mod=11 /x87=17 + ST7 + + + + + fcomp3 + X87 UNDOC + + dc /mod=11 /x87=18 + ST0 + + + dc /mod=11 /x87=19 + ST1 + + + dc /mod=11 /x87=1a + ST2 + + + dc /mod=11 /x87=1b + ST3 + + + dc /mod=11 /x87=1c + ST4 + + + dc /mod=11 /x87=1d + ST5 + + + dc /mod=11 /x87=1e + ST6 + + + dc /mod=11 /x87=1f + ST7 + + + + + fcomi + X87 + + db /mod=11 /x87=30 + ST0 ST0 + + + db /mod=11 /x87=31 + ST0 ST1 + + + db /mod=11 /x87=32 + ST0 ST2 + + + db /mod=11 /x87=33 + ST0 ST3 + + + db /mod=11 /x87=34 + ST0 ST4 + + + db /mod=11 /x87=35 + ST0 ST5 + + + db /mod=11 /x87=36 + ST0 ST6 + + + db /mod=11 /x87=37 + ST0 ST7 + + + + + fucomip + X87 + + df /mod=11 /x87=28 + ST0 ST0 + + + df /mod=11 /x87=29 + ST0 ST1 + + + df /mod=11 /x87=2a + ST0 ST2 + + + df /mod=11 /x87=2b + ST0 ST3 + + + df /mod=11 /x87=2c + ST0 ST4 + + + df /mod=11 /x87=2d + ST0 ST5 + + + df /mod=11 /x87=2e + ST0 ST6 + + + df /mod=11 /x87=2f + ST0 ST7 + + + + + fcomip + X87 + + df /mod=11 /x87=30 + ST0 ST0 + + + df /mod=11 /x87=31 + ST0 ST1 + + + df /mod=11 /x87=32 + ST0 ST2 + + + df /mod=11 /x87=33 + ST0 ST3 + + + df /mod=11 /x87=34 + ST0 ST4 + + + df /mod=11 /x87=35 + ST0 ST5 + + + df /mod=11 /x87=36 + ST0 ST6 + + + df /mod=11 /x87=37 + ST0 ST7 + + + + + fcomp + X87 + + aso rexr rexx rexb + d8 /mod=!11 /reg=3 + Md + + + aso rexr rexx rexb + dc /mod=!11 /reg=3 + Mq + + + d8 /mod=11 /x87=18 + ST0 ST0 + + + d8 /mod=11 /x87=19 + ST0 ST1 + + + d8 /mod=11 /x87=1a + ST0 ST2 + + + d8 /mod=11 /x87=1b + ST0 ST3 + + + d8 /mod=11 /x87=1c + ST0 ST4 + + + d8 /mod=11 /x87=1d + ST0 ST5 + + + d8 /mod=11 /x87=1e + ST0 ST6 + + + d8 /mod=11 /x87=1f + ST0 ST7 + + + + + fcomp5 + X87 UNDOC + + de /mod=11 /x87=10 + ST0 + + + de /mod=11 /x87=11 + ST1 + + + de /mod=11 /x87=12 + ST2 + + + de /mod=11 /x87=13 + ST3 + + + de /mod=11 /x87=14 + ST4 + + + de /mod=11 /x87=15 + ST5 + + + de /mod=11 /x87=16 + ST6 + + + de /mod=11 /x87=17 + ST7 + + + + + fcompp + X87 + + de /mod=11 /x87=19 + + + + + fcos + X87 + + d9 /mod=11 /x87=3f + + + + + fdecstp + X87 + + d9 /mod=11 /x87=36 + + + + + fdiv + X87 + + aso rexr rexx rexb + dc /mod=!11 /reg=6 + Mq + + + dc /mod=11 /x87=38 + ST0 ST0 + + + dc /mod=11 /x87=39 + ST1 ST0 + + + dc /mod=11 /x87=3a + ST2 ST0 + + + dc /mod=11 /x87=3b + ST3 ST0 + + + dc /mod=11 /x87=3c + ST4 ST0 + + + dc /mod=11 /x87=3d + ST5 ST0 + + + dc /mod=11 /x87=3e + ST6 ST0 + + + dc /mod=11 /x87=3f + ST7 ST0 + + + aso rexr rexx rexb + d8 /mod=!11 /reg=6 + Md + + + d8 /mod=11 /x87=30 + ST0 ST0 + + + d8 /mod=11 /x87=31 + ST0 ST1 + + + d8 /mod=11 /x87=32 + ST0 ST2 + + + d8 /mod=11 /x87=33 + ST0 ST3 + + + d8 /mod=11 /x87=34 + ST0 ST4 + + + d8 /mod=11 /x87=35 + ST0 ST5 + + + d8 /mod=11 /x87=36 + ST0 ST6 + + + d8 /mod=11 /x87=37 + ST0 ST7 + + + + + fdivp + X87 + + de /mod=11 /x87=38 + ST0 ST0 + + + de /mod=11 /x87=39 + ST1 ST0 + + + de /mod=11 /x87=3a + ST2 ST0 + + + de /mod=11 /x87=3b + ST3 ST0 + + + de /mod=11 /x87=3c + ST4 ST0 + + + de /mod=11 /x87=3d + ST5 ST0 + + + de /mod=11 /x87=3e + ST6 ST0 + + + de /mod=11 /x87=3f + ST7 ST0 + + + + + fdivr + X87 + + aso rexr rexx rexb + dc /mod=!11 /reg=7 + Mq + + + dc /mod=11 /x87=30 + ST0 ST0 + + + dc /mod=11 /x87=31 + ST1 ST0 + + + dc /mod=11 /x87=32 + ST2 ST0 + + + dc /mod=11 /x87=33 + ST3 ST0 + + + dc /mod=11 /x87=34 + ST4 ST0 + + + dc /mod=11 /x87=35 + ST5 ST0 + + + dc /mod=11 /x87=36 + ST6 ST0 + + + dc /mod=11 /x87=37 + ST7 ST0 + + + aso rexr rexx rexb + d8 /mod=!11 /reg=7 + Md + + + d8 /mod=11 /x87=38 + ST0 ST0 + + + d8 /mod=11 /x87=39 + ST0 ST1 + + + d8 /mod=11 /x87=3a + ST0 ST2 + + + d8 /mod=11 /x87=3b + ST0 ST3 + + + d8 /mod=11 /x87=3c + ST0 ST4 + + + d8 /mod=11 /x87=3d + ST0 ST5 + + + d8 /mod=11 /x87=3e + ST0 ST6 + + + d8 /mod=11 /x87=3f + ST0 ST7 + + + + + fdivrp + X87 + + de /mod=11 /x87=30 + ST0 ST0 + + + de /mod=11 /x87=31 + ST1 ST0 + + + de /mod=11 /x87=32 + ST2 ST0 + + + de /mod=11 /x87=33 + ST3 ST0 + + + de /mod=11 /x87=34 + ST4 ST0 + + + de /mod=11 /x87=35 + ST5 ST0 + + + de /mod=11 /x87=36 + ST6 ST0 + + + de /mod=11 /x87=37 + ST7 ST0 + + + + + femms + + 0f 0e + + + + + ffree + X87 + + dd /mod=11 /x87=00 + ST0 + + + dd /mod=11 /x87=01 + ST1 + + + dd /mod=11 /x87=02 + ST2 + + + dd /mod=11 /x87=03 + ST3 + + + dd /mod=11 /x87=04 + ST4 + + + dd /mod=11 /x87=05 + ST5 + + + dd /mod=11 /x87=06 + ST6 + + + dd /mod=11 /x87=07 + ST7 + + + + + ffreep + X87 + + df /mod=11 /x87=00 + ST0 + + + df /mod=11 /x87=01 + ST1 + + + df /mod=11 /x87=02 + ST2 + + + df /mod=11 /x87=03 + ST3 + + + df /mod=11 /x87=04 + ST4 + + + df /mod=11 /x87=05 + ST5 + + + df /mod=11 /x87=06 + ST6 + + + df /mod=11 /x87=07 + ST7 + + + + + ficom + X87 + + aso rexr rexx rexb + de /mod=!11 /reg=2 + Mw + + + aso rexr rexx rexb + da /mod=!11 /reg=2 + Md + + + + + ficomp + X87 + + aso rexr rexx rexb + de /mod=!11 /reg=3 + Mw + + + aso rexr rexx rexb + da /mod=!11 /reg=3 + Md + + + + + fild + X87 + + aso rexr rexx rexb + df /mod=!11 /reg=0 + Mw + + + aso rexr rexx rexb + df /mod=!11 /reg=5 + Mq + + + aso rexr rexx rexb + db /mod=!11 /reg=0 + Md + + + + + fincstp + X87 + + d9 /mod=11 /x87=37 + + + + + fninit + X87 + + db /mod=11 /x87=23 + + + + + fiadd + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=0 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=0 + Mw + + + + + fidivr + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=7 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=7 + Mw + + + + + fidiv + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=6 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=6 + Mw + + + + + fisub + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=4 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=4 + Mw + + + + + fisubr + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=5 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=5 + Mw + + + + + fist + X87 + + aso rexr rexx rexb + df /mod=!11 /reg=2 + Mw + + + aso rexr rexx rexb + db /mod=!11 /reg=2 + Md + + + + + fistp + X87 + + aso rexr rexx rexb + df /mod=!11 /reg=3 + Mw + + + aso rexr rexx rexb + df /mod=!11 /reg=7 + Mq + + + aso rexr rexx rexb + db /mod=!11 /reg=3 + Md + + + + + fisttp + X87 + + aso rexr rexx rexb + db /mod=!11 /reg=1 + Md + + + aso rexr rexx rexb + dd /mod=!11 /reg=1 + Mq + + + aso rexr rexx rexb + df /mod=!11 /reg=1 + Mw + + + + + fld + X87 + + aso rexr rexx rexb + db /mod=!11 /reg=5 + Mt + + + aso rexr rexx rexb + dd /mod=!11 /reg=0 + Mq + + + aso rexr rexx rexb + d9 /mod=!11 /reg=0 + Md + + + d9 /mod=11 /x87=00 + ST0 + + + d9 /mod=11 /x87=01 + ST1 + + + d9 /mod=11 /x87=02 + ST2 + + + d9 /mod=11 /x87=03 + ST3 + + + d9 /mod=11 /x87=04 + ST4 + + + d9 /mod=11 /x87=05 + ST5 + + + d9 /mod=11 /x87=06 + ST6 + + + d9 /mod=11 /x87=07 + ST7 + + + + + fld1 + X87 + + d9 /mod=11 /x87=28 + + + + + fldl2t + X87 + + d9 /mod=11 /x87=29 + + + + + fldl2e + X87 + + d9 /mod=11 /x87=2a + + + + + fldpi + X87 + + d9 /mod=11 /x87=2b + + + + + fldlg2 + X87 + + d9 /mod=11 /x87=2c + + + + + fldln2 + X87 + + d9 /mod=11 /x87=2d + + + + + fldz + X87 + + d9 /mod=11 /x87=2e + + + + + fldcw + X87 + + aso rexr rexx rexb + d9 /mod=!11 /reg=5 + Mw + + + + + fldenv + X87 + + aso rexr rexx rexb + d9 /mod=!11 /reg=4 + M + + + + + fmul + X87 + + aso rexr rexx rexb + dc /mod=!11 /reg=1 + Mq + + + dc /mod=11 /x87=08 + ST0 ST0 + + + dc /mod=11 /x87=09 + ST1 ST0 + + + dc /mod=11 /x87=0a + ST2 ST0 + + + dc /mod=11 /x87=0b + ST3 ST0 + + + dc /mod=11 /x87=0c + ST4 ST0 + + + dc /mod=11 /x87=0d + ST5 ST0 + + + dc /mod=11 /x87=0e + ST6 ST0 + + + dc /mod=11 /x87=0f + ST7 ST0 + + + aso rexr rexx rexb + d8 /mod=!11 /reg=1 + Md + + + d8 /mod=11 /x87=08 + ST0 ST0 + + + d8 /mod=11 /x87=09 + ST0 ST1 + + + d8 /mod=11 /x87=0a + ST0 ST2 + + + d8 /mod=11 /x87=0b + ST0 ST3 + + + d8 /mod=11 /x87=0c + ST0 ST4 + + + d8 /mod=11 /x87=0d + ST0 ST5 + + + d8 /mod=11 /x87=0e + ST0 ST6 + + + d8 /mod=11 /x87=0f + ST0 ST7 + + + + + fmulp + X87 + + de /mod=11 /x87=08 + ST0 ST0 + + + de /mod=11 /x87=09 + ST1 ST0 + + + de /mod=11 /x87=0a + ST2 ST0 + + + de /mod=11 /x87=0b + ST3 ST0 + + + de /mod=11 /x87=0c + ST4 ST0 + + + de /mod=11 /x87=0d + ST5 ST0 + + + de /mod=11 /x87=0e + ST6 ST0 + + + de /mod=11 /x87=0f + ST7 ST0 + + + + + fimul + X87 + + aso rexr rexx rexb + da /mod=!11 /reg=1 + Md + + + aso rexr rexx rexb + de /mod=!11 /reg=1 + Mw + + + + + fnop + X87 + + d9 /mod=11 /x87=10 + + + + + fndisi + X87 + + db /mod=11 /x87=21 + + + + + fneni + X87 + + db /mod=11 /x87=20 + + + + + fnsetpm + X87 + + db /mod=11 /x87=24 + + + + + fpatan + X87 + + d9 /mod=11 /x87=33 + + + + + fprem + X87 + + d9 /mod=11 /x87=38 + + + + + fprem1 + X87 + + d9 /mod=11 /x87=35 + + + + + fptan + X87 + + d9 /mod=11 /x87=32 + + + + + frndint + X87 + + d9 /mod=11 /x87=3c + + + + + frstor + X87 + + aso rexr rexx rexb + dd /mod=!11 /reg=4 + M + + + + + frstpm + X87 + + db /mod=11 /x87=25 + + + + + fnsave + X87 + + aso rexr rexx rexb + dd /mod=!11 /reg=6 + M + + + + + fscale + X87 + + d9 /mod=11 /x87=3d + + + + + fsin + X87 + + d9 /mod=11 /x87=3e + + + + + fsincos + X87 + + d9 /mod=11 /x87=3b + + + + + fsqrt + X87 + + d9 /mod=11 /x87=3a + + + + + fstp + X87 + + aso rexr rexx rexb + db /mod=!11 /reg=7 + Mt + + + aso rexr rexx rexb + dd /mod=!11 /reg=3 + Mq + + + aso rexr rexx rexb + d9 /mod=!11 /reg=3 + Md + + + dd /mod=11 /x87=18 + ST0 + + + dd /mod=11 /x87=19 + ST1 + + + dd /mod=11 /x87=1a + ST2 + + + dd /mod=11 /x87=1b + ST3 + + + dd /mod=11 /x87=1c + ST4 + + + dd /mod=11 /x87=1d + ST5 + + + dd /mod=11 /x87=1e + ST6 + + + dd /mod=11 /x87=1f + ST7 + + + + + fstp1 + + d9 /mod=11 /x87=18 + ST0 + + + d9 /mod=11 /x87=19 + ST1 + + + d9 /mod=11 /x87=1a + ST2 + + + d9 /mod=11 /x87=1b + ST3 + + + d9 /mod=11 /x87=1c + ST4 + + + d9 /mod=11 /x87=1d + ST5 + + + d9 /mod=11 /x87=1e + ST6 + + + d9 /mod=11 /x87=1f + ST7 + + + + + fstp8 + + df /mod=11 /x87=10 + ST0 + + + df /mod=11 /x87=11 + ST1 + + + df /mod=11 /x87=12 + ST2 + + + df /mod=11 /x87=13 + ST3 + + + df /mod=11 /x87=14 + ST4 + + + df /mod=11 /x87=15 + ST5 + + + df /mod=11 /x87=16 + ST6 + + + df /mod=11 /x87=17 + ST7 + + + + + fstp9 + + df /mod=11 /x87=18 + ST0 + + + df /mod=11 /x87=19 + ST1 + + + df /mod=11 /x87=1a + ST2 + + + df /mod=11 /x87=1b + ST3 + + + df /mod=11 /x87=1c + ST4 + + + df /mod=11 /x87=1d + ST5 + + + df /mod=11 /x87=1e + ST6 + + + df /mod=11 /x87=1f + ST7 + + + + + fst + X87 + + aso rexr rexx rexb + d9 /mod=!11 /reg=2 + Md + + + aso rexr rexx rexb + dd /mod=!11 /reg=2 + Mq + + + dd /mod=11 /x87=10 + ST0 + + + dd /mod=11 /x87=11 + ST1 + + + dd /mod=11 /x87=12 + ST2 + + + dd /mod=11 /x87=13 + ST3 + + + dd /mod=11 /x87=14 + ST4 + + + dd /mod=11 /x87=15 + ST5 + + + dd /mod=11 /x87=16 + ST6 + + + dd /mod=11 /x87=17 + ST7 + + + + + fnstcw + X87 + + aso rexr rexx rexb + d9 /mod=!11 /reg=7 + Mw + + + + + fnstenv + X87 + + aso rexr rexx rexb + d9 /mod=!11 /reg=6 + M + + + + + fnstsw + X87 + + aso rexr rexx rexb + dd /mod=!11 /reg=7 + Mw + + + df /mod=11 /x87=20 + AX + + + + + fsub + X87 + + aso rexr rexx rexb + d8 /mod=!11 /reg=4 + Md + + + aso rexr rexx rexb + dc /mod=!11 /reg=4 + Mq + + + d8 /mod=11 /x87=20 + ST0 ST0 + + + d8 /mod=11 /x87=21 + ST0 ST1 + + + d8 /mod=11 /x87=22 + ST0 ST2 + + + d8 /mod=11 /x87=23 + ST0 ST3 + + + d8 /mod=11 /x87=24 + ST0 ST4 + + + d8 /mod=11 /x87=25 + ST0 ST5 + + + d8 /mod=11 /x87=26 + ST0 ST6 + + + d8 /mod=11 /x87=27 + ST0 ST7 + + + dc /mod=11 /x87=28 + ST0 ST0 + + + dc /mod=11 /x87=29 + ST1 ST0 + + + dc /mod=11 /x87=2a + ST2 ST0 + + + dc /mod=11 /x87=2b + ST3 ST0 + + + dc /mod=11 /x87=2c + ST4 ST0 + + + dc /mod=11 /x87=2d + ST5 ST0 + + + dc /mod=11 /x87=2e + ST6 ST0 + + + dc /mod=11 /x87=2f + ST7 ST0 + + + + + fsubp + X87 + + de /mod=11 /x87=28 + ST0 ST0 + + + de /mod=11 /x87=29 + ST1 ST0 + + + de /mod=11 /x87=2a + ST2 ST0 + + + de /mod=11 /x87=2b + ST3 ST0 + + + de /mod=11 /x87=2c + ST4 ST0 + + + de /mod=11 /x87=2d + ST5 ST0 + + + de /mod=11 /x87=2e + ST6 ST0 + + + de /mod=11 /x87=2f + ST7 ST0 + + + + + fsubr + X87 + + aso rexr rexx rexb + dc /mod=!11 /reg=5 + Mq + + + d8 /mod=11 /x87=28 + ST0 ST0 + + + d8 /mod=11 /x87=29 + ST0 ST1 + + + d8 /mod=11 /x87=2a + ST0 ST2 + + + d8 /mod=11 /x87=2b + ST0 ST3 + + + d8 /mod=11 /x87=2c + ST0 ST4 + + + d8 /mod=11 /x87=2d + ST0 ST5 + + + d8 /mod=11 /x87=2e + ST0 ST6 + + + d8 /mod=11 /x87=2f + ST0 ST7 + + + dc /mod=11 /x87=20 + ST0 ST0 + + + dc /mod=11 /x87=21 + ST1 ST0 + + + dc /mod=11 /x87=22 + ST2 ST0 + + + dc /mod=11 /x87=23 + ST3 ST0 + + + dc /mod=11 /x87=24 + ST4 ST0 + + + dc /mod=11 /x87=25 + ST5 ST0 + + + dc /mod=11 /x87=26 + ST6 ST0 + + + dc /mod=11 /x87=27 + ST7 ST0 + + + aso rexr rexx rexb + d8 /mod=!11 /reg=5 + Md + + + + + fsubrp + X87 + + de /mod=11 /x87=20 + ST0 ST0 + + + de /mod=11 /x87=21 + ST1 ST0 + + + de /mod=11 /x87=22 + ST2 ST0 + + + de /mod=11 /x87=23 + ST3 ST0 + + + de /mod=11 /x87=24 + ST4 ST0 + + + de /mod=11 /x87=25 + ST5 ST0 + + + de /mod=11 /x87=26 + ST6 ST0 + + + de /mod=11 /x87=27 + ST7 ST0 + + + + + ftst + X87 + + d9 /mod=11 /x87=24 + + + + + fucom + X87 + + dd /mod=11 /x87=20 + ST0 + + + dd /mod=11 /x87=21 + ST1 + + + dd /mod=11 /x87=22 + ST2 + + + dd /mod=11 /x87=23 + ST3 + + + dd /mod=11 /x87=24 + ST4 + + + dd /mod=11 /x87=25 + ST5 + + + dd /mod=11 /x87=26 + ST6 + + + dd /mod=11 /x87=27 + ST7 + + + + + fucomp + X87 + + dd /mod=11 /x87=28 + ST0 + + + dd /mod=11 /x87=29 + ST1 + + + dd /mod=11 /x87=2a + ST2 + + + dd /mod=11 /x87=2b + ST3 + + + dd /mod=11 /x87=2c + ST4 + + + dd /mod=11 /x87=2d + ST5 + + + dd /mod=11 /x87=2e + ST6 + + + dd /mod=11 /x87=2f + ST7 + + + + + fucompp + X87 + + da /mod=11 /x87=29 + + + + + fxam + X87 + + d9 /mod=11 /x87=25 + + + + + fxch + X87 + + d9 /mod=11 /x87=08 + ST0 ST0 + + + d9 /mod=11 /x87=09 + ST0 ST1 + + + d9 /mod=11 /x87=0a + ST0 ST2 + + + d9 /mod=11 /x87=0b + ST0 ST3 + + + d9 /mod=11 /x87=0c + ST0 ST4 + + + d9 /mod=11 /x87=0d + ST0 ST5 + + + d9 /mod=11 /x87=0e + ST0 ST6 + + + d9 /mod=11 /x87=0f + ST0 ST7 + + + + + fxch4 + X87 + + dd /mod=11 /x87=08 + ST0 + + + dd /mod=11 /x87=09 + ST1 + + + dd /mod=11 /x87=0a + ST2 + + + dd /mod=11 /x87=0b + ST3 + + + dd /mod=11 /x87=0c + ST4 + + + dd /mod=11 /x87=0d + ST5 + + + dd /mod=11 /x87=0e + ST6 + + + dd /mod=11 /x87=0f + ST7 + + + + + fxch7 + X87 + + df /mod=11 /x87=08 + ST0 + + + df /mod=11 /x87=09 + ST1 + + + df /mod=11 /x87=0a + ST2 + + + df /mod=11 /x87=0b + ST3 + + + df /mod=11 /x87=0c + ST4 + + + df /mod=11 /x87=0d + ST5 + + + df /mod=11 /x87=0e + ST6 + + + df /mod=11 /x87=0f + ST7 + + + + + fxrstor + + aso rexw rexr rexx rexb + 0f ae /mod=!11 /reg=1 + M + + + + + fxsave + + aso rexw rexr rexx rexb + 0f ae /mod=!11 /reg=0 + M + + + + + fxtract + X87 + + d9 /mod=11 /x87=34 + + + + + fyl2x + X87 + + d9 /mod=11 /x87=31 + + + + + fyl2xp1 + X87 + + d9 /mod=11 /x87=39 + + + + + hlt + + f4 + + + + + idiv + + aso oso rexw rexr rexx rexb + f7 /reg=7 + Ev + + + aso rexw rexr rexx rexb + f6 /reg=7 + Eb + + + + + in + + e4 + AL Ib + + + oso + e5 + eAX Ib + + + ec + AL DX + + + oso + ed + eAX DX + + + + + imul + + aso oso rexw rexr rexx rexb + 0f af + Gv Ev + + + aso rexw rexr rexx rexb + f6 /reg=5 + Eb + + + aso oso rexw rexr rexx rexb + f7 /reg=5 + Ev + + + aso oso rexw rexr rexx rexb + 69 + Gv Ev Iz + + + aso oso rexw rexr rexx rexb + 6b + Gv Ev sIb + + + + + inc + + oso + 40 + R0z + + + oso + 41 + R1z + + + oso + 42 + R2z + + + oso + 43 + R3z + + + oso + 44 + R4z + + + oso + 45 + R5z + + + oso + 46 + R6z + + + oso + 47 + R7z + + + aso oso rexw rexr rexx rexb + ff /reg=0 + Ev + + + aso rexw rexr rexx rexb + fe /reg=0 + Eb + + + + + insb + + rep seg + 6c + + + + + insw + + rep oso seg + 6d /o=16 + + + + + insd + + rep oso seg + 6d /o=32 + + + + + int1 + + f1 + + + + + int3 + + cc + + + + + int + + cd + Ib + + + + + into + + ce /m=!64 + inv64 + + + + + invd + + 0f 08 + + + + + invept + intel + + /sse=66 0f 38 80 /m=32 + Gd Mo + + + /sse=66 0f 38 80 /m=64 + Gq Mo + + + + + invlpg + + aso rexr rexx rexb + 0f 01 /reg=7 /mod=!11 + M + + + + + invlpga + amd + + 0f 01 /reg=3 /mod=11 /rm=7 + + + + + invvpid + intel + + /sse=66 0f 38 81 /m=32 + Gd Mo + + + /sse=66 0f 38 81 /m=64 + Gq Mo + + + + + iretw + + oso rexw + cf /o=16 + + + + + iretd + + oso rexw + cf /o=32 + + + + + iretq + + oso rexw + cf /o=64 + + + + + jo + + 70 + Jb + + + oso + 0f 80 + Jz + def64 + + + + + jno + + 71 + Jb + + + oso + 0f 81 + Jz + def64 + + + + + jb + + 72 + Jb + + + oso + 0f 82 + Jz + def64 + + + + + jae + + 73 + Jb + + + oso + 0f 83 + Jz + def64 + + + + + jz + + 74 + Jb + + + oso + 0f 84 + Jz + def64 + + + + + jnz + + 75 + Jb + + + oso + 0f 85 + Jz + def64 + + + + + jbe + + 76 + Jb + + + oso + 0f 86 + Jz + def64 + + + + + ja + + 77 + Jb + + + oso + 0f 87 + Jz + def64 + + + + + js + + 78 + Jb + + + oso + 0f 88 + Jz + def64 + + + + + jns + + 79 + Jb + + + oso + 0f 89 + Jz + def64 + + + + + jp + + 7a + Jb + + + oso + 0f 8a + Jz + def64 + + + + + jnp + + 7b + Jb + + + oso + 0f 8b + Jz + def64 + + + + + jl + + 7c + Jb + + + oso + 0f 8c + Jz + def64 + + + + + jge + + 7d + Jb + + + oso + 0f 8d + Jz + def64 + + + + + jle + + 7e + Jb + + + oso + 0f 8e + Jz + def64 + + + + + jg + + 7f + Jb + + + oso + 0f 8f + Jz + def64 + + + + + jcxz + + aso + e3 /a=16 + Jb + + + + + jecxz + + aso + e3 /a=32 + Jb + + + + + jrcxz + + aso + e3 /a=64 + Jb + + + + + jmp + + aso oso rexw rexr rexx rexb + ff /reg=4 + Ev + def64 + + + aso oso rexw rexr rexx rexb + ff /reg=5 + Fv + + + oso + e9 + Jz + def64 + + + oso + ea /m=!64 + Av + + + eb + Jb + def64 + + + + + lahf + + 9f + + + + + lar + + aso oso rexw rexr rexx rexb + 0f 02 + Gv Ew + + + + + ldmxcsr + + aso rexw rexr rexx rexb + 0f ae /reg=2 /mod=!11 + Md + + + + + lds + + aso oso + c5 /vex=none /m=!64 + Gv M + + + + + lea + + aso oso rexw rexr rexx rexb + 8d + Gv M + + + + + les + + aso oso + c4 /m=!64 + Gv M + + + + + lfs + + aso oso rexw rexr rexx rexb + 0f b4 + Gz M + + + + + lgs + + aso oso rexw rexr rexx rexb + 0f b5 + Gz M + + + + + lidt + + aso rexr rexx rexb + 0f 01 /reg=3 /mod=!11 + M + + + + + lss + + aso oso rexw rexr rexx rexb + 0f b2 + Gv M + + + + + leave + + c9 + + + + + lfence + + 0f ae /reg=5 /mod=11 /rm=0 + + + 0f ae /reg=5 /mod=11 /rm=1 + + + 0f ae /reg=5 /mod=11 /rm=2 + + + 0f ae /reg=5 /mod=11 /rm=3 + + + 0f ae /reg=5 /mod=11 /rm=4 + + + 0f ae /reg=5 /mod=11 /rm=5 + + + 0f ae /reg=5 /mod=11 /rm=6 + + + 0f ae /reg=5 /mod=11 /rm=7 + + + + + lgdt + + aso rexr rexx rexb + 0f 01 /reg=2 /mod=!11 + M + + + + + lldt + + aso rexr rexx rexb + 0f 00 /reg=2 + Ew + + + + + lmsw + + aso rexr rexx rexb + 0f 01 /reg=6 /mod=!11 + Ew + + + aso rexr rexx rexb + 0f 01 /reg=6 /mod=11 + Ew + + + + + lock + + f0 + + + + + lodsb + + rep seg + ac + + + + + lodsw + + rep seg oso rexw + ad /o=16 + + + + + lodsd + + rep seg oso rexw + ad /o=32 + + + + + lodsq + + rep seg oso rexw + ad /o=64 + + + + + loopne + + e0 + Jb + + + + + loope + + e1 + Jb + + + + + loop + + e2 + Jb + + + + + lsl + + aso oso rexw rexr rexx rexb + 0f 03 + Gv Ew + + + + + ltr + + aso rexr rexx rexb + 0f 00 /reg=3 + Ew + + + + + maskmovq + + aso rexr rexx rexb + 0f f7 /mod=11 + P N + + + + + maxpd + + aso rexr rexx rexb vexl + /sse=66 0f 5f + V H W + sse2 avx + + + + + maxps + + aso rexr rexx rexb vexl + 0f 5f + V H W + sse avx + + + + + maxsd + + aso rexr rexx rexb + /sse=f2 0f 5f + V H W + sse2 avx + + + + + maxss + + aso rexr rexx rexb + /sse=f3 0f 5f + V H W + sse avx + + + + + mfence + + 0f ae /reg=6 /mod=11 /rm=0 + + + 0f ae /reg=6 /mod=11 /rm=1 + + + 0f ae /reg=6 /mod=11 /rm=2 + + + 0f ae /reg=6 /mod=11 /rm=3 + + + 0f ae /reg=6 /mod=11 /rm=4 + + + 0f ae /reg=6 /mod=11 /rm=5 + + + 0f ae /reg=6 /mod=11 /rm=6 + + + 0f ae /reg=6 /mod=11 /rm=7 + + + + + minpd + + aso rexr rexx rexb vexl + /sse=66 0f 5d + V H W + sse2 avx + + + + + minps + + aso rexr rexx rexb + 0f 5d + V H W + sse2 avx + + + + + minsd + + aso rexr rexx rexb + /sse=f2 0f 5d + V H MqU + sse2 avx + + + + + minss + + aso rexr rexx rexb + /sse=f3 0f 5d + V H MdU + sse avx + + + + + monitor + + 0f 01 /reg=1 /mod=11 /rm=0 + + + + + montmul + + 0f a6 /mod=11 /rm=0 /reg=0 + + + + + mov + + aso rexw rexr rexx rexb + c6 /reg=0 + Eb Ib + + + aso oso rexw rexr rexx rexb + c7 /reg=0 + Ev sIz + + + aso rexr rexx rexb + 88 + Eb Gb + + + aso oso rexw rexr rexx rexb + 89 + Ev Gv + + + aso rexr rexx rexb + 8a + Gb Eb + + + aso oso rexw rexr rexx rexb + 8b + Gv Ev + + + aso oso rexw rexr rexx rexb + 8c + MwRv S + + + aso oso rexw rexr rexx rexb + 8e + S MwRv + + + a0 + AL Ob + + + aso oso rexw + a1 + rAX Ov + + + a2 + Ob AL + + + aso oso rexw + a3 + Ov rAX + + + rexb + b0 + R0b Ib + + + rexb + b1 + R1b Ib + + + rexb + b2 + R2b Ib + + + rexb + b3 + R3b Ib + + + rexb + b4 + R4b Ib + + + rexb + b5 + R5b Ib + + + rexb + b6 + R6b Ib + + + rexb + b7 + R7b Ib + + + oso rexw rexb + b8 + R0v Iv + + + oso rexw rexb + b9 + R1v Iv + + + oso rexw rexb + ba + R2v Iv + + + oso rexw rexb + bb + R3v Iv + + + oso rexw rexb + bc + R4v Iv + + + oso rexw rexb + bd + R5v Iv + + + oso rexw rexb + be + R6v Iv + + + oso rexw rexb + bf + R7v Iv + + + rexr rexw rexb + 0f 20 + R C + + + rexr rexw rexb + 0f 21 + R D + + + rexr rexw rexb + 0f 22 + C R + + + rexr rexw rexb + 0f 23 + D R + + + + + movapd + + aso rexr rexx rexb vexl + /sse=66 0f 28 + V W + sse2 avx + + + aso rexr rexx rexb vexl + /sse=66 0f 29 + W V + sse2 avx + + + + + movaps + + aso rexr rexx rexb vexl + 0f 28 + V W + sse avx + + + aso rexr rexx rexb vexl + 0f 29 + W V + sse avx + + + + + movd + + aso rexw rexr rexx rexb + 0f 6e /o=16 + P Ey + mmx + + + aso rexw rexr rexx rexb + 0f 6e /o=32 + P Ey + mmx + + + + aso rexw rexr rexx rexb + /sse=66 0f 6e /o=16 + V Ey + sse2 avx + + + aso rexw rexr rexx rexb + /sse=66 0f 6e /o=32 + V Ey + sse2 avx + + + aso rexw rexr rexx rexb + 0f 7e /o=16 + Ey P + mmx + + + aso rexw rexr rexx rexb + 0f 7e /o=32 + Ey P + mmx + + + aso rexw rexr rexx rexb + /sse=66 0f 7e /o=16 + Ey V + sse2 avx + + + aso rexw rexr rexx rexb + /sse=66 0f 7e /o=32 + Ey V + sse2 avx + + + + + movhpd + + aso rexr rexx rexb + /sse=66 0f 16 /mod=!11 + V H M + sse2 avx + + + aso rexr rexx rexb + /sse=66 0f 17 + M V + sse2 avx + + + + + movhps + + aso rexr rexx rexb + 0f 16 /mod=!11 + V H M + sse avx + + + aso rexr rexx rexb + 0f 17 + M V + sse avx + + + + + movlhps + + aso rexr rexx rexb + 0f 16 /mod=11 + V H U + sse avx + + + + + movlpd + + aso rexr rexx rexb + /sse=66 0f 12 /mod=!11 + V M + + + aso rexr rexx rexb + /sse=66 0f 13 + M V + + sse2 avx + + + + movlps + + aso rexr rexx rexb + 0f 12 /mod=!11 + V M + + + aso rexr rexx rexb + 0f 13 + M V + + sse avx + + + + movhlps + + aso rexr rexx rexb + 0f 12 /mod=11 + V U + sse avx + + + + + movmskpd + + oso rexr rexb vexl + /sse=66 0f 50 + Gd U + sse2 avx + + + + + movmskps + + oso rexr rexb + 0f 50 + Gd U + sse2 avx + + + + + movntdq + + aso rexr rexx rexb vexl + /sse=66 0f e7 + M V + sse2 avx + + + + + movnti + + aso rexw rexr rexx rexb + 0f c3 + M Gy + + + + + movntpd + + aso rexr rexx rexb vexl + /sse=66 0f 2b + M V + sse2 avx + + + + + movntps + + aso rexr rexx rexb vexl + 0f 2b + M V + sse2 avx + + + + + movntq + + aso rexr rexx rexb + 0f e7 + M P + + + + + movq + + aso rexw rexr rexx rexb + 0f 6e /o=64 + P Eq + mmx + + + aso rexw rexr rexx rexb + /sse=66 0f 6e /o=64 + V Eq + sse2 avx + + + aso rexw rexr rexx rexb + 0f 7e /o=64 + Eq P + mmx + + + aso rexw rexr rexx rexb + /sse=66 0f 7e /o=64 + Eq V + sse2 avx + + + aso rexw rexr rexx rexb + /sse=f3 0f 7e + V W + sse2 avx + + + aso rexw rexr rexx rexb + /sse=66 0f d6 + W V + sse2 avx + + + aso rexw rexr rexx rexb + 0f 6f + P Q + mmx + + + aso rexw rexr rexx rexb + 0f 7f + Q P + mmx + + + + + movsb + + rep seg + a4 + + + + + movsw + + rep seg oso rexw + a5 /o=16 + + + + + movsd + + rep seg oso rexw + a5 /o=32 + + + aso rexr rexx rexb + /sse=f2 0f 10 + V MqU + sse2 + + + aso rexr rexx rexb + /sse=f2 0f 11 + W V + sse2 + + + + + movsq + + rep seg oso rexw + a5 /o=64 + + + + + movss + + aso rexr rexx rexb + /sse=f3 0f 10 + V MdU + sse + + + aso rexr rexx rexb + /sse=f3 0f 11 + W V + sse + + + + + movsx + + aso oso rexw rexr rexx rexb + 0f be + Gv Eb + + + aso oso rexw rexr rexx rexb + 0f bf + Gy Ew + + + + + movupd + + aso rexr rexx rexb vexl + /sse=66 0f 10 + V W + sse2 avx + + + aso rexr rexx rexb vexl + /sse=66 0f 11 + W V + sse2 avx + + + + + movups + + aso rexr rexx rexb vexl + 0f 10 + V W + sse2 avx + + + aso rexr rexx rexb vexl + 0f 11 + W V + sse2 avx + + + + + movzx + + aso oso rexw rexr rexx rexb + 0f b6 + Gv Eb + + + aso oso rexw rexr rexx rexb + 0f b7 + Gy Ew + + + + + mul + + aso rexw rexr rexx rexb + f6 /reg=4 + Eb + + + aso oso rexw rexr rexx rexb + f7 /reg=4 + Ev + + + + + mulpd + + aso rexr rexx rexb vexl + /sse=66 0f 59 + V H W + sse2 avx + + + + + mulps + + aso rexr rexx rexb vexl + 0f 59 + V H W + sse2 avx + + + + + mulsd + + aso rexr rexx rexb + /sse=f2 0f 59 + V H W + sse2 avx + + + + + mulss + + aso rexr rexx rexb + /sse=f3 0f 59 + V H W + sse avx + + + + + mwait + + 0f 01 /reg=1 /mod=11 /rm=1 + + + + + neg + + aso rexw rexr rexx rexb + f6 /reg=3 + Eb + + + aso oso rexw rexr rexx rexb + f7 /reg=3 + Ev + + + + + nop + + aso rexr rexx rexb + 0f 19 + M + + + aso rexr rexx rexb + 0f 1a + M + + + aso rexr rexx rexb + 0f 1b + M + + + aso rexr rexx rexb + 0f 1c + M + + + aso rexr rexx rexb + 0f 1d + M + + + aso rexr rexx rexb + 0f 1e + M + + + aso rexr rexx rexb + 0f 1f + M + + + + + not + + aso rexw rexr rexx rexb + f6 /reg=2 + Eb + + + aso oso rexw rexr rexx rexb + f7 /reg=2 + Ev + + + + + or + + aso rexr rexx rexb + 08 + Eb Gb + + + aso oso rexw rexr rexx rexb + 09 + Ev Gv + + + aso rexr rexx rexb + 0a + Gb Eb + + + aso oso rexw rexr rexx rexb + 0b + Gv Ev + + + 0c + AL Ib + + + oso rexw + 0d + rAX sIz + + + aso rexr rexx rexb + 80 /reg=1 + Eb Ib + + + aso oso rexw rexr rexx rexb + 81 /reg=1 + Ev sIz + + + aso rexr rexx rexb + 82 /reg=1 /m=!64 + Eb Ib + + + aso oso rexw rexr rexx rexb + 83 /reg=1 + Ev sIb + + + + + orpd + + aso rexr rexx rexb vexl + /sse=66 0f 56 + V H W + sse2 avx + + + + + orps + + aso rexr rexx rexb vexl + 0f 56 + V H W + sse avx + + + + + out + + e6 + Ib AL + + + oso + e7 + Ib eAX + + + ee + DX AL + + + oso + ef + DX eAX + + + + + outsb + + rep seg + 6e + + + + + outsw + + rep oso seg + 6f /o=16 + + + + + outsd + + rep oso seg + 6f /o=32 + + + + + packsswb + + aso rexr rexx rexb vexl + /sse=66 0f 63 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 63 + P Q + mmx + + + + + packssdw + + aso rexr rexx rexb vexl + /sse=66 0f 6b + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 6b + P Q + mmx + + + + + packuswb + + aso rexr rexx rexb vexl + /sse=66 0f 67 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 67 + P Q + mmx + + + + + paddb + + aso rexr rexx rexb vexl + /sse=66 0f fc + V H W + sse2 avx + + + aso rexr rexx rexb + 0f fc + P Q + mmx + + + + + paddw + + aso rexr rexx rexb + 0f fd + P Q + mmx + + + aso rexr rexx rexb vexl + /sse=66 0f fd + V H W + sse2 avx + + + + + paddd + + aso rexr rexx rexb + 0f fe + P Q + mmx + + + aso rexr rexx rexb vexl + /sse=66 0f fe + V H W + sse2 avx + + + + + + paddsb + + aso rexr rexx rexb + 0f ec + P Q + + + aso rexr rexx rexb + /sse=66 0f ec + V H W + sse2 avx + + + + + paddsw + + aso rexr rexx rexb + 0f ed + P Q + + + aso rexr rexx rexb + /sse=66 0f ed + V H W + sse2 avx + + + + + paddusb + + aso rexr rexx rexb + 0f dc + P Q + + + aso rexr rexx rexb + /sse=66 0f dc + V H W + sse2 avx + + + + + paddusw + + aso rexr rexx rexb + 0f dd + P Q + + + aso rexr rexx rexb + /sse=66 0f dd + V H W + sse2 avx + + + + + pand + + aso rexr rexx rexb + /sse=66 0f db + V H W + sse2 avx + + + aso rexr rexx rexb + 0f db + P Q + + + + + pandn + + aso rexr rexx rexb + /sse=66 0f df + V H W + sse2 avx + + + aso rexr rexx rexb + 0f df + P Q + + + + + pavgb + + aso rexr rexx rexb + /sse=66 0f e0 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f e0 + P Q + + + + + pavgw + + aso rexr rexx rexb + /sse=66 0f e3 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f e3 + P Q + + + + + pcmpeqb + + aso rexr rexx rexb + 0f 74 + P Q + + + aso rexr rexx rexb + /sse=66 0f 74 + V H W + sse2 avx + + + + + pcmpeqw + + aso rexr rexx rexb + 0f 75 + P Q + + + aso rexr rexx rexb + /sse=66 0f 75 + V H W + sse2 avx + + + + + pcmpeqd + + aso rexr rexx rexb + 0f 76 + P Q + + + aso rexr rexx rexb + /sse=66 0f 76 + V H W + sse2 avx + + + + + pcmpgtb + + aso rexr rexx rexb + /sse=66 0f 64 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 64 + P Q + + + + + pcmpgtw + + aso rexr rexx rexb + /sse=66 0f 65 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 65 + P Q + + + + + pcmpgtd + + aso rexr rexx rexb + /sse=66 0f 66 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 66 + P Q + + + + + pextrb + + aso rexx rexr rexb + /sse=66 0f 3a 14 /vexw=0 + MbRv V Ib + def64 + sse4.1 avx + + + + + pextrd + + aso rexr rexx rexw rexb + /sse=66 0f 3a 16 /o=16 /vexw=0 + Ed V Ib + sse4.1 avx + + + aso rexr rexx rexw rexb + /sse=66 0f 3a 16 /o=32 /vexw=0 + Ed V Ib + sse4.1 avx + + + + + pextrq + + aso rexr rexw rexb + /sse=66 0f 3a 16 /o=64 /vexw=1 + Eq V Ib + def64 + sse4.1 avx + + + + + pextrw + + aso rexw rexr rexb + /sse=66 0f c5 + Gd U Ib + sse avx + + + aso rexw rexr rexx rexb + 0f c5 + Gd N Ib + + + aso rexw rexx rexr rexb + /sse=66 0f 3a 15 + MwRd V Ib + sse4.1 avx + + + + + pinsrb + + aso rexw rexr rexx rexb + /sse=66 0f 3a 20 + V MbRd Ib + sse4.1 + + + + + pinsrw + + aso rexw rexr rexx rexb + 0f c4 + P MwRy Ib + def64 + + + aso rexw rexr rexx rexb + /sse=66 0f c4 + V MwRy Ib + def64 + sse2 avx + + + + + pinsrd + + aso rexw rexr rexx rexb + /sse=66 0f 3a 22 /o=16 + V Ed Ib + sse4.1 + + + + aso rexw rexr rexx rexb + /sse=66 0f 3a 22 /o=32 + V Ed Ib + sse4.1 + + + + + pinsrq + + aso oso rexw rexr rexx rexb + /sse=66 0f 3a 22 /o=64 + V Eq Ib + sse4.1 + + + + + vpinsrb + + aso rexw rexr rexx rexb + /vex=66_0f3a 20 /vexw=0 /vexl=0 + V H MbRd Ib + avx + + + + + vpinsrd + + aso oso rexw rexr rexx rexb + /vex=66_0f3a 22 /m=!64 /vexw=0 /vexl=0 + V H Ed Ib + avx + + + aso oso rexw rexr rexx rexb + /vex=66_0f3a 22 /m=64 /vexw=0 /vexl=0 + V H Ed Ib + avx + + + + + + vpinsrq + + aso oso rexw rexr rexx rexb + /vex=66_0f3a 22 /m=64 /vexw=1 /vexl=0 + V H Eq Ib + avx + + + + + + pmaddwd + + aso rexr rexx rexb + 0f f5 + P Q + + + aso rexr rexx rexb + /sse=66 0f f5 + V H W + sse4.1 avx + + + + + pmaxsw + + aso rexr rexx rexb + /sse=66 0f ee + V H W + sse4.1 avx + + + aso rexr rexx rexb + 0f ee + P Q + + + + + pmaxub + + aso rexr rexx rexb + 0f de + P Q + + + aso rexr rexx rexb + /sse=66 0f de + V H W + sse2 avx + + + + + pminsw + + aso rexr rexx rexb + /sse=66 0f ea + V H W + sse2 avx + + + aso rexr rexx rexb + 0f ea + P Q + + + + + pminub + + aso rexr rexx rexb + /sse=66 0f da + V H W + sse2 avx + + + aso rexr rexx rexb + 0f da + P Q + + + + + pmovmskb + + oso rexr rexw rexb + /sse=66 0f d7 /vexl=0 + Gd U + sse2 avx + + + oso rexr rexw rexb + 0f d7 + Gd N + + + + + pmulhuw + + aso rexr rexx rexb + 0f e4 + P Q + + + aso rexr rexx rexb + /sse=66 0f e4 + V H W + sse2 avx + + + + + pmulhw + + aso rexr rexx rexb + /sse=66 0f e5 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f e5 + P Q + + + + + pmullw + + aso rexr rexx rexb + 0f d5 + P Q + + + aso rexr rexx rexb + /sse=66 0f d5 + V H W + sse2 avx + + + + + pop + + 07 /m=!64 + ES + inv64 + + + 17 /m=!64 + SS + inv64 + + + 1f /m=!64 + DS + inv64 + + + 0f a9 + GS + + + 0f a1 + FS + + + oso rexb + 58 + R0v + def64 + + + oso rexb + 59 + R1v + def64 + + + oso rexb + 5a + R2v + def64 + + + oso rexb + 5b + R3v + def64 + + + oso rexb + 5c + R4v + def64 + + + oso rexb + 5d + R5v + def64 + + + oso rexb + 5e + R6v + def64 + + + oso rexb + 5f + R7v + def64 + + + aso oso rexw rexr rexx rexb + 8f /reg=0 + Ev + def64 + + + + + popa + + oso + 61 /o=16 /m=!64 + inv64 + + + + + popad + + oso + 61 /o=32 /m=!64 + inv64 + + + + + popfw + + oso + 9d /m=!64 /o=16 + + + + + popfd + + oso + 9d /m=!64 /o=32 + + + + + popfq + + oso + 9d /m=64 /o=32 + def64 + + + oso + 9d /m=64 /o=64 + def64 + + + + + por + + aso rexr rexx rexb + /sse=66 0f eb + V H W + sse2 avx + + + aso rexr rexx rexb + 0f eb + P Q + + + + + prefetch + + aso rexw rexr rexx rexb + 0f 0d /reg=0 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=1 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=2 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=3 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=4 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=5 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=6 + M + + + aso rexw rexr rexx rexb + 0f 0d /reg=7 + M + + + + + prefetchnta + + aso rexw rexr rexx rexb + 0f 18 /reg=0 + M + + + + + prefetcht0 + + aso rexw rexr rexx rexb + 0f 18 /reg=1 + M + + + + + prefetcht1 + + aso rexw rexr rexx rexb + 0f 18 /reg=2 + M + + + + + prefetcht2 + + aso rexw rexr rexx rexb + 0f 18 /reg=3 + M + + + + + psadbw + + aso rexr rexx rexb + /sse=66 0f f6 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f f6 + P Q + + + + + pshufw + + aso rexr rexx rexb + 0f 70 + P Q Ib + + + + + psllw + + aso rexr rexx rexb + /sse=66 0f f1 + V W + sse2 + + + aso rexr rexx rexb + 0f f1 + P Q + + + rexb + /sse=66 0f 71 /reg=6 + U Ib + sse2 + + + 0f 71 /reg=6 + N Ib + + + + + pslld + + aso rexr rexx rexb + /sse=66 0f f2 + V W + sse2 + + + aso rexr rexx rexb + 0f f2 + P Q + + + rexb + /sse=66 0f 72 /reg=6 + U Ib + sse2 + + + 0f 72 /reg=6 + N Ib + + + + + psllq + + aso rexr rexx rexb + /sse=66 0f f3 + V W + sse2 + + + aso rexr rexx rexb + 0f f3 + P Q + + + rexb + /sse=66 0f 73 /reg=6 + U Ib + sse2 + + + 0f 73 /reg=6 + N Ib + + + + + psraw + + aso rexr rexx rexb + 0f e1 + P Q + + + aso rexr rexx rexb + /sse=66 0f e1 + V H W + sse2 avx + + + rexb + /sse=66 0f 71 /reg=4 + H U Ib + sse2 avx + + + 0f 71 /reg=4 + N Ib + + + + + psrad + + 0f 72 /reg=4 + N Ib + + + aso rexr rexx rexb + /sse=66 0f e2 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f e2 + P Q + + + rexb + /sse=66 0f 72 /reg=4 + H U Ib + sse2 avx + + + + + psrlw + + 0f 71 /reg=2 + N Ib + + + aso rexr rexx rexb + 0f d1 + P Q + + + aso rexr rexx rexb + /sse=66 0f d1 + V H W + sse2 avx + + + rexb + /sse=66 0f 71 /reg=2 + H U Ib + sse2 avx + + + + + psrld + + 0f 72 /reg=2 + N Ib + + + aso rexr rexx rexb + 0f d2 + P Q + + + aso rexr rexx rexb + /sse=66 0f d2 + V H W + sse2 avx + + + rexb + /sse=66 0f 72 /reg=2 + H U Ib + sse2 avx + + + + + psrlq + + 0f 73 /reg=2 + N Ib + + + aso rexr rexx rexb + 0f d3 + P Q + + + aso rexr rexx rexb + /sse=66 0f d3 + V H W + sse2 avx + + + rexb + /sse=66 0f 73 /reg=2 + H U Ib + sse2 avx + + + + + psubb + + aso rexr rexx rexb + /sse=66 0f f8 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f f8 + P Q + + + + + psubw + + aso rexr rexx rexb + /sse=66 0f f9 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f f9 + P Q + + + + + psubd + + aso rexr rexx rexb + 0f fa + P Q + + + aso rexr rexx rexb + /sse=66 0f fa + V H W + sse2 avx + + + + + psubsb + + aso rexr rexx rexb + 0f e8 + P Q + + + aso rexr rexx rexb + /sse=66 0f e8 + V H W + sse2 avx + + + + + psubsw + + aso rexr rexx rexb + 0f e9 + P Q + + + aso rexr rexx rexb + /sse=66 0f e9 + V H W + sse2 avx + + + + + psubusb + + aso rexr rexx rexb + 0f d8 + P Q + + + aso rexr rexx rexb + /sse=66 0f d8 + V H W + sse2 avx + + + + + psubusw + + aso rexr rexx rexb + 0f d9 + P Q + + + aso rexr rexx rexb + /sse=66 0f d9 + V H W + sse2 avx + + + + + punpckhbw + + aso rexr rexx rexb + /sse=66 0f 68 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 68 + P Q + + + + + punpckhwd + + aso rexr rexx rexb + /sse=66 0f 69 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 69 + P Q + + + + + punpckhdq + + aso rexr rexx rexb + /sse=66 0f 6a + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 6a + P Q + + + + + punpcklbw + + aso rexr rexx rexb + /sse=66 0f 60 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 60 + P Q + + + + + punpcklwd + + aso rexr rexx rexb + /sse=66 0f 61 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 61 + P Q + + + + + punpckldq + + aso rexr rexx rexb + /sse=66 0f 62 + V H W + sse2 avx + + + aso rexr rexx rexb + 0f 62 + P Q + + + + + pi2fw + + aso rexr rexx rexb + 0f 0f /3dnow=0c + P Q + + + + + pi2fd + + aso rexr rexx rexb + 0f 0f /3dnow=0d + P Q + + + + + pf2iw + + aso rexr rexx rexb + 0f 0f /3dnow=1c + P Q + + + + + pf2id + + aso rexr rexx rexb + 0f 0f /3dnow=1d + P Q + + + + + pfnacc + + aso rexr rexx rexb + 0f 0f /3dnow=8a + P Q + + + + + pfpnacc + + aso rexr rexx rexb + 0f 0f /3dnow=8e + P Q + + + + + pfcmpge + + aso rexr rexx rexb + 0f 0f /3dnow=90 + P Q + + + + + pfmin + + aso rexr rexx rexb + 0f 0f /3dnow=94 + P Q + + + + + pfrcp + + aso rexr rexx rexb + 0f 0f /3dnow=96 + P Q + + + + + pfrsqrt + + aso rexr rexx rexb + 0f 0f /3dnow=97 + P Q + + + + + pfsub + + aso rexr rexx rexb + 0f 0f /3dnow=9a + P Q + + + + + pfadd + + aso rexr rexx rexb + 0f 0f /3dnow=9e + P Q + + + + + pfcmpgt + + aso rexr rexx rexb + 0f 0f /3dnow=a0 + P Q + + + + + pfmax + + aso rexr rexx rexb + 0f 0f /3dnow=a4 + P Q + + + + + pfrcpit1 + + aso rexr rexx rexb + 0f 0f /3dnow=a6 + P Q + + + + + pfrsqit1 + + aso rexr rexx rexb + 0f 0f /3dnow=a7 + P Q + + + + + pfsubr + + aso rexr rexx rexb + 0f 0f /3dnow=aa + P Q + + + + + pfacc + + aso rexr rexx rexb + 0f 0f /3dnow=ae + P Q + + + + + pfcmpeq + + aso rexr rexx rexb + 0f 0f /3dnow=b0 + P Q + + + + + pfmul + + aso rexr rexx rexb + 0f 0f /3dnow=b4 + P Q + + + + + pfrcpit2 + + aso rexr rexx rexb + 0f 0f /3dnow=b6 + P Q + + + + + pmulhrw + + aso rexr rexx rexb + 0f 0f /3dnow=b7 + P Q + + + + + pswapd + + aso rexr rexx rexb + 0f 0f /3dnow=bb + P Q + + + + + pavgusb + + aso rexr rexx rexb + 0f 0f /3dnow=bf + P Q + + + + + push + + 06 /m=!64 + ES + inv64 + + + 0e /m=!64 + CS + inv64 + + + 16 /m=!64 + SS + inv64 + + + 1e /m=!64 + DS + inv64 + + + 0f a8 + GS + + + 0f a0 + FS + + + oso rexb + 50 + R0v + def64 + + + oso rexb + 51 + R1v + def64 + + + oso rexb + 52 + R2v + def64 + + + oso rexb + 53 + R3v + def64 + + + oso rexb + 54 + R4v + def64 + + + oso rexb + 55 + R5v + def64 + + + oso rexb + 56 + R6v + def64 + + + oso rexb + 57 + R7v + def64 + + + oso + 68 + sIz + def64 + + + aso oso rexw rexr rexx rexb + ff /reg=6 + Ev + def64 + + + oso + 6a + sIb + def64 + + + + + pusha + + oso + 60 /o=16 /m=!64 + inv64 + + + + + pushad + + oso + 60 /o=32 /m=!64 + inv64 + + + + + pushfw + + oso + 9c /m=!64 /o=16 + + + oso rexw + 9c /m=64 /o=16 + def64 + + + + + pushfd + + oso + 9c /m=!64 /o=32 + + + + + pushfq + + oso rexw + 9c /m=64 /o=32 + def64 + + + oso rexw + 9c /m=64 /o=64 + def64 + + + + + pxor + + aso rexr rexx rexb + /sse=66 0f ef + V H W + sse2 avx + + + aso rexr rexx rexb + 0f ef + P Q + + + + + rcl + + aso rexw rexr rexx rexb + c0 /reg=2 + Eb Ib + + + aso oso rexw rexr rexx rexb + c1 /reg=2 + Ev Ib + + + aso rexw rexr rexx rexb + d0 /reg=2 + Eb I1 + + + aso rexw rexr rexx rexb + d2 /reg=2 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=2 + Ev CL + + + aso oso rexw rexr rexx rexb + d1 /reg=2 + Ev I1 + + + + + rcr + + aso rexw rexr rexx rexb + d0 /reg=3 + Eb I1 + + + aso oso rexw rexr rexx rexb + c1 /reg=3 + Ev Ib + + + aso rexw rexr rexx rexb + c0 /reg=3 + Eb Ib + + + aso oso rexw rexr rexx rexb + d1 /reg=3 + Ev I1 + + + aso rexw rexr rexx rexb + d2 /reg=3 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=3 + Ev CL + + + + + rol + + aso rexw rexr rexx rexb + c0 /reg=0 + Eb Ib + + + aso rexw rexr rexx rexb + d0 /reg=0 + Eb I1 + + + aso oso rexw rexr rexx rexb + d1 /reg=0 + Ev I1 + + + aso rexw rexr rexx rexb + d2 /reg=0 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=0 + Ev CL + + + aso oso rexw rexr rexx rexb + c1 /reg=0 + Ev Ib + + + + + ror + + aso rexw rexr rexx rexb + d0 /reg=1 + Eb I1 + + + aso rexw rexr rexx rexb + c0 /reg=1 + Eb Ib + + + aso oso rexw rexr rexx rexb + c1 /reg=1 + Ev Ib + + + aso oso rexw rexr rexx rexb + d1 /reg=1 + Ev I1 + + + aso rexw rexr rexx rexb + d2 /reg=1 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=1 + Ev CL + + + + + rcpps + + aso rexr rexx rexb vexl + 0f 53 + V W + sse avx + + + + + rcpss + + aso rexr rexx rexb + /sse=f3 0f 53 + V W + sse avx + + + + + rdmsr + + 0f 32 + + + + + rdpmc + + 0f 33 + + + + + rdtsc + + 0f 31 + + + + + rdtscp + amd + + 0f 01 /reg=7 /mod=11 /rm=1 + + + + + repne + + f2 + + + + + rep + + f3 + + + + + ret + + c2 + Iw + + + c3 + + + + + retf + + ca + Iw + + + cb + + + + + rsm + + 0f aa + + + + + rsqrtps + + aso rexr rexx rexb vexl + 0f 52 + V W + sse avx + + + + + rsqrtss + + aso rexr rexx rexb + /sse=f3 0f 52 + V W + sse avx + + + + + sahf + + 9e + + + + + sal + + + + salc + + d6 /m=!64 + inv64 + + + + + sar + + aso oso rexw rexr rexx rexb + d1 /reg=7 + Ev I1 + + + aso rexw rexr rexx rexb + c0 /reg=7 + Eb Ib + + + aso rexw rexr rexx rexb + d0 /reg=7 + Eb I1 + + + aso oso rexw rexr rexx rexb + c1 /reg=7 + Ev Ib + + + aso rexw rexr rexx rexb + d2 /reg=7 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=7 + Ev CL + + + + + shl + + aso rexw rexr rexx rexb + c0 /reg=6 + Eb Ib + + + aso oso rexw rexr rexx rexb + c1 /reg=6 + Ev Ib + + + aso rexw rexr rexx rexb + d0 /reg=6 + Eb I1 + + + aso rexw rexr rexx rexb + d2 /reg=6 + Eb CL + + + aso oso rexw rexr rexx rexb + d3 /reg=6 + Ev CL + + + aso oso rexw rexr rexx rexb + c1 /reg=4 + Ev Ib + + + aso rexr rexx rexb + d2 /reg=4 + Eb CL + + + aso oso rexw rexr rexx rexb + d1 /reg=4 + Ev I1 + + + aso rexw rexr rexx rexb + d0 /reg=4 + Eb I1 + + + aso rexw rexr rexx rexb + c0 /reg=4 + Eb Ib + + + aso oso rexw rexr rexx rexb + d3 /reg=4 + Ev CL + + + aso oso rexw rexr rexx rexb + d1 /reg=6 + Ev I1 + + + + + shr + + aso oso rexw rexr rexx rexb + c1 /reg=5 + Ev Ib + + + aso rexw rexr rexx rexb + d2 /reg=5 + Eb CL + + + aso oso rexw rexr rexx rexb + d1 /reg=5 + Ev I1 + + + aso rexw rexr rexx rexb + d0 /reg=5 + Eb I1 + + + aso rexw rexr rexx rexb + c0 /reg=5 + Eb Ib + + + aso oso rexw rexr rexx rexb + d3 /reg=5 + Ev CL + + + + + sbb + + aso rexr rexx rexb + 18 + Eb Gb + + + aso oso rexw rexr rexx rexb + 19 + Ev Gv + + + aso rexr rexx rexb + 1a + Gb Eb + + + aso oso rexw rexr rexx rexb + 1b + Gv Ev + + + 1c + AL Ib + + + oso rexw + 1d + rAX sIz + + + aso rexr rexx rexb + 80 /reg=3 + Eb Ib + + + aso oso rexw rexr rexx rexb + 81 /reg=3 + Ev sIz + + + aso rexr rexx rexb + 82 /reg=3 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 83 /reg=3 + Ev sIb + + + + + scasb + + repz + ae + + + + + scasw + + repz oso rexw + af /o=16 + + + + + scasd + + repz oso rexw + af /o=32 + + + + + scasq + + repz oso rexw + af /o=64 + + + + + seto + + aso rexr rexx rexb + 0f 90 + Eb + + + + + setno + + aso rexr rexx rexb + 0f 91 + Eb + + + + + setb + + aso rexr rexx rexb + 0f 92 + Eb + + + + + setae + + aso rexr rexx rexb + 0f 93 + Eb + + + + + setz + + aso rexr rexx rexb + 0f 94 + Eb + + + + + setnz + + aso rexr rexx rexb + 0f 95 + Eb + + + + + setbe + + aso rexr rexx rexb + 0f 96 + Eb + + + + + seta + + aso rexr rexx rexb + 0f 97 + Eb + + + + + sets + + aso rexr rexx rexb + 0f 98 + Eb + + + + + setns + + aso rexr rexx rexb + 0f 99 + Eb + + + + + setp + + aso rexr rexx rexb + 0f 9a + Eb + + + + + setnp + + aso rexr rexx rexb + 0f 9b + Eb + + + + + setl + + aso rexr rexx rexb + 0f 9c + Eb + + + + + setge + + aso rexr rexx rexb + 0f 9d + Eb + + + + + setle + + aso rexr rexx rexb + 0f 9e + Eb + + + + + setg + + aso rexr rexx rexb + 0f 9f + Eb + + + + + sfence + + 0f ae /reg=7 /mod=11 /rm=0 + + + 0f ae /reg=7 /mod=11 /rm=1 + + + 0f ae /reg=7 /mod=11 /rm=2 + + + 0f ae /reg=7 /mod=11 /rm=3 + + + 0f ae /reg=7 /mod=11 /rm=4 + + + 0f ae /reg=7 /mod=11 /rm=5 + + + 0f ae /reg=7 /mod=11 /rm=6 + + + 0f ae /reg=7 /mod=11 /rm=7 + + + + + sgdt + + aso rexr rexx rexb + 0f 01 /reg=0 /mod=!11 + M + + + + + shld + + aso oso rexw rexr rexx rexb + 0f a4 + Ev Gv Ib + + + aso oso rexw rexr rexx rexb + 0f a5 + Ev Gv CL + + + + + shrd + + aso oso rexw rexr rexx rexb + 0f ac + Ev Gv Ib + + + aso oso rexw rexr rexx rexb + 0f ad + Ev Gv CL + + + + + shufpd + + aso rexr rexx rexb vexl + /sse=66 0f c6 + V H W Ib + sse2 avx + + + + + shufps + + aso rexr rexx rexb + 0f c6 + V H W Ib + sse2 avx + + + + + sidt + + aso rexr rexx rexb + 0f 01 /reg=1 /mod=!11 + M + + + + + sldt + + aso oso rexr rexw rexx rexb + 0f 00 /reg=0 + MwRv + + + + + smsw + + aso oso rexr rexw rexx rexb + 0f 01 /reg=4 /mod=!11 + MwRv + + + aso oso rexr rexw rexx rexb + 0f 01 /reg=4 /mod=11 + MwRv + + + + + sqrtps + + aso rexr rexx rexb vexl + 0f 51 + V W + sse avx + + + + + sqrtpd + + aso rexr rexx rexb + /sse=66 0f 51 + V W + sse2 avx + + + + + sqrtsd + + aso rexr rexx rexb + /sse=f2 0f 51 + V H W + sse2 avx + + + + + sqrtss + + aso rexr rexx rexb + /sse=f3 0f 51 + V H W + sse avx + + + + + stc + + f9 + + + + + std + + fd + + + + + stgi + amd + + 0f 01 /reg=3 /mod=11 /rm=4 + + + + + sti + + fb + + + + + skinit + amd + + 0f 01 /reg=3 /mod=11 /rm=6 + + + + + stmxcsr + + aso rexw rexr rexx rexb + 0f ae /mod=!11 /reg=3 + Md + sse avx + + + + + stosb + + rep seg + aa + + + + + stosw + + rep seg oso rexw + ab /o=16 + + + + + stosd + + rep seg oso rexw + ab /o=32 + + + + + stosq + + rep seg oso rexw + ab /o=64 + + + + + str + + aso oso rexr rexw rexx rexb + 0f 00 /reg=1 + MwRv + + + + + sub + + aso rexr rexx rexb + 28 + Eb Gb + + + aso oso rexw rexr rexx rexb + 29 + Ev Gv + + + aso rexr rexx rexb + 2a + Gb Eb + + + aso oso rexw rexr rexx rexb + 2b + Gv Ev + + + 2c + AL Ib + + + oso rexw + 2d + rAX sIz + + + aso rexr rexx rexb + 80 /reg=5 + Eb Ib + + + aso oso rexw rexr rexx rexb + 81 /reg=5 + Ev sIz + + + aso rexr rexx rexb + 82 /reg=5 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 83 /reg=5 + Ev sIb + + + + + subpd + + aso rexr rexx rexb vexl + /sse=66 0f 5c + V H W + sse2 avx + + + + + subps + + aso rexr rexx rexb vexl + 0f 5c + V H W + sse avx + + + + + subsd + + aso rexr rexx rexb + /sse=f2 0f 5c + V H W + sse2 avx + + + + + subss + + aso rexr rexx rexb + /sse=f3 0f 5c + V H W + sse avx + + + + + swapgs + + 0f 01 /reg=7 /mod=11 /rm=0 + + + + + syscall + + 0f 05 + + + + + sysenter + + 0f 34 /m=!64 + + + 0f 34 /m=64 + intel + + + + + sysexit + + 0f 35 /m=!64 + + + 0f 35 /m=64 + intel + + + + + sysret + + 0f 07 + + + + + test + + aso rexw rexr rexx rexb + f6 /reg=0 + Eb Ib + + + aso rexr rexx rexb + 84 + Eb Gb + + + aso oso rexw rexr rexx rexb + 85 + Ev Gv + + + a8 + AL Ib + + + oso rexw + a9 + rAX sIz + + + aso rexw rexr rexx rexb + f6 /reg=1 + Eb Ib + + + aso oso rexw rexr rexx rexb + f7 /reg=0 + Ev sIz + + + aso oso rexw rexr rexx rexb + f7 /reg=1 + Ev Iz + + + + + ucomisd + + aso rexr rexx rexb + /sse=66 0f 2e + V W + sse2 avx + + + + + ucomiss + + aso rexr rexx rexb + 0f 2e + V W + sse avx + + + + + ud2 + + 0f 0b + + + + + unpckhpd + + aso rexr rexx rexb vexl + /sse=66 0f 15 + V H W + sse2 avx + + + + + unpckhps + + aso rexr rexx rexb + 0f 15 + V H W + sse avx + + + + + unpcklps + + aso rexr rexx rexb + 0f 14 + V H W + sse avx + + + + + unpcklpd + + aso rexr rexx rexb vexl + /sse=66 0f 14 + V H W + sse2 avx + + + + + verr + + aso rexr rexx rexb + 0f 00 /reg=4 + Ew + + + + + verw + + aso rexr rexx rexb + 0f 00 /reg=5 + Ew + + + + + vmcall + intel + + 0f 01 /reg=0 /mod=11 /rm=1 + + + + + rdrand + + oso rexr rexw rexx rexb + 0f c7 /mod=11 /reg=6 + R + + rdrand + + + + vmclear + intel + + aso rexr rexx rexb + /sse=66 0f c7 /mod=!11 /reg=6 + Mq + + + + + vmxon + intel + + aso rexr rexx rexb + /sse=f3 0f c7 /mod=!11 /reg=6 + Mq + + + + + vmptrld + intel + + aso rexr rexx rexb + 0f c7 /mod=!11 /reg=6 + Mq + + + + + vmptrst + intel + + aso rexr rexx rexb + 0f c7 /mod=!11 /reg=7 + Mq + + + + + vmlaunch + intel + + 0f 01 /reg=0 /mod=11 /rm=2 + + + + + vmresume + intel + + 0f 01 /reg=0 /mod=11 /rm=3 + + + + + vmxoff + intel + + 0f 01 /reg=0 /mod=11 /rm=4 + + + + + vmread + intel + + aso rexr rexx rexb + 0f 78 + Ey Gy + def64 + + + + + vmwrite + intel + + aso rexr rexx rexb + 0f 79 + Gy Ey + def64 + + + + + vmrun + amd + + 0f 01 /reg=3 /mod=11 /rm=0 + + + + + vmmcall + amd + + 0f 01 /reg=3 /mod=11 /rm=1 + + + + + vmload + amd + + 0f 01 /reg=3 /mod=11 /rm=2 + + + + + vmsave + amd + + 0f 01 /reg=3 /mod=11 /rm=3 + + + + + wait + + 9b + + + + + wbinvd + + 0f 09 + + + + + wrmsr + + 0f 30 + + + + + xadd + + aso oso rexr rexx rexb + 0f c0 + Eb Gb + + + aso oso rexw rexr rexx rexb + 0f c1 + Ev Gv + + + + + xchg + + aso rexr rexx rexb + 86 + Eb Gb + + + aso oso rexw rexr rexx rexb + 87 + Ev Gv + + + oso rexw rexb + 90 + R0v rAX + + + oso rexw rexb + 91 + R1v rAX + + + oso rexw rexb + 92 + R2v rAX + + + oso rexw rexb + 93 + R3v rAX + + + oso rexw rexb + 94 + R4v rAX + + + oso rexw rexb + 95 + R5v rAX + + + oso rexw rexb + 96 + R6v rAX + + + oso rexw rexb + 97 + R7v rAX + + + + + xgetbv + + 0f 01 /mod=11 /reg=2 /rm=0 + + + + + xlatb + + rexw seg + d7 + + + + + xor + + aso rexr rexx rexb + 30 + Eb Gb + + + aso oso rexw rexr rexx rexb + 31 + Ev Gv + + + aso rexr rexx rexb + 32 + Gb Eb + + + aso oso rexw rexr rexx rexb + 33 + Gv Ev + + + 34 + AL Ib + + + oso rexw + 35 + rAX sIz + + + aso rexr rexx rexb + 80 /reg=6 + Eb Ib + + + aso oso rexw rexr rexx rexb + 81 /reg=6 + Ev sIz + + + aso rexr rexx rexb + 82 /reg=6 /m=!64 + Eb Ib + inv64 + + + aso oso rexw rexr rexx rexb + 83 /reg=6 + Ev sIb + + + + + xorpd + + aso rexr rexx rexb vexl + /sse=66 0f 57 + V H W + sse2 avx + + + + + xorps + + aso rexr rexx rexb + 0f 57 + V H W + sse2 avx + + + + + xcryptecb + + 0f a7 /mod=11 /rm=0 /reg=1 + + + + + xcryptcbc + + 0f a7 /mod=11 /rm=0 /reg=2 + + + + + xcryptctr + + 0f a7 /mod=11 /rm=0 /reg=3 + + + + + xcryptcfb + + 0f a7 /mod=11 /rm=0 /reg=4 + + + + + xcryptofb + + 0f a7 /mod=11 /rm=0 /reg=5 + + + + + xrstor + + aso rexw rexr rexx rexb + 0f ae /reg=5 /mod=!11 + M + + + + + xsave + + aso rexw rexr rexx rexb + 0f ae /reg=4 /mod=!11 + M + + + + + xsetbv + + 0f 01 /mod=11 /reg=2 /rm=1 + + + + + xsha1 + + 0f a6 /mod=11 /rm=0 /reg=1 + + + + + xsha256 + + 0f a6 /mod=11 /rm=0 /reg=2 + + + + + xstore + + 0f a7 /mod=11 /rm=0 /reg=0 + + + + + pclmulqdq + + aso rexr rexx rexb + /sse=66 0f 3a 44 + V H W Ib + aesni avx + + + + + + + getsec + smx + + 0f 37 + + + + + + + movdqa + + aso rexr rexx rexb vexl + /sse=66 0f 7f + W V + + + aso rexr rexx rexb vexl + /sse=66 0f 6f + V W + + sse2 avx + + + + maskmovdqu + + aso rexr rexx rexb + /sse=66 0f f7 /mod=11 + V U + sse2 avx + + + + + movdq2q + + aso rexb + /sse=f2 0f d6 + P U + + + + + movdqu + + aso rexr rexx rexb vexl + /sse=f3 0f 6f + V W + + + aso rexr rexx rexb vexl + /sse=f3 0f 7f + W V + + sse2 avx + + + + movq2dq + + aso rexr + /sse=f3 0f d6 + V N + + + + + paddq + + aso rexr rexx rexb + 0f d4 + P Q + + + aso rexr rexx rexb + /sse=66 0f d4 + V H W + sse2 avx + + + + + psubq + + aso rexr rexx rexb + /sse=66 0f fb + V H W + sse2 avx + + + aso rexr rexx rexb + 0f fb + P Q + + + + + pmuludq + + aso rexr rexx rexb + 0f f4 + P Q + + + aso rexr rexx rexb + /sse=66 0f f4 + V W + + + + + pshufhw + + aso rexr rexx rexb + /sse=f3 0f 70 + V W Ib + sse2 avx + + + + + pshuflw + + aso rexr rexx rexb + /sse=f2 0f 70 + V W Ib + sse2 avx + + + + + pshufd + + aso rexr rexx rexb + /sse=66 0f 70 + V W Ib + sse2 avx + + + + + pslldq + + rexb + /sse=66 0f 73 /reg=7 + H U Ib + sse2 avx + + + + + psrldq + + rexb + /sse=66 0f 73 /reg=3 + H U Ib + sse2 avx + + + + + punpckhqdq + + aso rexr rexx rexb + /sse=66 0f 6d + V H W + sse2 avx + + + + + punpcklqdq + + aso rexr rexx rexb + /sse=66 0f 6c + V H W + sse2 avx + + + + + haddpd + + aso rexr rexx rexb vexl + /sse=66 0f 7c + V H W + sse3 avx + + + + + haddps + + aso rexr rexx rexb vexl + /sse=f2 0f 7c + V H W + sse3 avx + + + + + hsubpd + + aso rexr rexx rexb vexl + /sse=66 0f 7d + V H W + sse3 avx + + + + + hsubps + + aso rexr rexx rexb vexl + /sse=f2 0f 7d + V H W + sse3 avx + + + + + insertps + + aso rexr rexw rexx rexb + /sse=66 0f 3a 21 + V H Md Ib + sse4.1 avx + + + + + lddqu + + aso rexr rexx rexb vexl + /sse=f2 0f f0 + V M + sse3 avx + + + + + movddup + + aso rexr rexx rexb + /sse=f2 0f 12 /mod=11 + V W + + + aso rexr rexx rexb + /sse=f2 0f 12 /mod=!11 + V W + + sse3 avx + + + + movshdup + + aso rexr rexx rexb vexl + /sse=f3 0f 16 /mod=11 + V W + sse3 avx + + + aso rexr rexx rexb vexl + /sse=f3 0f 16 /mod=!11 + V W + sse3 avx + + + + + movsldup + + aso rexr rexx rexb vexl + /sse=f3 0f 12 /mod=11 + V W + sse3 avx + + + aso rexr rexx rexb vexl + /sse=f3 0f 12 /mod=!11 + V W + sse3 avx + + + + + + + pabsb + + aso rexr rexx rexb + 0f 38 1c + P Q + ssse3 + + + aso rexr rexx rexb vexl + /sse=66 0f 38 1c + V W + ssse3 avx + + + + + pabsw + + aso rexr rexx rexb + 0f 38 1d + P Q + ssse3 + + + aso rexr rexx rexb vexl + /sse=66 0f 38 1d + V W + ssse3 avx + + + + + pabsd + + aso rexr rexx rexb + 0f 38 1e + P Q + ssse3 + + + aso rexr rexx rexb vexl + /sse=66 0f 38 1e + V W + ssse3 avx + + + + + pshufb + + aso rexr rexx rexb + 0f 38 00 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 00 + V H W + ssse3 avx + + + + + phaddw + + aso rexr rexx rexb + 0f 38 01 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 01 + V H W + ssse3 avx + + + + + phaddd + + aso rexr rexx rexb + 0f 38 02 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 02 + V H W + ssse3 avx + + + + + phaddsw + + aso rexr rexx rexb + 0f 38 03 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 03 + V H W + ssse3 avx + + + + + pmaddubsw + + aso rexr rexx rexb + 0f 38 04 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 04 + V H W + ssse3 avx + + + + + phsubw + + aso rexr rexx rexb + 0f 38 05 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 05 + V H W + ssse3 avx + + + + + phsubd + + aso rexr rexx rexb + 0f 38 06 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 06 + V H W + ssse3 avx + + + + + phsubsw + + aso rexr rexx rexb + 0f 38 07 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 07 + V H W + ssse3 avx + + + + + psignb + + aso rexr rexx rexb + 0f 38 08 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 08 + V H W + ssse3 avx + + + + + psignd + + aso rexr rexx rexb + 0f 38 0a + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 0a + V H W + ssse3 avx + + + + + psignw + + aso rexr rexx rexb + 0f 38 09 + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 09 + V H W + ssse3 avx + + + + + pmulhrsw + + aso rexr rexx rexb + 0f 38 0b + P Q + + + aso rexr rexx rexb + /sse=66 0f 38 0b + V H W + ssse3 avx + + + + + palignr + + aso rexr rexx rexb + 0f 3a 0f + P Q Ib + + + aso rexr rexx rexb + /sse=66 0f 3a 0f + V H W Ib + ssse3 avx + + + + + + + pblendvb + + aso rexr rexx rexb + /sse=66 0f 38 10 + V W + sse4.1 + + + + + pmuldq + + aso rexr rexx rexb + /sse=66 0f 38 28 + V H W + sse4.1 avx + + + + + pminsb + + aso rexr rexx rexb + /sse=66 0f 38 38 + V H W + sse4.1 avx + + + + + pminsd + + aso rexr rexx rexb + /sse=66 0f 38 39 + V H W + sse4.1 avx + + + + + pminuw + + aso rexr rexx rexb + /sse=66 0f 38 3a + V H W + sse4.1 avx + + + + + pminud + + aso rexr rexx rexb + /sse=66 0f 38 3b + V H W + sse4.1 avx + + + + + pmaxsb + + aso rexr rexx rexb + /sse=66 0f 38 3c + V H W + sse4.1 avx + + + + + pmaxsd + + aso rexr rexx rexb + /sse=66 0f 38 3d + V H W + sse4.1 avx + + + + + pmaxud + + aso rexr rexx rexb + /sse=66 0f 38 3f + V H W + sse4.1 avx + + + + + pmaxuw + + aso rexr rexx rexb + /sse=66 0f 38 3e + V H W + sse4.1 avx + + + + + pmulld + + aso rexr rexx rexb + /sse=66 0f 38 40 + V H W + sse4.1 avx + + + + + phminposuw + + aso rexr rexx rexb + /sse=66 0f 38 41 + V W + sse4.1 avx + + + + + roundps + + aso rexr rexx rexb vexl + /sse=66 0f 3a 08 + V W Ib + sse avx + + + + + roundpd + + aso rexr rexx rexb vexl + /sse=66 0f 3a 09 + V W Ib + sse4.1 avx + + + + + roundss + + aso rexr rexx rexb + /sse=66 0f 3a 0a + V H W Ib + sse4.1 avx + + + + + roundsd + + aso rexr rexx rexb + /sse=66 0f 3a 0b + V H W Ib + sse4.1 avx + + + + + blendpd + + aso rexr rexx rexb vexl + /sse=66 0f 3a 0d + V H W Ib + sse4.1 avx + + + + + blendps + + aso rexr rexx rexb + /sse=66 0f 3a 0c + V H W Ib + sse4.1 avx + + + + + blendvpd + + aso rexr rexx rexb + /sse=66 0f 38 15 + V W + sse4.1 + + + + + blendvps + + aso rexr rexx rexb + /sse=66 0f 38 14 + V W + sse4.1 + + + + + bound + + aso oso + 62 /m=!64 + Gv M + + + + + bsf + + aso oso rexw rexr rexx rexb + 0f bc + Gv Ev + + + + + bsr + + aso oso rexw rexr rexx rexb + 0f bd + Gv Ev + + + + + bswap + + oso rexw rexb + 0f c8 + R0y + + + oso rexw rexb + 0f c9 + R1y + + + oso rexw rexb + 0f ca + R2y + + + oso rexw rexb + 0f cb + R3y + + + oso rexw rexb + 0f cc + R4y + + + oso rexw rexb + 0f cd + R5y + + + oso rexw rexb + 0f ce + R6y + + + oso rexw rexb + 0f cf + R7y + + + + + bt + + aso oso rexw rexr rexx rexb + 0f ba /reg=4 + Ev Ib + + + aso oso rexw rexr rexx rexb + 0f a3 + Ev Gv + + + + + btc + + aso oso rexw rexr rexx rexb + 0f bb + Ev Gv + + + aso oso rexw rexr rexx rexb + 0f ba /reg=7 + Ev Ib + + + + + btr + + aso oso rexw rexr rexx rexb + 0f b3 + Ev Gv + + + aso oso rexw rexr rexx rexb + 0f ba /reg=6 + Ev Ib + + + + + bts + + aso oso rexw rexr rexx rexb + 0f ab + Ev Gv + + + aso oso rexw rexr rexx rexb + 0f ba /reg=5 + Ev Ib + + + + + pblendw + + aso rexr rexx rexb + /sse=66 0f 3a 0e + V H W Ib + sse4.1 avx + + + + + mpsadbw + + aso rexr rexx rexb vexl + /sse=66 0f 3a 42 + V H W Ib + sse4.1 avx + + + + + movntdqa + + aso rexr rexw rexx rexb vexl + /sse=66 0f 38 2a + V M + sse4.1 avx + + + + + packusdw + + aso rexr rexw rexx rexb vexl + /sse=66 0f 38 2b + V H W + sse2 avx + + + + + pmovsxbw + + aso rexr rexw rexx rexb + /sse=66 0f 38 20 + V MqU + sse4.1 avx + + + + + pmovsxbd + + aso rexr rexw rexx rexb + /sse=66 0f 38 21 + V MdU + sse4.1 avx + + + + + pmovsxbq + + aso rexr rexw rexx rexb + /sse=66 0f 38 22 + V MwU + sse4.1 avx + + + + + pmovsxwd + + aso rexr rexw rexx rexb + /sse=66 0f 38 23 + V MqU + sse4.1 avx + + + + + pmovsxwq + + aso rexr rexw rexx rexb + /sse=66 0f 38 24 + V MdU + sse4.1 avx + + + + + pmovsxdq + + aso rexr rexw rexx rexb + /sse=66 0f 38 25 + V MqU + sse4.1 + + + + + pmovzxbw + + aso rexr rexw rexx rexb + /sse=66 0f 38 30 + V MqU + sse4.1 avx + + + + + pmovzxbd + + aso rexr rexw rexx rexb + /sse=66 0f 38 31 + V MdU + sse4.1 avx + + + + + pmovzxbq + + aso rexr rexw rexx rexb + /sse=66 0f 38 32 + V MwU + sse4.1 avx + + + + + pmovzxwd + + aso rexr rexw rexx rexb + /sse=66 0f 38 33 + V MqU + sse4.1 avx + + + + + pmovzxwq + + aso rexr rexw rexx rexb + /sse=66 0f 38 34 + V MdU + sse4.1 avx + + + + + pmovzxdq + + aso rexr rexw rexx rexb + /sse=66 0f 38 35 + V MqU + sse4.1 avx + + + + + pcmpeqq + + aso rexr rexw rexx rexb + /sse=66 0f 38 29 + V H W + sse4.1 avx + + + + + popcnt + + aso oso rexr rexw rexx rexb + /sse=f3 0f b8 + Gv Ev + + sse4.2 + + + + ptest + + aso rexr rexw rexx rexb vexl + /sse=66 0f 38 17 + V W + sse4.1 avx + + + + + pcmpestri + + aso rexr rexw rexx rexb + /sse=66 0f 3a 61 + V W Ib + sse4.2 avx + + + + + pcmpestrm + + aso rexr rexw rexx rexb + /sse=66 0f 3a 60 + V W Ib + sse4.2 avx + + + + + pcmpgtq + + aso rexr rexw rexx rexb + /sse=66 0f 38 37 + V H W + sse4.2 avx + + + + + pcmpistri + + aso rexr rexw rexx rexb + /sse=66 0f 3a 63 + V W Ib + sse4.2 avx + + + + + pcmpistrm + + aso rexr rexw rexx rexb + /sse=66 0f 3a 62 + V W Ib + sse4.2 avx + + + + + movbe + + aso oso rexr rexw rexx rexb + 0f 38 f0 + Gv Mv + sse3 atom + + + aso oso rexr rexw rexx rexb + 0f 38 f1 + Mv Gv + sse3 atom + + + + + crc32 + + aso oso rexr rexw rexx rexb + /sse=f2 0f 38 f0 + Gy Eb + sse4.2 + + + aso oso rexr rexw rexx rexb + /sse=f2 0f 38 f1 + Gy Ev + sse4.2 + + + + + invalid + + + + vbroadcastss + + aso rexr rexx rexb vexl + /vex=66_0f38 18 /vexw=0 + V Md + avx + + + + + vbroadcastsd + + aso rexr rexx rexb vexl + /vex=66_0f38 19 /vexw=0 /vexl=1 + Vqq Mq + avx + + + + + vextractf128 + + aso rexr rexx rexb vexl + /vex=66_0f3a 19 /vexw=0 /vexl=1 + Wdq Vqq Ib + avx + + + + + vinsertf128 + + aso rexr rexx rexb vexl + /vex=66_0f3a 18 /vexw=0 /vexl=1 + Vqq Hqq Wdq Ib + avx + + + + + vmaskmovps + + aso rexr rexx rexb vexl + /vex=66_0f38 2c /vexw=0 + V H M + avx + + + aso rexr rexx rexb vexl + /vex=66_0f38 2e /vexw=0 + M H V + avx + + + + + vmaskmovpd + + aso rexr rexx rexb vexl + /vex=66_0f38 2d /vexw=0 + V H M + avx + + + aso rexr rexx rexb vexl + /vex=66_0f38 2f /vexw=0 + M H V + avx + + + + + vpermilpd + + aso rexr rexx rexb vexl + /vex=66_0f38 0d /vexw=0 + Vx Hx Wx + avx + + + aso rexr rexx rexb vexl + /vex=66_0f3a 05 /vexw=0 + V W Ib + avx + + + + + vpermilps + + aso rexr rexx rexb vexl + /vex=66_0f38 0c /vexw=0 + Vx Hx Wx + avx + + + aso rexr rexx rexb vexl + /vex=66_0f3a 04 /vexw=0 + Vx Wx Ib + avx + + + + + vperm2f128 + + aso rexr rexx rexb vexl + /vex=66_0f3a 06 /vexw=0 /vexl=1 + Vqq Hqq Wqq Ib + avx + + + + + vtestps + + aso rexr rexx rexb vexl + /vex=66_0f38 0e /vexw=0 + Vx Wx + avx + + + + + vtestpd + + aso rexr rexx rexb vexl + /vex=66_0f38 0f /vexw=0 + Vx Wx + avx + + + + + vzeroupper + + /vex=0f 77 /vexl=0 + avx + + + + + vzeroall + + /vex=0f 77 /vexl=1 + avx + + + + + vblendvpd + + aso rexr rexx rexb vexl + /vex=66_0f3a 4b /vexw=0 + Vx Hx Wx Lx + avx + + + + + vblendvps + + aso rexr rexx rexb vexl + /vex=66_0f3a 4a /vexw=0 + Vx Hx Wx Lx + avx + + + + + vmovsd + + aso rexr rexx rexb + /vex=f2_0f 10 /mod=11 + V H U + avx + + + aso rexr rexx rexb + /vex=f2_0f 10 /mod=!11 + V Mq + avx + + + aso rexr rexx rexb + /vex=f2_0f 11 /mod=11 + U H V + avx + + + aso rexr rexx rexb + /vex=f2_0f 11 /mod=!11 + Mq V + avx + + + + + vmovss + + aso rexr rexx rexb + /vex=f3_0f 10 /mod=11 + V H U + avx + + + aso rexr rexx rexb + /vex=f3_0f 10 /mod=!11 + V Md + avx + + + aso rexr rexx rexb + /vex=f3_0f 11 /mod=11 + U H V + avx + + + aso rexr rexx rexb + /vex=f3_0f 11 /mod=!11 + Md V + avx + + + + + vpblendvb + + aso rexr rexx rexb + /vex=66_0f3a 4c /vexw=0 + V H W L + avx + + + + + vpsllw + + aso rexr rexx rexb + /vex=66_0f f1 /vexl=0 + V H W + avx + + + aso rexr rexx rexb + /vex=66_0f 71 /reg=6 /vexl=0 + H V W + avx + + + + + vpslld + + aso rexr rexx rexb + /vex=66_0f f2 /vexl=0 + V H W + avx + + + aso rexr rexx rexb + /vex=66_0f 72 /reg=6 /vexl=0 + H V W + avx + + + + + vpsllq + + aso rexr rexx rexb + /vex=66_0f f3 /vexl=0 + V H W + avx + + + aso rexr rexx rexb + /vex=66_0f 73 /reg=6 /vexl=0 + H V W + avx + + + + diff --git a/udis86/docs/x86/optable.xsl b/udis86/docs/x86/optable.xsl new file mode 100644 index 0000000..930730a --- /dev/null +++ b/udis86/docs/x86/optable.xsl @@ -0,0 +1,73 @@ + + + + + + x86 opcode table + + + +

x86/optable.xml

+

+ udis86.sourceforge.net

+ + + + + + + + + + + + + +
MnemonicOpcodesVendor
+ + + + + + ; + ; + +
+
+
+ + +
+
+
+ +

+ Copyright (c) 2008, Vivek Thampi +

+ + + +
+
diff --git a/udis86/libudis86/Makefile.am b/udis86/libudis86/Makefile.am index 5cce407..c61cf9d 100644 --- a/udis86/libudis86/Makefile.am +++ b/udis86/libudis86/Makefile.am @@ -1,27 +1,51 @@ -noinst_LTLIBRARIES = libudis86.la +# +# -- udis86/libudis86 +# -#include_ladir = ${includedir} -#libudis86_ladir = ${includedir}/libudis86 +PYTHON = @PYTHON@ +OPTABLE = @top_srcdir@/docs/x86/optable.xml -libudis86_la_SOURCES = itab.c \ - input.c \ - decode.c \ - syn.c \ - syn-intel.c \ - syn-att.c \ - udis86.c \ - input.h \ - syn.h \ - decode.h \ - extern.h \ - types.h \ - itab.h \ - opgen.py +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libudis86.la + +libudis86_la_SOURCES = \ + itab.c \ + decode.c \ + syn.c \ + syn-intel.c \ + syn-att.c \ + udis86.c \ + udint.h \ + syn.h \ + decode.h + +include_ladir = ${includedir}/libudis86 +include_la_HEADERS = \ + types.h \ + extern.h \ + itab.h +BUILT_SOURCES = \ + itab.c \ + itab.h -itab.c itab.h: ../docs/x86optable.xml opgen.py - python ./opgen.py +# +# DLLs may not contain undefined symbol references. +# We have the linker check this explicitly. +# +if TARGET_WINDOWS +libudis86_la_LDFLAGS = -no-undefined -version-info 0:0:0 +endif -# generate the generated sources prior to the compilation -BUILT_SOURCES = itab.c itab.h +itab.c itab.h: $(OPTABLE) \ + $(top_srcdir)/scripts/ud_itab.py \ + $(top_srcdir)/scripts/ud_opcode.py + $(PYTHON) $(top_srcdir)/scripts/ud_itab.py $(OPTABLE) $(srcdir) + + +clean-local: + rm -rf $(BUILT_SOURCES) + +maintainer-clean-local: diff --git a/udis86/libudis86/decode.c b/udis86/libudis86/decode.c index 70fa9ad..036b9ed 100644 --- a/udis86/libudis86/decode.c +++ b/udis86/libudis86/decode.c @@ -1,386 +1,373 @@ -/* ----------------------------------------------------------------------------- - * decode.c - * - * Copyright (c) 2005, 2006, Vivek Mohan - * All rights reserved. See LICENSE - * ----------------------------------------------------------------------------- +/* udis86 - libudis86/decode.c + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include -#include - +#include "udint.h" #include "types.h" -#include "itab.h" -#include "input.h" +#include "extern.h" #include "decode.h" +#ifndef __UD_STANDALONE__ +# include +#endif /* __UD_STANDALONE__ */ + /* The max number of prefixes to an instruction */ #define MAX_PREFIXES 15 -static struct ud_itab_entry ie_invalid = { UD_Iinvalid, O_NONE, O_NONE, O_NONE, P_none }; -static struct ud_itab_entry ie_pause = { UD_Ipause, O_NONE, O_NONE, O_NONE, P_none }; -static struct ud_itab_entry ie_nop = { UD_Inop, O_NONE, O_NONE, O_NONE, P_none }; +/* rex prefix bits */ +#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) +#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) +#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) +#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) +#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ + ( P_REXR(n) << 2 ) | \ + ( P_REXX(n) << 1 ) | \ + ( P_REXB(n) << 0 ) ) +/* scable-index-base bits */ +#define SIB_S(b) ( ( b ) >> 6 ) +#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) +#define SIB_B(b) ( ( b ) & 7 ) -/* Looks up mnemonic code in the mnemonic string table - * Returns NULL if the mnemonic code is invalid +/* modrm bits */ +#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) +#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) +#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) +#define MODRM_RM(b) ( ( b ) & 7 ) + +static int decode_ext(struct ud *u, uint16_t ptr); +static int decode_opcode(struct ud *u); + +enum reg_class { /* register classes */ + REGCLASS_GPR, + REGCLASS_MMX, + REGCLASS_CR, + REGCLASS_DB, + REGCLASS_SEG, + REGCLASS_XMM +}; + + /* + * inp_start + * Should be called before each de-code operation. */ -const char * ud_lookup_mnemonic( enum ud_mnemonic_code c ) +static void +inp_start(struct ud *u) { - if ( c < UD_Id3vil ) - return ud_mnemonics_str[ c ]; - return NULL; + u->inp_ctr = 0; } - -/* Extracts instruction prefixes. - */ -static int get_prefixes( struct ud* u ) +static uint8_t +inp_peek(struct ud *u) { - unsigned int have_pfx = 1; - unsigned int i; - uint8_t curr; - - /* if in error state, bail out */ - if ( u->error ) - return -1; - - /* keep going as long as there are prefixes available */ - for ( i = 0; have_pfx ; ++i ) { - - /* Get next byte. */ - inp_next(u); - if ( u->error ) - return -1; - curr = inp_curr( u ); - - /* rex prefixes in 64bit mode */ - if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) { - u->pfx_rex = curr; - } else { - switch ( curr ) - { - case 0x2E : - u->pfx_seg = UD_R_CS; - u->pfx_rex = 0; - break; - case 0x36 : - u->pfx_seg = UD_R_SS; - u->pfx_rex = 0; - break; - case 0x3E : - u->pfx_seg = UD_R_DS; - u->pfx_rex = 0; - break; - case 0x26 : - u->pfx_seg = UD_R_ES; - u->pfx_rex = 0; - break; - case 0x64 : - u->pfx_seg = UD_R_FS; - u->pfx_rex = 0; - break; - case 0x65 : - u->pfx_seg = UD_R_GS; - u->pfx_rex = 0; - break; - case 0x67 : /* adress-size override prefix */ - u->pfx_adr = 0x67; - u->pfx_rex = 0; - break; - case 0xF0 : - u->pfx_lock = 0xF0; - u->pfx_rex = 0; - break; - case 0x66: - /* the 0x66 sse prefix is only effective if no other sse prefix - * has already been specified. - */ - if ( !u->pfx_insn ) u->pfx_insn = 0x66; - u->pfx_opr = 0x66; - u->pfx_rex = 0; - break; - case 0xF2: - u->pfx_insn = 0xF2; - u->pfx_repne = 0xF2; - u->pfx_rex = 0; - break; - case 0xF3: - u->pfx_insn = 0xF3; - u->pfx_rep = 0xF3; - u->pfx_repe = 0xF3; - u->pfx_rex = 0; - break; - default : - /* No more prefixes */ - have_pfx = 0; - break; - } - } - - /* check if we reached max instruction length */ - if ( i + 1 == MAX_INSN_LENGTH ) { - u->error = 1; - break; - } - } - - /* return status */ - if ( u->error ) - return -1; - - /* rewind back one byte in stream, since the above loop - * stops with a non-prefix byte. - */ - inp_back(u); - - /* speculatively determine the effective operand mode, - * based on the prefixes and the current disassembly - * mode. This may be inaccurate, but useful for mode - * dependent decoding. - */ - if ( u->dis_mode == 64 ) { - u->opr_mode = REX_W( u->pfx_rex ) ? 64 : ( ( u->pfx_opr ) ? 16 : 32 ) ; - u->adr_mode = ( u->pfx_adr ) ? 32 : 64; - } else if ( u->dis_mode == 32 ) { - u->opr_mode = ( u->pfx_opr ) ? 16 : 32; - u->adr_mode = ( u->pfx_adr ) ? 16 : 32; - } else if ( u->dis_mode == 16 ) { - u->opr_mode = ( u->pfx_opr ) ? 32 : 16; - u->adr_mode = ( u->pfx_adr ) ? 32 : 16; - } - - return 0; -} - - -/* Searches the instruction tables for the right entry. - */ -static int search_itab( struct ud * u ) -{ - struct ud_itab_entry * e = NULL; - enum ud_itab_index table; - uint8_t peek; - uint8_t did_peek = 0; - uint8_t curr; - uint8_t index; - - /* if in state of error, return */ - if ( u->error ) - return -1; - - /* get first byte of opcode. */ - inp_next(u); - if ( u->error ) - return -1; - curr = inp_curr(u); - - /* resolve xchg, nop, pause crazyness */ - if ( 0x90 == curr ) { - if ( !( u->dis_mode == 64 && REX_B( u->pfx_rex ) ) ) { - if ( u->pfx_rep ) { - u->pfx_rep = 0; - e = & ie_pause; - } else { - e = & ie_nop; - } - goto found_entry; - } - } - - /* get top-level table */ - if ( 0x0F == curr ) { - table = ITAB__0F; - curr = inp_next(u); - if ( u->error ) - return -1; - - /* 2byte opcodes can be modified by 0x66, F3, and F2 prefixes */ - if ( 0x66 == u->pfx_insn ) { - if ( ud_itab_list[ ITAB__PFX_SSE66__0F ][ curr ].mnemonic != UD_Iinvalid ) { - table = ITAB__PFX_SSE66__0F; - u->pfx_opr = 0; - } - } else if ( 0xF2 == u->pfx_insn ) { - if ( ud_itab_list[ ITAB__PFX_SSEF2__0F ][ curr ].mnemonic != UD_Iinvalid ) { - table = ITAB__PFX_SSEF2__0F; - u->pfx_repne = 0; - } - } else if ( 0xF3 == u->pfx_insn ) { - if ( ud_itab_list[ ITAB__PFX_SSEF3__0F ][ curr ].mnemonic != UD_Iinvalid ) { - table = ITAB__PFX_SSEF3__0F; - u->pfx_repe = 0; - u->pfx_rep = 0; - } - } - /* pick an instruction from the 1byte table */ + if (u->inp_end == 0) { + if (u->inp_buf != NULL) { + if (u->inp_buf_index < u->inp_buf_size) { + return u->inp_buf[u->inp_buf_index]; + } + } else if (u->inp_peek != UD_EOI) { + return u->inp_peek; } else { - table = ITAB__1BYTE; + int c; + if ((c = u->inp_hook(u)) != UD_EOI) { + u->inp_peek = c; + return u->inp_peek; + } } - - index = curr; - -search: - - e = & ud_itab_list[ table ][ index ]; - - /* if mnemonic constant is a standard instruction constant - * our search is over. - */ - - if ( e->mnemonic < UD_Id3vil ) { - if ( e->mnemonic == UD_Iinvalid ) { - if ( did_peek ) { - inp_next( u ); if ( u->error ) return -1; - } - goto found_entry; - } - goto found_entry; + } + u->inp_end = 1; + UDERR(u, "byte expected, eoi received\n"); + return 0; +} + +static uint8_t +inp_next(struct ud *u) +{ + if (u->inp_end == 0) { + if (u->inp_buf != NULL) { + if (u->inp_buf_index < u->inp_buf_size) { + u->inp_ctr++; + return (u->inp_curr = u->inp_buf[u->inp_buf_index++]); + } + } else { + int c = u->inp_peek; + if (c != UD_EOI || (c = u->inp_hook(u)) != UD_EOI) { + u->inp_peek = UD_EOI; + u->inp_curr = c; + u->inp_sess[u->inp_ctr++] = u->inp_curr; + return u->inp_curr; + } } + } + u->inp_end = 1; + UDERR(u, "byte expected, eoi received\n"); + return 0; +} - table = e->prefix; - - switch ( e->mnemonic ) - { - case UD_Igrp_reg: - peek = inp_peek( u ); - did_peek = 1; - index = MODRM_REG( peek ); - break; - - case UD_Igrp_mod: - peek = inp_peek( u ); - did_peek = 1; - index = MODRM_MOD( peek ); - if ( index == 3 ) - index = ITAB__MOD_INDX__11; - else - index = ITAB__MOD_INDX__NOT_11; - break; - - case UD_Igrp_rm: - curr = inp_next( u ); - did_peek = 0; - if ( u->error ) - return -1; - index = MODRM_RM( curr ); - break; - - case UD_Igrp_x87: - curr = inp_next( u ); - did_peek = 0; - if ( u->error ) - return -1; - index = curr - 0xC0; - break; - - case UD_Igrp_osize: - if ( u->opr_mode == 64 ) - index = ITAB__MODE_INDX__64; - else if ( u->opr_mode == 32 ) - index = ITAB__MODE_INDX__32; - else - index = ITAB__MODE_INDX__16; - break; - - case UD_Igrp_asize: - if ( u->adr_mode == 64 ) - index = ITAB__MODE_INDX__64; - else if ( u->adr_mode == 32 ) - index = ITAB__MODE_INDX__32; - else - index = ITAB__MODE_INDX__16; - break; - - case UD_Igrp_mode: - if ( u->dis_mode == 64 ) - index = ITAB__MODE_INDX__64; - else if ( u->dis_mode == 32 ) - index = ITAB__MODE_INDX__32; - else - index = ITAB__MODE_INDX__16; - break; - - case UD_Igrp_vendor: - if ( u->vendor == UD_VENDOR_INTEL ) - index = ITAB__VENDOR_INDX__INTEL; - else if ( u->vendor == UD_VENDOR_AMD ) - index = ITAB__VENDOR_INDX__AMD; - else - assert( !"unrecognized vendor id" ); - break; - - case UD_Id3vil: - assert( !"invalid instruction mnemonic constant Id3vil" ); - break; - - default: - assert( !"invalid instruction mnemonic constant" ); - break; - } - - goto search; - -found_entry: - - u->itab_entry = e; - u->mnemonic = u->itab_entry->mnemonic; - - return 0; +static uint8_t +inp_curr(struct ud *u) +{ + return u->inp_curr; } -static unsigned int resolve_operand_size( const struct ud * u, unsigned int s ) +/* + * inp_uint8 + * int_uint16 + * int_uint32 + * int_uint64 + * Load little-endian values from input + */ +static uint8_t +inp_uint8(struct ud* u) { - switch ( s ) - { - case SZ_V: - return ( u->opr_mode ); - case SZ_Z: - return ( u->opr_mode == 16 ) ? 16 : 32; - case SZ_P: - return ( u->opr_mode == 16 ) ? SZ_WP : SZ_DP; - case SZ_MDQ: - return ( u->opr_mode == 16 ) ? 32 : u->opr_mode; - case SZ_RDQ: - return ( u->dis_mode == 64 ) ? 64 : 32; - default: - return s; + return inp_next(u); +} + +static uint16_t +inp_uint16(struct ud* u) +{ + uint16_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + return ret | (r << 8); +} + +static uint32_t +inp_uint32(struct ud* u) +{ + uint32_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + ret = ret | (r << 8); + r = inp_next(u); + ret = ret | (r << 16); + r = inp_next(u); + return ret | (r << 24); +} + +static uint64_t +inp_uint64(struct ud* u) +{ + uint64_t r, ret; + + ret = inp_next(u); + r = inp_next(u); + ret = ret | (r << 8); + r = inp_next(u); + ret = ret | (r << 16); + r = inp_next(u); + ret = ret | (r << 24); + r = inp_next(u); + ret = ret | (r << 32); + r = inp_next(u); + ret = ret | (r << 40); + r = inp_next(u); + ret = ret | (r << 48); + r = inp_next(u); + return ret | (r << 56); +} + + +static UD_INLINE int +eff_opr_mode(int dis_mode, int rex_w, int pfx_opr) +{ + if (dis_mode == 64) { + return rex_w ? 64 : (pfx_opr ? 16 : 32); + } else if (dis_mode == 32) { + return pfx_opr ? 16 : 32; + } else { + UD_ASSERT(dis_mode == 16); + return pfx_opr ? 32 : 16; + } +} + + +static UD_INLINE int +eff_adr_mode(int dis_mode, int pfx_adr) +{ + if (dis_mode == 64) { + return pfx_adr ? 32 : 64; + } else if (dis_mode == 32) { + return pfx_adr ? 16 : 32; + } else { + UD_ASSERT(dis_mode == 16); + return pfx_adr ? 32 : 16; + } +} + + +/* + * decode_prefixes + * + * Extracts instruction prefixes. + */ +static int +decode_prefixes(struct ud *u) +{ + int done = 0; + uint8_t curr = 0, last = 0; + UD_RETURN_ON_ERROR(u); + + do { + last = curr; + curr = inp_next(u); + UD_RETURN_ON_ERROR(u); + if (u->inp_ctr == MAX_INSN_LENGTH) { + UD_RETURN_WITH_ERROR(u, "max instruction length"); } + + switch (curr) + { + case 0x2E: + u->pfx_seg = UD_R_CS; + break; + case 0x36: + u->pfx_seg = UD_R_SS; + break; + case 0x3E: + u->pfx_seg = UD_R_DS; + break; + case 0x26: + u->pfx_seg = UD_R_ES; + break; + case 0x64: + u->pfx_seg = UD_R_FS; + break; + case 0x65: + u->pfx_seg = UD_R_GS; + break; + case 0x67: /* adress-size override prefix */ + u->pfx_adr = 0x67; + break; + case 0xF0: + u->pfx_lock = 0xF0; + break; + case 0x66: + u->pfx_opr = 0x66; + break; + case 0xF2: + u->pfx_str = 0xf2; + break; + case 0xF3: + u->pfx_str = 0xf3; + break; + default: + /* consume if rex */ + done = (u->dis_mode == 64 && (curr & 0xF0) == 0x40) ? 0 : 1; + break; + } + } while (!done); + /* rex prefixes in 64bit mode, must be the last prefix */ + if (u->dis_mode == 64 && (last & 0xF0) == 0x40) { + u->pfx_rex = last; + } + return 0; +} + + +/* + * vex_l, vex_w + * Return the vex.L and vex.W bits + */ +static UD_INLINE uint8_t +vex_l(const struct ud *u) +{ + UD_ASSERT(u->vex_op != 0); + return ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 2) & 1; +} + +static UD_INLINE uint8_t +vex_w(const struct ud *u) +{ + UD_ASSERT(u->vex_op != 0); + return u->vex_op == 0xc4 ? ((u->vex_b2 >> 7) & 1) : 0; +} + + +static UD_INLINE uint8_t +modrm(struct ud * u) +{ + if ( !u->have_modrm ) { + u->modrm = inp_next( u ); + u->modrm_offset = (uint8_t) (u->inp_ctr - 1); + u->have_modrm = 1; + } + return u->modrm; +} + + +static unsigned int +resolve_operand_size(const struct ud* u, ud_operand_size_t osize) +{ + switch (osize) { + case SZ_V: + return u->opr_mode; + case SZ_Z: + return u->opr_mode == 16 ? 16 : 32; + case SZ_Y: + return u->opr_mode == 16 ? 32 : u->opr_mode; + case SZ_RDQ: + return u->dis_mode == 64 ? 64 : 32; + case SZ_X: + UD_ASSERT(u->vex_op != 0); + return (P_VEXL(u->itab_entry->prefix) && vex_l(u)) ? SZ_QQ : SZ_DQ; + default: + return osize; + } } static int resolve_mnemonic( struct ud* u ) { - /* far/near flags */ - u->br_far = 0; - u->br_near = 0; - /* readjust operand sizes for call/jmp instrcutions */ - if ( u->mnemonic == UD_Icall || u->mnemonic == UD_Ijmp ) { - /* WP: 16bit pointer */ - if ( u->operand[ 0 ].size == SZ_WP ) { - u->operand[ 0 ].size = 16; - u->br_far = 1; - u->br_near= 0; - /* DP: 32bit pointer */ - } else if ( u->operand[ 0 ].size == SZ_DP ) { - u->operand[ 0 ].size = 32; - u->br_far = 1; - u->br_near= 0; - } else { - u->br_far = 0; - u->br_near= 1; - } /* resolve 3dnow weirdness. */ - } else if ( u->mnemonic == UD_I3dnow ) { - u->mnemonic = ud_itab_list[ ITAB__3DNOW ][ inp_curr( u ) ].mnemonic; + if ( u->mnemonic == UD_I3dnow ) { + u->mnemonic = ud_itab[ u->le->table[ inp_curr( u ) ] ].mnemonic; } /* SWAPGS is only valid in 64bits mode */ if ( u->mnemonic == UD_Iswapgs && u->dis_mode != 64 ) { - u->error = 1; + UDERR(u, "swapgs invalid in 64bits mode\n"); return -1; } + if (u->mnemonic == UD_Ixchg) { + if ((u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_AX && + u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_AX) || + (u->operand[0].type == UD_OP_REG && u->operand[0].base == UD_R_EAX && + u->operand[1].type == UD_OP_REG && u->operand[1].base == UD_R_EAX)) { + u->operand[0].type = UD_NONE; + u->operand[1].type = UD_NONE; + u->mnemonic = UD_Inop; + } + } + + if (u->mnemonic == UD_Inop && u->pfx_repe) { + u->pfx_repe = 0; + u->mnemonic = UD_Ipause; + } return 0; } @@ -414,15 +401,11 @@ decode_a(struct ud* u, struct ud_operand *op) static enum ud_type decode_gpr(register struct ud* u, unsigned int s, unsigned char rm) { - s = resolve_operand_size(u, s); - switch (s) { case 64: return UD_R_RAX + rm; - case SZ_DP: case 32: return UD_R_EAX + rm; - case SZ_WP: case 16: return UD_R_AX + rm; case 8: @@ -431,621 +414,515 @@ decode_gpr(register struct ud* u, unsigned int s, unsigned char rm) return UD_R_SPL + (rm-4); return UD_R_AL + rm; } else return UD_R_AL + rm; + case 0: + /* invalid size in case of a decode error */ + UD_ASSERT(u->error); + return UD_NONE; default: - return 0; + UD_ASSERT(!"invalid operand size"); + return UD_NONE; } } -/* ----------------------------------------------------------------------------- - * resolve_gpr64() - 64bit General Purpose Register-Selection. - * ----------------------------------------------------------------------------- - */ -static enum ud_type -resolve_gpr64(struct ud* u, enum ud_operand_code gpr_op) -{ - if (gpr_op >= OP_rAXr8 && gpr_op <= OP_rDIr15) - gpr_op = (gpr_op - OP_rAXr8) | (REX_B(u->pfx_rex) << 3); - else gpr_op = (gpr_op - OP_rAX); - - if (u->opr_mode == 16) - return gpr_op + UD_R_AX; - if (u->dis_mode == 32 || - (u->opr_mode == 32 && ! (REX_W(u->pfx_rex) || u->default64))) { - return gpr_op + UD_R_EAX; - } - - return gpr_op + UD_R_RAX; -} - -/* ----------------------------------------------------------------------------- - * resolve_gpr32 () - 32bit General Purpose Register-Selection. - * ----------------------------------------------------------------------------- - */ -static enum ud_type -resolve_gpr32(struct ud* u, enum ud_operand_code gpr_op) -{ - gpr_op = gpr_op - OP_eAX; - - if (u->opr_mode == 16) - return gpr_op + UD_R_AX; - - return gpr_op + UD_R_EAX; -} - -/* ----------------------------------------------------------------------------- - * resolve_reg() - Resolves the register type - * ----------------------------------------------------------------------------- - */ -static enum ud_type -resolve_reg(struct ud* u, unsigned int type, unsigned char i) +static void +decode_reg(struct ud *u, + struct ud_operand *opr, + int type, + int num, + int size) { + int reg; + size = resolve_operand_size(u, size); switch (type) { - case T_MMX : return UD_R_MM0 + (i & 7); - case T_XMM : return UD_R_XMM0 + i; - case T_CRG : return UD_R_CR0 + i; - case T_DBG : return UD_R_DR0 + i; - case T_SEG : return UD_R_ES + (i & 7); - case T_NONE: - default: return UD_NONE; + case REGCLASS_GPR : reg = decode_gpr(u, size, num); break; + case REGCLASS_MMX : reg = UD_R_MM0 + (num & 7); break; + case REGCLASS_XMM : + reg = num + (size == SZ_QQ ? UD_R_YMM0 : UD_R_XMM0); + break; + case REGCLASS_CR : reg = UD_R_CR0 + num; break; + case REGCLASS_DB : reg = UD_R_DR0 + num; break; + case REGCLASS_SEG : { + /* + * Only 6 segment registers, anything else is an error. + */ + if ((num & 7) > 5) { + UDERR(u, "invalid segment register value\n"); + return; + } else { + reg = UD_R_ES + (num & 7); + } + break; + } + default: + UD_ASSERT(!"invalid register type"); + return; } + opr->type = UD_OP_REG; + opr->base = reg; + opr->size = size; } -/* ----------------------------------------------------------------------------- - * decode_imm() - Decodes Immediate values. - * ----------------------------------------------------------------------------- + +/* + * decode_imm + * + * Decode Immediate values. */ static void -decode_imm(struct ud* u, unsigned int s, struct ud_operand *op) +decode_imm(struct ud* u, unsigned int size, struct ud_operand *op) { - op->size = resolve_operand_size(u, s); + op->size = resolve_operand_size(u, size); op->type = UD_OP_IMM; switch (op->size) { - case 8: op->lval.sbyte = inp_uint8(u); break; - case 16: op->lval.uword = inp_uint16(u); break; - case 32: op->lval.udword = inp_uint32(u); break; - case 64: op->lval.uqword = inp_uint64(u); break; - default: return; + case 8: op->lval.sbyte = inp_uint8(u); break; + case 16: op->lval.uword = inp_uint16(u); break; + case 32: op->lval.udword = inp_uint32(u); break; + case 64: op->lval.uqword = inp_uint64(u); break; + default: return; } } -/* ----------------------------------------------------------------------------- - * decode_modrm() - Decodes ModRM Byte - * ----------------------------------------------------------------------------- + +/* + * decode_mem_disp + * + * Decode mem address displacement. */ static void -decode_modrm(struct ud* u, struct ud_operand *op, unsigned int s, - unsigned char rm_type, struct ud_operand *opreg, - unsigned char reg_size, unsigned char reg_type) +decode_mem_disp(struct ud* u, unsigned int size, struct ud_operand *op) { - unsigned char mod, rm, reg; + switch (size) { + case 8: + op->offset = 8; + op->lval.ubyte = inp_uint8(u); + break; + case 16: + op->offset = 16; + op->lval.uword = inp_uint16(u); + break; + case 32: + op->offset = 32; + op->lval.udword = inp_uint32(u); + break; + case 64: + op->offset = 64; + op->lval.uqword = inp_uint64(u); + break; + default: + return; + } +} - inp_next(u); + +/* + * decode_modrm_reg + * + * Decodes reg field of mod/rm byte + * + */ +static UD_INLINE void +decode_modrm_reg(struct ud *u, + struct ud_operand *operand, + unsigned int type, + unsigned int size) +{ + uint8_t reg = (REX_R(u->_rex) << 3) | MODRM_REG(modrm(u)); + decode_reg(u, operand, type, reg, size); +} + + +/* + * decode_modrm_rm + * + * Decodes rm field of mod/rm byte + * + */ +static void +decode_modrm_rm(struct ud *u, + struct ud_operand *op, + unsigned char type, /* register type */ + unsigned int size) /* operand size */ + +{ + size_t offset = 0; + unsigned char mod, rm; /* get mod, r/m and reg fields */ - mod = MODRM_MOD(inp_curr(u)); - rm = (REX_B(u->pfx_rex) << 3) | MODRM_RM(inp_curr(u)); - reg = (REX_R(u->pfx_rex) << 3) | MODRM_REG(inp_curr(u)); + mod = MODRM_MOD(modrm(u)); + rm = (REX_B(u->_rex) << 3) | MODRM_RM(modrm(u)); - op->size = resolve_operand_size(u, s); - - /* if mod is 11b, then the UD_R_m specifies a gpr/mmx/sse/control/debug */ + /* + * If mod is 11b, then the modrm.rm specifies a register. + * + */ if (mod == 3) { - op->type = UD_OP_REG; - if (rm_type == T_GPR) - op->base = decode_gpr(u, op->size, rm); - else op->base = resolve_reg(u, rm_type, (REX_B(u->pfx_rex) << 3) | (rm&7)); - } - /* else its memory addressing */ - else { - op->type = UD_OP_MEM; - - /* 64bit addressing */ - if (u->adr_mode == 64) { - - op->base = UD_R_RAX + rm; - - /* get offset type */ - if (mod == 1) - op->offset = 8; - else if (mod == 2) - op->offset = 32; - else if (mod == 0 && (rm & 7) == 5) { - op->base = UD_R_RIP; - op->offset = 32; - } else op->offset = 0; - - /* Scale-Index-Base (SIB) */ - if ((rm & 7) == 4) { - inp_next(u); - - op->scale = (1 << SIB_S(inp_curr(u))) & ~1; - op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); - op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); - - /* special conditions for base reference */ - if (op->index == UD_R_RSP) { - op->index = UD_NONE; - op->scale = UD_NONE; - } - - if (op->base == UD_R_RBP || op->base == UD_R_R13) { - if (mod == 0) - op->base = UD_NONE; - if (mod == 1) - op->offset = 8; - else op->offset = 32; - } - } - } - - /* 32-Bit addressing mode */ - else if (u->adr_mode == 32) { - - /* get base */ - op->base = UD_R_EAX + rm; - - /* get offset type */ - if (mod == 1) - op->offset = 8; - else if (mod == 2) - op->offset = 32; - else if (mod == 0 && rm == 5) { - op->base = UD_NONE; - op->offset = 32; - } else op->offset = 0; - - /* Scale-Index-Base (SIB) */ - if ((rm & 7) == 4) { - inp_next(u); - - op->scale = (1 << SIB_S(inp_curr(u))) & ~1; - op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); - op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); - - if (op->index == UD_R_ESP) { - op->index = UD_NONE; - op->scale = UD_NONE; - } - - /* special condition for base reference */ - if (op->base == UD_R_EBP) { - if (mod == 0) - op->base = UD_NONE; - if (mod == 1) - op->offset = 8; - else op->offset = 32; - } - } - } - - /* 16bit addressing mode */ - else { - switch (rm) { - case 0: op->base = UD_R_BX; op->index = UD_R_SI; break; - case 1: op->base = UD_R_BX; op->index = UD_R_DI; break; - case 2: op->base = UD_R_BP; op->index = UD_R_SI; break; - case 3: op->base = UD_R_BP; op->index = UD_R_DI; break; - case 4: op->base = UD_R_SI; break; - case 5: op->base = UD_R_DI; break; - case 6: op->base = UD_R_BP; break; - case 7: op->base = UD_R_BX; break; - } - - if (mod == 0 && rm == 6) { - op->offset= 16; - op->base = UD_NONE; - } - else if (mod == 1) - op->offset = 8; - else if (mod == 2) - op->offset = 16; - } - } - - /* extract offset, if any */ - switch(op->offset) { - case 8 : op->lval.ubyte = inp_uint8(u); break; - case 16: op->lval.uword = inp_uint16(u); break; - case 32: op->lval.udword = inp_uint32(u); break; - case 64: op->lval.uqword = inp_uint64(u); break; - default: break; + decode_reg(u, op, type, rm, size); + return; } - /* resolve register encoded in reg field */ - if (opreg) { - opreg->type = UD_OP_REG; - opreg->size = resolve_operand_size(u, reg_size); - if (reg_type == T_GPR) - opreg->base = decode_gpr(u, opreg->size, reg); - else opreg->base = resolve_reg(u, reg_type, reg); - } -} - -/* ----------------------------------------------------------------------------- - * decode_o() - Decodes offset - * ----------------------------------------------------------------------------- - */ -static void -decode_o(struct ud* u, unsigned int s, struct ud_operand *op) -{ - switch (u->adr_mode) { - case 64: - op->offset = 64; - op->lval.uqword = inp_uint64(u); - break; - case 32: - op->offset = 32; - op->lval.udword = inp_uint32(u); - break; - case 16: - op->offset = 16; - op->lval.uword = inp_uint16(u); - break; - default: - return; - } + /* + * !11b => Memory Address + */ op->type = UD_OP_MEM; - op->size = resolve_operand_size(u, s); -} + op->size = resolve_operand_size(u, size); -/* ----------------------------------------------------------------------------- - * disasm_operands() - Disassembles Operands. - * ----------------------------------------------------------------------------- - */ -static int disasm_operands(register struct ud* u) -{ + if (u->adr_mode == 64) { + op->base = UD_R_RAX + rm; + if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 32; + } else if (mod == 0 && (rm & 7) == 5) { + op->base = UD_R_RIP; + offset = 32; + } else { + offset = 0; + } + /* + * Scale-Index-Base (SIB) + */ + if ((rm & 7) == 4) { + inp_next(u); + + op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (REX_B(u->_rex) << 3)); + op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (REX_X(u->_rex) << 3)); + /* special conditions for base reference */ + if (op->index == UD_R_RSP) { + op->index = UD_NONE; + op->scale = UD_NONE; + } else { + op->scale = (1 << SIB_S(inp_curr(u))) & ~1; + } - - /* mopXt = map entry, operand X, type; */ - enum ud_operand_code mop1t = u->itab_entry->operand1.type; - enum ud_operand_code mop2t = u->itab_entry->operand2.type; - enum ud_operand_code mop3t = u->itab_entry->operand3.type; - - /* mopXs = map entry, operand X, size */ - unsigned int mop1s = u->itab_entry->operand1.size; - unsigned int mop2s = u->itab_entry->operand2.size; - unsigned int mop3s = u->itab_entry->operand3.size; - - /* iop = instruction operand */ - register struct ud_operand* iop = u->operand; - - switch(mop1t) { - - case OP_A : - decode_a(u, &(iop[0])); - break; - - /* M[b] ... */ - case OP_M : - if (MODRM_MOD(inp_peek(u)) == 3) - u->error= 1; - /* E, G/P/V/I/CL/1/S */ - case OP_E : - if (mop2t == OP_G) { - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_GPR); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); - else if (mop3t == OP_CL) { - iop[2].type = UD_OP_REG; - iop[2].base = UD_R_CL; - iop[2].size = 8; - } + if (op->base == UD_R_RBP || op->base == UD_R_R13) { + if (mod == 0) { + op->base = UD_NONE; + } + if (mod == 1) { + offset = 8; + } else { + offset = 32; } - else if (mop2t == OP_P) - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_MMX); - else if (mop2t == OP_V) - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_XMM); - else if (mop2t == OP_S) - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_SEG); - else { - decode_modrm(u, &(iop[0]), mop1s, T_GPR, NULL, 0, T_NONE); - if (mop2t == OP_CL) { - iop[1].type = UD_OP_REG; - iop[1].base = UD_R_CL; - iop[1].size = 8; - } else if (mop2t == OP_I1) { - iop[1].type = UD_OP_CONST; - u->operand[1].lval.udword = 1; - } else if (mop2t == OP_I) { - decode_imm(u, mop2s, &(iop[1])); - } - } - break; - - /* G, E/PR[,I]/VR */ - case OP_G : - if (mop2t == OP_M) { - if (MODRM_MOD(inp_peek(u)) == 3) - u->error= 1; - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR); - } else if (mop2t == OP_E) { - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); - } else if (mop2t == OP_PR) { - decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_GPR); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); - } else if (mop2t == OP_VR) { - if (MODRM_MOD(inp_peek(u)) != 3) - u->error = 1; - decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR); - } else if (mop2t == OP_W) - decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR); - break; - - /* AL..BH, I/O/DX */ - case OP_AL : case OP_CL : case OP_DL : case OP_BL : - case OP_AH : case OP_CH : case OP_DH : case OP_BH : - - iop[0].type = UD_OP_REG; - iop[0].base = UD_R_AL + (mop1t - OP_AL); - iop[0].size = 8; - - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - else if (mop2t == OP_DX) { - iop[1].type = UD_OP_REG; - iop[1].base = UD_R_DX; - iop[1].size = 16; - } - else if (mop2t == OP_O) - decode_o(u, mop2s, &(iop[1])); - break; - - /* rAX[r8]..rDI[r15], I/rAX..rDI/O */ - case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 : - case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 : - case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX : - case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI : - - iop[0].type = UD_OP_REG; - iop[0].base = resolve_gpr64(u, mop1t); - - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - else if (mop2t >= OP_rAX && mop2t <= OP_rDI) { - iop[1].type = UD_OP_REG; - iop[1].base = resolve_gpr64(u, mop2t); - } - else if (mop2t == OP_O) { - decode_o(u, mop2s, &(iop[1])); - iop[0].size = resolve_operand_size(u, mop2s); - } - break; - - /* AL[r8b]..BH[r15b], I */ - case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b : - case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b : - { - ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL + - (REX_B(u->pfx_rex) << 3); - if (UD_R_AH <= gpr && u->pfx_rex) - gpr = gpr + 4; - iop[0].type = UD_OP_REG; - iop[0].base = gpr; - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - break; + } + } else { + op->scale = UD_NONE; + op->index = UD_NONE; + } + } else if (u->adr_mode == 32) { + op->base = UD_R_EAX + rm; + if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 32; + } else if (mod == 0 && rm == 5) { + op->base = UD_NONE; + offset = 32; + } else { + offset = 0; } - /* eAX..eDX, DX/I */ - case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX : - case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI : - iop[0].type = UD_OP_REG; - iop[0].base = resolve_gpr32(u, mop1t); - if (mop2t == OP_DX) { - iop[1].type = UD_OP_REG; - iop[1].base = UD_R_DX; - iop[1].size = 16; - } else if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - break; + /* Scale-Index-Base (SIB) */ + if ((rm & 7) == 4) { + inp_next(u); - /* ES..GS */ - case OP_ES : case OP_CS : case OP_DS : - case OP_SS : case OP_FS : case OP_GS : + op->scale = (1 << SIB_S(inp_curr(u))) & ~1; + op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (REX_X(u->pfx_rex) << 3)); + op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (REX_B(u->pfx_rex) << 3)); - /* in 64bits mode, only fs and gs are allowed */ - if (u->dis_mode == 64) - if (mop1t != OP_FS && mop1t != OP_GS) - u->error= 1; - iop[0].type = UD_OP_REG; - iop[0].base = (mop1t - OP_ES) + UD_R_ES; - iop[0].size = 16; + if (op->index == UD_R_ESP) { + op->index = UD_NONE; + op->scale = UD_NONE; + } - break; - - /* J */ - case OP_J : - decode_imm(u, mop1s, &(iop[0])); - iop[0].type = UD_OP_JIMM; - break ; - - /* PR, I */ - case OP_PR: - if (MODRM_MOD(inp_peek(u)) != 3) - u->error = 1; - decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE); - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - break; - - /* VR, I */ - case OP_VR: - if (MODRM_MOD(inp_peek(u)) != 3) - u->error = 1; - decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE); - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - break; - - /* P, Q[,I]/W/E[,I],VR */ - case OP_P : - if (mop2t == OP_Q) { - decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); - } else if (mop2t == OP_W) { - decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX); - } else if (mop2t == OP_VR) { - if (MODRM_MOD(inp_peek(u)) != 3) - u->error = 1; - decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX); - } else if (mop2t == OP_E) { - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); + /* special condition for base reference */ + if (op->base == UD_R_EBP) { + if (mod == 0) { + op->base = UD_NONE; + } + if (mod == 1) { + offset = 8; + } else { + offset = 32; } - break; - - /* R, C/D */ - case OP_R : - if (mop2t == OP_C) - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG); - else if (mop2t == OP_D) - decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG); - break; - - /* C, R */ - case OP_C : - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG); - break; - - /* D, R */ - case OP_D : - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG); - break; - - /* Q, P */ - case OP_Q : - decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX); - break; - - /* S, E */ - case OP_S : - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG); - break; - - /* W, V */ - case OP_W : - decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM); - break; - - /* V, W[,I]/Q/M/E */ - case OP_V : - if (mop2t == OP_W) { - /* special cases for movlps and movhps */ - if (MODRM_MOD(inp_peek(u)) == 3) { - if (u->mnemonic == UD_Imovlps) - u->mnemonic = UD_Imovhlps; - else - if (u->mnemonic == UD_Imovhps) - u->mnemonic = UD_Imovlhps; - } - decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM); - if (mop3t == OP_I) - decode_imm(u, mop3s, &(iop[2])); - } else if (mop2t == OP_Q) - decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM); - else if (mop2t == OP_M) { - if (MODRM_MOD(inp_peek(u)) == 3) - u->error= 1; - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM); - } else if (mop2t == OP_E) { - decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM); - } else if (mop2t == OP_PR) { - decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM); - } - break; - - /* DX, eAX/AL */ - case OP_DX : - iop[0].type = UD_OP_REG; - iop[0].base = UD_R_DX; - iop[0].size = 16; - - if (mop2t == OP_eAX) { - iop[1].type = UD_OP_REG; - iop[1].base = resolve_gpr32(u, mop2t); - } else if (mop2t == OP_AL) { - iop[1].type = UD_OP_REG; - iop[1].base = UD_R_AL; - iop[1].size = 8; - } - - break; - - /* I, I/AL/eAX */ - case OP_I : - decode_imm(u, mop1s, &(iop[0])); - if (mop2t == OP_I) - decode_imm(u, mop2s, &(iop[1])); - else if (mop2t == OP_AL) { - iop[1].type = UD_OP_REG; - iop[1].base = UD_R_AL; - iop[1].size = 16; - } else if (mop2t == OP_eAX) { - iop[1].type = UD_OP_REG; - iop[1].base = resolve_gpr32(u, mop2t); - } - break; - - /* O, AL/eAX */ - case OP_O : - decode_o(u, mop1s, &(iop[0])); - iop[1].type = UD_OP_REG; - iop[1].size = resolve_operand_size(u, mop1s); - if (mop2t == OP_AL) - iop[1].base = UD_R_AL; - else if (mop2t == OP_eAX) - iop[1].base = resolve_gpr32(u, mop2t); - else if (mop2t == OP_rAX) - iop[1].base = resolve_gpr64(u, mop2t); - break; - - /* 3 */ - case OP_I3 : - iop[0].type = UD_OP_CONST; - iop[0].lval.sbyte = 3; - break; - - /* ST(n), ST(n) */ - case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 : - case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 : - - iop[0].type = UD_OP_REG; - iop[0].base = (mop1t-OP_ST0) + UD_R_ST0; - iop[0].size = 0; - - if (mop2t >= OP_ST0 && mop2t <= OP_ST7) { - iop[1].type = UD_OP_REG; - iop[1].base = (mop2t-OP_ST0) + UD_R_ST0; - iop[1].size = 0; - } - break; - - /* AX */ - case OP_AX: - iop[0].type = UD_OP_REG; - iop[0].base = UD_R_AX; - iop[0].size = 16; - break; - - /* none */ - default : - iop[0].type = iop[1].type = iop[2].type = UD_NONE; + } + } else { + op->scale = UD_NONE; + op->index = UD_NONE; + } + } else { + const unsigned int bases[] = { UD_R_BX, UD_R_BX, UD_R_BP, UD_R_BP, + UD_R_SI, UD_R_DI, UD_R_BP, UD_R_BX }; + const unsigned int indices[] = { UD_R_SI, UD_R_DI, UD_R_SI, UD_R_DI, + UD_NONE, UD_NONE, UD_NONE, UD_NONE }; + op->base = bases[rm & 7]; + op->index = indices[rm & 7]; + op->scale = UD_NONE; + if (mod == 0 && rm == 6) { + offset = 16; + op->base = UD_NONE; + } else if (mod == 1) { + offset = 8; + } else if (mod == 2) { + offset = 16; + } } + if (offset) { + decode_mem_disp(u, offset, op); + } else { + op->offset = 0; + } +} + + +/* + * decode_moffset + * Decode offset-only memory operand + */ +static void +decode_moffset(struct ud *u, unsigned int size, struct ud_operand *opr) +{ + opr->type = UD_OP_MEM; + opr->base = UD_NONE; + opr->index = UD_NONE; + opr->scale = UD_NONE; + opr->size = resolve_operand_size(u, size); + decode_mem_disp(u, u->adr_mode, opr); +} + + +static void +decode_vex_vvvv(struct ud *u, struct ud_operand *opr, unsigned size) +{ + uint8_t vvvv; + UD_ASSERT(u->vex_op != 0); + vvvv = ((u->vex_op == 0xc4 ? u->vex_b2 : u->vex_b1) >> 3) & 0xf; + decode_reg(u, opr, REGCLASS_XMM, (0xf & ~vvvv), size); +} + + +/* + * decode_vex_immreg + * Decode source operand encoded in immediate byte [7:4] + */ +static int +decode_vex_immreg(struct ud *u, struct ud_operand *opr, unsigned size) +{ + uint8_t imm = inp_next(u); + uint8_t mask = u->dis_mode == 64 ? 0xf : 0x7; + UD_RETURN_ON_ERROR(u); + UD_ASSERT(u->vex_op != 0); + decode_reg(u, opr, REGCLASS_XMM, mask & (imm >> 4), size); return 0; } + +/* + * decode_operand + * + * Decodes a single operand. + * Returns the type of the operand (UD_NONE if none) + */ +static int +decode_operand(struct ud *u, + struct ud_operand *operand, + enum ud_operand_code type, + unsigned int size) +{ + operand->type = UD_NONE; + operand->_oprcode = type; + + switch (type) { + case OP_A : + decode_a(u, operand); + break; + case OP_MR: + decode_modrm_rm(u, operand, REGCLASS_GPR, + MODRM_MOD(modrm(u)) == 3 ? + Mx_reg_size(size) : Mx_mem_size(size)); + break; + case OP_F: + u->br_far = 1; + /* intended fall through */ + case OP_M: + if (MODRM_MOD(modrm(u)) == 3) { + UDERR(u, "expected modrm.mod != 3\n"); + } + /* intended fall through */ + case OP_E: + decode_modrm_rm(u, operand, REGCLASS_GPR, size); + break; + case OP_G: + decode_modrm_reg(u, operand, REGCLASS_GPR, size); + break; + case OP_sI: + case OP_I: + decode_imm(u, size, operand); + break; + case OP_I1: + operand->type = UD_OP_CONST; + operand->lval.udword = 1; + break; + case OP_N: + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + /* intended fall through */ + case OP_Q: + decode_modrm_rm(u, operand, REGCLASS_MMX, size); + break; + case OP_P: + decode_modrm_reg(u, operand, REGCLASS_MMX, size); + break; + case OP_U: + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + /* intended fall through */ + case OP_W: + decode_modrm_rm(u, operand, REGCLASS_XMM, size); + break; + case OP_V: + decode_modrm_reg(u, operand, REGCLASS_XMM, size); + break; + case OP_H: + decode_vex_vvvv(u, operand, size); + break; + case OP_MU: + decode_modrm_rm(u, operand, REGCLASS_XMM, + MODRM_MOD(modrm(u)) == 3 ? + Mx_reg_size(size) : Mx_mem_size(size)); + break; + case OP_S: + decode_modrm_reg(u, operand, REGCLASS_SEG, size); + break; + case OP_O: + decode_moffset(u, size, operand); + break; + case OP_R0: + case OP_R1: + case OP_R2: + case OP_R3: + case OP_R4: + case OP_R5: + case OP_R6: + case OP_R7: + decode_reg(u, operand, REGCLASS_GPR, + (REX_B(u->_rex) << 3) | (type - OP_R0), size); + break; + case OP_AL: + case OP_AX: + case OP_eAX: + case OP_rAX: + decode_reg(u, operand, REGCLASS_GPR, 0, size); + break; + case OP_CL: + case OP_CX: + case OP_eCX: + decode_reg(u, operand, REGCLASS_GPR, 1, size); + break; + case OP_DL: + case OP_DX: + case OP_eDX: + decode_reg(u, operand, REGCLASS_GPR, 2, size); + break; + case OP_ES: + case OP_CS: + case OP_DS: + case OP_SS: + case OP_FS: + case OP_GS: + /* in 64bits mode, only fs and gs are allowed */ + if (u->dis_mode == 64) { + if (type != OP_FS && type != OP_GS) { + UDERR(u, "invalid segment register in 64bits\n"); + } + } + operand->type = UD_OP_REG; + operand->base = (type - OP_ES) + UD_R_ES; + operand->size = 16; + break; + case OP_J : + decode_imm(u, size, operand); + operand->type = UD_OP_JIMM; + break ; + case OP_R : + if (MODRM_MOD(modrm(u)) != 3) { + UDERR(u, "expected modrm.mod == 3\n"); + } + decode_modrm_rm(u, operand, REGCLASS_GPR, size); + break; + case OP_C: + decode_modrm_reg(u, operand, REGCLASS_CR, size); + break; + case OP_D: + decode_modrm_reg(u, operand, REGCLASS_DB, size); + break; + case OP_I3 : + operand->type = UD_OP_CONST; + operand->lval.sbyte = 3; + break; + case OP_ST0: + case OP_ST1: + case OP_ST2: + case OP_ST3: + case OP_ST4: + case OP_ST5: + case OP_ST6: + case OP_ST7: + operand->type = UD_OP_REG; + operand->base = (type - OP_ST0) + UD_R_ST0; + operand->size = 80; + break; + case OP_L: + decode_vex_immreg(u, operand, size); + break; + default : + operand->type = UD_NONE; + break; + } + return operand->type; +} + + +/* + * decode_operands + * + * Disassemble upto 3 operands of the current instruction being + * disassembled. By the end of the function, the operand fields + * of the ud structure will have been filled. + */ +static int +decode_operands(struct ud* u) +{ + decode_operand(u, &u->operand[0], + u->itab_entry->operand1.type, + u->itab_entry->operand1.size); + if (u->operand[0].type != UD_NONE) { + decode_operand(u, &u->operand[1], + u->itab_entry->operand2.type, + u->itab_entry->operand2.size); + } + if (u->operand[1].type != UD_NONE) { + decode_operand(u, &u->operand[2], + u->itab_entry->operand3.type, + u->itab_entry->operand3.size); + } + if (u->operand[2].type != UD_NONE) { + decode_operand(u, &u->operand[3], + u->itab_entry->operand4.type, + u->itab_entry->operand4.size); + } + return 0; +} + /* ----------------------------------------------------------------------------- - * clear_insn() - clear instruction pointer + * clear_insn() - clear instruction structure * ----------------------------------------------------------------------------- */ -static int clear_insn(register struct ud* u) +static void +clear_insn(register struct ud* u) { u->error = 0; u->pfx_seg = 0; @@ -1055,45 +932,77 @@ static int clear_insn(register struct ud* u) u->pfx_repne = 0; u->pfx_rep = 0; u->pfx_repe = 0; - u->pfx_seg = 0; u->pfx_rex = 0; - u->pfx_insn = 0; + u->pfx_str = 0; u->mnemonic = UD_Inone; u->itab_entry = NULL; + u->have_modrm = 0; + u->br_far = 0; + u->vex_op = 0; + u->_rex = 0; + u->operand[0].type = UD_NONE; + u->operand[1].type = UD_NONE; + u->operand[2].type = UD_NONE; + u->operand[3].type = UD_NONE; +} - memset( &u->operand[ 0 ], 0, sizeof( struct ud_operand ) ); - memset( &u->operand[ 1 ], 0, sizeof( struct ud_operand ) ); - memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) ); - + +static UD_INLINE int +resolve_pfx_str(struct ud* u) +{ + if (u->pfx_str == 0xf3) { + if (P_STR(u->itab_entry->prefix)) { + u->pfx_rep = 0xf3; + } else { + u->pfx_repe = 0xf3; + } + } else if (u->pfx_str == 0xf2) { + u->pfx_repne = 0xf3; + } return 0; } -static int do_mode( struct ud* u ) + +static int +resolve_mode( struct ud* u ) { + int default64; /* if in error state, bail out */ if ( u->error ) return -1; - /* propagate perfix effects */ + /* propagate prefix effects */ if ( u->dis_mode == 64 ) { /* set 64bit-mode flags */ /* Check validity of instruction m64 */ if ( P_INV64( u->itab_entry->prefix ) ) { - u->error = 1; - return -1; + UDERR(u, "instruction invalid in 64bits\n"); + return -1; } - /* effective rex prefix is the effective mask for the - * instruction hard-coded in the opcode map. + /* compute effective rex based on, + * - vex prefix (if any) + * - rex prefix (if any, and not vex) + * - allowed prefixes specified by the opcode map */ - u->pfx_rex = ( u->pfx_rex & 0x40 ) | - ( u->pfx_rex & REX_PFX_MASK( u->itab_entry->prefix ) ); + if (u->vex_op == 0xc4) { + /* vex has rex.rxb in 1's complement */ + u->_rex = ((~(u->vex_b1 >> 5) & 0x7) /* rex.0rxb */ | + ((u->vex_b2 >> 4) & 0x8) /* rex.w000 */); + } else if (u->vex_op == 0xc5) { + /* vex has rex.r in 1's complement */ + u->_rex = (~(u->vex_b1 >> 5)) & 4; + } else { + UD_ASSERT(u->vex_op == 0); + u->_rex = u->pfx_rex; + } + u->_rex &= REX_PFX_MASK(u->itab_entry->prefix); /* whether this instruction has a default operand size of * 64bit, also hardcoded into the opcode map. */ - u->default64 = P_DEF64( u->itab_entry->prefix ); + default64 = P_DEF64( u->itab_entry->prefix ); /* calculate effective operand size */ - if ( REX_W( u->pfx_rex ) ) { + if (REX_W(u->_rex)) { u->opr_mode = 64; } else if ( u->pfx_opr ) { u->opr_mode = 16; @@ -1102,7 +1011,7 @@ static int do_mode( struct ud* u ) * the effective operand size in the absence of rex.w * prefix is 32. */ - u->opr_mode = ( u->default64 ) ? 64 : 32; + u->opr_mode = default64 ? 64 : 32; } /* calculate effective address size */ @@ -1115,79 +1024,243 @@ static int do_mode( struct ud* u ) u->adr_mode = ( u->pfx_adr ) ? 32 : 16; } - /* These flags determine which operand to apply the operand size - * cast to. - */ - u->c1 = ( P_C1( u->itab_entry->prefix ) ) ? 1 : 0; - u->c2 = ( P_C2( u->itab_entry->prefix ) ) ? 1 : 0; - u->c3 = ( P_C3( u->itab_entry->prefix ) ) ? 1 : 0; - - /* set flags for implicit addressing */ - u->implicit_addr = P_IMPADDR( u->itab_entry->prefix ); - return 0; } -static int gen_hex( struct ud *u ) + +static UD_INLINE int +decode_insn(struct ud *u, uint16_t ptr) { - unsigned int i; - unsigned char *src_ptr = inp_sess( u ); - char* src_hex; + UD_ASSERT((ptr & 0x8000) == 0); + u->itab_entry = &ud_itab[ ptr ]; + u->mnemonic = u->itab_entry->mnemonic; + return (resolve_pfx_str(u) == 0 && + resolve_mode(u) == 0 && + decode_operands(u) == 0 && + resolve_mnemonic(u) == 0) ? 0 : -1; +} - /* bail out if in error stat. */ - if ( u->error ) return -1; - /* output buffer pointe */ - src_hex = ( char* ) u->insn_hexcode; - /* for each byte used to decode instruction */ - for ( i = 0; i < u->inp_ctr; ++i, ++src_ptr) { - sprintf( src_hex, "%02x", *src_ptr & 0xFF ); - src_hex += 2; + +/* + * decode_3dnow() + * + * Decoding 3dnow is a little tricky because of its strange opcode + * structure. The final opcode disambiguation depends on the last + * byte that comes after the operands have been decoded. Fortunately, + * all 3dnow instructions have the same set of operand types. So we + * go ahead and decode the instruction by picking an arbitrarily chosen + * valid entry in the table, decode the operands, and read the final + * byte to resolve the menmonic. + */ +static UD_INLINE int +decode_3dnow(struct ud* u) +{ + uint16_t ptr; + UD_ASSERT(u->le->type == UD_TAB__OPC_3DNOW); + UD_ASSERT(u->le->table[0xc] != 0); + decode_insn(u, u->le->table[0xc]); + inp_next(u); + if (u->error) { + return -1; } + ptr = u->le->table[inp_curr(u)]; + UD_ASSERT((ptr & 0x8000) == 0); + u->mnemonic = ud_itab[ptr].mnemonic; return 0; } + +static int +decode_ssepfx(struct ud *u) +{ + uint8_t idx; + uint8_t pfx; + + /* + * String prefixes (f2, f3) take precedence over operand + * size prefix (66). + */ + pfx = u->pfx_str; + if (pfx == 0) { + pfx = u->pfx_opr; + } + idx = ((pfx & 0xf) + 1) / 2; + if (u->le->table[idx] == 0) { + idx = 0; + } + if (idx && u->le->table[idx] != 0) { + /* + * "Consume" the prefix as a part of the opcode, so it is no + * longer exported as an instruction prefix. + */ + u->pfx_str = 0; + if (pfx == 0x66) { + /* + * consume "66" only if it was used for decoding, leaving + * it to be used as an operands size override for some + * simd instructions. + */ + u->pfx_opr = 0; + } + } + return decode_ext(u, u->le->table[idx]); +} + + +static int +decode_vex(struct ud *u) +{ + uint8_t index; + if (u->dis_mode != 64 && MODRM_MOD(inp_peek(u)) != 0x3) { + index = 0; + } else { + u->vex_op = inp_curr(u); + u->vex_b1 = inp_next(u); + if (u->vex_op == 0xc4) { + uint8_t pp, m; + /* 3-byte vex */ + u->vex_b2 = inp_next(u); + UD_RETURN_ON_ERROR(u); + m = u->vex_b1 & 0x1f; + if (m == 0 || m > 3) { + UD_RETURN_WITH_ERROR(u, "reserved vex.m-mmmm value"); + } + pp = u->vex_b2 & 0x3; + index = (pp << 2) | m; + } else { + /* 2-byte vex */ + UD_ASSERT(u->vex_op == 0xc5); + index = 0x1 | ((u->vex_b1 & 0x3) << 2); + } + } + return decode_ext(u, u->le->table[index]); +} + + +/* + * decode_ext() + * + * Decode opcode extensions (if any) + */ +static int +decode_ext(struct ud *u, uint16_t ptr) +{ + uint8_t idx = 0; + if ((ptr & 0x8000) == 0) { + return decode_insn(u, ptr); + } + u->le = &ud_lookup_table_list[(~0x8000 & ptr)]; + if (u->le->type == UD_TAB__OPC_3DNOW) { + return decode_3dnow(u); + } + + switch (u->le->type) { + case UD_TAB__OPC_MOD: + /* !11 = 0, 11 = 1 */ + idx = (MODRM_MOD(modrm(u)) + 1) / 4; + break; + /* disassembly mode/operand size/address size based tables. + * 16 = 0,, 32 = 1, 64 = 2 + */ + case UD_TAB__OPC_MODE: + idx = u->dis_mode != 64 ? 0 : 1; + break; + case UD_TAB__OPC_OSIZE: + idx = eff_opr_mode(u->dis_mode, REX_W(u->pfx_rex), u->pfx_opr) / 32; + break; + case UD_TAB__OPC_ASIZE: + idx = eff_adr_mode(u->dis_mode, u->pfx_adr) / 32; + break; + case UD_TAB__OPC_X87: + idx = modrm(u) - 0xC0; + break; + case UD_TAB__OPC_VENDOR: + if (u->vendor == UD_VENDOR_ANY) { + /* choose a valid entry */ + idx = (u->le->table[idx] != 0) ? 0 : 1; + } else if (u->vendor == UD_VENDOR_AMD) { + idx = 0; + } else { + idx = 1; + } + break; + case UD_TAB__OPC_RM: + idx = MODRM_RM(modrm(u)); + break; + case UD_TAB__OPC_REG: + idx = MODRM_REG(modrm(u)); + break; + case UD_TAB__OPC_SSE: + return decode_ssepfx(u); + case UD_TAB__OPC_VEX: + return decode_vex(u); + case UD_TAB__OPC_VEX_W: + idx = vex_w(u); + break; + case UD_TAB__OPC_VEX_L: + idx = vex_l(u); + break; + case UD_TAB__OPC_TABLE: + inp_next(u); + return decode_opcode(u); + default: + UD_ASSERT(!"not reached"); + break; + } + + return decode_ext(u, u->le->table[idx]); +} + + +static int +decode_opcode(struct ud *u) +{ + uint16_t ptr; + UD_ASSERT(u->le->type == UD_TAB__OPC_TABLE); + UD_RETURN_ON_ERROR(u); + ptr = u->le->table[inp_curr(u)]; + return decode_ext(u, ptr); +} + + /* ============================================================================= * ud_decode() - Instruction decoder. Returns the number of bytes decoded. * ============================================================================= */ -unsigned int ud_decode( struct ud* u ) +unsigned int +ud_decode(struct ud *u) { inp_start(u); - - if ( clear_insn( u ) ) { - ; /* error */ - } else if ( get_prefixes( u ) != 0 ) { - ; /* error */ - } else if ( search_itab( u ) != 0 ) { - ; /* error */ - } else if ( do_mode( u ) != 0 ) { - ; /* error */ - } else if ( disasm_operands( u ) != 0 ) { - ; /* error */ - } else if ( resolve_mnemonic( u ) != 0 ) { - ; /* error */ - } - + clear_insn(u); + u->le = &ud_lookup_table_list[0]; + u->error = decode_prefixes(u) == -1 || + decode_opcode(u) == -1 || + u->error; /* Handle decode error. */ - if ( u->error ) { + if (u->error) { /* clear out the decode data. */ - clear_insn( u ); + clear_insn(u); /* mark the sequence of bytes as invalid. */ - u->itab_entry = & ie_invalid; + u->itab_entry = &ud_itab[0]; /* entry 0 is invalid */ u->mnemonic = u->itab_entry->mnemonic; } + /* maybe this stray segment override byte + * should be spewed out? + */ + if ( !P_SEG( u->itab_entry->prefix ) && + u->operand[0].type != UD_OP_MEM && + u->operand[1].type != UD_OP_MEM ) + u->pfx_seg = 0; + u->insn_offset = u->pc; /* set offset of instruction */ - u->insn_fill = 0; /* set translation buffer index to 0 */ + u->asm_buf_fill = 0; /* set translation buffer index to 0 */ u->pc += u->inp_ctr; /* move program counter by bytes decoded */ - gen_hex( u ); /* generate hex code */ /* return number of bytes disassembled. */ return u->inp_ctr; } -/* vim:cindent - * vim:ts=4 - * vim:sw=4 - * vim:expandtab - */ +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/decode.h b/udis86/libudis86/decode.h index 3d62096..3949c4e 100644 --- a/udis86/libudis86/decode.h +++ b/udis86/libudis86/decode.h @@ -1,66 +1,71 @@ +/* udis86 - libudis86/decode.h + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef UD_DECODE_H #define UD_DECODE_H -#define MAX_INSN_LENGTH 15 +#include "types.h" +#include "udint.h" +#include "itab.h" -/* register classes */ -#define T_NONE 0 -#define T_GPR 1 -#define T_MMX 2 -#define T_CRG 3 -#define T_DBG 4 -#define T_SEG 5 -#define T_XMM 6 +#define MAX_INSN_LENGTH 15 /* itab prefix bits */ #define P_none ( 0 ) -#define P_c1 ( 1 << 0 ) -#define P_C1(n) ( ( n >> 0 ) & 1 ) -#define P_rexb ( 1 << 1 ) -#define P_REXB(n) ( ( n >> 1 ) & 1 ) -#define P_depM ( 1 << 2 ) -#define P_DEPM(n) ( ( n >> 2 ) & 1 ) -#define P_c3 ( 1 << 3 ) -#define P_C3(n) ( ( n >> 3 ) & 1 ) -#define P_inv64 ( 1 << 4 ) -#define P_INV64(n) ( ( n >> 4 ) & 1 ) + +#define P_inv64 ( 1 << 0 ) +#define P_INV64(n) ( ( n >> 0 ) & 1 ) +#define P_def64 ( 1 << 1 ) +#define P_DEF64(n) ( ( n >> 1 ) & 1 ) + +#define P_oso ( 1 << 2 ) +#define P_OSO(n) ( ( n >> 2 ) & 1 ) +#define P_aso ( 1 << 3 ) +#define P_ASO(n) ( ( n >> 3 ) & 1 ) + +#define P_rexb ( 1 << 4 ) +#define P_REXB(n) ( ( n >> 4 ) & 1 ) #define P_rexw ( 1 << 5 ) #define P_REXW(n) ( ( n >> 5 ) & 1 ) -#define P_c2 ( 1 << 6 ) -#define P_C2(n) ( ( n >> 6 ) & 1 ) -#define P_def64 ( 1 << 7 ) -#define P_DEF64(n) ( ( n >> 7 ) & 1 ) -#define P_rexr ( 1 << 8 ) -#define P_REXR(n) ( ( n >> 8 ) & 1 ) -#define P_oso ( 1 << 9 ) -#define P_OSO(n) ( ( n >> 9 ) & 1 ) -#define P_aso ( 1 << 10 ) -#define P_ASO(n) ( ( n >> 10 ) & 1 ) -#define P_rexx ( 1 << 11 ) -#define P_REXX(n) ( ( n >> 11 ) & 1 ) -#define P_ImpAddr ( 1 << 12 ) -#define P_IMPADDR(n) ( ( n >> 12 ) & 1 ) +#define P_rexr ( 1 << 6 ) +#define P_REXR(n) ( ( n >> 6 ) & 1 ) +#define P_rexx ( 1 << 7 ) +#define P_REXX(n) ( ( n >> 7 ) & 1 ) -/* rex prefix bits */ -#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) -#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) -#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) -#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) -#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \ - ( P_REXR(n) << 2 ) | \ - ( P_REXX(n) << 1 ) | \ - ( P_REXB(n) << 0 ) ) +#define P_seg ( 1 << 8 ) +#define P_SEG(n) ( ( n >> 8 ) & 1 ) -/* scable-index-base bits */ -#define SIB_S(b) ( ( b ) >> 6 ) -#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 ) -#define SIB_B(b) ( ( b ) & 7 ) +#define P_vexl ( 1 << 9 ) +#define P_VEXL(n) ( ( n >> 9 ) & 1 ) +#define P_vexw ( 1 << 10 ) +#define P_VEXW(n) ( ( n >> 10 ) & 1 ) -/* modrm bits */ -#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 ) -#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 ) -#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 ) -#define MODRM_RM(b) ( ( b ) & 7 ) +#define P_str ( 1 << 11 ) +#define P_STR(n) ( ( n >> 11 ) & 1 ) +#define P_strz ( 1 << 12 ) +#define P_STR_ZF(n) ( ( n >> 12 ) & 1 ) /* operand type constants -- order is important! */ @@ -68,25 +73,15 @@ enum ud_operand_code { OP_NONE, OP_A, OP_E, OP_M, OP_G, - OP_I, + OP_I, OP_F, - OP_AL, OP_CL, OP_DL, OP_BL, - OP_AH, OP_CH, OP_DH, OP_BH, + OP_R0, OP_R1, OP_R2, OP_R3, + OP_R4, OP_R5, OP_R6, OP_R7, - OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b, - OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b, - - OP_AX, OP_CX, OP_DX, OP_BX, - OP_SI, OP_DI, OP_SP, OP_BP, - - OP_rAX, OP_rCX, OP_rDX, OP_rBX, - OP_rSP, OP_rBP, OP_rSI, OP_rDI, - - OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11, - OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15, - - OP_eAX, OP_eCX, OP_eDX, OP_eBX, - OP_eSP, OP_eBP, OP_eSI, OP_eDI, + OP_AL, OP_CL, OP_DL, + OP_AX, OP_CX, OP_DX, + OP_eAX, OP_eCX, OP_eDX, + OP_rAX, OP_rCX, OP_rDX, OP_ES, OP_CS, OP_SS, OP_DS, OP_FS, OP_GS, @@ -95,152 +90,71 @@ enum ud_operand_code { OP_ST4, OP_ST5, OP_ST6, OP_ST7, OP_J, OP_S, OP_O, - OP_I1, OP_I3, + OP_I1, OP_I3, OP_sI, OP_V, OP_W, OP_Q, OP_P, + OP_U, OP_N, OP_MU, OP_H, + OP_L, - OP_R, OP_C, OP_D, OP_VR, OP_PR -}; + OP_R, OP_C, OP_D, + + OP_MR +} UD_ATTR_PACKED; -/* operand size constants */ +/* + * Operand size constants + * + * Symbolic constants for various operand sizes. Some of these constants + * are given a value equal to the width of the data (SZ_B == 8), such + * that they maybe used interchangeably in the internals. Modifying them + * will most certainly break things! + */ +typedef uint16_t ud_operand_size_t; -enum ud_operand_size { - SZ_NA = 0, - SZ_Z = 1, - SZ_V = 2, - SZ_P = 3, - SZ_WP = 4, - SZ_DP = 5, - SZ_MDQ = 6, - SZ_RDQ = 7, +#define SZ_NA 0 +#define SZ_Z 1 +#define SZ_V 2 +#define SZ_Y 3 +#define SZ_X 4 +#define SZ_RDQ 7 +#define SZ_B 8 +#define SZ_W 16 +#define SZ_D 32 +#define SZ_Q 64 +#define SZ_T 80 +#define SZ_O 12 +#define SZ_DQ 128 /* double quad */ +#define SZ_QQ 256 /* quad quad */ - /* the following values are used as is, - * and thus hard-coded. changing them - * will break internals - */ - SZ_B = 8, - SZ_W = 16, - SZ_D = 32, - SZ_Q = 64, - SZ_T = 80, -}; +/* + * Complex size types; that encode sizes for operands of type MR (memory or + * register); for internal use only. Id space above 256. + */ +#define SZ_BD ((SZ_B << 8) | SZ_D) +#define SZ_BV ((SZ_B << 8) | SZ_V) +#define SZ_WD ((SZ_W << 8) | SZ_D) +#define SZ_WV ((SZ_W << 8) | SZ_V) +#define SZ_WY ((SZ_W << 8) | SZ_Y) +#define SZ_DY ((SZ_D << 8) | SZ_Y) +#define SZ_WO ((SZ_W << 8) | SZ_O) +#define SZ_DO ((SZ_D << 8) | SZ_O) +#define SZ_QO ((SZ_Q << 8) | SZ_O) -/* itab entry operand definitions */ -#define O_rSPr12 { OP_rSPr12, SZ_NA } -#define O_BL { OP_BL, SZ_NA } -#define O_BH { OP_BH, SZ_NA } -#define O_BP { OP_BP, SZ_NA } -#define O_AHr12b { OP_AHr12b, SZ_NA } -#define O_BX { OP_BX, SZ_NA } -#define O_Jz { OP_J, SZ_Z } -#define O_Jv { OP_J, SZ_V } -#define O_Jb { OP_J, SZ_B } -#define O_rSIr14 { OP_rSIr14, SZ_NA } -#define O_GS { OP_GS, SZ_NA } -#define O_D { OP_D, SZ_NA } -#define O_rBPr13 { OP_rBPr13, SZ_NA } -#define O_Ob { OP_O, SZ_B } -#define O_P { OP_P, SZ_NA } -#define O_Ow { OP_O, SZ_W } -#define O_Ov { OP_O, SZ_V } -#define O_Gw { OP_G, SZ_W } -#define O_Gv { OP_G, SZ_V } -#define O_rDX { OP_rDX, SZ_NA } -#define O_Gx { OP_G, SZ_MDQ } -#define O_Gd { OP_G, SZ_D } -#define O_Gb { OP_G, SZ_B } -#define O_rBXr11 { OP_rBXr11, SZ_NA } -#define O_rDI { OP_rDI, SZ_NA } -#define O_rSI { OP_rSI, SZ_NA } -#define O_ALr8b { OP_ALr8b, SZ_NA } -#define O_eDI { OP_eDI, SZ_NA } -#define O_Gz { OP_G, SZ_Z } -#define O_eDX { OP_eDX, SZ_NA } -#define O_DHr14b { OP_DHr14b, SZ_NA } -#define O_rSP { OP_rSP, SZ_NA } -#define O_PR { OP_PR, SZ_NA } -#define O_NONE { OP_NONE, SZ_NA } -#define O_rCX { OP_rCX, SZ_NA } -#define O_jWP { OP_J, SZ_WP } -#define O_rDXr10 { OP_rDXr10, SZ_NA } -#define O_Md { OP_M, SZ_D } -#define O_C { OP_C, SZ_NA } -#define O_G { OP_G, SZ_NA } -#define O_Mb { OP_M, SZ_B } -#define O_Mt { OP_M, SZ_T } -#define O_S { OP_S, SZ_NA } -#define O_Mq { OP_M, SZ_Q } -#define O_W { OP_W, SZ_NA } -#define O_ES { OP_ES, SZ_NA } -#define O_rBX { OP_rBX, SZ_NA } -#define O_Ed { OP_E, SZ_D } -#define O_DLr10b { OP_DLr10b, SZ_NA } -#define O_Mw { OP_M, SZ_W } -#define O_Eb { OP_E, SZ_B } -#define O_Ex { OP_E, SZ_MDQ } -#define O_Ez { OP_E, SZ_Z } -#define O_Ew { OP_E, SZ_W } -#define O_Ev { OP_E, SZ_V } -#define O_Ep { OP_E, SZ_P } -#define O_FS { OP_FS, SZ_NA } -#define O_Ms { OP_M, SZ_W } -#define O_rAXr8 { OP_rAXr8, SZ_NA } -#define O_eBP { OP_eBP, SZ_NA } -#define O_Isb { OP_I, SZ_SB } -#define O_eBX { OP_eBX, SZ_NA } -#define O_rCXr9 { OP_rCXr9, SZ_NA } -#define O_jDP { OP_J, SZ_DP } -#define O_CH { OP_CH, SZ_NA } -#define O_CL { OP_CL, SZ_NA } -#define O_R { OP_R, SZ_RDQ } -#define O_V { OP_V, SZ_NA } -#define O_CS { OP_CS, SZ_NA } -#define O_CHr13b { OP_CHr13b, SZ_NA } -#define O_eCX { OP_eCX, SZ_NA } -#define O_eSP { OP_eSP, SZ_NA } -#define O_SS { OP_SS, SZ_NA } -#define O_SP { OP_SP, SZ_NA } -#define O_BLr11b { OP_BLr11b, SZ_NA } -#define O_SI { OP_SI, SZ_NA } -#define O_eSI { OP_eSI, SZ_NA } -#define O_DL { OP_DL, SZ_NA } -#define O_DH { OP_DH, SZ_NA } -#define O_DI { OP_DI, SZ_NA } -#define O_DX { OP_DX, SZ_NA } -#define O_rBP { OP_rBP, SZ_NA } -#define O_Gvw { OP_G, SZ_MDQ } -#define O_I1 { OP_I1, SZ_NA } -#define O_I3 { OP_I3, SZ_NA } -#define O_DS { OP_DS, SZ_NA } -#define O_ST4 { OP_ST4, SZ_NA } -#define O_ST5 { OP_ST5, SZ_NA } -#define O_ST6 { OP_ST6, SZ_NA } -#define O_ST7 { OP_ST7, SZ_NA } -#define O_ST0 { OP_ST0, SZ_NA } -#define O_ST1 { OP_ST1, SZ_NA } -#define O_ST2 { OP_ST2, SZ_NA } -#define O_ST3 { OP_ST3, SZ_NA } -#define O_E { OP_E, SZ_NA } -#define O_AH { OP_AH, SZ_NA } -#define O_M { OP_M, SZ_NA } -#define O_AL { OP_AL, SZ_NA } -#define O_CLr9b { OP_CLr9b, SZ_NA } -#define O_Q { OP_Q, SZ_NA } -#define O_eAX { OP_eAX, SZ_NA } -#define O_VR { OP_VR, SZ_NA } -#define O_AX { OP_AX, SZ_NA } -#define O_rAX { OP_rAX, SZ_NA } -#define O_Iz { OP_I, SZ_Z } -#define O_rDIr15 { OP_rDIr15, SZ_NA } -#define O_Iw { OP_I, SZ_W } -#define O_Iv { OP_I, SZ_V } -#define O_Ap { OP_A, SZ_P } -#define O_CX { OP_CX, SZ_NA } -#define O_Ib { OP_I, SZ_B } -#define O_BHr15b { OP_BHr15b, SZ_NA } +/* resolve complex size type. + */ +static UD_INLINE ud_operand_size_t +Mx_mem_size(ud_operand_size_t size) +{ + return (size >> 8) & 0xff; +} +static UD_INLINE ud_operand_size_t +Mx_reg_size(ud_operand_size_t size) +{ + return size & 0xff; +} /* A single operand of an entry in the instruction table. * (internal use only) @@ -248,7 +162,7 @@ enum ud_operand_size { struct ud_itab_entry_operand { enum ud_operand_code type; - enum ud_operand_size size; + ud_operand_size_t size; }; @@ -261,10 +175,18 @@ struct ud_itab_entry struct ud_itab_entry_operand operand1; struct ud_itab_entry_operand operand2; struct ud_itab_entry_operand operand3; + struct ud_itab_entry_operand operand4; uint32_t prefix; }; -extern const char * ud_lookup_mnemonic( enum ud_mnemonic_code c ); +struct ud_lookup_table_list_entry { + const uint16_t *table; + enum ud_table_type type; + const char *meta; +}; + +extern struct ud_itab_entry ud_itab[]; +extern struct ud_lookup_table_list_entry ud_lookup_table_list[]; #endif /* UD_DECODE_H */ diff --git a/udis86/libudis86/extern.h b/udis86/libudis86/extern.h index c33baf5..71a01fd 100644 --- a/udis86/libudis86/extern.h +++ b/udis86/libudis86/extern.h @@ -1,9 +1,27 @@ -/* ----------------------------------------------------------------------------- - * extern.h +/* udis86 - libudis86/extern.h * - * Copyright (c) 2004, 2005, 2006, Vivek Mohan - * All rights reserved. See LICENSE - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2009, 2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UD_EXTERN_H #define UD_EXTERN_H @@ -12,56 +30,84 @@ extern "C" { #endif -#include #include "types.h" +#if defined(_MSC_VER) && defined(_USRDLL) +# ifdef LIBUDIS86_EXPORTS +# define LIBUDIS86_DLLEXTERN __declspec(dllexport) +# else +# define LIBUDIS86_DLLEXTERN __declspec(dllimport) +# endif +#else +# define LIBUDIS86_DLLEXTERN +#endif + /* ============================= PUBLIC API ================================= */ -extern void ud_init(struct ud*); +extern LIBUDIS86_DLLEXTERN void ud_init(struct ud*); -extern void ud_set_mode(struct ud*, uint8_t); +extern LIBUDIS86_DLLEXTERN void ud_set_mode(struct ud*, uint8_t); -extern void ud_set_pc(struct ud*, uint64_t); +extern LIBUDIS86_DLLEXTERN void ud_set_pc(struct ud*, uint64_t); -extern void ud_set_input_hook(struct ud*, int (*)(struct ud*)); +extern LIBUDIS86_DLLEXTERN void ud_set_input_hook(struct ud*, int (*)(struct ud*)); -extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t); +extern LIBUDIS86_DLLEXTERN void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); #ifndef __UD_STANDALONE__ -extern void ud_set_input_file(struct ud*, FILE*); +extern LIBUDIS86_DLLEXTERN void ud_set_input_file(struct ud*, FILE*); #endif /* __UD_STANDALONE__ */ -extern void ud_set_vendor(struct ud*, unsigned); +extern LIBUDIS86_DLLEXTERN void ud_set_vendor(struct ud*, unsigned); -extern void ud_set_syntax(struct ud*, void (*)(struct ud*)); +extern LIBUDIS86_DLLEXTERN void ud_set_syntax(struct ud*, void (*)(struct ud*)); -extern void ud_input_skip(struct ud*, size_t); +extern LIBUDIS86_DLLEXTERN void ud_input_skip(struct ud*, size_t); -extern int ud_input_end(struct ud*); +extern LIBUDIS86_DLLEXTERN int ud_input_end(const struct ud*); -extern unsigned int ud_decode(struct ud*); +extern LIBUDIS86_DLLEXTERN unsigned int ud_decode(struct ud*); -extern unsigned int ud_disassemble(struct ud*); +extern LIBUDIS86_DLLEXTERN unsigned int ud_disassemble(struct ud*); -extern void ud_translate_intel(struct ud*); +extern LIBUDIS86_DLLEXTERN void ud_translate_intel(struct ud*); -extern void ud_translate_att(struct ud*); +extern LIBUDIS86_DLLEXTERN void ud_translate_att(struct ud*); -extern char* ud_insn_asm(struct ud* u); +extern LIBUDIS86_DLLEXTERN const char* ud_insn_asm(const struct ud* u); -extern uint8_t* ud_insn_ptr(struct ud* u); +extern LIBUDIS86_DLLEXTERN const uint8_t* ud_insn_ptr(const struct ud* u); -extern uint64_t ud_insn_off(struct ud*); +extern LIBUDIS86_DLLEXTERN uint64_t ud_insn_off(const struct ud*); -extern char* ud_insn_hex(struct ud*); +extern LIBUDIS86_DLLEXTERN const char* ud_insn_hex(struct ud*); -extern unsigned int ud_insn_len(struct ud* u); +extern LIBUDIS86_DLLEXTERN unsigned int ud_insn_len(const struct ud* u); -extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); +extern LIBUDIS86_DLLEXTERN const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); + +extern LIBUDIS86_DLLEXTERN int ud_opr_is_sreg(const struct ud_operand *opr); + +extern LIBUDIS86_DLLEXTERN int ud_opr_is_gpr(const struct ud_operand *opr); + +extern LIBUDIS86_DLLEXTERN enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u); + +extern LIBUDIS86_DLLEXTERN const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); + +extern LIBUDIS86_DLLEXTERN void ud_set_user_opaque_data(struct ud*, void*); + +extern LIBUDIS86_DLLEXTERN void* ud_get_user_opaque_data(const struct ud*); + +extern LIBUDIS86_DLLEXTERN void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); + +extern LIBUDIS86_DLLEXTERN void ud_set_sym_resolver(struct ud *u, + const char* (*resolver)(struct ud*, + uint64_t addr, + int64_t *offset)); /* ========================================================================== */ #ifdef __cplusplus } #endif -#endif +#endif /* UD_EXTERN_H */ diff --git a/udis86/libudis86/syn-att.c b/udis86/libudis86/syn-att.c index 79fcc7f..d1ba89b 100644 --- a/udis86/libudis86/syn-att.c +++ b/udis86/libudis86/syn-att.c @@ -1,16 +1,34 @@ -/* ----------------------------------------------------------------------------- - * syn-att.c +/* udis86 - libudis86/syn-att.c * - * Copyright (c) 2004, 2005, 2006 Vivek Mohan - * All rights reserved. See (LICENSE) - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "types.h" #include "extern.h" #include "decode.h" #include "itab.h" #include "syn.h" +#include "udint.h" /* ----------------------------------------------------------------------------- * opr_cast() - Prints an operand cast. @@ -20,9 +38,9 @@ static void opr_cast(struct ud* u, struct ud_operand* op) { switch(op->size) { - case 16 : case 32 : - mkasm(u, "*"); break; - default: break; + case 16 : case 32 : + ud_asmprintf(u, "*"); break; + default: break; } } @@ -34,79 +52,66 @@ static void gen_operand(struct ud* u, struct ud_operand* op) { switch(op->type) { - case UD_OP_REG: - mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); - break; + case UD_OP_CONST: + ud_asmprintf(u, "$0x%x", op->lval.udword); + break; - case UD_OP_MEM: - if (u->br_far) opr_cast(u, op); - if (u->pfx_seg) - mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); - if (op->offset == 8) { - if (op->lval.sbyte < 0) - mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff); - else mkasm(u, "0x%x", op->lval.sbyte); - } - else if (op->offset == 16) - mkasm(u, "0x%x", op->lval.uword); - else if (op->offset == 32) - mkasm(u, "0x%lx", op->lval.udword); - else if (op->offset == 64) - mkasm(u, "0x" FMT64 "x", op->lval.uqword); + case UD_OP_REG: + ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); + break; - if (op->base) - mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); - if (op->index) { - if (op->base) - mkasm(u, ","); - else mkasm(u, "("); - mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); - } - if (op->scale) - mkasm(u, ",%d", op->scale); - if (op->base || op->index) - mkasm(u, ")"); - break; + case UD_OP_MEM: + if (u->br_far) { + opr_cast(u, op); + } + if (u->pfx_seg) { + ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + if (op->offset != 0) { + ud_syn_print_mem_disp(u, op, 0); + } + if (op->base) { + ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); + } + if (op->index) { + if (op->base) { + ud_asmprintf(u, ","); + } else { + ud_asmprintf(u, "("); + } + ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); + } + if (op->scale) { + ud_asmprintf(u, ",%d", op->scale); + } + if (op->base || op->index) { + ud_asmprintf(u, ")"); + } + break; - case UD_OP_IMM: - switch (op->size) { - case 8: mkasm(u, "$0x%x", op->lval.ubyte); break; - case 16: mkasm(u, "$0x%x", op->lval.uword); break; - case 32: mkasm(u, "$0x%lx", op->lval.udword); break; - case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break; - default: break; - } - break; + case UD_OP_IMM: + ud_asmprintf(u, "$"); + ud_syn_print_imm(u, op); + break; - case UD_OP_JIMM: - switch (op->size) { - case 8: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); - break; - case 16: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword); - break; - case 32: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword); - break; - default:break; - } - break; + case UD_OP_JIMM: + ud_syn_print_addr(u, ud_syn_rel_target(u, op)); + break; - case UD_OP_PTR: - switch (op->size) { - case 32: - mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg, - op->lval.ptr.off & 0xFFFF); - break; - case 48: - mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg, - op->lval.ptr.off); - break; - } - break; - - default: return; + case UD_OP_PTR: + switch (op->size) { + case 32: + ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, + op->lval.ptr.off & 0xFFFF); + break; + case 48: + ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, + op->lval.ptr.off); + break; + } + break; + + default: return; } } @@ -118,94 +123,106 @@ extern void ud_translate_att(struct ud *u) { int size = 0; + int star = 0; /* check if P_OSO prefix is used */ if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { - switch (u->dis_mode) { - case 16: - mkasm(u, "o32 "); - break; - case 32: - case 64: - mkasm(u, "o16 "); - break; - } + switch (u->dis_mode) { + case 16: + ud_asmprintf(u, "o32 "); + break; + case 32: + case 64: + ud_asmprintf(u, "o16 "); + break; + } } /* check if P_ASO prefix was used */ if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { - switch (u->dis_mode) { - case 16: - mkasm(u, "a32 "); - break; - case 32: - mkasm(u, "a16 "); - break; - case 64: - mkasm(u, "a32 "); - break; - } + switch (u->dis_mode) { + case 16: + ud_asmprintf(u, "a32 "); + break; + case 32: + ud_asmprintf(u, "a16 "); + break; + case 64: + ud_asmprintf(u, "a32 "); + break; + } } if (u->pfx_lock) - mkasm(u, "lock "); - if (u->pfx_rep) - mkasm(u, "rep "); - if (u->pfx_repne) - mkasm(u, "repne "); + ud_asmprintf(u, "lock "); + if (u->pfx_rep) { + ud_asmprintf(u, "rep "); + } else if (u->pfx_repe) { + ud_asmprintf(u, "repe "); + } else if (u->pfx_repne) { + ud_asmprintf(u, "repne "); + } /* special instructions */ switch (u->mnemonic) { - case UD_Iretf: - mkasm(u, "lret "); - break; - case UD_Idb: - mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte); - return; - case UD_Ijmp: - case UD_Icall: - if (u->br_far) mkasm(u, "l"); - mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); - break; - case UD_Ibound: - case UD_Ienter: - if (u->operand[0].type != UD_NONE) - gen_operand(u, &u->operand[0]); - if (u->operand[1].type != UD_NONE) { - mkasm(u, ","); - gen_operand(u, &u->operand[1]); - } - return; - default: - mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); + case UD_Iretf: + ud_asmprintf(u, "lret "); + break; + case UD_Idb: + ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte); + return; + case UD_Ijmp: + case UD_Icall: + if (u->br_far) ud_asmprintf(u, "l"); + if (u->operand[0].type == UD_OP_REG) { + star = 1; + } + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); + break; + case UD_Ibound: + case UD_Ienter: + if (u->operand[0].type != UD_NONE) + gen_operand(u, &u->operand[0]); + if (u->operand[1].type != UD_NONE) { + ud_asmprintf(u, ","); + gen_operand(u, &u->operand[1]); + } + return; + default: + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); } - if (u->c1) - size = u->operand[0].size; - else if (u->c2) - size = u->operand[1].size; - else if (u->c3) - size = u->operand[2].size; + if (size == 8) { + ud_asmprintf(u, "b"); + } else if (size == 16) { + ud_asmprintf(u, "w"); + } else if (size == 64) { + ud_asmprintf(u, "q"); + } - if (size == 8) - mkasm(u, "b"); - else if (size == 16) - mkasm(u, "w"); - else if (size == 64) - mkasm(u, "q"); - - mkasm(u, " "); + if (star) { + ud_asmprintf(u, " *"); + } else { + ud_asmprintf(u, " "); + } + if (u->operand[3].type != UD_NONE) { + gen_operand(u, &u->operand[3]); + ud_asmprintf(u, ", "); + } if (u->operand[2].type != UD_NONE) { - gen_operand(u, &u->operand[2]); - mkasm(u, ", "); + gen_operand(u, &u->operand[2]); + ud_asmprintf(u, ", "); } - if (u->operand[1].type != UD_NONE) { - gen_operand(u, &u->operand[1]); - mkasm(u, ", "); + gen_operand(u, &u->operand[1]); + ud_asmprintf(u, ", "); + } + if (u->operand[0].type != UD_NONE) { + gen_operand(u, &u->operand[0]); } - - if (u->operand[0].type != UD_NONE) - gen_operand(u, &u->operand[0]); } + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/syn-intel.c b/udis86/libudis86/syn-intel.c index 350253a..0664fea 100644 --- a/udis86/libudis86/syn-intel.c +++ b/udis86/libudis86/syn-intel.c @@ -1,16 +1,34 @@ -/* ----------------------------------------------------------------------------- - * syn-intel.c +/* udis86 - libudis86/syn-intel.c * - * Copyright (c) 2002, 2003, 2004 Vivek Mohan - * All rights reserved. See (LICENSE) - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "types.h" #include "extern.h" #include "decode.h" #include "itab.h" #include "syn.h" +#include "udint.h" /* ----------------------------------------------------------------------------- * opr_cast() - Prints an operand cast. @@ -19,18 +37,19 @@ static void opr_cast(struct ud* u, struct ud_operand* op) { - switch(op->size) { - case 8: mkasm(u, "byte " ); break; - case 16: mkasm(u, "word " ); break; - case 32: mkasm(u, "dword "); break; - case 64: mkasm(u, "qword "); break; - case 80: mkasm(u, "tword "); break; - default: break; + if (u->br_far) { + ud_asmprintf(u, "far "); + } + switch(op->size) { + case 8: ud_asmprintf(u, "byte " ); break; + case 16: ud_asmprintf(u, "word " ); break; + case 32: ud_asmprintf(u, "dword "); break; + case 64: ud_asmprintf(u, "qword "); break; + case 80: ud_asmprintf(u, "tword "); break; + case 128: ud_asmprintf(u, "oword "); break; + case 256: ud_asmprintf(u, "yword "); break; + default: break; } - if (u->br_far) - mkasm(u, "far "); - else if (u->br_near) - mkasm(u, "near "); } /* ----------------------------------------------------------------------------- @@ -40,105 +59,63 @@ opr_cast(struct ud* u, struct ud_operand* op) static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast) { switch(op->type) { - case UD_OP_REG: - mkasm(u, ud_reg_tab[op->base - UD_R_AL]); - break; + case UD_OP_REG: + ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); + break; - case UD_OP_MEM: { + case UD_OP_MEM: + if (syn_cast) { + opr_cast(u, op); + } + ud_asmprintf(u, "["); + if (u->pfx_seg) { + ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + if (op->base) { + ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]); + } + if (op->index) { + ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "", + ud_reg_tab[op->index - UD_R_AL]); + if (op->scale) { + ud_asmprintf(u, "*%d", op->scale); + } + } + if (op->offset != 0) { + ud_syn_print_mem_disp(u, op, (op->base != UD_NONE || + op->index != UD_NONE) ? 1 : 0); + } + ud_asmprintf(u, "]"); + break; + + case UD_OP_IMM: + ud_syn_print_imm(u, op); + break; - int op_f = 0; - if (syn_cast) - opr_cast(u, op); + case UD_OP_JIMM: + ud_syn_print_addr(u, ud_syn_rel_target(u, op)); + break; - mkasm(u, "["); + case UD_OP_PTR: + switch (op->size) { + case 32: + ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg, + op->lval.ptr.off & 0xFFFF); + break; + case 48: + ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg, + op->lval.ptr.off); + break; + } + break; - if (u->pfx_seg) - mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); + case UD_OP_CONST: + if (syn_cast) opr_cast(u, op); + ud_asmprintf(u, "%d", op->lval.udword); + break; - if (op->base) { - mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]); - op_f = 1; - } - - if (op->index) { - if (op_f) - mkasm(u, "+"); - mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]); - op_f = 1; - } - - if (op->scale) - mkasm(u, "*%d", op->scale); - - if (op->offset == 8) { - if (op->lval.sbyte < 0) - mkasm(u, "-0x%x", -op->lval.sbyte); - else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte); - } - else if (op->offset == 16) - mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword); - else if (op->offset == 32) { - if (u->adr_mode == 64) { - if (op->lval.sdword < 0) - mkasm(u, "-0x%x", -op->lval.sdword); - else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword); - } - else mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword); - } - else if (op->offset == 64) - mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword); - - mkasm(u, "]"); - break; - } - - case UD_OP_IMM: - if (syn_cast) opr_cast(u, op); - switch (op->size) { - case 8: mkasm(u, "0x%x", op->lval.ubyte); break; - case 16: mkasm(u, "0x%x", op->lval.uword); break; - case 32: mkasm(u, "0x%lx", op->lval.udword); break; - case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break; - default: break; - } - break; - - case UD_OP_JIMM: - if (syn_cast) opr_cast(u, op); - switch (op->size) { - case 8: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); - break; - case 16: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword); - break; - case 32: - mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword); - break; - default:break; - } - break; - - case UD_OP_PTR: - switch (op->size) { - case 32: - mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg, - op->lval.ptr.off & 0xFFFF); - break; - case 48: - mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg, - op->lval.ptr.off); - break; - } - break; - - case UD_OP_CONST: - if (syn_cast) opr_cast(u, op); - mkasm(u, "%d", op->lval.udword); - break; - - default: return; + default: return; } } @@ -146,63 +123,102 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast) * translates to intel syntax * ============================================================================= */ -extern void ud_translate_intel(struct ud* u) +extern void +ud_translate_intel(struct ud* u) { - /* -- prefixes -- */ - /* check if P_OSO prefix is used */ - if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { - switch (u->dis_mode) { - case 16: - mkasm(u, "o32 "); - break; - case 32: - case 64: - mkasm(u, "o16 "); - break; - } + if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) { + switch (u->dis_mode) { + case 16: ud_asmprintf(u, "o32 "); break; + case 32: + case 64: ud_asmprintf(u, "o16 "); break; + } } /* check if P_ASO prefix was used */ - if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { - switch (u->dis_mode) { - case 16: - mkasm(u, "a32 "); - break; - case 32: - mkasm(u, "a16 "); - break; - case 64: - mkasm(u, "a32 "); - break; - } + if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) { + switch (u->dis_mode) { + case 16: ud_asmprintf(u, "a32 "); break; + case 32: ud_asmprintf(u, "a16 "); break; + case 64: ud_asmprintf(u, "a32 "); break; + } } - if (u->pfx_lock) - mkasm(u, "lock "); - if (u->pfx_rep) - mkasm(u, "rep "); - if (u->pfx_repne) - mkasm(u, "repne "); - if (u->implicit_addr && u->pfx_seg) - mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); + if (u->pfx_seg && + u->operand[0].type != UD_OP_MEM && + u->operand[1].type != UD_OP_MEM ) { + ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); + } + + if (u->pfx_lock) { + ud_asmprintf(u, "lock "); + } + if (u->pfx_rep) { + ud_asmprintf(u, "rep "); + } else if (u->pfx_repe) { + ud_asmprintf(u, "repe "); + } else if (u->pfx_repne) { + ud_asmprintf(u, "repne "); + } /* print the instruction mnemonic */ - mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic)); + ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); - /* operand 1 */ if (u->operand[0].type != UD_NONE) { - gen_operand(u, &u->operand[0], u->c1); - } - /* operand 2 */ - if (u->operand[1].type != UD_NONE) { - mkasm(u, ", "); - gen_operand(u, &u->operand[1], u->c2); + int cast = 0; + ud_asmprintf(u, " "); + if (u->operand[0].type == UD_OP_MEM) { + if (u->operand[1].type == UD_OP_IMM || + u->operand[1].type == UD_OP_CONST || + u->operand[1].type == UD_NONE || + (u->operand[0].size != u->operand[1].size)) { + cast = 1; + } else if (u->operand[1].type == UD_OP_REG && + u->operand[1].base == UD_R_CL) { + switch (u->mnemonic) { + case UD_Ircl: + case UD_Irol: + case UD_Iror: + case UD_Ircr: + case UD_Ishl: + case UD_Ishr: + case UD_Isar: + cast = 1; + break; + default: break; + } + } + } + gen_operand(u, &u->operand[0], cast); + } + + if (u->operand[1].type != UD_NONE) { + int cast = 0; + ud_asmprintf(u, ", "); + if (u->operand[1].type == UD_OP_MEM && + u->operand[0].size != u->operand[1].size && + !ud_opr_is_sreg(&u->operand[0])) { + cast = 1; + } + gen_operand(u, &u->operand[1], cast); } - /* operand 3 */ if (u->operand[2].type != UD_NONE) { - mkasm(u, ", "); - gen_operand(u, &u->operand[2], u->c3); + int cast = 0; + ud_asmprintf(u, ", "); + if (u->operand[2].type == UD_OP_MEM && + u->operand[2].size != u->operand[1].size) { + cast = 1; + } + gen_operand(u, &u->operand[2], cast); + } + + if (u->operand[3].type != UD_NONE) { + ud_asmprintf(u, ", "); + gen_operand(u, &u->operand[3], 0); } } + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/syn.c b/udis86/libudis86/syn.c index 8019a11..1b9e1d4 100644 --- a/udis86/libudis86/syn.c +++ b/udis86/libudis86/syn.c @@ -1,61 +1,212 @@ -/* ----------------------------------------------------------------------------- - * syn.c +/* udis86 - libudis86/syn.c * - * Copyright (c) 2002, 2003, 2004 Vivek Mohan - * All rights reserved. See (LICENSE) - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "types.h" +#include "decode.h" +#include "syn.h" +#include "udint.h" -/* ----------------------------------------------------------------------------- - * Intel Register Table - Order Matters (types.h)! - * ----------------------------------------------------------------------------- +/* + * Register Table - Order Matters (types.h)! + * */ const char* ud_reg_tab[] = { - "al", "cl", "dl", "bl", - "ah", "ch", "dh", "bh", - "spl", "bpl", "sil", "dil", - "r8b", "r9b", "r10b", "r11b", - "r12b", "r13b", "r14b", "r15b", + "al", "cl", "dl", "bl", + "ah", "ch", "dh", "bh", + "spl", "bpl", "sil", "dil", + "r8b", "r9b", "r10b", "r11b", + "r12b", "r13b", "r14b", "r15b", - "ax", "cx", "dx", "bx", - "sp", "bp", "si", "di", - "r8w", "r9w", "r10w", "r11w", - "r12w", "r13W" , "r14w", "r15w", - - "eax", "ecx", "edx", "ebx", - "esp", "ebp", "esi", "edi", - "r8d", "r9d", "r10d", "r11d", - "r12d", "r13d", "r14d", "r15d", - - "rax", "rcx", "rdx", "rbx", - "rsp", "rbp", "rsi", "rdi", - "r8", "r9", "r10", "r11", - "r12", "r13", "r14", "r15", + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di", + "r8w", "r9w", "r10w", "r11w", + "r12w", "r13w", "r14w", "r15w", + + "eax", "ecx", "edx", "ebx", + "esp", "ebp", "esi", "edi", + "r8d", "r9d", "r10d", "r11d", + "r12d", "r13d", "r14d", "r15d", + + "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", - "es", "cs", "ss", "ds", - "fs", "gs", + "es", "cs", "ss", "ds", + "fs", "gs", - "cr0", "cr1", "cr2", "cr3", - "cr4", "cr5", "cr6", "cr7", - "cr8", "cr9", "cr10", "cr11", - "cr12", "cr13", "cr14", "cr15", - - "dr0", "dr1", "dr2", "dr3", - "dr4", "dr5", "dr6", "dr7", - "dr8", "dr9", "dr10", "dr11", - "dr12", "dr13", "dr14", "dr15", + "cr0", "cr1", "cr2", "cr3", + "cr4", "cr5", "cr6", "cr7", + "cr8", "cr9", "cr10", "cr11", + "cr12", "cr13", "cr14", "cr15", + + "dr0", "dr1", "dr2", "dr3", + "dr4", "dr5", "dr6", "dr7", + "dr8", "dr9", "dr10", "dr11", + "dr12", "dr13", "dr14", "dr15", - "mm0", "mm1", "mm2", "mm3", - "mm4", "mm5", "mm6", "mm7", + "mm0", "mm1", "mm2", "mm3", + "mm4", "mm5", "mm6", "mm7", - "st0", "st1", "st2", "st3", - "st4", "st5", "st6", "st7", + "st0", "st1", "st2", "st3", + "st4", "st5", "st6", "st7", - "xmm0", "xmm1", "xmm2", "xmm3", - "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", - "xmm12", "xmm13", "xmm14", "xmm15", + "xmm0", "xmm1", "xmm2", "xmm3", + "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", + "xmm12", "xmm13", "xmm14", "xmm15", + + "ymm0", "ymm1", "ymm2", "ymm3", + "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", + "ymm12", "ymm13", "ymm14", "ymm15", "rip" }; + + +uint64_t +ud_syn_rel_target(struct ud *u, struct ud_operand *opr) +{ + const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode); + switch (opr->size) { + case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask; + case 16: return (u->pc + opr->lval.sword) & trunc_mask; + case 32: return (u->pc + opr->lval.sdword) & trunc_mask; + default: UD_ASSERT(!"invalid relative offset size."); + return 0ull; + } +} + + +/* + * asmprintf + * Printf style function for printing translated assembly + * output. Returns the number of characters written and + * moves the buffer pointer forward. On an overflow, + * returns a negative number and truncates the output. + */ +int +ud_asmprintf(struct ud *u, const char *fmt, ...) +{ + int ret; + int avail; + va_list ap; + va_start(ap, fmt); + avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */; + ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap); + if (ret < 0 || ret > avail) { + u->asm_buf_fill = u->asm_buf_size - 1; + } else { + u->asm_buf_fill += ret; + } + va_end(ap); + return ret; +} + + +void +ud_syn_print_addr(struct ud *u, uint64_t addr) +{ + const char *name = NULL; + if (u->sym_resolver) { + int64_t offset = 0; + name = u->sym_resolver(u, addr, &offset); + if (name) { + if (offset) { + ud_asmprintf(u, "%s%+" FMT64 "d", name, offset); + } else { + ud_asmprintf(u, "%s", name); + } + return; + } + } + ud_asmprintf(u, "0x%" FMT64 "x", addr); +} + + +void +ud_syn_print_imm(struct ud* u, const struct ud_operand *op) +{ + uint64_t v; + if (op->_oprcode == OP_sI && op->size != u->opr_mode) { + if (op->size == 8) { + v = (int64_t)op->lval.sbyte; + } else { + UD_ASSERT(op->size == 32); + v = (int64_t)op->lval.sdword; + } + if (u->opr_mode < 64) { + v = v & ((1ull << u->opr_mode) - 1ull); + } + } else { + switch (op->size) { + case 8 : v = op->lval.ubyte; break; + case 16: v = op->lval.uword; break; + case 32: v = op->lval.udword; break; + case 64: v = op->lval.uqword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + } + ud_asmprintf(u, "0x%" FMT64 "x", v); +} + + +void +ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign) +{ + UD_ASSERT(op->offset != 0); + if (op->base == UD_NONE && op->index == UD_NONE) { + uint64_t v; + UD_ASSERT(op->scale == UD_NONE && op->offset != 8); + /* unsigned mem-offset */ + switch (op->offset) { + case 16: v = op->lval.uword; break; + case 32: v = op->lval.udword; break; + case 64: v = op->lval.uqword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + ud_asmprintf(u, "0x%" FMT64 "x", v); + } else { + int64_t v; + UD_ASSERT(op->offset != 64); + switch (op->offset) { + case 8 : v = op->lval.sbyte; break; + case 16: v = op->lval.sword; break; + case 32: v = op->lval.sdword; break; + default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */ + } + if (v < 0) { + ud_asmprintf(u, "-0x%" FMT64 "x", -v); + } else if (v > 0) { + ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v); + } + } +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/syn.h b/udis86/libudis86/syn.h index 7e62066..d3b1e3f 100644 --- a/udis86/libudis86/syn.h +++ b/udis86/libudis86/syn.h @@ -1,25 +1,53 @@ -/* ----------------------------------------------------------------------------- - * syn.h +/* udis86 - libudis86/syn.h * - * Copyright (c) 2006, Vivek Mohan - * All rights reserved. See LICENSE - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2009 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UD_SYN_H #define UD_SYN_H -#include -#include #include "types.h" +#ifndef __UD_STANDALONE__ +# include +#endif /* __UD_STANDALONE__ */ extern const char* ud_reg_tab[]; -static void mkasm(struct ud* u, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - u->insn_fill += vsprintf((char*) u->insn_buffer + u->insn_fill, fmt, ap); - va_end(ap); -} +uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*); +#ifdef __GNUC__ +int ud_asmprintf(struct ud *u, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); +#else +int ud_asmprintf(struct ud *u, const char *fmt, ...); #endif + +void ud_syn_print_addr(struct ud *u, uint64_t addr); +void ud_syn_print_imm(struct ud* u, const struct ud_operand *op); +void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign); + +#endif /* UD_SYN_H */ + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/types.h b/udis86/libudis86/types.h index 46afdc6..69072ca 100644 --- a/udis86/libudis86/types.h +++ b/udis86/libudis86/types.h @@ -1,31 +1,56 @@ -/* ----------------------------------------------------------------------------- - * types.h +/* udis86 - libudis86/types.h * - * Copyright (c) 2006, Vivek Mohan - * All rights reserved. See LICENSE - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UD_TYPES_H #define UD_TYPES_H -#include +#ifdef __KERNEL__ + /* + * -D__KERNEL__ is automatically passed on the command line when + * building something as part of the Linux kernel. Assume standalone + * mode. + */ +# include +# include +# ifndef __UD_STANDALONE__ +# define __UD_STANDALONE__ 1 +# endif +#endif /* __KERNEL__ */ -#ifdef _MSC_VER -# define FMT64 "%I64" - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; - typedef __int8 int8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef __int64 int64_t; -#else -# define FMT64 "%ll" -# include +#if !defined(__UD_STANDALONE__) +# include +# include #endif -#include "itab.h" +/* gcc specific extensions */ +#ifdef __GNUC__ +# define UD_ATTR_PACKED __attribute__((packed)) +#else +# define UD_ATTR_PACKED +#endif /* UD_ATTR_PACKED */ + /* ----------------------------------------------------------------------------- * All possible "types" of objects in udis86. Order is Important! @@ -36,95 +61,107 @@ enum ud_type UD_NONE, /* 8 bit GPRs */ - UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, - UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, - UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, - UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, - UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, + UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL, + UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH, + UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL, + UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B, + UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B, /* 16 bit GPRs */ - UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, - UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, - UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, - UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, - + UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX, + UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI, + UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W, + UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W, + /* 32 bit GPRs */ - UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, - UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, - UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, - UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, - + UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX, + UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI, + UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D, + UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D, + /* 64 bit GPRs */ - UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, - UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, - UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, - UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, + UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX, + UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI, + UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11, + UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15, /* segment registers */ - UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, - UD_R_FS, UD_R_GS, + UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS, + UD_R_FS, UD_R_GS, /* control registers*/ - UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, - UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, - UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, - UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, - + UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3, + UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7, + UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11, + UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15, + /* debug registers */ - UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, - UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, - UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, - UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, + UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3, + UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7, + UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11, + UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15, /* mmx registers */ - UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, - UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, + UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3, + UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7, /* x87 registers */ - UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, - UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, + UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3, + UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7, /* extended multimedia registers */ - UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, - UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, - UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, - UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, + UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3, + UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7, + UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11, + UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15, + + /* 256B multimedia registers */ + UD_R_YMM0, UD_R_YMM1, UD_R_YMM2, UD_R_YMM3, + UD_R_YMM4, UD_R_YMM5, UD_R_YMM6, UD_R_YMM7, + UD_R_YMM8, UD_R_YMM9, UD_R_YMM10, UD_R_YMM11, + UD_R_YMM12, UD_R_YMM13, UD_R_YMM14, UD_R_YMM15, UD_R_RIP, /* Operand Types */ - UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, - UD_OP_JIMM, UD_OP_CONST + UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM, + UD_OP_JIMM, UD_OP_CONST +}; + +#include "itab.h" + +union ud_lval { + int8_t sbyte; + uint8_t ubyte; + int16_t sword; + uint16_t uword; + int32_t sdword; + uint32_t udword; + int64_t sqword; + uint64_t uqword; + struct { + uint16_t seg; + uint32_t off; + } ptr; }; /* ----------------------------------------------------------------------------- * struct ud_operand - Disassembled instruction Operand. * ----------------------------------------------------------------------------- */ -struct ud_operand -{ - enum ud_type type; - uint8_t size; - union { - int8_t sbyte; - uint8_t ubyte; - int16_t sword; - uint16_t uword; - int32_t sdword; - uint32_t udword; - int64_t sqword; - uint64_t uqword; - - struct { - uint16_t seg; - uint32_t off; - } ptr; - } lval; - - enum ud_type base; - enum ud_type index; - uint8_t offset; - uint8_t scale; +struct ud_operand { + enum ud_type type; + uint16_t size; + enum ud_type base; + enum ud_type index; + uint8_t scale; + uint8_t offset; + union ud_lval lval; + /* + * internal use only + */ + uint64_t _legacy; /* this will be removed in 1.8 */ + uint8_t _oprcode; }; /* ----------------------------------------------------------------------------- @@ -133,68 +170,91 @@ struct ud_operand */ struct ud { - int (*inp_hook) (struct ud*); - uint8_t inp_curr; - uint8_t inp_fill; - FILE* inp_file; - uint8_t inp_ctr; - uint8_t* inp_buff; - uint8_t* inp_buff_end; - uint8_t inp_end; - void (*translator)(struct ud*); - uint64_t insn_offset; - char insn_hexcode[32]; - char insn_buffer[64]; - unsigned int insn_fill; - uint8_t dis_mode; - uint64_t pc; - uint8_t vendor; - struct map_entry* mapen; - enum ud_mnemonic_code mnemonic; - struct ud_operand operand[3]; - uint8_t error; - uint8_t pfx_rex; - uint8_t pfx_seg; - uint8_t pfx_opr; - uint8_t pfx_adr; - uint8_t pfx_lock; - uint8_t pfx_rep; - uint8_t pfx_repe; - uint8_t pfx_repne; - uint8_t pfx_insn; - uint8_t default64; - uint8_t opr_mode; - uint8_t adr_mode; - uint8_t br_far; - uint8_t br_near; - uint8_t implicit_addr; - uint8_t c1; - uint8_t c2; - uint8_t c3; - uint8_t inp_cache[256]; - uint8_t inp_sess[64]; + /* + * input buffering + */ + int (*inp_hook) (struct ud*); +#ifndef __UD_STANDALONE__ + FILE* inp_file; +#endif + const uint8_t* inp_buf; + size_t inp_buf_size; + size_t inp_buf_index; + uint8_t inp_curr; + size_t inp_ctr; + uint8_t inp_sess[64]; + int inp_end; + int inp_peek; + + void (*translator)(struct ud*); + uint64_t insn_offset; + char insn_hexcode[64]; + + /* + * Assembly output buffer + */ + char *asm_buf; + size_t asm_buf_size; + size_t asm_buf_fill; + char asm_buf_int[128]; + + /* + * Symbol resolver for use in the translation phase. + */ + const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset); + + uint8_t dis_mode; + uint64_t pc; + uint8_t vendor; + enum ud_mnemonic_code mnemonic; + struct ud_operand operand[4]; + uint8_t error; + uint8_t _rex; + uint8_t pfx_rex; + uint8_t pfx_seg; + uint8_t pfx_opr; + uint8_t pfx_adr; + uint8_t pfx_lock; + uint8_t pfx_str; + uint8_t pfx_rep; + uint8_t pfx_repe; + uint8_t pfx_repne; + uint8_t opr_mode; + uint8_t adr_mode; + uint8_t br_far; + uint8_t br_near; + uint8_t have_modrm; + uint8_t modrm; + uint8_t modrm_offset; + uint8_t vex_op; + uint8_t vex_b1; + uint8_t vex_b2; + uint8_t primary_opcode; + void * user_opaque_data; struct ud_itab_entry * itab_entry; + struct ud_lookup_table_list_entry *le; }; /* ----------------------------------------------------------------------------- * Type-definitions * ----------------------------------------------------------------------------- */ -typedef enum ud_type ud_type_t; -typedef enum ud_mnemonic_code ud_mnemonic_code_t; +typedef enum ud_type ud_type_t; +typedef enum ud_mnemonic_code ud_mnemonic_code_t; -typedef struct ud ud_t; -typedef struct ud_operand ud_operand_t; +typedef struct ud ud_t; +typedef struct ud_operand ud_operand_t; -#define UD_SYN_INTEL ud_translate_intel -#define UD_SYN_ATT ud_translate_att -#define UD_EOI -1 -#define UD_INP_CACHE_SZ 32 -#define UD_VENDOR_AMD 0 -#define UD_VENDOR_INTEL 1 - -#define bail_out(ud,error_code) longjmp( (ud)->bailout, error_code ) -#define try_decode(ud) if ( setjmp( (ud)->bailout ) == 0 ) -#define catch_error() else +#define UD_SYN_INTEL ud_translate_intel +#define UD_SYN_ATT ud_translate_att +#define UD_EOI (-1) +#define UD_INP_CACHE_SZ 32 +#define UD_VENDOR_AMD 0 +#define UD_VENDOR_INTEL 1 +#define UD_VENDOR_ANY 2 #endif + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/udis86/libudis86/udint.h b/udis86/libudis86/udint.h new file mode 100644 index 0000000..734f0ea --- /dev/null +++ b/udis86/libudis86/udint.h @@ -0,0 +1,99 @@ +/* udis86 - libudis86/udint.h -- definitions for internal use only + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _UDINT_H_ +#define _UDINT_H_ + +#include "types.h" + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#if defined(UD_DEBUG) && HAVE_ASSERT_H +# include +# define UD_ASSERT(_x) assert(_x) +#else +# define UD_ASSERT(_x) +#endif /* !HAVE_ASSERT_H */ + +#if defined(UD_DEBUG) + #define UDERR(u, msg) \ + do { \ + (u)->error = 1; \ + fprintf(stderr, "decode-error: %s:%d: %s", \ + __FILE__, __LINE__, (msg)); \ + } while (0) +#else + #define UDERR(u, m) \ + do { \ + (u)->error = 1; \ + } while (0) +#endif /* !LOGERR */ + +#define UD_RETURN_ON_ERROR(u) \ + do { \ + if ((u)->error != 0) { \ + return (u)->error; \ + } \ + } while (0) + +#define UD_RETURN_WITH_ERROR(u, m) \ + do { \ + UDERR(u, m); \ + return (u)->error; \ + } while (0) + +#ifndef __UD_STANDALONE__ +# define UD_NON_STANDALONE(x) x +#else +# define UD_NON_STANDALONE(x) +#endif + +/* printf formatting int64 specifier */ +#ifdef FMT64 +# undef FMT64 +#endif +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define FMT64 "I64" +#else +# if defined(__APPLE__) +# define FMT64 "ll" +# elif defined(__amd64__) || defined(__x86_64__) +# define FMT64 "l" +# else +# define FMT64 "ll" +# endif /* !x64 */ +#endif + +/* define an inline macro */ +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define UD_INLINE __inline /* MS Visual Studio requires __inline + instead of inline for C code */ +#else +# define UD_INLINE inline +#endif + +#endif /* _UDINT_H_ */ diff --git a/udis86/libudis86/udis86.c b/udis86/libudis86/udis86.c index dd1422f..e039c4e 100644 --- a/udis86/libudis86/udis86.c +++ b/udis86/libudis86/udis86.c @@ -1,20 +1,44 @@ -/* ----------------------------------------------------------------------------- - * udis86.c +/* udis86 - libudis86/udis86.c * - * Copyright (c) 2004, 2005, 2006, Vivek Mohan - * All rights reserved. See LICENSE - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include - -#include "input.h" +#include "udint.h" #include "extern.h" +#include "decode.h" + +#if !defined(__UD_STANDALONE__) +# if HAVE_STRING_H +# include +# endif +#endif /* !__UD_STANDALONE__ */ + +static void ud_inp_init(struct ud *u); /* ============================================================================= - * ud_init() - Initializes ud_t object. + * ud_init + * Initializes ud_t object. * ============================================================================= */ extern void @@ -27,30 +51,34 @@ ud_init(struct ud* u) #ifndef __UD_STANDALONE__ ud_set_input_file(u, stdin); #endif /* __UD_STANDALONE__ */ + + ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); } + /* ============================================================================= - * ud_disassemble() - disassembles one instruction and returns the number of - * bytes disassembled. A zero means end of disassembly. + * ud_disassemble + * Disassembles one instruction and returns the number of + * bytes disassembled. A zero means end of disassembly. * ============================================================================= */ extern unsigned int ud_disassemble(struct ud* u) { - if (ud_input_end(u)) - return 0; - - - u->insn_buffer[0] = u->insn_hexcode[0] = 0; - - - if (ud_decode(u) == 0) - return 0; - if (u->translator) - u->translator(u); - return ud_insn_len(u); + int len; + if (u->inp_end) { + return 0; + } + if ((len = ud_decode(u)) > 0) { + if (u->translator != NULL) { + u->asm_buf[0] = '\0'; + u->translator(u); + } + } + return len; } + /* ============================================================================= * ud_set_mode() - Set Disassemly Mode. * ============================================================================= @@ -59,10 +87,10 @@ extern void ud_set_mode(struct ud* u, uint8_t m) { switch(m) { - case 16: - case 32: - case 64: u->dis_mode = m ; return; - default: u->dis_mode = 16; return; + case 16: + case 32: + case 64: u->dis_mode = m ; return; + default: u->dis_mode = 16; return; } } @@ -74,11 +102,14 @@ extern void ud_set_vendor(struct ud* u, unsigned v) { switch(v) { - case UD_VENDOR_INTEL: - u->vendor = v; - break; - default: - u->vendor = UD_VENDOR_AMD; + case UD_VENDOR_INTEL: + u->vendor = v; + break; + case UD_VENDOR_ANY: + u->vendor = v; + break; + default: + u->vendor = UD_VENDOR_AMD; } } @@ -106,18 +137,18 @@ ud_set_syntax(struct ud* u, void (*t)(struct ud*)) * ud_insn() - returns the disassembled instruction * ============================================================================= */ -extern char* -ud_insn_asm(struct ud* u) +const char* +ud_insn_asm(const struct ud* u) { - return u->insn_buffer; + return u->asm_buf; } /* ============================================================================= * ud_insn_offset() - Returns the offset. * ============================================================================= */ -extern uint64_t -ud_insn_off(struct ud* u) +uint64_t +ud_insn_off(const struct ud* u) { return u->insn_offset; } @@ -127,28 +158,301 @@ ud_insn_off(struct ud* u) * ud_insn_hex() - Returns hex form of disassembled instruction. * ============================================================================= */ -extern char* +const char* ud_insn_hex(struct ud* u) { + u->insn_hexcode[0] = 0; + if (!u->error) { + unsigned int i; + const unsigned char *src_ptr = ud_insn_ptr(u); + char* src_hex; + src_hex = (char*) u->insn_hexcode; + /* for each byte used to decode instruction */ + for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2; + ++i, ++src_ptr) { + sprintf(src_hex, "%02x", *src_ptr & 0xFF); + src_hex += 2; + } + } return u->insn_hexcode; } -/* ============================================================================= - * ud_insn_ptr() - Returns code disassembled. - * ============================================================================= - */ -extern uint8_t* -ud_insn_ptr(struct ud* u) -{ - return u->inp_sess; -} /* ============================================================================= - * ud_insn_len() - Returns the count of bytes disassembled. + * ud_insn_ptr + * Returns a pointer to buffer containing the bytes that were + * disassembled. + * ============================================================================= + */ +extern const uint8_t* +ud_insn_ptr(const struct ud* u) +{ + return (u->inp_buf == NULL) ? + u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr); +} + + +/* ============================================================================= + * ud_insn_len + * Returns the count of bytes disassembled. * ============================================================================= */ extern unsigned int -ud_insn_len(struct ud* u) +ud_insn_len(const struct ud* u) { return u->inp_ctr; } + + +/* ============================================================================= + * ud_insn_get_opr + * Return the operand struct representing the nth operand of + * the currently disassembled instruction. Returns NULL if + * there's no such operand. + * ============================================================================= + */ +const struct ud_operand* +ud_insn_opr(const struct ud *u, unsigned int n) +{ + if (n > 3 || u->operand[n].type == UD_NONE) { + return NULL; + } else { + return &u->operand[n]; + } +} + + +/* ============================================================================= + * ud_opr_is_sreg + * Returns non-zero if the given operand is of a segment register type. + * ============================================================================= + */ +int +ud_opr_is_sreg(const struct ud_operand *opr) +{ + return opr->type == UD_OP_REG && + opr->base >= UD_R_ES && + opr->base <= UD_R_GS; +} + + +/* ============================================================================= + * ud_opr_is_sreg + * Returns non-zero if the given operand is of a general purpose + * register type. + * ============================================================================= + */ +int +ud_opr_is_gpr(const struct ud_operand *opr) +{ + return opr->type == UD_OP_REG && + opr->base >= UD_R_AL && + opr->base <= UD_R_R15; +} + + +/* ============================================================================= + * ud_set_user_opaque_data + * ud_get_user_opaque_data + * Get/set user opaqute data pointer + * ============================================================================= + */ +void +ud_set_user_opaque_data(struct ud * u, void* opaque) +{ + u->user_opaque_data = opaque; +} + +void* +ud_get_user_opaque_data(const struct ud *u) +{ + return u->user_opaque_data; +} + + +/* ============================================================================= + * ud_set_asm_buffer + * Allow the user to set an assembler output buffer. If `buf` is NULL, + * we switch back to the internal buffer. + * ============================================================================= + */ +void +ud_set_asm_buffer(struct ud *u, char *buf, size_t size) +{ + if (buf == NULL) { + ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int)); + } else { + u->asm_buf = buf; + u->asm_buf_size = size; + } +} + + +/* ============================================================================= + * ud_set_sym_resolver + * Set symbol resolver for relative targets used in the translation + * phase. + * + * The resolver is a function that takes a uint64_t address and returns a + * symbolic name for the that address. The function also takes a second + * argument pointing to an integer that the client can optionally set to a + * non-zero value for offsetted targets. (symbol+offset) The function may + * also return NULL, in which case the translator only prints the target + * address. + * + * The function pointer maybe NULL which resets symbol resolution. + * ============================================================================= + */ +void +ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*, + uint64_t addr, + int64_t *offset)) +{ + u->sym_resolver = resolver; +} + + +/* ============================================================================= + * ud_insn_mnemonic + * Return the current instruction mnemonic. + * ============================================================================= + */ +enum ud_mnemonic_code +ud_insn_mnemonic(const struct ud *u) +{ + return u->mnemonic; +} + + +/* ============================================================================= + * ud_lookup_mnemonic + * Looks up mnemonic code in the mnemonic string table. + * Returns NULL if the mnemonic code is invalid. + * ============================================================================= + */ +const char* +ud_lookup_mnemonic(enum ud_mnemonic_code c) +{ + if (c < UD_MAX_MNEMONIC_CODE) { + return ud_mnemonics_str[c]; + } else { + return NULL; + } +} + + +/* + * ud_inp_init + * Initializes the input system. + */ +static void +ud_inp_init(struct ud *u) +{ + u->inp_hook = NULL; + u->inp_buf = NULL; + u->inp_buf_size = 0; + u->inp_buf_index = 0; + u->inp_curr = 0; + u->inp_ctr = 0; + u->inp_end = 0; + u->inp_peek = UD_EOI; + UD_NON_STANDALONE(u->inp_file = NULL); +} + + +/* ============================================================================= + * ud_inp_set_hook + * Sets input hook. + * ============================================================================= + */ +void +ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) +{ + ud_inp_init(u); + u->inp_hook = hook; +} + +/* ============================================================================= + * ud_inp_set_buffer + * Set buffer as input. + * ============================================================================= + */ +void +ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) +{ + ud_inp_init(u); + u->inp_buf = buf; + u->inp_buf_size = len; + u->inp_buf_index = 0; +} + + +#ifndef __UD_STANDALONE__ +/* ============================================================================= + * ud_input_set_file + * Set FILE as input. + * ============================================================================= + */ +static int +inp_file_hook(struct ud* u) +{ + return fgetc(u->inp_file); +} + +void +ud_set_input_file(register struct ud* u, FILE* f) +{ + ud_inp_init(u); + u->inp_hook = inp_file_hook; + u->inp_file = f; +} +#endif /* __UD_STANDALONE__ */ + + +/* ============================================================================= + * ud_input_skip + * Skip n input bytes. + * ============================================================================ + */ +void +ud_input_skip(struct ud* u, size_t n) +{ + if (u->inp_end) { + return; + } + if (u->inp_buf == NULL) { + while (n--) { + int c = u->inp_hook(u); + if (c == UD_EOI) { + goto eoi; + } + } + return; + } else { + if (n > u->inp_buf_size || + u->inp_buf_index > u->inp_buf_size - n) { + u->inp_buf_index = u->inp_buf_size; + goto eoi; + } + u->inp_buf_index += n; + return; + } +eoi: + u->inp_end = 1; + UDERR(u, "cannot skip, eoi received\b"); + return; +} + + +/* ============================================================================= + * ud_input_end + * Returns non-zero on end-of-input. + * ============================================================================= + */ +int +ud_input_end(const struct ud *u) +{ + return u->inp_end; +} + +/* vim:set ts=2 sw=2 expandtab */ diff --git a/udis86/m4/ax_compare_version.m4 b/udis86/m4/ax_compare_version.m4 new file mode 100644 index 0000000..74dc0fd --- /dev/null +++ b/udis86/m4/ax_compare_version.m4 @@ -0,0 +1,177 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# This macro compares two version strings. Due to the various number of +# minor-version numbers that can exist, and the fact that string +# comparisons are not compatible with numeric comparisons, this is not +# necessarily trivial to do in a autoconf script. This macro makes doing +# these comparisons easy. +# +# The six basic comparisons are available, as well as checking equality +# limited to a certain number of minor-version levels. +# +# The operator OP determines what type of comparison to do, and can be one +# of: +# +# eq - equal (test A == B) +# ne - not equal (test A != B) +# le - less than or equal (test A <= B) +# ge - greater than or equal (test A >= B) +# lt - less than (test A < B) +# gt - greater than (test A > B) +# +# Additionally, the eq and ne operator can have a number after it to limit +# the test to that number of minor versions. +# +# eq0 - equal up to the length of the shorter version +# ne0 - not equal up to the length of the shorter version +# eqN - equal up to N sub-version levels +# neN - not equal up to N sub-version levels +# +# When the condition is true, shell commands ACTION-IF-TRUE are run, +# otherwise shell commands ACTION-IF-FALSE are run. The environment +# variable 'ax_compare_version' is always set to either 'true' or 'false' +# as well. +# +# Examples: +# +# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) +# +# would both be true. +# +# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) +# +# would both be false. +# +# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) +# +# would be true because it is only comparing two minor versions. +# +# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) +# +# would be true because it is only comparing the lesser number of minor +# versions of the two values. +# +# Note: The characters that separate the version numbers do not matter. An +# empty string is the same as version 0. OP is evaluated by autoconf, not +# configure, so must be a string, not a variable. +# +# The author would like to acknowledge Guido Draheim whose advice about +# the m4_case and m4_ifvaln functions make this macro only include the +# portions necessary to perform the specific comparison specified by the +# OP argument in the final configure script. +# +# LICENSE +# +# Copyright (c) 2008 Tim Toolan +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +dnl ######################################################################### +AC_DEFUN([AX_COMPARE_VERSION], [ + AC_REQUIRE([AC_PROG_AWK]) + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + AS_VAR_PUSHDEF([A],[ax_compare_version_A]) + A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + AS_VAR_PUSHDEF([B],[ax_compare_version_B]) + B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary + dnl # then the first line is used to determine if the condition is true. + dnl # The sed right after the echo is to remove any indented white space. + m4_case(m4_tolower($2), + [lt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [gt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [le],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ], + [ge],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ],[ + dnl Split the operator from the subversion count if present. + m4_bmatch(m4_substr($2,2), + [0],[ + # A count of zero means use the length of the shorter version. + # Determine the number of characters in A and B. + ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` + ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` + + # Set A to no more than B's length and B to no more than A's length. + A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` + B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` + ], + [[0-9]+],[ + # A count greater than zero means use only that many subversions + A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + ], + [.+],[ + AC_WARNING( + [illegal OP numeric parameter: $2]) + ],[]) + + # Pad zeros at end of numbers to make same length. + ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" + B="$B`echo $A | sed 's/./0/g'`" + A="$ax_compare_version_tmp_A" + + # Check for equality or inequality as necessary. + m4_case(m4_tolower(m4_substr($2,0,2)), + [eq],[ + test "x$A" = "x$B" && ax_compare_version=true + ], + [ne],[ + test "x$A" != "x$B" && ax_compare_version=true + ],[ + AC_WARNING([illegal OP parameter: $2]) + ]) + ]) + + AS_VAR_POPDEF([A])dnl + AS_VAR_POPDEF([B])dnl + + dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. + if test "$ax_compare_version" = "true" ; then + m4_ifvaln([$4],[$4],[:])dnl + m4_ifvaln([$5],[else $5])dnl + fi +]) dnl AX_COMPARE_VERSION diff --git a/udis86/m4/ax_prog_sphinx_version.m4 b/udis86/m4/ax_prog_sphinx_version.m4 new file mode 100644 index 0000000..70ae7e2 --- /dev/null +++ b/udis86/m4/ax_prog_sphinx_version.m4 @@ -0,0 +1,60 @@ +# SYNOPSIS +# +# AX_PROG_SPHINX_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# Makes sure that sphinx-build supports the version indicated. If true +# the shell commands in ACTION-IF-TRUE are executed. If not the shell +# commands in ACTION-IF-FALSE are run. Note if $SPHINX_BUILD is not set +# (for example by running AX_WITH_PROG) the macro will fail. +# +# Example: +# +# AX_WITH_PROG(SPHINX_BUILD,sphinx-build) +# AX_PROG_SPHINX([1.1.1],[ ... ],[ ... ]) +# +# LICENSE +# +# ax_prog_python_version.m4 +# +# Copyright (c) 2009 Francesco Salvestrini +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. +# +# ax_prog_sphinx_version.m4 +# +# Copyright (c) 2013 Vivek Thampi + + +AC_DEFUN([AX_PROG_SPHINX],[ + AC_REQUIRE([AC_PROG_SED]) + AC_REQUIRE([AC_PROG_GREP]) + + + AS_IF([test -n "$SPHINX_BUILD"],[ + ax_sphinx_version="$1" + + AC_MSG_CHECKING([for sphinx version]) + changequote(<<,>>) + sphinx_version=`$SPHINX_BUILD -h 2>&1 | $GREP "^Sphinx v" | $SED -e 's/^.* v\([0-9]*\.[0-9]*\.[0-9]*\)/\1/'` + changequote([,]) + AC_MSG_RESULT($sphinx_version) + + AC_SUBST([SPHINX_VERSION],[$sphinx_version]) + + AX_COMPARE_VERSION([$ax_sphinx_version],[le],[$sphinx_version],[ + : + $2 + ],[ + : + $3 + ]) + ],[ + AC_MSG_WARN([could not find the sphinx documentation tool]) + $3 + ]) +]) diff --git a/udis86/m4/ax_prog_yasm_version.m4 b/udis86/m4/ax_prog_yasm_version.m4 new file mode 100644 index 0000000..9adafcb --- /dev/null +++ b/udis86/m4/ax_prog_yasm_version.m4 @@ -0,0 +1,60 @@ +# SYNOPSIS +# +# AX_PROG_YASM_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# Makes sure that yasm supports the version indicated. If true +# the shell commands in ACTION-IF-TRUE are executed. If not the shell +# commands in ACTION-IF-FALSE are run. Note if $YASM is not set +# (for example by running AX_WITH_PROG) the macro will fail. +# +# Example: +# +# AX_WITH_PROG(YASM,yasm) +# AX_PROG_YASM_VERSION([1.1.1],[ ... ],[ ... ]) +# +# LICENSE +# +# ax_prog_python_version.m4 +# +# Copyright (c) 2009 Francesco Salvestrini +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. +# +# ax_prog_yasm_version.m4 +# +# Copyright (c) 2013 Vivek Thampi + + +AC_DEFUN([AX_PROG_YASM_VERSION],[ + AC_REQUIRE([AC_PROG_SED]) + AC_REQUIRE([AC_PROG_GREP]) + + + AS_IF([test -n "$YASM"],[ + ax_yasm_version="$1" + + AC_MSG_CHECKING([for yasm version]) + changequote(<<,>>) + yasm_version=`$YASM --version 2>&1 | $GREP "^yasm " | $SED -e 's/^.* \([0-9]*\.[0-9]*\.[0-9]*\)/\1/'` + changequote([,]) + AC_MSG_RESULT($yasm_version) + + AC_SUBST([YASM_VERSION],[$yasm_version]) + + AX_COMPARE_VERSION([$ax_yasm_version],[le],[$yasm_version],[ + : + $2 + ],[ + : + $3 + ]) + ],[ + AC_MSG_WARN([could not find the yasm]) + $3 + ]) +]) diff --git a/udis86/m4/ax_with_prog.m4 b/udis86/m4/ax_with_prog.m4 new file mode 100644 index 0000000..e20276c --- /dev/null +++ b/udis86/m4/ax_with_prog.m4 @@ -0,0 +1,67 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_with_prog.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH]) +# +# DESCRIPTION +# +# Locates an installed program binary, placing the result in the precious +# variable VARIABLE. Accepts a present VARIABLE, then --with-program, and +# failing that searches for program in the given path (which defaults to +# the system path). If program is found, VARIABLE is set to the full path +# of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND +# if provided, unchanged otherwise. +# +# A typical example could be the following one: +# +# AX_WITH_PROG(PERL,perl) +# +# NOTE: This macro is based upon the original AX_WITH_PYTHON macro from +# Dustin J. Mitchell . +# +# LICENSE +# +# Copyright (c) 2008 Francesco Salvestrini +# Copyright (c) 2008 Dustin J. Mitchell +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_WITH_PROG],[ + AC_PREREQ([2.61]) + + pushdef([VARIABLE],$1) + pushdef([EXECUTABLE],$2) + pushdef([VALUE_IF_NOT_FOUND],$3) + pushdef([PATH_PROG],$4) + + AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable) + + AS_IF(test -z "$VARIABLE",[ + AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided) + AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[[PATH]]]]],absolute path to EXECUTABLE executable), [ + AS_IF([test "$withval" != yes -a "$withval" != no],[ + VARIABLE="$withval" + AC_MSG_RESULT($VARIABLE) + ],[ + VARIABLE="" + AC_MSG_RESULT([no]) + AS_IF([test "$withval" != no], [ + AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) + ]) + ]) + ],[ + AC_MSG_RESULT([no]) + AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) + ]) + ]) + + popdef([PATH_PROG]) + popdef([VALUE_IF_NOT_FOUND]) + popdef([EXECUTABLE]) + popdef([VARIABLE]) +]) diff --git a/udis86/m4/ax_with_python.m4 b/udis86/m4/ax_with_python.m4 new file mode 100644 index 0000000..e109928 --- /dev/null +++ b/udis86/m4/ax_with_python.m4 @@ -0,0 +1,32 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_with_python.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_WITH_PYTHON([VALUE-IF-NOT-FOUND],[PATH]) +# +# DESCRIPTION +# +# Locates an installed Python binary, placing the result in the precious +# variable $PYTHON. Accepts a present $PYTHON, then --with-python, and +# failing that searches for python in the given path (which defaults to +# the system path). If python is found, $PYTHON is set to the full path of +# the binary; if it is not found $PYTHON is set to VALUE-IF-NOT-FOUND if +# provided, unchanged otherwise. +# +# A typical use could be the following one: +# +# AX_WITH_PYTHON +# +# LICENSE +# +# Copyright (c) 2008 Francesco Salvestrini +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_WITH_PYTHON],[ + AX_WITH_PROG(PYTHON,python,$1,$2) +]) diff --git a/udis86/scripts/Makefile.am b/udis86/scripts/Makefile.am new file mode 100644 index 0000000..2996a6c --- /dev/null +++ b/udis86/scripts/Makefile.am @@ -0,0 +1,9 @@ +EXTRA_DIST = \ + ud_opcode.py \ + ud_itab.py + +MAINTAINERCLEANFILES = Makefile.in + +clean-local: + -rm -f *.pyc + -rm -f ud_asmtest* diff --git a/udis86/scripts/asmtest.sh b/udis86/scripts/asmtest.sh new file mode 100644 index 0000000..4406cea --- /dev/null +++ b/udis86/scripts/asmtest.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +objdump="otool -tV" +yasm=yasm +asmfile="ud_yasmtest.asm" +binfile="ud_yasmtest.bin" +Sfile="ud_yasmtest.S" +objfile="ud_yasmtest.o" + +echo "[bits $1]" > $asmfile +echo $2 >> $asmfile + +$yasm -f bin -o $binfile $asmfile + +if [ ! $? -eq 0 ]; then + echo "error: failed to assemble" + exit 1 +fi + +echo "-- hexdump --------------------------------------" +hexdump $binfile +echo + +echo "-- objdump --------------------------------------" +hexdump -e '1/1 ".byte 0x%02x\n"' $binfile > $Sfile +gcc -c $Sfile -o $objfile +$objdump -d $objfile +echo + +echo "-- udcli (intel) ---------------------------------" +../udcli/udcli -$1 $binfile +echo + +echo "-- udcli (at&t) ----------------------------------" +../udcli/udcli -$1 -att $binfile +echo + +exit 0 diff --git a/udis86/scripts/ud_itab.py b/udis86/scripts/ud_itab.py new file mode 100644 index 0000000..31d859e --- /dev/null +++ b/udis86/scripts/ud_itab.py @@ -0,0 +1,379 @@ +# udis86 - scripts/ud_itab.py +# +# Copyright (c) 2009, 2013 Vivek Thampi +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +from ud_opcode import UdOpcodeTable, UdOpcodeTables, UdInsnDef + +class UdItabGenerator: + + OperandDict = { + "Av" : [ "OP_A" , "SZ_V" ], + "E" : [ "OP_E" , "SZ_NA" ], + "Eb" : [ "OP_E" , "SZ_B" ], + "Ew" : [ "OP_E" , "SZ_W" ], + "Ev" : [ "OP_E" , "SZ_V" ], + "Ed" : [ "OP_E" , "SZ_D" ], + "Ey" : [ "OP_E" , "SZ_Y" ], + "Eq" : [ "OP_E" , "SZ_Q" ], + "Ez" : [ "OP_E" , "SZ_Z" ], + "Fv" : [ "OP_F" , "SZ_V" ], + "G" : [ "OP_G" , "SZ_NA" ], + "Gb" : [ "OP_G" , "SZ_B" ], + "Gw" : [ "OP_G" , "SZ_W" ], + "Gv" : [ "OP_G" , "SZ_V" ], + "Gy" : [ "OP_G" , "SZ_Y" ], + "Gd" : [ "OP_G" , "SZ_D" ], + "Gq" : [ "OP_G" , "SZ_Q" ], + "Gz" : [ "OP_G" , "SZ_Z" ], + "M" : [ "OP_M" , "SZ_NA" ], + "Mb" : [ "OP_M" , "SZ_B" ], + "Mw" : [ "OP_M" , "SZ_W" ], + "Ms" : [ "OP_M" , "SZ_W" ], + "Md" : [ "OP_M" , "SZ_D" ], + "Mq" : [ "OP_M" , "SZ_Q" ], + "Mdq" : [ "OP_M" , "SZ_DQ" ], + "Mv" : [ "OP_M" , "SZ_V" ], + "Mt" : [ "OP_M" , "SZ_T" ], + "Mo" : [ "OP_M" , "SZ_O" ], + "MbRd" : [ "OP_MR" , "SZ_BD" ], + "MbRv" : [ "OP_MR" , "SZ_BV" ], + "MwRv" : [ "OP_MR" , "SZ_WV" ], + "MwRd" : [ "OP_MR" , "SZ_WD" ], + "MwRy" : [ "OP_MR" , "SZ_WY" ], + "MdRy" : [ "OP_MR" , "SZ_DY" ], + "I1" : [ "OP_I1" , "SZ_NA" ], + "I3" : [ "OP_I3" , "SZ_NA" ], + "Ib" : [ "OP_I" , "SZ_B" ], + "Iw" : [ "OP_I" , "SZ_W" ], + "Iv" : [ "OP_I" , "SZ_V" ], + "Iz" : [ "OP_I" , "SZ_Z" ], + "sIb" : [ "OP_sI" , "SZ_B" ], + "sIz" : [ "OP_sI" , "SZ_Z" ], + "sIv" : [ "OP_sI" , "SZ_V" ], + "Jv" : [ "OP_J" , "SZ_V" ], + "Jz" : [ "OP_J" , "SZ_Z" ], + "Jb" : [ "OP_J" , "SZ_B" ], + "R" : [ "OP_R" , "SZ_RDQ" ], + "C" : [ "OP_C" , "SZ_NA" ], + "D" : [ "OP_D" , "SZ_NA" ], + "S" : [ "OP_S" , "SZ_W" ], + "Ob" : [ "OP_O" , "SZ_B" ], + "Ow" : [ "OP_O" , "SZ_W" ], + "Ov" : [ "OP_O" , "SZ_V" ], + "U" : [ "OP_U" , "SZ_O" ], + "Ux" : [ "OP_U" , "SZ_X" ], + "V" : [ "OP_V" , "SZ_DQ" ], + "Vdq" : [ "OP_V" , "SZ_DQ" ], + "Vqq" : [ "OP_V" , "SZ_QQ" ], + "Vsd" : [ "OP_V" , "SZ_Q" ], + "Vx" : [ "OP_V" , "SZ_X" ], + "H" : [ "OP_H" , "SZ_X" ], + "Hx" : [ "OP_H" , "SZ_X" ], + "Hqq" : [ "OP_H" , "SZ_QQ" ], + "W" : [ "OP_W" , "SZ_DQ" ], + "Wdq" : [ "OP_W" , "SZ_DQ" ], + "Wqq" : [ "OP_W" , "SZ_QQ" ], + "Wsd" : [ "OP_W" , "SZ_Q" ], + "Wx" : [ "OP_W" , "SZ_X" ], + "L" : [ "OP_L" , "SZ_O" ], + "Lx" : [ "OP_L" , "SZ_X" ], + "MwU" : [ "OP_MU" , "SZ_WO" ], + "MdU" : [ "OP_MU" , "SZ_DO" ], + "MqU" : [ "OP_MU" , "SZ_QO" ], + "N" : [ "OP_N" , "SZ_Q" ], + "P" : [ "OP_P" , "SZ_Q" ], + "Q" : [ "OP_Q" , "SZ_Q" ], + "AL" : [ "OP_AL" , "SZ_B" ], + "AX" : [ "OP_AX" , "SZ_W" ], + "eAX" : [ "OP_eAX" , "SZ_Z" ], + "rAX" : [ "OP_rAX" , "SZ_V" ], + "CL" : [ "OP_CL" , "SZ_B" ], + "CX" : [ "OP_CX" , "SZ_W" ], + "eCX" : [ "OP_eCX" , "SZ_Z" ], + "rCX" : [ "OP_rCX" , "SZ_V" ], + "DL" : [ "OP_DL" , "SZ_B" ], + "DX" : [ "OP_DX" , "SZ_W" ], + "eDX" : [ "OP_eDX" , "SZ_Z" ], + "rDX" : [ "OP_rDX" , "SZ_V" ], + "R0b" : [ "OP_R0" , "SZ_B" ], + "R1b" : [ "OP_R1" , "SZ_B" ], + "R2b" : [ "OP_R2" , "SZ_B" ], + "R3b" : [ "OP_R3" , "SZ_B" ], + "R4b" : [ "OP_R4" , "SZ_B" ], + "R5b" : [ "OP_R5" , "SZ_B" ], + "R6b" : [ "OP_R6" , "SZ_B" ], + "R7b" : [ "OP_R7" , "SZ_B" ], + "R0w" : [ "OP_R0" , "SZ_W" ], + "R1w" : [ "OP_R1" , "SZ_W" ], + "R2w" : [ "OP_R2" , "SZ_W" ], + "R3w" : [ "OP_R3" , "SZ_W" ], + "R4w" : [ "OP_R4" , "SZ_W" ], + "R5w" : [ "OP_R5" , "SZ_W" ], + "R6w" : [ "OP_R6" , "SZ_W" ], + "R7w" : [ "OP_R7" , "SZ_W" ], + "R0v" : [ "OP_R0" , "SZ_V" ], + "R1v" : [ "OP_R1" , "SZ_V" ], + "R2v" : [ "OP_R2" , "SZ_V" ], + "R3v" : [ "OP_R3" , "SZ_V" ], + "R4v" : [ "OP_R4" , "SZ_V" ], + "R5v" : [ "OP_R5" , "SZ_V" ], + "R6v" : [ "OP_R6" , "SZ_V" ], + "R7v" : [ "OP_R7" , "SZ_V" ], + "R0z" : [ "OP_R0" , "SZ_Z" ], + "R1z" : [ "OP_R1" , "SZ_Z" ], + "R2z" : [ "OP_R2" , "SZ_Z" ], + "R3z" : [ "OP_R3" , "SZ_Z" ], + "R4z" : [ "OP_R4" , "SZ_Z" ], + "R5z" : [ "OP_R5" , "SZ_Z" ], + "R6z" : [ "OP_R6" , "SZ_Z" ], + "R7z" : [ "OP_R7" , "SZ_Z" ], + "R0y" : [ "OP_R0" , "SZ_Y" ], + "R1y" : [ "OP_R1" , "SZ_Y" ], + "R2y" : [ "OP_R2" , "SZ_Y" ], + "R3y" : [ "OP_R3" , "SZ_Y" ], + "R4y" : [ "OP_R4" , "SZ_Y" ], + "R5y" : [ "OP_R5" , "SZ_Y" ], + "R6y" : [ "OP_R6" , "SZ_Y" ], + "R7y" : [ "OP_R7" , "SZ_Y" ], + "ES" : [ "OP_ES" , "SZ_NA" ], + "CS" : [ "OP_CS" , "SZ_NA" ], + "DS" : [ "OP_DS" , "SZ_NA" ], + "SS" : [ "OP_SS" , "SZ_NA" ], + "GS" : [ "OP_GS" , "SZ_NA" ], + "FS" : [ "OP_FS" , "SZ_NA" ], + "ST0" : [ "OP_ST0" , "SZ_NA" ], + "ST1" : [ "OP_ST1" , "SZ_NA" ], + "ST2" : [ "OP_ST2" , "SZ_NA" ], + "ST3" : [ "OP_ST3" , "SZ_NA" ], + "ST4" : [ "OP_ST4" , "SZ_NA" ], + "ST5" : [ "OP_ST5" , "SZ_NA" ], + "ST6" : [ "OP_ST6" , "SZ_NA" ], + "ST7" : [ "OP_ST7" , "SZ_NA" ], + "NONE" : [ "OP_NONE" , "SZ_NA" ], + } + + # + # opcode prefix dictionary + # + PrefixDict = { + "rep" : "P_str", + "repz" : "P_strz", + "aso" : "P_aso", + "oso" : "P_oso", + "rexw" : "P_rexw", + "rexb" : "P_rexb", + "rexx" : "P_rexx", + "rexr" : "P_rexr", + "vexl" : "P_vexl", + "vexw" : "P_vexw", + "seg" : "P_seg", + "inv64" : "P_inv64", + "def64" : "P_def64", + "cast" : "P_cast", + } + + MnemonicAliases = ( "invalid", "3dnow", "none", "db", "pause" ) + + def __init__(self, tables): + self.tables = tables + self._insnIndexMap, i = {}, 0 + for insn in tables.getInsnList(): + self._insnIndexMap[insn], i = i, i + 1 + + self._tableIndexMap, i = {}, 0 + for table in tables.getTableList(): + self._tableIndexMap[table], i = i, i + 1 + + def getInsnIndex(self, insn): + assert isinstance(insn, UdInsnDef) + return self._insnIndexMap[insn] + + def getTableIndex(self, table): + assert isinstance(table, UdOpcodeTable) + return self._tableIndexMap[table] + + def getTableName(self, table): + return "ud_itab__%d" % self.getTableIndex(table) + + def genOpcodeTable(self, table, isGlobal=False): + """Emit Opcode Table in C. + """ + self.ItabC.write( "\n" ); + if not isGlobal: + self.ItabC.write('static ') + self.ItabC.write( "const uint16_t %s[] = {\n" % self.getTableName(table)) + for i in range(table.size()): + if i > 0 and i % 4 == 0: + self.ItabC.write( "\n" ) + if i % 4 == 0: + self.ItabC.write( " /* %2x */" % i) + e = table.entryAt(i) + if e is None: + self.ItabC.write("%12s," % "INVALID") + elif isinstance(e, UdOpcodeTable): + self.ItabC.write("%12s," % ("GROUP(%d)" % self.getTableIndex(e))) + elif isinstance(e, UdInsnDef): + self.ItabC.write("%12s," % self.getInsnIndex(e)) + self.ItabC.write( "\n" ) + self.ItabC.write( "};\n" ) + + + def genOpcodeTables(self): + tables = self.tables.getTableList() + for table in tables: + self.genOpcodeTable(table, table is self.tables.root) + + + def genOpcodeTablesLookupIndex(self): + self.ItabC.write( "\n\n" ); + self.ItabC.write( "struct ud_lookup_table_list_entry ud_lookup_table_list[] = {\n" ) + for table in self.tables.getTableList(): + f0 = self.getTableName(table) + "," + f1 = table.label() + "," + f2 = "\"%s\"" % table.meta() + self.ItabC.write(" /* %03d */ { %s %s %s },\n" % + (self.getTableIndex(table), f0, f1, f2)) + self.ItabC.write( "};" ) + + + def genInsnTable( self ): + self.ItabC.write( "struct ud_itab_entry ud_itab[] = {\n" ); + for insn in self.tables.getInsnList(): + opr_c = [ "O_NONE", "O_NONE", "O_NONE", "O_NONE" ] + pfx_c = [] + opr = insn.operands + for i in range(len(opr)): + if not (opr[i] in self.OperandDict.keys()): + print("error: invalid operand declaration: %s\n" % opr[i]) + opr_c[i] = "O_" + opr[i] + opr = "%s %s %s %s" % (opr_c[0] + ",", opr_c[1] + ",", + opr_c[2] + ",", opr_c[3]) + + for p in insn.prefixes: + if not ( p in self.PrefixDict.keys() ): + print("error: invalid prefix specification: %s \n" % pfx) + pfx_c.append( self.PrefixDict[p] ) + if len(insn.prefixes) == 0: + pfx_c.append( "P_none" ) + pfx = "|".join( pfx_c ) + + self.ItabC.write( " /* %04d */ { UD_I%s %s, %s },\n" \ + % ( self.getInsnIndex(insn), insn.mnemonic + ',', opr, pfx ) ) + self.ItabC.write( "};\n" ) + + + def getMnemonicsList(self): + mnemonics = self.tables.getMnemonicsList() + mnemonics.extend(self.MnemonicAliases) + return mnemonics + + def genMnemonicsList(self): + mnemonics = self.getMnemonicsList() + self.ItabC.write( "\n\n" ); + self.ItabC.write( "const char* ud_mnemonics_str[] = {\n " ) + self.ItabC.write( ",\n ".join( [ "\"%s\"" % m for m in mnemonics ] ) ) + self.ItabC.write( "\n};\n" ) + + + def genItabH( self, filePath ): + self.ItabH = open( filePath, "w" ) + + # Generate Table Type Enumeration + self.ItabH.write( "#ifndef UD_ITAB_H\n" ) + self.ItabH.write( "#define UD_ITAB_H\n\n" ) + + self.ItabH.write("/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */\n\n") + + # table type enumeration + self.ItabH.write( "/* ud_table_type -- lookup table types (see decode.c) */\n" ) + self.ItabH.write( "enum ud_table_type {\n " ) + enum = UdOpcodeTable.getLabels() + self.ItabH.write( ",\n ".join( enum ) ) + self.ItabH.write( "\n};\n\n" ); + + # mnemonic enumeration + self.ItabH.write( "/* ud_mnemonic -- mnemonic constants */\n" ) + enum = "enum ud_mnemonic_code {\n " + enum += ",\n ".join( [ "UD_I%s" % m for m in self.getMnemonicsList() ] ) + enum += ",\n UD_MAX_MNEMONIC_CODE" + enum += "\n};\n" + self.ItabH.write( enum ) + self.ItabH.write( "\n" ) + + self.ItabH.write( "extern const char * ud_mnemonics_str[];\n" ) + + self.ItabH.write( "\n#endif /* UD_ITAB_H */\n" ) + + self.ItabH.close() + + + def genItabC(self, filePath): + self.ItabC = open(filePath, "w") + self.ItabC.write("/* itab.c -- generated by udis86:scripts/ud_itab.py, do no edit") + self.ItabC.write(" */\n"); + self.ItabC.write("#include \"decode.h\"\n\n"); + + self.ItabC.write("#define GROUP(n) (0x8000 | (n))\n") + self.ItabC.write("#define INVALID %d\n\n" % self.getInsnIndex(self.tables.invalidInsn)) + + self.genOpcodeTables() + self.genOpcodeTablesLookupIndex() + + # + # Macros defining short-names for operands + # + self.ItabC.write("\n\n/* itab entry operand definitions (for readability) */\n"); + operands = self.OperandDict.keys() + operands = sorted(operands) + for o in operands: + self.ItabC.write("#define O_%-7s { %-12s %-8s }\n" % + (o, self.OperandDict[o][0] + ",", self.OperandDict[o][1])); + self.ItabC.write("\n"); + + self.genInsnTable() + self.genMnemonicsList() + + self.ItabC.close() + + def genItab( self, location ): + self.genItabC(os.path.join(location, "itab.c")) + self.genItabH(os.path.join(location, "itab.h")) + +def usage(): + print("usage: ud_itab.py ") + +def main(): + + if len(sys.argv) != 3: + usage() + sys.exit(1) + + tables = UdOpcodeTables(xml=sys.argv[1]) + itab = UdItabGenerator(tables) + itab.genItab(sys.argv[2]) + +if __name__ == '__main__': + main() diff --git a/udis86/scripts/ud_opcode.py b/udis86/scripts/ud_opcode.py new file mode 100644 index 0000000..6753f6d --- /dev/null +++ b/udis86/scripts/ud_opcode.py @@ -0,0 +1,622 @@ +# udis86 - scripts/ud_opcode.py +# +# Copyright (c) 2009, 2013 Vivek Thampi +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os + +# Some compatibility stuff for supporting python 2.x as well as python 3.x +def itemslist(dict): + try: + return dict.iteritems() # python 2.x + except AttributeError: + return list(dict.items()) # python 3.x + +class UdInsnDef: + """An x86 instruction definition + """ + def __init__(self, **insnDef): + self.mnemonic = insnDef['mnemonic'] + self.prefixes = insnDef['prefixes'] + self.opcodes = insnDef['opcodes'] + self.operands = insnDef['operands'] + self._cpuid = insnDef['cpuid'] + self._opcexts = {} + + for opc in self.opcodes: + if opc.startswith('/'): + e, v = opc.split('=') + self._opcexts[e] = v + + def lookupPrefix(self, pfx): + """Lookup prefix (if any, None otherwise), by name""" + return True if pfx in self.prefixes else None + + + @property + def vendor(self): + return self._opcexts.get('/vendor', None) + + @property + def mode(self): + return self._opcexts.get('/m', None) + + @property + def osize(self): + return self._opcexts.get('/o', None) + + def isDef64(self): + return 'def64' in self.prefixes + + def __str__(self): + return self.mnemonic + " " + ', '.join(self.operands) + \ + " " + ' '.join(self.opcodes) + + +class UdOpcodeTable: + """A single table of instruction definitions, indexed by + a decode field. + """ + + class CollisionError(Exception): + pass + + class IndexError(Exception): + """Invalid Index Error""" + pass + + @classmethod + def vendor2idx(cls, v): + return (0 if v == 'amd' + else (1 if v == 'intel' + else 2)) + + @classmethod + def vex2idx(cls, v): + if v.startswith("none_"): + v = v[5:] + vexOpcExtMap = { + 'none' : 0x0, + '0f' : 0x1, + '0f38' : 0x2, + '0f3a' : 0x3, + '66' : 0x4, + '66_0f' : 0x5, + '66_0f38' : 0x6, + '66_0f3a' : 0x7, + 'f3' : 0x8, + 'f3_0f' : 0x9, + 'f3_0f38' : 0xa, + 'f3_0f3a' : 0xb, + 'f2' : 0xc, + 'f2_0f' : 0xd, + 'f2_0f38' : 0xe, + 'f2_0f3a' : 0xf, + } + return vexOpcExtMap[v] + + + # A mapping of opcode extensions to their representational + # values used in the opcode map. + OpcExtMap = { + '/rm' : lambda v: int(v, 16), + '/x87' : lambda v: int(v, 16), + '/3dnow' : lambda v: int(v, 16), + '/reg' : lambda v: int(v, 16), + # modrm.mod + # (!11, 11) => (00b, 01b) + '/mod' : lambda v: 0 if v == '!11' else 1, + # Mode extensions: + # (16, 32, 64) => (00, 01, 02) + '/o' : lambda v: (int(v) / 32), + '/a' : lambda v: (int(v) / 32), + # Disassembly mode + # (!64, 64) => (00b, 01b) + '/m' : lambda v: 1 if v == '64' else 0, + # SSE + # none => 0 + # f2 => 1 + # f3 => 2 + # 66 => 3 + '/sse' : lambda v: (0 if v == 'none' + else (((int(v, 16) & 0xf) + 1) / 2)), + # AVX + '/vex' : lambda v: UdOpcodeTable.vex2idx(v), + '/vexw' : lambda v: 0 if v == '0' else 1, + '/vexl' : lambda v: 0 if v == '0' else 1, + # Vendor + '/vendor': lambda v: UdOpcodeTable.vendor2idx(v) + } + + + _TableInfo = { + 'opctbl' : { 'label' : 'UD_TAB__OPC_TABLE', 'size' : 256 }, + '/sse' : { 'label' : 'UD_TAB__OPC_SSE', 'size' : 4 }, + '/reg' : { 'label' : 'UD_TAB__OPC_REG', 'size' : 8 }, + '/rm' : { 'label' : 'UD_TAB__OPC_RM', 'size' : 8 }, + '/mod' : { 'label' : 'UD_TAB__OPC_MOD', 'size' : 2 }, + '/m' : { 'label' : 'UD_TAB__OPC_MODE', 'size' : 2 }, + '/x87' : { 'label' : 'UD_TAB__OPC_X87', 'size' : 64 }, + '/a' : { 'label' : 'UD_TAB__OPC_ASIZE', 'size' : 3 }, + '/o' : { 'label' : 'UD_TAB__OPC_OSIZE', 'size' : 3 }, + '/3dnow' : { 'label' : 'UD_TAB__OPC_3DNOW', 'size' : 256 }, + '/vendor' : { 'label' : 'UD_TAB__OPC_VENDOR', 'size' : 3 }, + '/vex' : { 'label' : 'UD_TAB__OPC_VEX', 'size' : 16 }, + '/vexw' : { 'label' : 'UD_TAB__OPC_VEX_W', 'size' : 2 }, + '/vexl' : { 'label' : 'UD_TAB__OPC_VEX_L', 'size' : 2 }, + } + + + def __init__(self, typ): + assert typ in self._TableInfo + self._typ = typ + self._entries = {} + + + def size(self): + return self._TableInfo[self._typ]['size'] + + def entries(self): + return itemslist(self._entries) + + def numEntries(self): + return len(self._entries.keys()) + + def label(self): + return self._TableInfo[self._typ]['label'] + + def typ(self): + return self._typ + + def meta(self): + return self._typ + + + def __str__(self): + return "table-%s" % self._typ + + + def add(self, opc, obj): + typ = UdOpcodeTable.getOpcodeTyp(opc) + idx = UdOpcodeTable.getOpcodeIdx(opc) + if self._typ != typ or idx in self._entries: + raise CollisionError() + self._entries[idx] = obj + + + def lookup(self, opc): + typ = UdOpcodeTable.getOpcodeTyp(opc) + idx = UdOpcodeTable.getOpcodeIdx(opc) + if self._typ != typ: + raise UdOpcodeTable.CollisionError("%s <-> %s" % (self._typ, typ)) + return self._entries.get(idx, None) + + + def entryAt(self, index): + """Returns the entry at a given index of the table, + None if there is none. Raises an exception if the + index is out of bounds. + """ + if index < self.size(): + return self._entries.get(index, None) + raise self.IndexError("index out of bounds: %s" % index) + + def setEntryAt(self, index, obj): + if index < self.size(): + self._entries[index] = obj + else: + raise self.IndexError("index out of bounds: %s" % index) + + @classmethod + def getOpcodeTyp(cls, opc): + if opc.startswith('/'): + return opc.split('=')[0] + else: + return 'opctbl' + + + @classmethod + def getOpcodeIdx(cls, opc): + if opc.startswith('/'): + typ, v = opc.split('=') + return cls.OpcExtMap[typ](v) + else: + # plain opctbl opcode + return int(opc, 16) + + + @classmethod + def getLabels(cls): + """Returns a list of all labels""" + return [cls._TableInfo[k]['label'] for k in cls._TableInfo.keys()] + + +class UdOpcodeTables(object): + """Collection of opcode tables + """ + + class CollisionError(Exception): + def __init__(self, obj1, obj2): + self.obj1, self.obj2 = obj1, obj2 + + def newTable(self, typ): + """Create a new opcode table of a give type `typ`. """ + tbl = UdOpcodeTable(typ) + self._tables.append(tbl) + return tbl + + def mkTrie(self, opcodes, obj): + """Recursively contruct a trie entry mapping a string of + opcodes to an object. + """ + if len(opcodes) == 0: + return obj + opc = opcodes[0] + tbl = self.newTable(UdOpcodeTable.getOpcodeTyp(opc)) + tbl.add(opc, self.mkTrie(opcodes[1:], obj)) + return tbl + + def walk(self, tbl, opcodes): + """Walk down the opcode trie, starting at a given opcode + table, given a string of opcodes. Return None if unable + to walk, the object at the leaf otherwise. + """ + opc = opcodes[0] + e = tbl.lookup(opc) + if e is None: + return None + elif isinstance(e, UdOpcodeTable) and len(opcodes[1:]): + return self.walk(e, opcodes[1:]) + return e + + def map(self, tbl, opcodes, obj): + """Create a mapping from a given string of opcodes to an + object in the opcode trie. Constructs trie branches as + needed. + """ + opc = opcodes[0] + e = tbl.lookup(opc) + if e is None: + tbl.add(opc, self.mkTrie(opcodes[1:], obj)) + else: + if len(opcodes[1:]) == 0: + raise self.CollisionError(e, obj) + self.map(e, opcodes[1:], obj) + + def __init__(self, xml): + self._tables = [] + self._insns = [] + self._mnemonics = {} + + # The root table is always a 256 entry opctbl, indexed + # by a plain opcode byte + self.root = self.newTable('opctbl') + + if os.getenv("UD_OPCODE_DEBUG"): + self._logFh = open("opcodeTables.log", "w") + + # add an invalid instruction entry without any mapping + # in the opcode tables. + self.invalidInsn = UdInsnDef(mnemonic="invalid", opcodes=[], cpuid=[], + operands=[], prefixes=[]) + self._insns.append(self.invalidInsn) + + # Construct UdOpcodeTables object from the given + # udis86 optable.xml + for insn in self.__class__.parseOptableXML(xml): + self.addInsnDef(insn) + self.patchAvx2byte() + self.mergeSSENONE() + self.printStats() + + def log(self, s): + if os.getenv("UD_OPCODE_DEBUG"): + self._logFh.write(s + "\n") + + + def mergeSSENONE(self): + """Merge sse tables with only one entry for /sse=none + """ + for table in self._tables: + for k, e in table.entries(): + if isinstance(e, UdOpcodeTable) and e.typ() == '/sse': + if e.numEntries() == 1: + sse = e.lookup("/sse=none") + if sse: + table.setEntryAt(k, sse) + uniqTables = {} + def genTableList(tbl): + if tbl not in uniqTables: + self._tables.append(tbl) + uniqTables[tbl] = 1 + for k, e in tbl.entries(): + if isinstance(e, UdOpcodeTable): + genTableList(e) + self._tables = [] + genTableList(self.root) + + + def patchAvx2byte(self): + # create avx tables + for pp in (None, 'f2', 'f3', '66'): + for m in (None, '0f', '0f38', '0f3a'): + if pp is None and m is None: + continue + if pp is None: + vex = m + elif m is None: + vex = pp + else: + vex = pp + '_' + m + table = self.walk(self.root, ('c4', '/vex=' + vex)) + self.map(self.root, ('c5', '/vex=' + vex), table) + + + def addInsn(self, **insnDef): + + # Canonicalize opcode list + opcexts = insnDef['opcexts'] + opcodes = list(insnDef['opcodes']) + + # Re-order vex + if '/vex' in opcexts: + assert opcodes[0] == 'c4' or opcodes[0] == 'c5' + opcodes.insert(1, '/vex=' + opcexts['/vex']) + + # Add extensions. The order is important, and determines how + # well the opcode table is packed. Also note, /sse must be + # before /o, because /sse may consume operand size prefix + # affect the outcome of /o. + for ext in ('/sse', '/mod', '/x87', '/reg', '/rm', '/o', '/a', '/m', + '/vexw', '/vexl', '/3dnow', '/vendor'): + if ext in opcexts: + opcodes.append(ext + '=' + opcexts[ext]) + + insn = UdInsnDef(mnemonic = insnDef['mnemonic'], + prefixes = insnDef['prefixes'], + operands = insnDef['operands'], + opcodes = opcodes, + cpuid = insnDef['cpuid']) + try: + self.map(self.root, opcodes, insn) + except self.CollisionError as e: + self.pprint() + print(opcodes, insn, str(e.obj1), str(e.obj2)) + raise + except Exception as e: + self.pprint() + raise + self._insns.append(insn) + # add to lookup by mnemonic structure + if insn.mnemonic not in self._mnemonics: + self._mnemonics[insn.mnemonic] = [ insn ] + else: + self._mnemonics[insn.mnemonic].append(insn) + + + def addInsnDef(self, insnDef): + opcodes = [] + opcexts = {} + + # pack plain opcodes first, and collect opcode + # extensions + for opc in insnDef['opcodes']: + if not opc.startswith('/'): + opcodes.append(opc) + else: + e, v = opc.split('=') + opcexts[e] = v + + # treat vendor as an opcode extension + if len(insnDef['vendor']): + opcexts['/vendor'] = insnDef['vendor'][0] + + if insnDef['mnemonic'] in ('lds', 'les'): + # + # Massage lds and les, which share the same prefix as AVX + # instructions, to work well with the opcode tree. + # + opcexts['/vex'] = 'none' + elif '/vex' in opcexts: + # A proper avx instruction definition; make sure there are + # no legacy opcode extensions + assert '/sse' not in opcodes + + # make sure the opcode definitions don't already include + # the avx prefixes. + assert opcodes[0] not in ('c4', 'c5') + + # An avx only instruction is defined by the /vex= opcode + # extension. They do not include the c4 (long form) or + # c5 (short form) prefix. As part of opcode table generate, + # here we create the long form definition, and then patch + # the table for c5 in a later stage. + # Construct a long-form definition of the avx instruction + opcodes.insert(0, 'c4') + elif (opcodes[0] == '0f' and opcodes[1] != '0f' and + '/sse' not in opcexts): + # Make all 2-byte opcode form isntructions play nice with sse + # opcode maps. + opcexts['/sse'] = 'none' + + # legacy sse defs that get promoted to avx + fn = self.addInsn + if 'avx' in insnDef['cpuid'] and '/sse' in opcexts: + fn = self.addSSE2AVXInsn + + fn(mnemonic = insnDef['mnemonic'], + prefixes = insnDef['prefixes'], + opcodes = opcodes, + opcexts = opcexts, + operands = insnDef['operands'], + cpuid = insnDef['cpuid']) + + + def addSSE2AVXInsn(self, **insnDef): + """Add an instruction definition containing an avx cpuid bit, but + declared in its legacy SSE form. The function splits the + definition to create two new definitions, one for SSE and one + promoted to an AVX form. + """ + + # SSE + ssemnemonic = insnDef['mnemonic'] + sseopcodes = insnDef['opcodes'] + # remove vex opcode extensions + sseopcexts = dict([(e, v) for e, v in itemslist(insnDef['opcexts']) + if not e.startswith('/vex')]) + # strip out avx operands, preserving relative ordering + # of remaining operands + sseoperands = [opr for opr in insnDef['operands'] + if opr not in ('H', 'L')] + # strip out avx prefixes + sseprefixes = [pfx for pfx in insnDef['prefixes'] + if not pfx.startswith('vex')] + # strip out avx bits from cpuid + ssecpuid = [flag for flag in insnDef['cpuid'] + if not flag.startswith('avx')] + + self.addInsn(mnemonic = ssemnemonic, + prefixes = sseprefixes, + opcodes = sseopcodes, + opcexts = sseopcexts, + operands = sseoperands, + cpuid = ssecpuid) + + # AVX + vexmnemonic = 'v' + insnDef['mnemonic'] + vexprefixes = insnDef['prefixes'] + vexopcodes = ['c4'] + vexopcexts = dict([(e, insnDef['opcexts'][e]) + for e in insnDef['opcexts'] if e != '/sse']) + vexopcexts['/vex'] = insnDef['opcexts']['/sse'] + '_' + '0f' + if insnDef['opcodes'][1] == '38' or insnDef['opcodes'][1] == '3a': + vexopcexts['/vex'] += insnDef['opcodes'][1] + vexopcodes.extend(insnDef['opcodes'][2:]) + else: + vexopcodes.extend(insnDef['opcodes'][1:]) + vexoperands = [] + for o in insnDef['operands']: + # make the operand size explicit: x + if o in ('V', 'W', 'H', 'U'): + o = o + 'x' + vexoperands.append(o) + vexcpuid = [flag for flag in insnDef['cpuid'] + if not flag.startswith('sse')] + + self.addInsn(mnemonic = vexmnemonic, + prefixes = vexprefixes, + opcodes = vexopcodes, + opcexts = vexopcexts, + operands = vexoperands, + cpuid = vexcpuid) + + def getInsnList(self): + """Returns a list of all instructions in the collection""" + return self._insns + + + def getTableList(self): + """Returns a list of all tables in the collection""" + return self._tables + + def getMnemonicsList(self): + """Returns a sorted list of mnemonics""" + return sorted(self._mnemonics.keys()) + + + def pprint(self): + def printWalk(tbl, indent=""): + entries = tbl.entries() + for k, e in entries: + if isinstance(e, UdOpcodeTable): + self.log("%s |-<%02x> %s" % (indent, k, e)) + printWalk(e, indent + " |") + elif isinstance(e, UdInsnDef): + self.log("%s |-<%02x> %s" % (indent, k, e)) + printWalk(self.root) + + + def printStats(self): + tables = self.getTableList() + self.log("stats: ") + self.log(" Num tables = %d" % len(tables)) + self.log(" Num insnDefs = %d" % len(self.getInsnList())) + self.log(" Num insns = %d" % len(self.getMnemonicsList())) + + totalSize = 0 + totalEntries = 0 + for table in tables: + totalSize += table.size() + totalEntries += table.numEntries() + self.log(" Packing Ratio = %d%%" % ((totalEntries * 100) / totalSize)) + self.log("--------------------") + + self.pprint() + + + @staticmethod + def parseOptableXML(xml): + """Parse udis86 optable.xml file and return list of + instruction definitions. + """ + from xml.dom import minidom + + xmlDoc = minidom.parse(xml) + tlNode = xmlDoc.firstChild + insns = [] + + while tlNode and tlNode.localName != "x86optable": + tlNode = tlNode.nextSibling + + for insnNode in tlNode.childNodes: + if not insnNode.localName: + continue + if insnNode.localName != "instruction": + raise Exception("warning: invalid insn node - %s" % insnNode.localName) + mnemonic = insnNode.getElementsByTagName('mnemonic')[0].firstChild.data + vendor, cpuid = '', [] + + for node in insnNode.childNodes: + if node.localName == 'vendor': + vendor = node.firstChild.data.split() + elif node.localName == 'cpuid': + cpuid = node.firstChild.data.split() + + for node in insnNode.childNodes: + if node.localName == 'def': + insnDef = { 'pfx' : [] } + for node in node.childNodes: + if not node.localName: + continue + if node.localName in ('pfx', 'opc', 'opr', 'vendor', 'cpuid'): + insnDef[node.localName] = node.firstChild.data.split() + elif node.localName == 'mode': + insnDef['pfx'].extend(node.firstChild.data.split()) + insns.append({'prefixes' : insnDef.get('pfx', []), + 'mnemonic' : mnemonic, + 'opcodes' : insnDef.get('opc', []), + 'operands' : insnDef.get('opr', []), + 'vendor' : insnDef.get('vendor', vendor), + 'cpuid' : insnDef.get('cpuid', cpuid)}) + return insns diff --git a/udis86/tests/Makefile.am b/udis86/tests/Makefile.am new file mode 100644 index 0000000..9fab323 --- /dev/null +++ b/udis86/tests/Makefile.am @@ -0,0 +1,88 @@ +# +# Automake definitions for udis86 tests +# +check_PROGRAMS = \ + symresolve \ + libcheck + +symresolve_SOURCES = symresolve.c +symresolve_LDADD = $(top_builddir)/libudis86/libudis86.la +symresolve_CFLAGS = -I$(top_srcdir)/libudis86 -I$(top_srcdir) + +libcheck_SOURCES = libcheck.c +libcheck_LDADD = $(top_builddir)/libudis86/libudis86.la +libcheck_CFLAGS = -I$(top_srcdir)/libudis86 -I$(top_srcdir) + +MAINTAINERCLEANFILES = Makefile.in + +DISTCLEANFILES = difftest.sh + +YASM = @YASM@ +PYTHON = @PYTHON@ +TESTDIS = $(top_builddir)/udcli/udcli + +EXTRA_DIST = \ + $(srcdir)/asm \ + $(srcdir)/oprgen.py \ + $(srcdir)/symresolve.ref \ + $(srcdir)/installcheck.c \ + $(srcdir)/libcheck.c + +if HAVE_YASM +tests: difftest test-sym-resolver test-libcheck +else +tests: warn_no_yasm test-sym-resolver test-libcheck +endif + +SEED = 1984 + + +.PHONY: test-sym-resolver +test-sym-resolver: symresolve + @$(top_builddir)/tests/$< > $@.out + @diff -w $(srcdir)/symresolve.ref $@.out && echo "$@: passed." + +.PHONY: test-libcheck +test-libcheck: libcheck + @./libcheck && echo "$@: passed" + +# +# generate operand tests +# +oprtest_generate = \ + outdir=$(builddir)/_results/asm/$(1) && \ + mkdir -p $${outdir} && \ + PYTHONPATH=$(top_srcdir)/scripts $(PYTHON) $(top_srcdir)/tests/oprgen.py \ + $(top_srcdir)/docs/x86/optable.xml $(SEED) $(1) >$${outdir}/oprtest.asm + +.PHONY: oprtest +oprtest: oprgen.py + @echo "Generating operand tests." + @$(call oprtest_generate,64) + @$(call oprtest_generate,32) + @$(call oprtest_generate,16) + + +.PHONY: difftest +difftest: oprtest $(builddir)/difftest.sh + @bash $(builddir)/difftest.sh + + +.PHONY: difftest-refup +difftest-refup: $(builddir)/difftest.sh + @bash $(builddir)/difftest.sh refup + + +.PHONY: warn_no_yasm +warn_no_yasm: + @echo "*** YASM NOT FOUND: Poor Test Coverage ***" + +check-local: tests + +installcheck-local: + @$(CC) $(srcdir)/installcheck.c -o installcheck.bin -I$(includedir) -L$(libdir) -ludis86 + @echo "$@: passed" + +clean-local: + rm -f $(builddir)/*.bin $(builddir)/*.out $(builddir)/*.pyc + rm -rf $(builddir)/_results diff --git a/udis86/tests/asm/16/disp.asm b/udis86/tests/asm/16/disp.asm new file mode 100644 index 0000000..d471158 --- /dev/null +++ b/udis86/tests/asm/16/disp.asm @@ -0,0 +1,6 @@ +[bits 16] + mov ax, [eax-0x10] + add bx, [esi+0x10] + add ax, [0xffff] + add ax, [esi+edi*4-0x10] + add ax, [bx+si-0x4877] diff --git a/udis86/tests/asm/16/test16.asm b/udis86/tests/asm/16/test16.asm new file mode 100644 index 0000000..15cda25 --- /dev/null +++ b/udis86/tests/asm/16/test16.asm @@ -0,0 +1,5 @@ +[bits 16] + movzx eax, word [bx] + iretd + dpps xmm2, xmm1, 0x10 + blendvpd xmm1, xmm2 diff --git a/udis86/tests/asm/32/att.asm b/udis86/tests/asm/32/att.asm new file mode 100644 index 0000000..e90bfaf --- /dev/null +++ b/udis86/tests/asm/32/att.asm @@ -0,0 +1,3 @@ +[bits 32] + mov eax, 0x1234 + mov eax, [0x1234] diff --git a/udis86/tests/asm/32/att.asm.Sref b/udis86/tests/asm/32/att.asm.Sref new file mode 100644 index 0000000..943f9be --- /dev/null +++ b/udis86/tests/asm/32/att.asm.Sref @@ -0,0 +1,2 @@ +0000000000000000 b834120000 mov $0x1234, %eax +0000000000000005 a134120000 mov 0x1234, %eax diff --git a/udis86/tests/asm/32/att.asm.ref b/udis86/tests/asm/32/att.asm.ref new file mode 100644 index 0000000..0902c97 --- /dev/null +++ b/udis86/tests/asm/32/att.asm.ref @@ -0,0 +1,2 @@ +0000000000000000 b834120000 mov eax, 0x1234 +0000000000000005 a134120000 mov eax, [0x1234] diff --git a/udis86/tests/asm/32/avx.asm b/udis86/tests/asm/32/avx.asm new file mode 100644 index 0000000..c1e6a7f --- /dev/null +++ b/udis86/tests/asm/32/avx.asm @@ -0,0 +1,18 @@ +[bits 32] + vaddsd xmm1, xmm2, xmm4 + vaddsd xmm2, xmm3, [eax] + vaddps ymm1, ymm2, ymm3 + vaddps ymm1, ymm7, [eax] + vblendpd ymm1, ymm7, ymm4, 0x42 + vcvtpd2ps xmm1, xmm2 + vcvtpd2ps xmm1, ymm3 + vcvtpd2ps xmm1, oword [eax] + vcvtpd2ps xmm1, yword [eax] + vcvtpd2dq xmm1, xmm2 + vcvtpd2dq xmm1, ymm3 + vcvtpd2dq xmm1, oword [eax] + vcvtpd2dq xmm1, yword [eax] + vcvttpd2dq xmm1, xmm2 + vcvttpd2dq xmm1, ymm3 + vcvttpd2dq xmm1, oword [eax] + vcvttpd2dq xmm1, yword [eax] diff --git a/udis86/tests/asm/32/avx.asm.Sref b/udis86/tests/asm/32/avx.asm.Sref new file mode 100644 index 0000000..f4ff830 --- /dev/null +++ b/udis86/tests/asm/32/avx.asm.Sref @@ -0,0 +1,17 @@ +0000000000000000 c5eb58cc vaddsd %xmm4, %xmm2, %xmm1 +0000000000000004 c5e35810 vaddsd (%eax), %xmm3, %xmm2 +0000000000000008 c5ec58cb vaddps %ymm3, %ymm2, %ymm1 +000000000000000c c5c45808 vaddps (%eax), %ymm7, %ymm1 +0000000000000010 c4e3450dcc42 vblendpd $0x42, %ymm4, %ymm7, %ymm1 +0000000000000016 c5f95aca vcvtpd2ps %xmm2, %xmm1 +000000000000001a c5fd5acb vcvtpd2ps %ymm3, %xmm1 +000000000000001e c5f95a08 vcvtpd2ps (%eax), %xmm1 +0000000000000022 c5fd5a08 vcvtpd2ps (%eax), %xmm1 +0000000000000026 c5fbe6ca vcvtpd2dq %xmm2, %xmm1 +000000000000002a c5ffe6cb vcvtpd2dq %ymm3, %xmm1 +000000000000002e c5fbe608 vcvtpd2dq (%eax), %xmm1 +0000000000000032 c5ffe608 vcvtpd2dq (%eax), %xmm1 +0000000000000036 c5f9e6ca vcvttpd2dq %xmm2, %xmm1 +000000000000003a c5fde6cb vcvttpd2dq %ymm3, %xmm1 +000000000000003e c5f9e608 vcvttpd2dq (%eax), %xmm1 +0000000000000042 c5fde608 vcvttpd2dq (%eax), %xmm1 diff --git a/udis86/tests/asm/32/avx.asm.ref b/udis86/tests/asm/32/avx.asm.ref new file mode 100644 index 0000000..2fff3c6 --- /dev/null +++ b/udis86/tests/asm/32/avx.asm.ref @@ -0,0 +1,17 @@ +0000000000000000 c5eb58cc vaddsd xmm1, xmm2, xmm4 +0000000000000004 c5e35810 vaddsd xmm2, xmm3, [eax] +0000000000000008 c5ec58cb vaddps ymm1, ymm2, ymm3 +000000000000000c c5c45808 vaddps ymm1, ymm7, [eax] +0000000000000010 c4e3450dcc42 vblendpd ymm1, ymm7, ymm4, 0x42 +0000000000000016 c5f95aca vcvtpd2ps xmm1, xmm2 +000000000000001a c5fd5acb vcvtpd2ps xmm1, ymm3 +000000000000001e c5f95a08 vcvtpd2ps xmm1, [eax] +0000000000000022 c5fd5a08 vcvtpd2ps xmm1, yword [eax] +0000000000000026 c5fbe6ca vcvtpd2dq xmm1, xmm2 +000000000000002a c5ffe6cb vcvtpd2dq xmm1, ymm3 +000000000000002e c5fbe608 vcvtpd2dq xmm1, [eax] +0000000000000032 c5ffe608 vcvtpd2dq xmm1, yword [eax] +0000000000000036 c5f9e6ca vcvttpd2dq xmm1, xmm2 +000000000000003a c5fde6cb vcvttpd2dq xmm1, ymm3 +000000000000003e c5f9e608 vcvttpd2dq xmm1, [eax] +0000000000000042 c5fde608 vcvttpd2dq xmm1, yword [eax] diff --git a/udis86/tests/asm/32/corner.asm b/udis86/tests/asm/32/corner.asm new file mode 100644 index 0000000..5a795a2 --- /dev/null +++ b/udis86/tests/asm/32/corner.asm @@ -0,0 +1,5 @@ +[bits 32] + + lar eax, [bx+si] + nop + pause diff --git a/udis86/tests/asm/32/corner.asm.ref b/udis86/tests/asm/32/corner.asm.ref new file mode 100644 index 0000000..086755c --- /dev/null +++ b/udis86/tests/asm/32/corner.asm.ref @@ -0,0 +1,3 @@ +0000000000000000 670f0200 lar eax, word [bx+si] +0000000000000004 90 nop +0000000000000005 f390 pause diff --git a/udis86/tests/asm/32/disp.asm b/udis86/tests/asm/32/disp.asm new file mode 100644 index 0000000..b6e4006 --- /dev/null +++ b/udis86/tests/asm/32/disp.asm @@ -0,0 +1,6 @@ +[bits 32] + mov eax, [eax-0x10] + add eax, [esi+0x10] + add eax, [0x10] + add eax, [esi+edi*4+0x10] + add eax, [bx+si-0x4877] diff --git a/udis86/tests/asm/32/disp.asm.Sref b/udis86/tests/asm/32/disp.asm.Sref new file mode 100644 index 0000000..009e242 --- /dev/null +++ b/udis86/tests/asm/32/disp.asm.Sref @@ -0,0 +1,5 @@ +0000000000000000 8b40f0 mov -0x10(%eax), %eax +0000000000000003 034610 add 0x10(%esi), %eax +0000000000000006 030510000000 add 0x10, %eax +000000000000000c 0344be10 add 0x10(%esi,%edi,4), %eax +0000000000000010 67038089b7 add -0x4877(%bx,%si), %eax diff --git a/udis86/tests/asm/32/invalid_seg.asm b/udis86/tests/asm/32/invalid_seg.asm new file mode 100644 index 0000000..93b171f --- /dev/null +++ b/udis86/tests/asm/32/invalid_seg.asm @@ -0,0 +1,2 @@ +[bits 32] + db 0x8C, 0x38 diff --git a/udis86/tests/asm/32/invalid_seg.asm.ref b/udis86/tests/asm/32/invalid_seg.asm.ref new file mode 100644 index 0000000..1f40e08 --- /dev/null +++ b/udis86/tests/asm/32/invalid_seg.asm.ref @@ -0,0 +1 @@ +0000000000000000 8c38 invalid diff --git a/udis86/tests/asm/32/obscure.asm b/udis86/tests/asm/32/obscure.asm new file mode 100644 index 0000000..8e26c34 --- /dev/null +++ b/udis86/tests/asm/32/obscure.asm @@ -0,0 +1,12 @@ + + db 0xd1, 0xf6 ; shl Ev, 0x1 + db 0xd0, 0xf6 ; shl Eb, 0x1 + db 0xd9, 0xd9 ; fstp1 st1 + db 0xdc, 0xd0 ; fcom2 + db 0xdc, 0xd8 ; fcomp3 + db 0xdd, 0xc8 ; fxch4 + db 0xde, 0xd1 ; fcomp5 + db 0xdf, 0xc3 ; fxch7 + db 0xdf, 0xd0 ; fstp8 + db 0xdf, 0xd8 ; fstp9 + db 0x83, 0xe2, 0xdf ; and edx, 0xffffffdf (sign-extension) diff --git a/udis86/tests/asm/32/obscure.asm.ref b/udis86/tests/asm/32/obscure.asm.ref new file mode 100644 index 0000000..77aaf58 --- /dev/null +++ b/udis86/tests/asm/32/obscure.asm.ref @@ -0,0 +1,11 @@ +0000000000000000 d1f6 shl esi, 1 +0000000000000002 d0f6 shl dh, 1 +0000000000000004 d9d9 fstp1 st1 +0000000000000006 dcd0 fcom2 st0 +0000000000000008 dcd8 fcomp3 st0 +000000000000000a ddc8 fxch4 st0 +000000000000000c ded1 fcomp5 st1 +000000000000000e dfc3 ffreep st3 +0000000000000010 dfd0 fstp8 st0 +0000000000000012 dfd8 fstp9 st0 +0000000000000014 83e2df and edx, 0xffffffdf diff --git a/udis86/tests/asm/32/reljmp.asm b/udis86/tests/asm/32/reljmp.asm new file mode 100644 index 0000000..cd9959a --- /dev/null +++ b/udis86/tests/asm/32/reljmp.asm @@ -0,0 +1,24 @@ +[bits 32] +[org 0x80000000] + +l1: + nop + nop + nop + nop + nop + + jmp l1 + nop + jmp word l2 + + nop + nop + jmp dword l2 + nop + nop + nop +l2: + nop + nop + jmp l1 diff --git a/udis86/tests/asm/32/reljmp.asm.ref b/udis86/tests/asm/32/reljmp.asm.ref new file mode 100644 index 0000000..aafcb3c --- /dev/null +++ b/udis86/tests/asm/32/reljmp.asm.ref @@ -0,0 +1,17 @@ +0000000080000000 90 nop +0000000080000001 90 nop +0000000080000002 90 nop +0000000080000003 90 nop +0000000080000004 90 nop +0000000080000005 ebf9 jmp 0x80000000 +0000000080000007 90 nop +0000000080000008 66e90a00 jmp 0x16 +000000008000000c 90 nop +000000008000000d 90 nop +000000008000000e e903000000 jmp 0x80000016 +0000000080000013 90 nop +0000000080000014 90 nop +0000000080000015 90 nop +0000000080000016 90 nop +0000000080000017 90 nop +0000000080000018 ebe6 jmp 0x80000000 diff --git a/udis86/tests/asm/32/sext.asm b/udis86/tests/asm/32/sext.asm new file mode 100644 index 0000000..a4f4900 --- /dev/null +++ b/udis86/tests/asm/32/sext.asm @@ -0,0 +1,23 @@ +[bits 32] + + ;; test sign extension + + adc ax, -100 + and edx, -3 + or dx, -1000 + or dx, -1 + add edx, -1000 + imul dx, bx, -100 + imul edx, ebx, -1 + imul edx, ebx, -128 + imul edx, ebx, -129 + imul ax, bx, -129 + sub dword [eax], -1 + sub word [eax], -2000 + test eax, 1 + test eax, -1 + push byte -1 + push word -1 + push dword -1000 + push word -1000 + diff --git a/udis86/tests/asm/32/sext.asm.ref b/udis86/tests/asm/32/sext.asm.ref new file mode 100644 index 0000000..99bc887 --- /dev/null +++ b/udis86/tests/asm/32/sext.asm.ref @@ -0,0 +1,18 @@ +0000000000000000 6683d09c adc ax, 0xff9c +0000000000000004 83e2fd and edx, 0xfffffffd +0000000000000007 6681ca18fc or dx, 0xfc18 +000000000000000c 6683caff or dx, 0xffff +0000000000000010 81c218fcffff add edx, 0xfffffc18 +0000000000000016 666bd39c imul dx, bx, 0xff9c +000000000000001a 6bd3ff imul edx, ebx, 0xffffffff +000000000000001d 6bd380 imul edx, ebx, 0xffffff80 +0000000000000020 69d37fffffff imul edx, ebx, 0xffffff7f +0000000000000026 6669c37fff imul ax, bx, 0xff7f +000000000000002b 8328ff sub dword [eax], 0xffffffff +000000000000002e 66812830f8 sub word [eax], 0xf830 +0000000000000033 a901000000 test eax, 0x1 +0000000000000038 a9ffffffff test eax, 0xffffffff +000000000000003d 6aff push 0xffffffff +000000000000003f 666aff push 0xffff +0000000000000042 6818fcffff push 0xfffffc18 +0000000000000047 666818fc push 0xfc18 diff --git a/udis86/tests/asm/32/test32.asm b/udis86/tests/asm/32/test32.asm new file mode 100644 index 0000000..5b088b1 --- /dev/null +++ b/udis86/tests/asm/32/test32.asm @@ -0,0 +1,282 @@ +[bits 32] + mov [0x1000], bx + mov [0x10], ax + mov ax, [0x10] + mov byte [bx+si], 0x10 + mov byte [bx+si+0x10], 0x10 + mov word [bp+0x10], 0x10 + mov word [bp+di+0x10], 0x10 + mov dword [si+0x10], 0x10 + mov word [di+0x10], 0x10 + mov dword [bx+0x10], 0x1000 + mov word [bx+0x1000], 0x1000 + mov dword [ebx+ecx*4], 0x100 + mov [eax+eax*2], eax + mov [edx+esi*8], ebp + mov dword [ecx*4+0x490], 0x100 + mov byte [cs:0x100000], 0x10 + mov word [eax+0x10], 0x10 + mov [eax+0x10], ax + mov [eax+0x1000], ebx + mov [ebp+eax+0x20], esi + mov [ebp+edi+0x100000], esp + mov byte [esp], 0x10 + add al, 0x10 + add eax, ebx + push es + pop es + adc eax, 0x10000 + and [eax], al + daa + inc ax + inc edx + push eax + push ax + pushad + bound eax, [eax] + bound ax, [ecx] + bsr ax, ax + bsf eax, [bx+si] + bswap eax + bt [eax], ax + btr ax, 0x10 + btc ebx, 0x10 + bts word [ebx], 0x10 + call ax + call word [bx+si] + call eax + call dword [eax+ecx] + call word 0x10:0x100 + call dword 0x10:0x10000 + call far word [eax] + call far dword [bp+si] + cbw + cwd + clc + cld + clflush [eax] + cmp eax, ebx + cmp ecx, [bx] + cmpsb + cmpsw + cmpsd + cmpxchg [eax], ax + cmpxchg8b [ebx] + cpuid + das + inc eax + inc word [ecx] + dec byte [si] + in al, 0x10 + in ax, 0x10 + in eax, 0x10 + insb + insw + insd + int 0x10 + into + lahf + lds ax, [eax] + les eax, [ebx] + lea ax, [eax] + lea eax, [bx+si] + leave + lodsb + lodsw + lodsd + test al, bl + test [eax], bl + test [eax], ebx + test [eax], bx + ret + ret 0x10 + aad 0x10 + aam 0x10 + salc + hlt + cmc + lock xchg ebx, eax + repne mov eax, ebx + repe mov eax, 0x10 + push cs + outsd + outsw + mov ax, es + mov bx, ds + mov [eax], es + mov [ebx+ecx], cs + mov cs, [ebx+ecx] + wait + pushfw + pushfd + lodsw + lodsd + retf 0x10 + int3 + into + iretw + iretd + lsl ax, [bx] + syscall + clts + sysret + movups xmm0, xmm1 + mov dr0, eax + ror word [ebx], cl + wrmsr + rdmsr + rdtsc + rdtscp + rdpmc + sysenter + sysexit + cmovo eax, [eax] + cmovno eax, [bx] + cmovb eax, [eax] + cmovae eax, [bx] + cmovo eax, [eax] + cmovz eax, ebx + cmovnz eax, [eax] + cmovbe eax, [bx] + cmova eax, [bx] + movmskps eax, xmm0 + movmskpd eax, xmm0 + sqrtps xmm1, xmm0 + rsqrtps xmm1, xmm0 + rcpps xmm1, xmm0 + andps xmm1, xmm0 + orps xmm1, xmm0 + xorps xmm1, xmm0 + andnps xmm1, xmm0 + sqrtss xmm1, xmm0 + rsqrtss xmm1, xmm0 + rcpss xmm1, xmm0 + sqrtpd xmm1, xmm0 + andpd xmm1, xmm0 + andnpd xmm1, xmm0 + orpd xmm1, xmm0 + xorpd xmm1, xmm0 + sqrtsd xmm1, xmm0 + punpcklbw mm0, [eax] + punpcklwd mm0, mm1 + punpckldq mm0, mm1 + packsswb mm0, mm1 + packsswb mm0, mm1 + pcmpgtb mm0, mm1 + pcmpgtw mm0, mm1 + pcmpgtd mm0, mm1 + packuswb mm0, mm1 + punpcklbw xmm0, [eax] + punpcklwd xmm0, xmm1 + punpckldq xmm0, xmm1 + packsswb xmm0, xmm1 + packsswb xmm0, xmm1 + pcmpgtb xmm0, xmm1 + pcmpgtw xmm0, xmm1 + pcmpgtd xmm0, xmm1 + packuswb xmm0, xmm1 + pshufw mm0, mm1, 0x10 + pcmpeqb mm0, mm1 + pcmpeqw mm0, mm1 + pcmpeqd mm0, mm1 + pcmpeqb xmm0, xmm1 + pcmpeqw xmm0, xmm1 + pcmpeqd xmm0, xmm1 + emms + pshufhw xmm0, xmm1, 0x10 + pshufd xmm0, xmm1, 0x10 + pshuflw xmm0, xmm1, 0x10 + seto byte [eax] + setno byte [bx] + setz byte [es:eax+ecx*2+0x100] + push fs + pop fs + cpuid + bt [eax], eax + shld eax, ebx, 0x10 + shld [eax], bx, cl + cmpxchg [eax], eax + lss eax, [eax] + btr [eax], eax + movnti [eax], eax + psrlw mm0, 0x10 + fadd dword [eax] + imul eax, [eax], 0xf6 + movd dword [eax], xmm0 + movzx eax, word [eax] + push word [0x10] + insw + insd + fnstsw ax + fucomip st0, st1 + fcomip st0, st7 + fucomp st4 + fucom st5 + fstp st3 + fst st1 + ffree st0 + fdiv st7, st0 + fdivr st2, st0 + fsub st4, st0 + fsubr st6, st0 + fmul st0, st0 + fadd st5, st0 + ficom word [eax] + fidivr word [eax] + fimul word [ebx] + fisub word [ecx] + fld qword [bx+si] + fisttp qword [edx+0x100] + fnstsw word [eax] + frstor [ebx] + prefetch [bx+si] + psrlq xmm0, 0x10 + psrldq xmm0, 0x10 + movsldup xmm0, [eax] + add [0xffffffff], eax + cvtsi2ss xmm1, dword [eax] + pop dword [eax] + out 0x0, al + lldt word [0x100] + lgdt [0x221] + sldt word [0x233] + sgdt [0x443] + lidt [eax+0x333] + lldt ax + ltr bx + verr cx + verw dx + sldt ax + str bx + str eax + and esp, 0xfc + psrlw xmm1, 0x10 + psraw xmm7, 0x1 + psllw xmm2, 0x23 + fldenv [0x10] + fldenv [0x123] + fldcw word [0x100] + fnstcw word [0x10] + ficom word [eax+ebx+0x10] + fstp tword [0x10] + fadd qword [eax+ebx*2+0x1] + frstor [0x100] + fnstsw word [0x100] + fiadd word [0x100] + fild word [0x10] + monitor + mwait + lfence + mfence + sfence + vmrun + vmmcall + vmload + vmsave + stgi + clgi + skinit + invlpga + blendpd xmm1, xmm6, 0x8 + psignw xmm4, [eax] + blendpd xmm1, [eax], 0x9 diff --git a/udis86/tests/asm/64/amd/invalid.asm b/udis86/tests/asm/64/amd/invalid.asm new file mode 100644 index 0000000..17f65da --- /dev/null +++ b/udis86/tests/asm/64/amd/invalid.asm @@ -0,0 +1,7 @@ +;; Test amd specific 64bit instructions + +[bits 64] + + ;; Invalid instructions in amd 64bit mode + db 0x0f, 0x34 ; sysenter (invalid) + db 0x0f, 0x35 ; sysexit (invalid) diff --git a/udis86/tests/asm/64/amd/invalid.asm.ref b/udis86/tests/asm/64/amd/invalid.asm.ref new file mode 100644 index 0000000..8005f0d --- /dev/null +++ b/udis86/tests/asm/64/amd/invalid.asm.ref @@ -0,0 +1,2 @@ +0000000000000000 0f34 invalid +0000000000000002 0f35 invalid diff --git a/udis86/tests/asm/64/avx.asm b/udis86/tests/asm/64/avx.asm new file mode 100644 index 0000000..3d661e4 --- /dev/null +++ b/udis86/tests/asm/64/avx.asm @@ -0,0 +1,5 @@ +[bits 64] + vaddsd xmm12, xmm4, xmm1 + vminsd xmm13, xmm15, qword [rbx+r8-0x10] + vaddps ymm8, ymm3, ymm14 + vaddps ymm8, ymm3, [rax] diff --git a/udis86/tests/asm/64/avx.asm.ref b/udis86/tests/asm/64/avx.asm.ref new file mode 100644 index 0000000..cc11b0d --- /dev/null +++ b/udis86/tests/asm/64/avx.asm.ref @@ -0,0 +1,4 @@ +0000000000000000 c55b58e1 vaddsd xmm12, xmm4, xmm1 +0000000000000004 c421035d6c03f0 vminsd xmm13, xmm15, qword [rbx+r8-0x10] +000000000000000b c4416458c6 vaddps ymm8, ymm3, ymm14 +0000000000000010 c5645800 vaddps ymm8, ymm3, [rax] diff --git a/udis86/tests/asm/64/branch.asm b/udis86/tests/asm/64/branch.asm new file mode 100644 index 0000000..9284459 --- /dev/null +++ b/udis86/tests/asm/64/branch.asm @@ -0,0 +1,21 @@ +;; Test branching instructions +;; +[bits 64] + + jnz near x + jo near x + jno word x + jc near x + jnc word x + jae dword x + jcxz x + jecxz x + jrcxz x + jmp dword near x + call dword near x + jmp word x + jmp dword x + jmp word [eax] +x: jmp qword [rax] + jmp word x + jmp dword x diff --git a/udis86/tests/asm/64/branch.asm.ref b/udis86/tests/asm/64/branch.asm.ref new file mode 100644 index 0000000..e42cf33 --- /dev/null +++ b/udis86/tests/asm/64/branch.asm.ref @@ -0,0 +1,17 @@ +0000000000000000 0f853b000000 jnz 0x41 +0000000000000006 0f8035000000 jo 0x41 +000000000000000c 660f813000 jno 0x41 +0000000000000011 0f822a000000 jb 0x41 +0000000000000017 660f832500 jae 0x41 +000000000000001c 0f831f000000 jae 0x41 +0000000000000022 67e31c jecxz 0x41 +0000000000000025 67e319 jecxz 0x41 +0000000000000028 e317 jrcxz 0x41 +000000000000002a e912000000 jmp 0x41 +000000000000002f e80d000000 call 0x41 +0000000000000034 66e90900 jmp 0x41 +0000000000000038 e904000000 jmp 0x41 +000000000000003d 6766ff20 jmp word [eax] +0000000000000041 ff20 jmp qword [rax] +0000000000000043 66e9faff jmp 0x41 +0000000000000047 e9f5ffffff jmp 0x41 diff --git a/udis86/tests/asm/64/disp.asm b/udis86/tests/asm/64/disp.asm new file mode 100644 index 0000000..e527775 --- /dev/null +++ b/udis86/tests/asm/64/disp.asm @@ -0,0 +1,7 @@ +[bits 64] + mov ax, [eax-0x10] + add bx, [esi+0x10] + add rax, [0xffff] + add ax, [esi+edi*4-0x10] + add r8, [rax+rbx*4-0x80000000] + mov rax, [qword 0x800000000000] diff --git a/udis86/tests/asm/64/disp.asm.Sref b/udis86/tests/asm/64/disp.asm.Sref new file mode 100644 index 0000000..09662c3 --- /dev/null +++ b/udis86/tests/asm/64/disp.asm.Sref @@ -0,0 +1,7 @@ +0000000000000000 67668b40f0 mov -0x10(%eax), %ax +0000000000000005 6766035e10 add 0x10(%esi), %bx +000000000000000a 48030425ffff0000 add 0xffff, %rax +0000000000000012 67660344bef0 add -0x10(%esi,%edi,4), %ax +0000000000000018 4c03849800000080 add -0x80000000(%rax,%rbx,4), %r8 +0000000000000020 48a1000000000080 mov 0x800000000000, %rax + -0000 diff --git a/udis86/tests/asm/64/disp.asm.ref b/udis86/tests/asm/64/disp.asm.ref new file mode 100644 index 0000000..65c5859 --- /dev/null +++ b/udis86/tests/asm/64/disp.asm.ref @@ -0,0 +1,7 @@ +0000000000000000 67668b40f0 mov ax, [eax-0x10] +0000000000000005 6766035e10 add bx, [esi+0x10] +000000000000000a 48030425ffff0000 add rax, [0xffff] +0000000000000012 67660344bef0 add ax, [esi+edi*4-0x10] +0000000000000018 4c03849800000080 add r8, [rax+rbx*4-0x80000000] +0000000000000020 48a1000000000080 mov rax, [0x800000000000] + -0000 diff --git a/udis86/tests/asm/64/intel/invalid.asm b/udis86/tests/asm/64/intel/invalid.asm new file mode 100644 index 0000000..3527050 --- /dev/null +++ b/udis86/tests/asm/64/intel/invalid.asm @@ -0,0 +1,8 @@ +;; Test intel specific instructions in 64bit mode + +[bits 64] + + ;; yasm doesn't seem to support a mode for intel + ;; specific instructions + db 0x0f, 0x34 ; sysenter + db 0x0f, 0x35 ; sysexit diff --git a/udis86/tests/asm/64/intel/invalid.asm.ref b/udis86/tests/asm/64/intel/invalid.asm.ref new file mode 100644 index 0000000..63eddce --- /dev/null +++ b/udis86/tests/asm/64/intel/invalid.asm.ref @@ -0,0 +1,2 @@ +0000000000000000 0f34 sysenter +0000000000000002 0f35 sysexit diff --git a/udis86/tests/asm/64/reljmp.asm b/udis86/tests/asm/64/reljmp.asm new file mode 100644 index 0000000..531d93e --- /dev/null +++ b/udis86/tests/asm/64/reljmp.asm @@ -0,0 +1,24 @@ +[bits 64] +[org 0x8000000000000000] + +l1: + nop + nop + nop + nop + nop + + jmp l1 + nop + jmp word l2 + + nop + nop + jmp dword l2 + nop + nop + nop +l2: + nop + nop + jmp l1 diff --git a/udis86/tests/asm/64/reljmp.asm.ref b/udis86/tests/asm/64/reljmp.asm.ref new file mode 100644 index 0000000..75fb0ff --- /dev/null +++ b/udis86/tests/asm/64/reljmp.asm.ref @@ -0,0 +1,17 @@ +8000000000000000 90 nop +8000000000000001 90 nop +8000000000000002 90 nop +8000000000000003 90 nop +8000000000000004 90 nop +8000000000000005 ebf9 jmp 0x8000000000000000 +8000000000000007 90 nop +8000000000000008 66e90a00 jmp 0x16 +800000000000000c 90 nop +800000000000000d 90 nop +800000000000000e e903000000 jmp 0x8000000000000016 +8000000000000013 90 nop +8000000000000014 90 nop +8000000000000015 90 nop +8000000000000016 90 nop +8000000000000017 90 nop +8000000000000018 ebe6 jmp 0x8000000000000000 diff --git a/udis86/tests/asm/64/sext.asm b/udis86/tests/asm/64/sext.asm new file mode 100644 index 0000000..215e537 --- /dev/null +++ b/udis86/tests/asm/64/sext.asm @@ -0,0 +1,19 @@ +[bits 64] + + ;; test sign extension + + adc al, -100 + adc ax, -100 + adc eax, -100 + adc rax, -100 + imul dx, bx, -100 + imul edx, ebx, -100 + imul rdx, r11, -100 + push byte -1 + push word -1 + push dword -1000 + push word -1000 + push -1 + push byte -1 + push dword -1 + push word -1 diff --git a/udis86/tests/asm/64/sext.asm.ref b/udis86/tests/asm/64/sext.asm.ref new file mode 100644 index 0000000..aa6b935 --- /dev/null +++ b/udis86/tests/asm/64/sext.asm.ref @@ -0,0 +1,15 @@ +0000000000000000 149c adc al, 0x9c +0000000000000002 6683d09c adc ax, 0xff9c +0000000000000006 83d09c adc eax, 0xffffff9c +0000000000000009 4883d09c adc rax, 0xffffffffffffff9c +000000000000000d 666bd39c imul dx, bx, 0xff9c +0000000000000011 6bd39c imul edx, ebx, 0xffffff9c +0000000000000014 496bd39c imul rdx, r11, 0xffffffffffffff9c +0000000000000018 6aff push 0xffffffffffffffff +000000000000001a 666aff push 0xffff +000000000000001d 6818fcffff push 0xfffffffffffffc18 +0000000000000022 666818fc push 0xfc18 +0000000000000026 6aff push 0xffffffffffffffff +0000000000000028 6aff push 0xffffffffffffffff +000000000000002a 6aff push 0xffffffffffffffff +000000000000002c 666aff push 0xffff diff --git a/udis86/tests/asm/64/test64.asm b/udis86/tests/asm/64/test64.asm new file mode 100644 index 0000000..127b700 --- /dev/null +++ b/udis86/tests/asm/64/test64.asm @@ -0,0 +1,158 @@ +[bits 64] + mov rax, 0x102030405060708 + mov [eax+0x10], ax + mov [eax+0x1000], ebx + mov [ebp+eax+0x40], esi + mov qword [ebp+edi+0x1000], 0x10 + mov byte [esp], 0x10 + mov [eax], rax + mov [r12], eax + mov [r13+r12+0x200], eax + mov [r8*4+0x670], sil + inc rax + dec rax + mov [rip+0x200], rax + mov rax, 0x10000 + push rax + push r12 + call qword [r8] + call qword [rax] + call far word [r8] + call far dword [rax] + cbw + cwde + cdqe + cwd + cdq + cqo + cmovl rax, [rax] + cmovge eax, [rax] + clflush [r14] + cmp [rax], rax + cmp rbx, r12 + cmp r12d, r8d + cmpsb + cmpsw + cmpsd + cmpsq + cmpxchg [eax], r14 + cmpxchg8b [ebx] + inc r12d + inc dword [rax] + dec r11w + hlt + imul rax, [eax+ebx*8+0x100000], 0x10 + idiv dword [r12] + enter 0x100, 0x0 + enter 0x100, 0x1 + enter 0x100, 0x10 + in al, 0x10 + in ax, 0x10 + in eax, 0x10 + lfs eax, [eax] + lgs eax, [ebx] + lea eax, [rbx] + lea r11, [eax] + lodsb + lodsq + lodsd + push rax + push r11 + xchg [eax], sil + xchg [eax], ebx + xchg [eax], bx + xchg r8, rax + xchg r9, rax + xchg cx, ax + movsd + movsq + mov al, r11b + mov sil, al + mov r11b, dil + ret 0x10 + pop rax + pop r11 + pop qword [eax] + insd + outsd + mov [r14d], cs + mov cs, [ebx+ecx] + pushfq + scasq + lsl ax, [rbx] + movups xmm0, [r12d] + movupd xmm0, [r12d] + movsldup xmm0, [r12d] + movups xmm0, xmm1 + movups xmm10, xmm12 + movups xmm0, xmm12 + movlps xmm0, [rax] + movlps [rax], xmm0 + unpcklps xmm4, xmm5 + unpckhps xmm4, xmm5 + movhps xmm3, [eax] + movhps [rax], xmm3 + movss xmm0, dword [eax] + movss [eax], xmm0 + movlpd [eax], xmm0 + movlpd xmm0, [eax] + unpcklpd xmm2, xmm4 + unpckhpd xmm3, [eax+ebx*8-0x1243] + movhpd xmm3, [rax] + movhpd [rax], xmm2 + movsd xmm3, xmm4 + movddup xmm3, [rax] + mov dr0, rax + mov rax, dr1 + movnti [eax], eax + movnti [rax], rax + movd dword [eax], xmm0 + movd dword [eax], xmm0 + movq xmm11, [eax] + vmmcall + vmrun + clgi + stgi + mfence + lfence + sfence + clflush [rax] + mov cr8, rax + push qword [eax] + push word [eax] + add bh, bh + add dil, dil + add sil, bpl + add al, sil + add rax, r12 + add eax, r12d + prefetcht0 [eax] + prefetchnta [eax] + prefetch [eax] + add [r8], r9b + mov [rax-0x1], eax + inc rax + jmp qword [eax] + jmp rax + mov [0x10], rax + mov rax, [0x10] + mov rax, 0x102030405060708 + xchg r8, rax + push ax + push rax + push r11 + mov rax, [0x100] + pmovmskb r12d, xmm14 + movdq2q mm0, xmm13 + psrlw xmm10, 0x10 + psraw xmm7, 0x1 + psllw xmm12, 0x23 + swapgs + fadd dword [rax+rbx] + shl rsi, 1 + cvtsi2ss xmm1, qword [eax] + cvtss2si rax, dword [eax] + cvttsd2si rax, [eax] + call 0x64 + mpsadbw xmm7, xmm6, 0x7 + popfq diff --git a/udis86/tests/difftest.sh.in b/udis86/tests/difftest.sh.in new file mode 100644 index 0000000..e670fbf --- /dev/null +++ b/udis86/tests/difftest.sh.in @@ -0,0 +1,144 @@ +# udis86 - tests/difftest.sh.in +# +# Copyright (c) 2013 Vivek Thampi +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +udcli=@top_builddir@/udcli/udcli +srcdir=@srcdir@ +builddir=@builddir@ +yasm=@YASM@ + + +function asm_org # (srcasm) +{ + cat $1 | sed -n 's/\[org \(.*\)\]/\1/p' +} + + +function vendor_opt # (vendor) +{ + if [ ! -z "$1" -a "$1" != "any" ]; then + echo "-v $1" + fi +} + + +function org_opt # (org) +{ + if [ ! -z "$1" ]; then + echo "-o $1" + fi +} + + +function update_ref # (srcasm, outasm, mode, vendor) +{ + local srcasm=$1 + local outasm=$2 + local mode=$3 + local vendor=$4 + local org=`org_opt $4` + local vendor=`vendor_opt $5` + + $yasm -f bin ${srcasm} -o ${outasm}.bin && + if [ -f "${srcasm}.ref" ]; then + echo "REFUP ${outasm}.out -> ${srcasm}.ref" + $udcli $vendor $org -${mode} ${outasm}.bin > ${outasm}.out && + cp ${outasm}.out ${srcasm}.ref + fi && + if [ -f "${srcasm}.Sref" ]; then + echo "REFUP ${outasm}.out -> ${srcasm}.Sref" + $udcli $vendor $org -att -${mode} ${outasm}.bin > ${outasm}.out && + cp ${outasm}.out ${srcasm}.Sref + fi +} + + + +function diff_test # (srcasm, outasm, mode, org, vendor) +{ + local srcasm=$1 + local outasm=$2 + local mode=$3 + local vendor=$4 + local org=`org_opt $4` + local vendor=`vendor_opt $5` + + $yasm -f bin ${srcasm} -o ${outasm}.bin && + if [ ! -f "${srcasm}.ref" ]; then + echo "[bits ${mode}]" > ${outasm}.out && + $udcli $vendor $org -${mode} -noff -nohex ${outasm}.bin >> ${outasm}.out && + diff -w ${srcasm} ${outasm}.out 2>&1 > ${outasm}.diff.log + else + $udcli ${vendor} $org -${mode} ${outasm}.bin > ${outasm}.out && + diff -w ${srcasm}.ref ${outasm}.out 2>&1 > ${outasm}.diff.log + fi && + if [ -f "${srcasm}.Sref" ]; then + $udcli ${vendor} $org -att -${mode} ${outasm}.bin > ${outasm}.out && + diff -w ${srcasm}.Sref ${outasm}.out 2>&1 > ${outasm}.diff.log + fi && + echo "DIFFTEST ${srcasm}: PASS" || + ( echo "DIFFTEST ${srcasm}: ***FAIL*** (${outasm}.diff.log)" && return 1 ) +} + + +function for_each_asm # (do_op) +{ + local do_op=$1 + local rc=0 + for mode in 16 32 64; do + for vendor in amd intel any; do + if [ "${vendor}" == "any" ]; then + asmdir=${srcdir}/asm/${mode} + outdir=${builddir}/_results/asm/${mode} + else + asmdir=${srcdir}/asm/${mode}/${vendor} + outdir=${builddir}/_results/asm/${mode}/${vendor} + fi + + if [ ! -d "${asmdir}" ]; then + continue + fi + + mkdir -p ${outdir} || ( echo "failed to create output dir" && exit 1 ) + + for a in `find ${asmdir} -maxdepth 1 -name "*.asm"` \ + `find ${outdir} -maxdepth 1 -name "*.asm"`; do + srcasm=$a + outasm=${outdir}/`basename $a` + org=`asm_org $srcasm` + $do_op $srcasm $outasm $mode "$org" "$vendor" || + rc=$? + done + done + done + return $rc +} + + +if [ "$1" == "refup" ]; then + for_each_asm update_ref && exit 0 || exit 1 +else + for_each_asm diff_test && exit 0 || exit 1 +fi diff --git a/udis86/tests/installcheck.c b/udis86/tests/installcheck.c new file mode 100644 index 0000000..71b96db --- /dev/null +++ b/udis86/tests/installcheck.c @@ -0,0 +1,18 @@ +#include +#include + +int main(void) +{ + ud_t ud_obj; + + ud_init(&ud_obj); + ud_set_input_file(&ud_obj, stdin); + ud_set_mode(&ud_obj, 64); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + + while (ud_disassemble(&ud_obj)) { + printf("\t%s\n", ud_insn_asm(&ud_obj)); + } + + return 0; +} diff --git a/udis86/tests/libcheck.c b/udis86/tests/libcheck.c new file mode 100644 index 0000000..3cd0aab --- /dev/null +++ b/udis86/tests/libcheck.c @@ -0,0 +1,232 @@ +/* udis86 - tests/libcheck.c + * + * Copyright (c) 2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +unsigned int testcase_check_count; +unsigned int testcase_check_fails; + +#define TEST_DECL(name) \ + const char * __testcase_name = name \ + +#define TEST_CASE() \ + do { \ + volatile int __c = ++ testcase_check_count; \ + if (0) __c += 1; \ + do + +#define TEST_CASE_SET_FAIL() \ + do { \ + testcase_check_fails++; \ + printf("Testcase %s: failure at line %d\n", __testcase_name, __LINE__); \ + } while (0) + +#define TEST_CASE_REPORT_ACTUAL(v) \ + printf("Testcase %s: actual = %d\n", __testcase_name, (v)) +#define TEST_CASE_REPORT_EXPECTED(v) \ + printf("Testcase %s: expected = %d\n", __testcase_name, (v)) + +#define TEST_CASE_END() \ + while (0); \ + } while (0) + +#define TEST_CHECK(cond) \ + TEST_CASE() { \ + int eval = (cond); \ + if (!eval) { \ + TEST_CASE_SET_FAIL(); \ + } \ + } TEST_CASE_END() + +#define TEST_CHECK_INT(expr, val) \ + TEST_CASE() { \ + int eval = (expr); \ + int val2 = (val); \ + if (eval != val2) { \ + TEST_CASE_SET_FAIL(); \ + TEST_CASE_REPORT_EXPECTED(val2); \ + TEST_CASE_REPORT_ACTUAL(eval); \ + } \ + } TEST_CASE_END() + +#define TEST_CHECK_OP_REG(o, n, r) \ + TEST_CHECK(ud_insn_opr(o, n)->type == UD_OP_REG && \ + ud_insn_opr(o, n)->base == (r)) + + +static int +input_callback(ud_t *u) +{ + int *n = (int *) ud_get_user_opaque_data(u); + if (*n == 0) { + return UD_EOI; + } + --*n; + return 0x90; +} + +static void +check_input(ud_t *ud_obj) +{ + TEST_DECL("check_input"); + const uint8_t code[] = { 0x89, 0xc8 }; /* mov eax, ecx */ + int i; + + /* truncate buffer */ + ud_set_mode(ud_obj, 32); + for (i = 0; i < 5; ++i) { + ud_set_input_buffer(ud_obj, code, (sizeof code) - 1); + TEST_CHECK(ud_disassemble(ud_obj) == 1); + TEST_CHECK(ud_insn_len(ud_obj) == 1); + TEST_CHECK(ud_obj->mnemonic == UD_Iinvalid); + } + + /* input skip on buffer */ + { + const uint8_t code[] = { 0x89, 0xc8, /* mov eax, ecx*/ + 0x90 }; /* nop */ + ud_set_input_buffer(ud_obj, code, (sizeof code)); + ud_input_skip(ud_obj, 2); + TEST_CHECK_INT(ud_disassemble(ud_obj), 1); + TEST_CHECK_INT(ud_obj->mnemonic, UD_Inop); + + ud_set_input_buffer(ud_obj, code, (sizeof code)); + ud_input_skip(ud_obj, 0); + TEST_CHECK_INT(ud_disassemble(ud_obj), 2); + TEST_CHECK_INT(ud_obj->mnemonic, UD_Imov); + TEST_CHECK(ud_insn_ptr(ud_obj)[0] == 0x89); + TEST_CHECK(ud_insn_ptr(ud_obj)[1] == 0xc8); + + /* bad skip */ + ud_set_input_buffer(ud_obj, code, (sizeof code)); + ud_input_skip(ud_obj, 3); + TEST_CHECK_INT(ud_disassemble(ud_obj), 0); + ud_input_skip(ud_obj, 1); + TEST_CHECK_INT(ud_disassemble(ud_obj), 0); + ud_set_input_buffer(ud_obj, code, (sizeof code)); + ud_input_skip(ud_obj, 0); + TEST_CHECK_INT(ud_disassemble(ud_obj), 2); + ud_input_skip(ud_obj, 1000); + TEST_CHECK_INT(ud_disassemble(ud_obj), 0); + } + + /* input hook test */ + { + int n; + ud_set_user_opaque_data(ud_obj, (void *) &n); + ud_set_input_hook(ud_obj, &input_callback); + + n = 0; + TEST_CHECK(ud_disassemble(ud_obj) == 0); + + n = 1; + ud_set_input_hook(ud_obj, &input_callback); + TEST_CHECK_INT(ud_disassemble(ud_obj), 1); + TEST_CHECK(ud_insn_ptr(ud_obj)[0] == 0x90); + TEST_CHECK_INT(ud_obj->mnemonic, UD_Inop); + + n = 2; + ud_set_input_hook(ud_obj, &input_callback); + ud_input_skip(ud_obj, 1); + TEST_CHECK(ud_disassemble(ud_obj) == 1); + TEST_CHECK(ud_obj->mnemonic == UD_Inop); + TEST_CHECK(ud_disassemble(ud_obj) == 0); + TEST_CHECK(ud_insn_len(ud_obj) == 0); + TEST_CHECK(ud_obj->mnemonic == UD_Iinvalid); + + n = 1; + ud_input_skip(ud_obj, 2); + TEST_CHECK_INT(ud_disassemble(ud_obj), 0); + TEST_CHECK(ud_input_end(ud_obj)); + } + + /* a known buffer overrun test case (used to be bufoverrun.c) */ + { + const uint8_t code[] = { 0xf0, 0x66, 0x36, 0x67, 0x65, 0x66, + 0xf3, 0x67, 0xda }; + ud_set_mode(ud_obj, 16); + ud_set_input_buffer(ud_obj, code, sizeof code); + TEST_CHECK(ud_disassemble(ud_obj) > 0); + } +} + +static void +check_mode(ud_t *ud_obj) +{ + TEST_DECL("check_mode"); + const uint8_t code[] = { 0x89, 0xc8 }; /* mov eax, ecx */ + ud_set_input_buffer(ud_obj, code, sizeof code); + ud_set_mode(ud_obj, 32); + TEST_CHECK(ud_disassemble(ud_obj) == 2); + TEST_CHECK_OP_REG(ud_obj, 0, UD_R_EAX); + TEST_CHECK_OP_REG(ud_obj, 1, UD_R_ECX); +} + +static void +check_disasm(ud_t *ud_obj) +{ + TEST_DECL("check_mode"); + const uint8_t code[] = { 0x89, 0xc8, /* mov eax, ecx */ + 0x90 }; /* nop */ + ud_set_input_buffer(ud_obj, code, sizeof code); + ud_set_mode(ud_obj, 32); + ud_set_pc(ud_obj, 0x100); + + TEST_CHECK(ud_disassemble(ud_obj) == 2); + TEST_CHECK(ud_insn_off(ud_obj) == 0x100); + TEST_CHECK(ud_insn_ptr(ud_obj)[0] == 0x89); + TEST_CHECK(ud_insn_ptr(ud_obj)[1] == 0xc8); + TEST_CHECK(ud_insn_mnemonic(ud_obj) == UD_Imov); + TEST_CHECK(strcmp(ud_lookup_mnemonic(UD_Imov), "mov") == 0); + + TEST_CHECK(ud_disassemble(ud_obj) == 1); + TEST_CHECK(ud_insn_off(ud_obj) == 0x102); + TEST_CHECK(ud_insn_ptr(ud_obj)[0] == 0x90); + TEST_CHECK(ud_insn_mnemonic(ud_obj) == UD_Inop); + TEST_CHECK(strcmp(ud_lookup_mnemonic(UD_Inop), "nop") == 0); +} + +int +main(void) +{ + ud_t ud_obj; + ud_init(&ud_obj); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + + check_input(&ud_obj); + check_mode(&ud_obj); + check_disasm(&ud_obj); + + if (testcase_check_fails > 0) { + printf("libcheck result: %d checks, %d failures\n", + testcase_check_count, testcase_check_fails); + return 1; + } + return 0; +} + +/* vim: set ts=2 sw=2 expandtab: */ diff --git a/udis86/tests/oprgen.py b/udis86/tests/oprgen.py new file mode 100644 index 0000000..0c6b462 --- /dev/null +++ b/udis86/tests/oprgen.py @@ -0,0 +1,1004 @@ +# udis86 - test/testgen.py +# +# Copyright (c) 2009 Vivek Thampi +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +import random + +if ( len( os.getenv( 'UD_SCRIPT_DIR', "" ) ) ): + scriptsPath = os.getenv( 'UD_SCRIPT_DIR' ) + "/scripts" +else: + scriptsPath = '../scripts' +sys.path.append( scriptsPath ); + +import ud_opcode + +def bits2name(bits): + bits2name_map = { + 8 : "byte", + 16 : "word", + 32 : "dword", + 64 : "qword", + 80 : "tword", + 128 : "oword", + 256 : "yword", + } + return bits2name_map[bits] + + +class UdTestGenerator( ud_opcode.UdOpcodeTables ): + + OprTable = [] + + ExcludeList = ( 'fcomp3', 'fcom2', 'fcomp5', 'fstp1', 'fstp8', 'fstp9', + 'fxch4', 'fxch7', 'nop', 'xchg', 'movd', + 'pmulhrw', # yasm bug + 'vcvtpd2ps', # operand casting issues + 'vcvtpd2dq', # - ditto - + 'vcvttpd2dq', # - ditto - + 'vmovd', 'vmovq' + ) + + def __init__(self, mode, xml): + super(UdTestGenerator, self).__init__(xml=xml) + self.mode = mode + pass + + def OprMem(self, size=None, cast=False): + choices = [] + if self.mode < 64: + choices = ["[bx+si+0x1234]", + "[bx+0x10]", + "[bp+di+0x27]", + "[di+0x100]"] + choices.extend(("[eax+ebx]", "[ebx+ecx*4]", + "[ebp+0x10]")) + if self.mode == 64: + choices.extend(("[rax+rbx]", "[rbx+r8-0x10]")) + addr = random.choice(choices) + if cast and size is not None: + addr = "%s %s" % (bits2name(size), addr) + return addr + + def OprImm(self, size, cast=False): + imm = "0x%x" % random.randint(2, 1 << (size - 1)) + if cast and size is not None: + imm = "%s %s" % (bits2name(size), imm) + return imm + + def Gpr(self, size): + if size == 8: + choices = ['al', 'cl'] + if self.mode == 64: + choices.extend(['sil', 'r10b']) + elif size == 16: + choices = ['ax', 'bp', 'dx'] + if self.mode == 64: + choices.extend(['r8w', 'r14w']) + elif size == 32: + choices = ['eax', 'ebp', 'edx'] + if self.mode == 64: + choices.extend(['r10d', 'r12d']) + elif size == 64: + choices = ['rax', 'rsi', 'rsp'] + if self.mode == 64: + choices.extend(['r9', 'r13']) + return random.choice(choices) + + def Xmm(self): + r = 16 if self.mode == 64 else 8 + return "xmm%d" % random.choice(range(r)) + + def Ymm(self): + r = 16 if self.mode == 64 else 8 + return "ymm%d" % random.choice(range(r)) + + def Mmx(self): + return "mm%d" % random.choice(range(8)) + + def Modrm_RM_GPR(self, size, cast=False): + return random.choice([self.Gpr(size), + self.OprMem(size=size, cast=cast)]) + + def Modrm_RM_XMM(self, size, cast=False): + return random.choice([self.Xmm(), + self.OprMem(size=size, cast=cast)]) + + def OprRxb(self, n): + regs = [ 'al', 'cl', 'dl', 'bl' ] + if self.mode == 64 and random.choice((False, True)): + regs += [ 'spl', 'bpl', 'sil', 'dil', + 'r8b', 'r9b', 'r10b', 'r11b', + 'r12b', 'r13b', 'r14b', 'r15b' ] + n |= random.choice((0, 8)) + else: + regs += [ 'ah', 'ch', 'dh', 'bh' ] + return regs[n] + + def OprRxw(self, n): + regs = [ 'ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di' ] + if self.mode == 64 and random.choice((False, True)): + regs += [ 'r8w', 'r9w', 'r10w', 'r11w', + 'r12w', 'r13w', 'r14w', 'r15w' ] + n |= random.choice((0, 8)) + return regs[n] + + def OprRxd(self, n): + regs = [ 'eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi' ] + if self.mode == 64 and random.choice((False, True)): + regs += [ 'r8d', 'r9d', 'r10d', 'r11d', + 'r12d', 'r13d', 'r14d', 'r15d' ] + n |= random.choice((0, 8)) + return regs[n] + + def OprRxq(self, n): + regs = [ 'rax', 'rcx', 'rdx', 'rbx', + 'rsp', 'rbp', 'rsi', 'rdi', + 'r8', 'r9', 'r10', 'r11', + 'r12', 'r13', 'r14', 'r15' ] + n |= random.choice((0, 8)) + return regs[n] + + def OprRxv(self, n): + choices = [ self.OprRxw(n), self.OprRxd(n) ] + if self.mode == 64: + choices.append(self.OprRxq(n)) + return random.choice(choices) + + def OprRxz(self, n): + choices = [ self.OprRxw(n), self.OprRxd(n) ] + return random.choice(choices) + + def OprRxy(self, n): + choices = [ self.OprRxd(n) ] + if self.mode == 64: + choices.append(self.OprRxq(n)) + return random.choice(choices) + + Opr_R0b = lambda s: s.OprRxb(0); + Opr_R1b = lambda s: s.OprRxb(1); + Opr_R2b = lambda s: s.OprRxb(2); + Opr_R3b = lambda s: s.OprRxb(3); + Opr_R4b = lambda s: s.OprRxb(4); + Opr_R5b = lambda s: s.OprRxb(5); + Opr_R6b = lambda s: s.OprRxb(6); + Opr_R7b = lambda s: s.OprRxb(7); + + Opr_R0y = lambda s: s.OprRxy(0); + Opr_R1y = lambda s: s.OprRxy(1); + Opr_R2y = lambda s: s.OprRxy(2); + Opr_R3y = lambda s: s.OprRxy(3); + Opr_R4y = lambda s: s.OprRxy(4); + Opr_R5y = lambda s: s.OprRxy(5); + Opr_R6y = lambda s: s.OprRxy(6); + Opr_R7y = lambda s: s.OprRxy(7); + + Opr_R0v = lambda s: s.OprRxv(0); + Opr_R1v = lambda s: s.OprRxv(1); + Opr_R2v = lambda s: s.OprRxv(2); + Opr_R3v = lambda s: s.OprRxv(3); + Opr_R4v = lambda s: s.OprRxv(4); + Opr_R5v = lambda s: s.OprRxv(5); + Opr_R6v = lambda s: s.OprRxv(6); + Opr_R7v = lambda s: s.OprRxv(7); + + Opr_R0z = lambda s: s.OprRxz(0); + Opr_R1z = lambda s: s.OprRxz(1); + Opr_R2z = lambda s: s.OprRxz(2); + Opr_R3z = lambda s: s.OprRxz(3); + Opr_R4z = lambda s: s.OprRxz(4); + Opr_R5z = lambda s: s.OprRxz(5); + Opr_R6z = lambda s: s.OprRxz(6); + Opr_R7z = lambda s: s.OprRxz(7); + + def Insn_Av(self): + return random.choice([("word 0x100:0x100",), ("dword 0x100:0xfaddbc",)]) + + def Opr_R(self): + if self.mode == 64: + return self.OprRxq(random.choice(range(8))) + return self.OprRxd(random.choice(range(8))); + + def Opr_C(self): + return "cr3" + + def Opr_D(self): + return "dr0" + + def Opr_S(self): + return "fs" + + def Opr_ST0(self): + return "st0" + + def Opr_ST1(self): + return "st1" + + def Opr_ST2(self): + return "st2" + + def Opr_ST3(self): + return "st3" + + def Opr_ST4(self): + return "st4" + + def Opr_ST5(self): + return "st5" + + def Opr_ST6(self): + return "st6" + + def Opr_ST7(self): + return "st7" + + def Opr_CS(self): + return "cs" + + def Opr_GS(self): + return "gs" + + def Opr_ES(self): + return "es" + + def Opr_FS(self): + return "fs" + + def Opr_DS(self): + return "ds" + + def Opr_SS(self): + return "ss" + + def Opr_Ib(self, cast=False): + return self.OprImm(8, cast=cast) + + def Opr_Iw(self, cast=False): + return self.OprImm(16, cast=cast) + + def Opr_Id(self, cast=False): + return self.OprImm(32, cast=cast) + + def Opr_Iq(self, cast=False): + return self.OprImm(64, cast=cast) + + def Opr_Iz(self, cast=False): + return random.choice((self.OprImm(16, cast=cast), + self.OprImm(32, cast=cast))) + Opr_sIz = Opr_Iz + + def Opr_Iw(self, cast=False): + return self.OprImm(16, cast=cast) + + def Opr_I1(self, cast=False): + return "1" + + def Opr_eAX(self): + return random.choice(['ax', 'eax']) + + def Opr_rAX(self): + choices = ['ax', 'eax'] + if self.mode == 64: + choices.append('rax') + return random.choice(choices) + + def Insn_rAX_Iz(self): + choices = [('ax', self.Opr_Iw()), ('eax', self.Opr_Id())] + if self.mode == 64: + choices.append(('rax', self.Opr_Id())) + return random.choice(choices) + Insn_rAX_sIz = Insn_rAX_Iz + + def Insn_Rxv_Iv(self, n): + choices = [(self.OprRxw(n), self.Opr_Iw()), + (self.OprRxd(n), self.Opr_Id())] + if self.mode == 64: + choices.append((self.OprRxq(n), self.Opr_Iq())) + return random.choice(choices) + + Insn_R0v_Iv = lambda s: s.Insn_Rxv_Iv(0) + Insn_R1v_Iv = lambda s: s.Insn_Rxv_Iv(1) + Insn_R2v_Iv = lambda s: s.Insn_Rxv_Iv(2) + Insn_R3v_Iv = lambda s: s.Insn_Rxv_Iv(3) + Insn_R4v_Iv = lambda s: s.Insn_Rxv_Iv(4) + Insn_R5v_Iv = lambda s: s.Insn_Rxv_Iv(5) + Insn_R6v_Iv = lambda s: s.Insn_Rxv_Iv(6) + Insn_R7v_Iv = lambda s: s.Insn_Rxv_Iv(7) + + def Insn_Rxv_rAX(self, n): + choices = [(self.OprRxw(n), "ax"), + (self.OprRxd(n), "eax")] + if self.mode == 64: + choices.append((self.OprRxq(n), "rax")) + return random.choice(choices) + + Insn_R0v_rAX = lambda s: s.Insn_Rxv_rAX(0) + Insn_R1v_rAX = lambda s: s.Insn_Rxv_rAX(1) + Insn_R2v_rAX = lambda s: s.Insn_Rxv_rAX(2) + Insn_R3v_rAX = lambda s: s.Insn_Rxv_rAX(3) + Insn_R4v_rAX = lambda s: s.Insn_Rxv_rAX(4) + Insn_R5v_rAX = lambda s: s.Insn_Rxv_rAX(5) + Insn_R6v_rAX = lambda s: s.Insn_Rxv_rAX(6) + Insn_R7v_rAX = lambda s: s.Insn_Rxv_rAX(7) + + def Opr_Gb(self): + return self.Gpr(8) + + def Opr_Gw(self): + return self.Gpr(16) + + def Opr_Gd(self): + return self.Gpr(32) + + def Opr_Gq(self): + return self.Gpr(64) + + def Opr_Gz(self): + return random.choice([self.Gpr(16), self.Gpr(32)]) + + def Opr_Gv(self): + choices = [self.Gpr(16), self.Gpr(32)] + if self.mode == 64: + choices.append(self.Gpr(64)) + return random.choice(choices) + + def Opr_Gy(self): + choices = [self.Gpr(32)] + if self.mode == 64: + choices.append(self.Gpr(64)) + return random.choice(choices) + + def Opr_M(self): + return self.OprMem(); + + def Opr_U(self, L=False): + return self.Xmm() if not L else self.Ymm() + Opr_Ux = Opr_U + + def Opr_N(self): + return self.Mmx(); + + def Opr_Mb(self, cast=False): + return self.OprMem(size=8, cast=cast); + + def Opr_Mw(self, cast=False): + return self.OprMem(size=16, cast=cast); + + def Opr_Md(self, cast=False): + return self.OprMem(size=32, cast=cast); + + def Opr_Mq(self, cast=False): + return self.OprMem(size=64, cast=cast); + + def Opr_Mdq(self, cast=False): + return self.OprMem(size=128, cast=cast); + + def Opr_Mt(self, cast=True): + return self.OprMem(size=80, cast=cast); + + def Opr_MwRd(self, cast=True): + return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gd())) + + def Opr_MwRv(self, cast=False): + return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gv())) + + def Opr_MwRy(self, cast=True): + return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gy())) + + def Opr_MdRy(self, cast=False): + return random.choice((self.Opr_Md(cast=cast), self.Opr_Gy())) + + def Opr_MbRv(self, cast=False): + return random.choice((self.Opr_Mb(cast=cast), self.Opr_Gv())) + + def Opr_MbRd(self, cast=False): + return random.choice((self.Opr_Mb(cast=cast), self.Opr_Gd())) + + def Opr_MwRw(self, cast=False): + return random.choice((self.Opr_Mw(cast=cast), self.Opr_Gw())) + + def Opr_MwU(self, cast=False): + return random.choice((self.Opr_Mw(cast=cast), self.Xmm())) + + def Opr_MdU(self, cast=False): + return random.choice((self.Opr_Md(cast=cast), self.Xmm())) + + def Opr_MqU(self, cast=False): + return random.choice((self.Opr_Mq(cast=cast), self.Xmm())) + + def Insn_V_MwU(self, cast=False): + return (self.Opr_V(), self.Opr_MwU(cast=True)) + + def Insn_V_MdU(self, cast=False): + return self.Opr_V(), self.Opr_MdU(cast=True) + + def Insn_V_MqU(self, cast=False): + return self.Opr_V(), self.Opr_MqU(cast=True) + + def Insn_Vx_MwU(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_MwU(cast=True) + + def Insn_Vx_MdU(self, cast=False): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(), self.Opr_MdU(cast=True) + + def Insn_Vx_MqU(self, cast=False): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(), self.Opr_MqU(cast=True) + + def Insn_V_Md(self, cast=False): + return self.Opr_V(), self.Opr_Md(cast=True) + + def Insn_V_Mq(self, cast=False): + return self.Opr_V(), self.Opr_Mq(cast=True) + + def Insn_Mq_V(self): + x, y = self.Insn_V_Mq() + return y, x + + def Insn_Md_V(self): + x, y = self.Insn_V_Md() + return y, x + + def Insn_Vqq_Mq(self, cast=False): + return self.Opr_Vqq(), self.Opr_Mq(cast=True) + + def Insn_Wdq_Vqq_Ib(self, cast=False): + return self.Opr_W(size=128, cast=True), self.Opr_Vqq(), self.Opr_Ib() + + def Insn_MbRv(self): + return [self.Opr_MbRv(cast=True)] + + def Insn_MbRv_V_Ib(self): + return [self.Opr_MbRv(cast=True), self.Opr_V(), self.Opr_Ib()] + + def Insn_V_MbRd_Ib(self): + return [self.Opr_V(), self.Opr_MbRd(cast=True), self.Opr_Ib()] + + def Insn_MwRv(self): + return [self.Opr_MwRv(cast=True)] + + def Insn_MwRd_V_Ib(self): + return [self.Opr_MwRd(cast=True), self.Opr_V(), self.Opr_Ib()] + Insn_MwRd_Vx_Ib = Insn_MwRd_V_Ib + + def Insn_S_MwRv(self): + if self.mode == 64: + return [self.Opr_S(), self.Opr_MwRd(cast=False)] + if self.mode == 16: + return [self.Opr_S(), self.Opr_MwRw(cast=False)] + if self.mode == 32: + return [self.Opr_S(), self.Opr_MwRd(cast=False)] + + def Insn_Mw(self): + return [self.Opr_Mw(cast=True)] + + def Insn_Md(self): + return [self.Opr_Md(cast=True)] + + def Insn_Mq(self): + return [self.Opr_Mq(cast=True)] + + def Opr_Eb(self, cast=False): + return self.Modrm_RM_GPR(8, cast=cast) + + def Opr_Ew(self, cast=False): + return self.Modrm_RM_GPR(16, cast=cast) + + def Opr_Ed(self, cast=False): + return self.Modrm_RM_GPR(32, cast=cast) + + def Opr_Eq(self, cast=False): + return self.Modrm_RM_GPR(64, cast=cast) + + def Opr_Ey(self, cast=False): + choices = [self.Modrm_RM_GPR(32, cast=cast)] + if self.mode == 64: + choices.append(self.Modrm_RM_GPR(64, cast=cast)) + return random.choice(choices) + + def Insn_Fv(self): + return ("far "+ self.Opr_Mv(cast=True),) + + def Insn_V_Ew_Ib(self): + return self.Opr_V(), self.Opr_Ew(cast=True), self.Opr_Ib() + + def Insn_V_Eq_Ib(self): + return self.Opr_V(), self.Opr_Eq(cast=True), self.Opr_Ib() + + def Insn_V_Mo(self): + return self.Opr_V(), self.Opr_M() + + def Insn_V_Md_Ib(self): + return self.Opr_V(), self.Opr_Md(cast=True), self.Opr_Ib() + + def Insn_V_Ed(self): + return self.Opr_V(), self.Opr_Ed(cast=True) + + def Insn_V_Ed_Ib(self): + x, y = self.Insn_V_Ed() + return x, y, self.Opr_Ib() + + def Insn_P_Ew_Ib(self): + return self.Opr_P(), self.Opr_Ew(cast=True), self.Opr_Ib() + + def Insn_V_Ey(self): + return self.Opr_V(), self.Opr_Ey(cast=True) + + def Insn_Ey_V(self): + x, y = self.Insn_V_Ey() + return y, x + + def Insn_P_Ey(self): + return self.Opr_P(), self.Opr_Ey(cast=True) + + def Insn_Ey_P(self): + x, y = self.Insn_P_Ey() + return y, x + + def Opr_Mv(self, cast=False): + choices = [self.Opr_Mw(cast), self.Opr_Md(cast)] + if self.mode == 64: + choices.append(self.Opr_Mq(cast)) + return random.choice(choices) + + def Opr_Ev(self, cast=False): + choices = [self.Opr_Ew(cast), self.Opr_Ed(cast)] + if self.mode == 64: + choices.append(self.Opr_Eq(cast)) + return random.choice(choices) + + def Insn_Ev(self): + choices = [self.Modrm_RM_GPR(16, cast=True), + self.Modrm_RM_GPR(32, cast=True)] + if self.mode == 64: + choices.append(self.Modrm_RM_GPR(64, cast=True)) + return [random.choice(choices)] + + def Opr_V(self, L=False): + return self.Xmm() if not L else self.Ymm() + Opr_Vdq = Xmm + Opr_Vqq = Ymm + Opr_Hqq = Ymm + + def Opr_Vsd(self, L=False): + return self.Xmm() if not L else self.Ymm() + + def Opr_L(self, L=False): + return self.Xmm() if not L else self.Ymm() + + def Opr_H(self, L=False): + return self.Opr_V(L) + + def Opr_W(self, L=False, cast=False, size=None): + if not L: + if size is None: size = 128 + return random.choice([self.Xmm(), self.OprMem(size=size, cast=cast)]) + else: + if size is None: size = 256 + return random.choice([self.Ymm(), self.OprMem(size=size, cast=cast)]) + Opr_Wx = Opr_W + + def Opr_Wdq(self, cast=False): + return self.Opr_W(cast=cast, size=128) + + def Opr_Wsd(self, L=False): + return random.choice([self.Xmm(), self.OprMem(size=64, cast=False)]) + + def Opr_Wdq(self, cast=False): + return random.choice([self.Xmm(), self.OprMem(size=128, cast=cast)]) + + def Opr_Wqq(self, L=False): + return random.choice([self.Ymm(), self.OprMem(size=256, cast=False)]) + + def Insn_V_H_W(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L)] + + def Insn_Vx_Wx(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_W(L, cast=False)] + + def Insn_Wx_Vx(self): + x, y = self.Insn_Vx_Wx() + return y, x + + def Insn_Vx_U(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_U(L) + + def Insn_Eq_Vx(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_Eq(), self.Opr_V(L) + + def Insn_Ey_Vx(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_Ey(cast=True), self.Opr_V(L) + + def Insn_Vx_Ey(self): + x, y = self.Insn_Ey_Vx() + return y, x + + def Insn_Vdq_Wx(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_Vdq(), self.Opr_W(L, cast=True)] + + def Insn_Vdq_W(self): + return [self.Opr_V(), self.Opr_W(cast=False)] + + def Insn_V_Wdq(self): + return [self.Opr_V(), self.Opr_W(cast=False)] + + def Insn_Vx_Ux(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_U(L) + + def Insn_Vx_Wdq(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_W(L=False, cast=L)] + + def Insn_Vx_Wx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_W(L), self.Opr_Ib()] + + def Insn_Vx_Hx_Wx(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L)] + + def Insn_Hx_Vx_Wx(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_H(L), self.Opr_V(L), self.Opr_W(L)] + + def Insn_Vx_Hx_Ux(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_U(L)] + + def Insn_Hx_Ux_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_H(L), self.Opr_U(L), self.Opr_Ib()] + + def Insn_Vx_Hx_Ey(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_H(L), self.Opr_Ey(cast=True) + + def Insn_Vx_Hx_Ed_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_H(L), self.Opr_Ed(cast=True), self.Opr_Ib() + Insn_V_H_Ed_Ib = Insn_Vx_Hx_Ed_Ib + + def Insn_V_H_Eq_Ib(self): + return self.Opr_V(), self.Opr_H(), self.Opr_Eq(cast=True), self.Opr_Ib() + + def Insn_V_H_MbRd_Ib(self): + return self.Opr_V(), self.Opr_H(), self.Opr_MbRd(cast=True), self.Opr_Ib() + + def Insn_Vx_Hx_Wx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L), self.Opr_Ib()] + + def Insn_Vx_Hx_M(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_H(L), self.Opr_M() + + def Insn_Vx_Hx_Md_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_Md(cast=True), self.Opr_Ib()] + + def Insn_Vqq_Hqq_Wdq_Ib(self): + return [self.Opr_Vqq(), self.Opr_Hqq(), self.Opr_Wdq(cast=True), self.Opr_Ib()] + + def Insn_Vx_Hx_Wx_Lx(self): + L = random.choice((True, False)) if self.vexl else False + return [self.Opr_V(L), self.Opr_H(L), self.Opr_W(L), self.Opr_L(L)] + + def Insn_Vx_Hx_MqU(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_H(L), self.Opr_MqU(cast=True) + + def Insn_Vx_Hx_MdU(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_H(L), self.Opr_MdU(cast=True) + + def Insn_Vx_M(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_V(L), self.Opr_M() + + def Insn_M_Vx(self): + x, y = self.Insn_Vx_M() + return y, x + + def Insn_MdRy_Vx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_MdRy(cast=True), self.Opr_V(L), self.Opr_Ib() + + def Insn_MdRy_V_Ib(self): + return self.Opr_MdRy(cast=True), self.Opr_V(), self.Opr_Ib() + + def Insn_MdRv_Vx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_MdRv(cast=True), self.Opr_V(L), self.Opr_Ib() + + def Insn_MdRv_V_Ib(self): + return self.Opr_MdRv(cast=True), self.Opr_V(), self.Opr_Ib() + + def Insn_MwRv_Vx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_MwRv(cast=True), self.Opr_V(L), self.Opr_Ib() + + def Insn_MwRv_V_Ib(self): + return self.Opr_MwRv(cast=True), self.Opr_V(), self.Opr_Ib() + + def Insn_Ed_Vx_Ib(self): + L = random.choice((True, False)) if self.vexl else False + return self.Opr_Ed(cast=True), self.Opr_V(L), self.Opr_Ib() + + def Opr_P(self): + return self.Mmx() + + def Opr_Q(self, cast=False): + return random.choice([self.Mmx(), self.OprMem(size=64, cast=cast)]) + + def Opr_CL(self): + return "cl" + + def Opr_AL(self): + return "al" + + def Opr_Ob(self): + return "[0x100]" + + def Insn_rAX_Ov(self): + choices = [ ("ax", "[0x100]"), ("eax", "[0x1000]") ] + if self.mode == 64: + choices.append(("rax", "[0x1223221]")) + return random.choice(choices) + + def Insn_Ov_rAX(self): + x, y = self.Insn_rAX_Ov() + return y, x + + def Opr_AX(self): + return "ax" + + def Opr_DX(self): + return "dx" + + def Insn_Eb_CL(self): + return self.Opr_Eb(cast=True), self.Opr_CL() + + def Insn_Ev_CL(self): + return self.Opr_Ev(cast=True), self.Opr_CL() + + def Insn_Eb(self): + return [self.Modrm_RM_GPR(size=8, cast=True)] + + def Insn_Ew(self): + return [self.Modrm_RM_GPR(size=16, cast=True)] + + def Insn_Ev_Gv(self): + choices = [ (self.Opr_Ew(), self.Opr_Gw()), + (self.Opr_Ed(), self.Opr_Gd()) ] + if self.mode == 64: + choices.append((self.Opr_Eq(), self.Opr_Gq())) + return random.choice(choices) + + def Insn_Ev_Gy(self): + choices = [ (self.Opr_Ew(), self.Opr_Gd()), + (self.Opr_Ed(), self.Opr_Gd()) ] + if self.mode == 64: + choices.append((self.Opr_Eq(), self.Opr_Gq())) + return random.choice(choices) + + def Insn_Ev_Gv_CL(self): + x, y = self.Insn_Ev_Gv(); + return x, y, self.Opr_CL() + + def Insn_Gv_Ev_CL(self): + x, y = self.Insn_Ev_Gv(); + return y, x, self.Opr_CL() + + def Insn_Gv_Ev_Ib(self): + x, y = self.Insn_Ev_Gv(); + return y, x, self.Opr_Ib(cast=False) + Insn_Gv_Ev_sIb = Insn_Gv_Ev_Ib + + def Insn_Gv_Ev_Iz(self): + choices = [ (self.Opr_Gw(), self.Opr_Ew(), self.Opr_Iw()), + (self.Opr_Gd(), self.Opr_Ed(), self.Opr_Id()) ] + if self.mode == 64: + choices.append((self.Opr_Gq(), self.Opr_Eq(), self.Opr_Iz())) + return random.choice(choices) + + def Insn_Ev_Ib(self): + return self.Opr_Ev(cast=True), self.Opr_Ib() + Insn_Ev_sIb = Insn_Ev_Ib + + def Insn_Gq_Ed(self): + return self.Opr_Gq(), self.Opr_Ed(cast=True) + + def Insn_Gy_Eb(self): + return self.Opr_Gy(), self.Opr_Eb(cast=True) + + def Insn_Gy_Ew(self): + return self.Opr_Gy(), self.Opr_Ew(cast=True) + + def Insn_Gy_W(self): + choices = [(self.Gpr(32), self.Opr_W(size=32, cast=False)),] + if self.mode == 64: + choices.append([self.Gpr(64), self.Opr_W(size=32, cast=True)]) + return random.choice(choices) + + def Insn_Gy_MqU(self): + choices = [(self.Gpr(32), self.Opr_W(size=64, cast=True)),] + if self.mode == 64: + choices.append([self.Gpr(64), self.Opr_W(size=64, cast=False)]) + return random.choice(choices) + + def Insn_Gy_MdU(self): + choices = [(self.Gpr(32), self.Opr_W(size=32, cast=False)),] + if self.mode == 64: + choices.append([self.Gpr(64), self.Opr_W(size=32, cast=True)]) + return random.choice(choices) + + def Insn_Gd_Ux(self): + L = random.choice((True, False)) if self.vexl else False + return self.Gpr(32), self.Opr_U(L) + + def Insn_Gy_Ux(self): + L = random.choice((True, False)) if self.vexl else False + choices = [(self.Gpr(32), self.Opr_U(L)),] + if self.mode == 64: + choices.append([self.Gpr(64), self.Opr_U(L)]) + return random.choice(choices) + + def Insn_Gy_Ux_Ib(self): + x, y = self.Insn_Gy_Ux() + return x, y, self.Opr_Ib() + + def Insn_Ev_Iz(self): + choices = [(self.Opr_Ew(cast=True), self.Opr_Iw()), + (self.Opr_Ed(cast=True), self.Opr_Id())] + if self.mode == 64: + choices.append((self.Opr_Eq(cast=True), self.Opr_Id())) + return random.choice(choices) + Insn_Ev_sIz = Insn_Ev_Iz + + def Insn_Gv_Ev(self): + x, y = self.Insn_Ev_Gv(); + return (y, x) + + def Insn_Gy_Ev(self): + x, y = self.Insn_Ev_Gy(); + return (y, x) + + def Insn_Gv_Eb(self): + return (self.Opr_Gv(), self.Opr_Eb(cast=True)) + + def Insn_Gv_Ew(self): + choices = [(self.Opr_Gw(), self.Opr_Ew(cast=False)), + (self.Opr_Gd(), self.Opr_Ew(cast=True))] + if self.mode == 64: + choices.append((self.Opr_Gq(), self.Opr_Ew(cast=True))) + return random.choice(choices) + + def Insn_V_Q(self): + return [self.Opr_V(), self.Opr_Q(cast=True)] + + def Insn_Eb_Ib(self): + return (self.Opr_Eb(cast=True), self.Opr_Ib(cast=False)) + + def Insn_Eb_I1(self): + return (self.Opr_Eb(cast=True), self.Opr_I1()) + + def Insn_Ev_I1(self): + return (self.Opr_Ev(cast=True), self.Opr_I1()) + + def Insn_Ev_Ib(self): + return (self.Opr_Ev(cast=True), self.Opr_Ib(cast=False)) + Insn_Ev_sIb = Insn_Ev_Ib + + def Insn_Ev_Gv_Ib(self): + choices = [ (self.Opr_Ew(), self.Opr_Gw(), self.Opr_Ib(cast=False)), + (self.Opr_Ed(), self.Opr_Gd(), self.Opr_Ib(cast=False)) ] + if self.mode == 64: + choices.append( + (self.Opr_Eq(), self.Opr_Gq(), self.Opr_Ib(cast=False)) ) + return random.choice(choices) + Insn_Ev_Gv_sIb = Insn_Ev_Gv_Ib + + def Insn_Ev_V_Ib(self): + return self.Opr_Ev(cast=True), self.Opr_V(), self.Opr_Ib(cast=False) + + def Insn_Ed_V_Ib(self): + return self.Opr_Ed(cast=True), self.Opr_V(), self.Opr_Ib(cast=False) + + def Insn_Ew_V_Ib(self): + return (self.Opr_Ew(cast=True), self.Opr_V(), self.Opr_Ib(cast=False)) + + def generate_yasm( self, mode, seed ): + opr_combos = {} + random.seed( seed ) + print("[bits %s]" % mode) + for insn in self.getInsnList(): + if insn.mnemonic in self.ExcludeList: + continue + if insn.vendor == 'intel': + continue + if ((insn.mode == '!64' and self.mode == 64) or + (insn.mode == '64' and self.mode != 64)): + continue + if insn.osize == '64' and self.mode != 64: + continue + if insn.isDef64(): + continue + if len(insn.operands) == 0: + continue + if "Jb" in insn.operands or "Jz" in insn.operands: + continue + + if insn.lookupPrefix("vexl"): + self.vexl = True + else: + self.vexl = False + + fusedName = '_'.join(insn.operands) + if fusedName not in opr_combos: + opr_combos[fusedName] = { 'covered' : False, 'freq' : 0 } + opr_combos[fusedName]['freq'] += 1 + + fn = getattr(self, "Insn_" + fusedName , None) + if fn is not None: + operands = ", ".join(fn()) + else: + oprgens = [ getattr(self, "Opr_" + opr, None) + for opr in insn.operands ] + if None not in oprgens: + operands = ", ".join([ oprgen() for oprgen in oprgens ]) + else: + operands = None + if operands is not None: + print("\t%s %s" % (insn.mnemonic, operands)) + opr_combos[fusedName]['covered'] = True + + # stats + total = 0 + covered = 0 + for combo in sorted(opr_combos, key=lambda k: opr_combos[k]['freq']): + total += 1 + is_covered = opr_combos[combo]['covered'] + covered += (1 if is_covered else 0) + if not is_covered: + sys.stderr.write("==> %12s : %5d\n" % + (combo, opr_combos[combo]['freq'])) + sys.stderr.write("MODE%s: Coverage = %d / %d (%d%%)\n" % + (self.mode, covered, total, (100 * covered / total))) + +def main(): + generator = UdTestGenerator(mode=int(sys.argv[3]), xml=sys.argv[1]) + generator.generate_yasm( sys.argv[ 3 ], int( sys.argv[ 2 ] ) ) + +if __name__ == '__main__': + main() diff --git a/udis86/tests/symresolve.c b/udis86/tests/symresolve.c new file mode 100644 index 0000000..cb91c63 --- /dev/null +++ b/udis86/tests/symresolve.c @@ -0,0 +1,53 @@ +#include +#include + +#if defined(__amd64__) || defined(__x86_64__) +# define FMT "l" +#else +# define FMT "ll" +#endif + +uint8_t bin[] = { + 0x01, 0xc0, 0xeb, 0x11, 0x01, 0xc0, 0xe8, 0x14, + 0x00, 0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x74, + 0x02, 0x01, 0xc0, 0x90, 0x90, 0xeb, 0xfe, 0x90, + 0x90, 0xeb, 0xf8, 0x90, 0x90, 0x74, 0xf6, 0x90, + 0x90, 0xe8, 0xf4, 0xff, 0xff, 0xff +}; + +static const char* +resolve(struct ud *u, uint64_t addr, int64_t *offset) +{ + *offset = addr - 0x15; + return "target"; +} + +static void +dis_loop(struct ud *ud_obj) +{ + while (ud_disassemble(ud_obj) != 0) { + printf("%016llx %-16s %s\n", ud_insn_off(ud_obj), + ud_insn_hex(ud_obj), + ud_insn_asm(ud_obj)); + } +} + +int +main() { + ud_t ud_obj; + ud_init(&ud_obj); + ud_set_mode(&ud_obj, 32); + ud_set_input_buffer(&ud_obj, bin, sizeof(bin)); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + + printf("==> Without Symbol Resolution\n"); + dis_loop(&ud_obj); + + printf("==> With Symbol Resolution\n"); + ud_set_pc(&ud_obj, 0); + ud_set_input_buffer(&ud_obj, bin, sizeof(bin)); + ud_set_sym_resolver(&ud_obj, &resolve); + dis_loop(&ud_obj); + + return 0; +} diff --git a/udis86/tests/symresolve.ref b/udis86/tests/symresolve.ref new file mode 100644 index 0000000..b0b5eac --- /dev/null +++ b/udis86/tests/symresolve.ref @@ -0,0 +1,42 @@ +==> Without Symbol Resolution +0000000000000000 01c0 add eax, eax +0000000000000002 eb11 jmp 0x15 +0000000000000004 01c0 add eax, eax +0000000000000006 e814000000 call 0x1f +000000000000000b 01c0 add eax, eax +000000000000000d 01c0 add eax, eax +000000000000000f 7402 jz 0x13 +0000000000000011 01c0 add eax, eax +0000000000000013 90 nop +0000000000000014 90 nop +0000000000000015 ebfe jmp 0x15 +0000000000000017 90 nop +0000000000000018 90 nop +0000000000000019 ebf8 jmp 0x13 +000000000000001b 90 nop +000000000000001c 90 nop +000000000000001d 74f6 jz 0x15 +000000000000001f 90 nop +0000000000000020 90 nop +0000000000000021 e8f4ffffff call 0x1a +==> With Symbol Resolution +0000000000000000 01c0 add eax, eax +0000000000000002 eb11 jmp target +0000000000000004 01c0 add eax, eax +0000000000000006 e814000000 call target+10 +000000000000000b 01c0 add eax, eax +000000000000000d 01c0 add eax, eax +000000000000000f 7402 jz target-2 +0000000000000011 01c0 add eax, eax +0000000000000013 90 nop +0000000000000014 90 nop +0000000000000015 ebfe jmp target +0000000000000017 90 nop +0000000000000018 90 nop +0000000000000019 ebf8 jmp target-2 +000000000000001b 90 nop +000000000000001c 90 nop +000000000000001d 74f6 jz target +000000000000001f 90 nop +0000000000000020 90 nop +0000000000000021 e8f4ffffff call target+5 diff --git a/udis86/udcli/Makefile.am b/udis86/udcli/Makefile.am new file mode 100644 index 0000000..dfe2784 --- /dev/null +++ b/udis86/udcli/Makefile.am @@ -0,0 +1,5 @@ +bin_PROGRAMS = udcli +udcli_SOURCES = udcli.c +udcli_CFLAGS = -I$(top_srcdir)/libudis86 -I$(top_srcdir) +udcli_LDADD = $(top_builddir)/libudis86/libudis86.la +MAINTAINERCLEANFILES = Makefile.in diff --git a/udis86/udcli/udcli.c b/udis86/udcli/udcli.c new file mode 100644 index 0000000..9b044ca --- /dev/null +++ b/udis86/udcli/udcli.c @@ -0,0 +1,273 @@ +/* udis86 - udcli/udcli.c + * + * Copyright (c) 2002-2013 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#ifdef _MSC_VER +#include "..\udis86.h" +#define PACKAGE_STRING "udis86 pre-1.8" +#else +#include +#include +#endif + +#if defined(__APPLE__) +# define FMT64 "ll" +#elif defined(__amd64__) || defined(__x86_64__) +# define FMT64 "l" +# else +# define FMT64 "ll" +#endif + +#if defined(__DJGPP__) || defined(_WIN32) +# include +# include +#endif + +#ifdef __DJGPP__ +# include /* for isatty() */ +# define _setmode setmode +# define _fileno fileno +# define _O_BINARY O_BINARY +#endif + +/* help string */ +static char help[] = +{ + "Usage: %s [-option[s]] file\n" + "Options:\n" + " -16 : Set the disassembly mode to 16 bits. \n" + " -32 : Set the disassembly mode to 32 bits. (default)\n" + " -64 : Set the disassembly mode to 64 bits.\n" + " -intel : Set the output to INTEL (NASM like) syntax. (default)\n" + " -att : Set the output to AT&T (GAS like) syntax.\n" + " -v : Set vendor. = {intel, amd}.\n" + " -o : Set the value of program counter to . (default = 0)\n" + " -s : Set the number of bytes to skip before disassembly to .\n" + " -c : Set the number of bytes to disassemble to .\n" + " -x : Set the input mode to whitespace separated 8-bit numbers in\n" + " hexadecimal representation. Example: 0f 01 ae 00\n" + " -noff : Do not display the offset of instructions.\n" + " -nohex : Do not display the hexadecimal code of instructions.\n" + " -h : Display this help message.\n" + " --version: Show version.\n" + "\n" + "Udcli is a front-end to the Udis86 Disassembler Library.\n" + "http://udis86.sourceforge.net/\n" +}; + +FILE* fptr = NULL; +uint64_t o_skip = 0; +uint64_t o_count = 0; +unsigned char o_do_count= 0; +unsigned char o_do_off = 1; +unsigned char o_do_hex = 1; +unsigned char o_do_x = 0; +unsigned o_vendor = UD_VENDOR_AMD; + +int input_hook_x(ud_t* u); +int input_hook_file(ud_t* u); + +int main(int argc, char **argv) +{ + char *prog_path = *argv; + char *s; + ud_t ud_obj; + + /* initialize */ + ud_init(&ud_obj); + ud_set_mode(&ud_obj, 32); + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + +#ifdef __DJGPP__ + if ( !isatty( fileno( stdin ) ) ) +#endif +#if defined(__DJGPP) || defined(_WIN32) + _setmode(_fileno(stdin), _O_BINARY); +#endif + + fptr = stdin; + + argv++; + + /* loop through the args */ + while(--argc > 0) { + if (strcmp(*argv, "-h") == 0) { + printf(help, prog_path); + exit(EXIT_SUCCESS); + } else if (strcmp(*argv,"-16") == 0) { + ud_set_mode(&ud_obj, 16); + } else if (strcmp(*argv,"-32") == 0) { + ud_set_mode(&ud_obj, 32); + } else if (strcmp(*argv,"-64") == 0) { + ud_set_mode(&ud_obj, 64); + } else if (strcmp(*argv,"-intel") == 0) + ud_set_syntax(&ud_obj, UD_SYN_INTEL); + else if (strcmp(*argv,"-att") == 0) + ud_set_syntax(&ud_obj, UD_SYN_ATT); + else if (strcmp(*argv,"-noff") == 0) + o_do_off = 0; + else if (strcmp(*argv,"-nohex") == 0) + o_do_hex = 0; + else if (strcmp(*argv,"-x") == 0) + o_do_x = 1; + else if (strcmp(*argv,"-s") == 0) + if (--argc) { + s = *(++argv); + if (sscanf(s, "%" FMT64 "u", &o_skip) == 0) + fprintf(stderr, "Invalid value given for -s.\n"); + } else { + fprintf(stderr, "No value given for -s.\n"); + printf(help, prog_path); + exit(EXIT_FAILURE); + } + else if (strcmp(*argv,"-c") == 0) + if (--argc) { + o_do_count= 1; + s = *(++argv); + if (sscanf(s, "%" FMT64 "u", &o_count) == 0) + fprintf(stderr, "Invalid value given for -c.\n"); + } else { + fprintf(stderr, "No value given for -c.\n"); + printf(help, prog_path); + exit(EXIT_FAILURE); + } + else if (strcmp(*argv,"-v") == 0) + if (--argc) { + s = *(++argv); + if (*s == 'i') + ud_set_vendor(&ud_obj, UD_VENDOR_INTEL); + } else { + fprintf(stderr, "No value given for -v.\n"); + printf(help, prog_path); + exit(EXIT_FAILURE); + } + else if (strcmp(*argv,"-o") == 0) { + if (--argc) { + uint64_t pc = 0; + s = *(++argv); + if (sscanf(s, "%" FMT64 "x", &pc) == 0) + fprintf(stderr, "Invalid value given for -o.\n"); + ud_set_pc(&ud_obj, pc); + } else { + fprintf(stderr, "No value given for -o.\n"); + printf(help, prog_path); + exit(EXIT_FAILURE); + } + } else if ( strcmp( *argv, "--version" ) == 0 ) { + fprintf(stderr, "%s\n", PACKAGE_STRING ); + exit(0); + } else if((*argv)[0] == '-') { + fprintf(stderr, "Invalid option %s.\n", *argv); + printf(help, prog_path); + exit(EXIT_FAILURE); + } else { + static int i = 0; + s = *argv; + if (i) { + fprintf(stderr, "Multiple files specified.\n"); + exit(EXIT_FAILURE); + } else i = 1; + if ((fptr = fopen(s, "rb")) == NULL) { + fprintf(stderr, "Failed to open file: %s.\n", s); + exit(EXIT_FAILURE); + } + } + argv++; + } + + if (o_do_x) + ud_set_input_hook(&ud_obj, input_hook_x); + else ud_set_input_hook(&ud_obj, input_hook_file); + + if (o_skip) { + o_count += o_skip; + ud_input_skip(&ud_obj, o_skip); + } + + /* disassembly loop */ + while (ud_disassemble(&ud_obj)) { + if (o_do_off) + printf("%016" FMT64 "x ", ud_insn_off(&ud_obj)); + if (o_do_hex) { + const char* hex1, *hex2; + hex1 = ud_insn_hex(&ud_obj); + hex2 = hex1 + 16; + printf("%-16.16s %-24s", hex1, ud_insn_asm(&ud_obj)); + if (strlen(hex1) > 16) { + printf("\n"); + if (o_do_off) + printf("%15s -", ""); + printf("%-16s", hex2); + } + } + else printf(" %-24s", ud_insn_asm(&ud_obj)); + + printf("\n"); + } + + exit(EXIT_SUCCESS); + return 0; +} + +int input_hook_x(ud_t* u) +{ + unsigned int c, i; + + if (o_do_count) { + if (! o_count) + return UD_EOI; + else --o_count; + } + + i = fscanf(fptr, "%x", &c); + + if (i == EOF) + return UD_EOI; + if (i == 0) { + fprintf(stderr, "Error: Invalid input, should be in hexadecimal form (8-bit).\n"); + return UD_EOI; + } + if (c > 0xFF) + fprintf(stderr, "Warning: Casting non-8-bit input (%x), to %x.\n", c, c & 0xFF); + return (int) (c & 0xFF); +} + +int input_hook_file(ud_t* u) +{ + int c; + + if (o_do_count) { + if (! o_count) { + return -1; + } else o_count -- ; + } + + if ((c = fgetc(fptr)) == EOF) + return UD_EOI; + return c; +} diff --git a/udis86/udis86.h b/udis86/udis86.h index 2228778..bdd3857 100644 --- a/udis86/udis86.h +++ b/udis86/udis86.h @@ -1,11 +1,28 @@ -/* ----------------------------------------------------------------------------- - * udis86.h +/* udis86 - udis86.h * - * Copyright (c) 2002, 2003, 2004 Vivek Mohan - * All rights reserved. See (LICENSE) - * ----------------------------------------------------------------------------- + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef UDIS86_H #define UDIS86_H