1 /* Disassembler for x86.
2 Copyright (C) 2007, 2008, 2009, 2011 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2007.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
44 #include <sys/param.h>
46 #include "../libebl/libeblP.h"
48 #define MACHINE_ENCODING __LITTLE_ENDIAN
49 #include "memory-access.h"
53 # define MNEFILE "i386.mnemonics"
56 #define MNESTRFIELD(line) MNESTRFIELD1 (line)
57 #define MNESTRFIELD1(line) str##line
58 static const union mnestr_t
62 #define MNE(name) char MNESTRFIELD (__LINE__)[sizeof (#name)];
70 #define MNE(name) #name,
76 /* The index can be stored in the instrtab. */
79 #define MNE(name) MNE_##name,
85 static const unsigned short int mneidx[] =
88 [MNE_##name] = offsetof (union mnestr_t, MNESTRFIELD (__LINE__)),
116 #define prefbit(pref) has_##pref = 1 << idx_##pref
135 #define SEGMENT_PREFIXES \
136 (has_cs | has_ds | has_es | has_fs | has_gs | has_ss)
138 #define prefix_cs 0x2e
139 #define prefix_ds 0x3e
140 #define prefix_es 0x26
141 #define prefix_fs 0x64
142 #define prefix_gs 0x65
143 #define prefix_ss 0x36
144 #define prefix_data16 0x66
145 #define prefix_addr16 0x67
146 #define prefix_rep 0xf3
147 #define prefix_repne 0xf2
148 #define prefix_lock 0xf0
151 static const uint8_t known_prefixes[] =
153 #define newpref(pref) [idx_##pref] = prefix_##pref
167 #define nknown_prefixes (sizeof (known_prefixes) / sizeof (known_prefixes[0]))
171 static const char *prefix_str[] =
173 #define newpref(pref) [idx_##pref] = #pref
190 static const char amd3dnowstr[] =
191 #define MNE_3DNOW_PAVGUSB 1
193 #define MNE_3DNOW_PFADD (MNE_3DNOW_PAVGUSB + 8)
195 #define MNE_3DNOW_PFSUB (MNE_3DNOW_PFADD + 6)
197 #define MNE_3DNOW_PFSUBR (MNE_3DNOW_PFSUB + 6)
199 #define MNE_3DNOW_PFACC (MNE_3DNOW_PFSUBR + 7)
201 #define MNE_3DNOW_PFCMPGE (MNE_3DNOW_PFACC + 6)
203 #define MNE_3DNOW_PFCMPGT (MNE_3DNOW_PFCMPGE + 8)
205 #define MNE_3DNOW_PFCMPEQ (MNE_3DNOW_PFCMPGT + 8)
207 #define MNE_3DNOW_PFMIN (MNE_3DNOW_PFCMPEQ + 8)
209 #define MNE_3DNOW_PFMAX (MNE_3DNOW_PFMIN + 6)
211 #define MNE_3DNOW_PI2FD (MNE_3DNOW_PFMAX + 6)
213 #define MNE_3DNOW_PF2ID (MNE_3DNOW_PI2FD + 6)
215 #define MNE_3DNOW_PFRCP (MNE_3DNOW_PF2ID + 6)
217 #define MNE_3DNOW_PFRSQRT (MNE_3DNOW_PFRCP + 6)
219 #define MNE_3DNOW_PFMUL (MNE_3DNOW_PFRSQRT + 8)
221 #define MNE_3DNOW_PFRCPIT1 (MNE_3DNOW_PFMUL + 6)
223 #define MNE_3DNOW_PFRSQIT1 (MNE_3DNOW_PFRCPIT1 + 9)
225 #define MNE_3DNOW_PFRCPIT2 (MNE_3DNOW_PFRSQIT1 + 9)
227 #define MNE_3DNOW_PMULHRW (MNE_3DNOW_PFRCPIT2 + 9)
230 #define AMD3DNOW_LOW_IDX 0x0d
231 #define AMD3DNOW_HIGH_IDX (sizeof (amd3dnow) + AMD3DNOW_LOW_IDX - 1)
232 #define AMD3DNOW_IDX(val) ((val) - AMD3DNOW_LOW_IDX)
233 static const unsigned char amd3dnow[] =
235 [AMD3DNOW_IDX (0xbf)] = MNE_3DNOW_PAVGUSB,
236 [AMD3DNOW_IDX (0x9e)] = MNE_3DNOW_PFADD,
237 [AMD3DNOW_IDX (0x9a)] = MNE_3DNOW_PFSUB,
238 [AMD3DNOW_IDX (0xaa)] = MNE_3DNOW_PFSUBR,
239 [AMD3DNOW_IDX (0xae)] = MNE_3DNOW_PFACC,
240 [AMD3DNOW_IDX (0x90)] = MNE_3DNOW_PFCMPGE,
241 [AMD3DNOW_IDX (0xa0)] = MNE_3DNOW_PFCMPGT,
242 [AMD3DNOW_IDX (0xb0)] = MNE_3DNOW_PFCMPEQ,
243 [AMD3DNOW_IDX (0x94)] = MNE_3DNOW_PFMIN,
244 [AMD3DNOW_IDX (0xa4)] = MNE_3DNOW_PFMAX,
245 [AMD3DNOW_IDX (0x0d)] = MNE_3DNOW_PI2FD,
246 [AMD3DNOW_IDX (0x1d)] = MNE_3DNOW_PF2ID,
247 [AMD3DNOW_IDX (0x96)] = MNE_3DNOW_PFRCP,
248 [AMD3DNOW_IDX (0x97)] = MNE_3DNOW_PFRSQRT,
249 [AMD3DNOW_IDX (0xb4)] = MNE_3DNOW_PFMUL,
250 [AMD3DNOW_IDX (0xa6)] = MNE_3DNOW_PFRCPIT1,
251 [AMD3DNOW_IDX (0xa7)] = MNE_3DNOW_PFRSQIT1,
252 [AMD3DNOW_IDX (0xb6)] = MNE_3DNOW_PFRCPIT2,
253 [AMD3DNOW_IDX (0xb7)] = MNE_3DNOW_PMULHRW
268 const uint8_t **param_start;
285 # define DISFILE "i386_dis.h"
290 #define ADD_CHAR(ch) \
292 if (unlikely (bufcnt == bufsize)) \
294 buf[bufcnt++] = (ch); \
297 #define ADD_STRING(str) \
299 const char *_str0 = (str); \
300 size_t _len0 = strlen (_str0); \
301 ADD_NSTRING (_str0, _len0); \
304 #define ADD_NSTRING(str, len) \
306 const char *_str = (str); \
307 size_t _len = (len); \
308 if (unlikely (bufcnt + _len > bufsize)) \
310 memcpy (buf + bufcnt, _str, _len); \
316 i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
317 const char *fmt, DisasmOutputCB_t outcb, DisasmGetSymCB_t symcb,
318 void *outcbarg, void *symcbarg)
320 const char *save_fmt = fmt;
323 char initbuf[BUFSIZE];
326 size_t bufsize = BUFSIZE;
328 const uint8_t *param_start;
330 struct output_data output_data =
332 .prefixes = &prefixes,
336 .param_start = ¶m_start,
345 const uint8_t *data = *startp;
346 const uint8_t *begin = data;
348 /* Recognize all prefixes. */
349 int last_prefix_bit = 0;
353 for (i = idx_cs; i < nknown_prefixes; ++i)
354 if (known_prefixes[i] == *data)
356 if (i == nknown_prefixes)
359 prefixes |= last_prefix_bit = 1 << i;
365 if (data < end && (*data & 0xf0) == 0x40)
366 prefixes |= ((*data++) & 0xf) | has_rex;
372 const uint8_t *curr = match_data;
373 const uint8_t *const match_end = match_data + sizeof (match_data);
375 assert (data <= end);
386 while (curr < match_end)
388 uint_fast8_t len = *curr++;
389 uint_fast8_t clen = len >> 4;
391 const uint8_t *next_curr = curr + clen + (len - clen) * 2;
394 assert (curr + clen + 2 * (len - clen) <= match_end);
396 const uint8_t *codep = data;
397 int correct_prefix = 0;
400 if (data > begin && codep[-1] == *curr && clen > 0)
402 /* We match a prefix byte. This is exactly one byte and
403 is matched exactly, without a mask. */
410 assert (last_prefix_bit != 0);
411 correct_prefix = last_prefix_bit;
417 if (*codep++ != *curr++)
421 if (codep == end && avail > 0)
427 uint_fast8_t masked = *codep++ & *curr++;
428 if (masked != *curr++)
438 if (codep == end && avail > 0)
442 if (len > end - data)
443 /* There is not enough data for the entire instruction. The
444 caller can figure this out by looking at the pointer into
448 assert (correct_prefix == 0
449 || (prefixes & correct_prefix) != 0);
450 prefixes ^= correct_prefix;
454 /* Resize the buffer. */
459 buf = malloc (2 * bufsize);
461 buf = realloc (buf, 2 * bufsize);
470 output_data.bufp = buf;
471 output_data.bufsize = bufsize;
476 assert (prefixes != 0);
480 /* gcc is not clever enough to see the following variables
481 are not used uninitialized. */
483 : "=mr" (opoff), "=mr" (correct_prefix), "=mr" (codep),
484 "=mr" (next_curr), "=mr" (len));
487 size_t prefix_size = 0;
489 // XXXonly print as prefix if valid?
490 if ((prefixes & has_lock) != 0)
492 ADD_STRING ("lock ");
496 if (instrtab[cnt].rep)
498 if ((prefixes & has_rep) != 0)
504 else if (instrtab[cnt].repe
505 && (prefixes & (has_rep | has_repne)) != 0)
507 if ((prefixes & has_repne) != 0)
509 ADD_STRING ("repne ");
512 else if ((prefixes & has_rep) != 0)
514 ADD_STRING ("repe ");
518 else if ((prefixes & (has_rep | has_repne)) != 0)
524 /* This is a prefix byte. Print it. */
531 ADD_STRING ("repne");
552 ADD_STRING ("data16");
555 ADD_STRING ("addr16");
579 puts ("unknown prefix");
588 /* We have a match. First determine how many bytes are
589 needed for the adressing mode. */
591 if (instrtab[cnt].modrm)
593 uint_fast8_t modrm = codep[-1];
596 if (likely ((prefixes & has_addr16) != 0))
598 /* Account for displacement. */
599 if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80)
601 else if ((modrm & 0xc0) == 0x40)
607 /* Account for SIB. */
608 if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 0x4)
611 /* Account for displacement. */
612 if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
613 || ((modrm & 0xc7) == 0x4 && (codep[0] & 0x7) == 0x5))
615 else if ((modrm & 0xc0) == 0x40)
619 if (unlikely (param_start > end))
623 output_data.addr = addr + (data - begin);
624 output_data.data = data;
626 unsigned long string_end_idx = 0;
628 const char *deferred_start = NULL;
629 size_t deferred_len = 0;
630 // XXX Can we get this from color.c?
631 static const char color_off[] = "\e[0m";
639 switch ((ch = *fmt++))
645 if (ch >= '0' && ch <= '7')
650 if (ch >= '0' && ch <= '7' && val < 32)
674 else if (ch == '\e' && *fmt == '[')
676 deferred_start = fmt - 1;
679 while (*fmt != 'm' && *fmt != '\0');
683 deferred_len = ++fmt - deferred_start;
687 fmt = deferred_start + 1;
688 deferred_start = NULL;
696 while (isdigit (*fmt))
697 width = width * 10 + (*fmt++ - '0');
701 while (isdigit (*++fmt))
702 prec = prec * 10 + (*fmt - '0');
704 size_t start_idx = bufcnt;
705 size_t non_printing = 0;
714 if (unlikely (instrtab[cnt].mnemonic == MNE_INVALID))
720 if (prefixes & has_rex_b)
728 if (prefixes == (has_rex_w | has_rex))
734 if (prefixes & ~has_data16)
736 str = prefixes & has_data16 ? "cbtw" : "cwtl";
741 if (prefixes == (has_rex_w | has_rex))
747 if (prefixes & ~has_data16)
749 str = prefixes & has_data16 ? "cwtd" : "cltd";
753 if (prefixes & ~has_addr16)
756 str = prefixes & has_addr16 ? "jecxz" : "jrcxz";
758 str = prefixes & has_addr16 ? "jcxz" : "jecxz";
765 /* AMD 3DNOW. We need one more byte. */
766 if (param_start >= end)
768 if (*param_start < AMD3DNOW_LOW_IDX
769 || *param_start > AMD3DNOW_HIGH_IDX)
772 = amd3dnow[AMD3DNOW_IDX (*param_start)];
775 str = amd3dnowstr + idx - 1;
776 /* Eat the immediate byte indicating the
784 str = ((prefixes & has_rex_w)
785 ? "cmpxchg16b" : "cmpxchg8b");
791 if (param_start >= end)
793 if (*param_start > 7)
795 static const char cmpops[][9] =
806 char *cp = stpcpy (mnebuf, cmpops[*param_start]);
807 if (correct_prefix & (has_rep | has_repne))
811 if (correct_prefix & (has_data16 | has_repne))
817 /* Eat the immediate byte indicating the
824 assert (! "INVALID not handled");
828 str = mnestr.str + mneidx[instrtab[cnt].mnemonic];
830 if (deferred_start != NULL)
832 ADD_NSTRING (deferred_start, deferred_len);
833 non_printing += deferred_len;
838 switch (instrtab[cnt].suffix)
844 if ((codep[-1] & 0xc0) != 0xc0)
850 if (prefixes & has_data16)
853 else if (prefixes & has_rex_w)
867 if ((codep[-1] & 0xc0) != 0xc0)
872 if ((data[0] & 0x4) == 0)
877 if (prefixes & has_data16)
880 prefixes &= ~has_data16;
889 if (prefixes & has_data16)
892 prefixes &= ~has_data16;
895 else if (prefixes & has_rex_w)
901 static const char tttn[16][3] =
903 "o", "no", "b", "ae", "e", "ne", "be", "a",
904 "s", "ns", "p", "np", "l", "ge", "le", "g"
906 ADD_STRING (tttn[codep[-1 - instrtab[cnt].modrm] & 0x0f]);
910 if ((codep[-1] & 0xc0) != 0xc0)
911 ADD_CHAR ((data[0] & 0x04) == 0 ? 's' : 'l');
915 printf("unknown suffix %d\n", instrtab[cnt].suffix);
919 if (deferred_start != NULL)
921 ADD_STRING (color_off);
922 non_printing += strlen (color_off);
925 string_end_idx = bufcnt;
929 if (prec == 1 && instrtab[cnt].fct1 != 0)
931 /* First parameter. */
932 if (deferred_start != NULL)
934 ADD_NSTRING (deferred_start, deferred_len);
935 non_printing += deferred_len;
938 if (instrtab[cnt].str1 != 0)
940 + op1_str_idx[instrtab[cnt].str1 - 1]);
942 output_data.opoff1 = (instrtab[cnt].off1_1
943 + OFF1_1_BIAS - opoff);
944 output_data.opoff2 = (instrtab[cnt].off1_2
945 + OFF1_2_BIAS - opoff);
946 output_data.opoff3 = (instrtab[cnt].off1_3
947 + OFF1_3_BIAS - opoff);
948 int r = op1_fct[instrtab[cnt].fct1] (&output_data);
954 if (deferred_start != NULL)
956 ADD_STRING (color_off);
957 non_printing += strlen (color_off);
960 string_end_idx = bufcnt;
962 else if (prec == 2 && instrtab[cnt].fct2 != 0)
964 /* Second parameter. */
965 if (deferred_start != NULL)
967 ADD_NSTRING (deferred_start, deferred_len);
968 non_printing += deferred_len;
971 if (instrtab[cnt].str2 != 0)
973 + op2_str_idx[instrtab[cnt].str2 - 1]);
975 output_data.opoff1 = (instrtab[cnt].off2_1
976 + OFF2_1_BIAS - opoff);
977 output_data.opoff2 = (instrtab[cnt].off2_2
978 + OFF2_2_BIAS - opoff);
979 output_data.opoff3 = (instrtab[cnt].off2_3
980 + OFF2_3_BIAS - opoff);
981 int r = op2_fct[instrtab[cnt].fct2] (&output_data);
987 if (deferred_start != NULL)
989 ADD_STRING (color_off);
990 non_printing += strlen (color_off);
993 string_end_idx = bufcnt;
995 else if (prec == 3 && instrtab[cnt].fct3 != 0)
997 /* Third parameter. */
998 if (deferred_start != NULL)
1000 ADD_NSTRING (deferred_start, deferred_len);
1001 non_printing += deferred_len;
1004 if (instrtab[cnt].str3 != 0)
1006 + op3_str_idx[instrtab[cnt].str3 - 1]);
1008 output_data.opoff1 = (instrtab[cnt].off3_1
1009 + OFF3_1_BIAS - opoff);
1010 output_data.opoff2 = (instrtab[cnt].off3_2
1011 + OFF3_2_BIAS - opoff);
1013 output_data.opoff3 = (instrtab[cnt].off3_3
1014 + OFF3_3_BIAS - opoff);
1016 output_data.opoff3 = 0;
1018 int r = op3_fct[instrtab[cnt].fct3] (&output_data);
1024 if (deferred_start != NULL)
1026 ADD_STRING (color_off);
1027 non_printing += strlen (color_off);
1030 string_end_idx = bufcnt;
1033 bufcnt = string_end_idx;
1037 string_end_idx = bufcnt;
1041 /* Pad to requested column. */
1042 while (bufcnt - non_printing < (size_t) width)
1048 if (deferred_start != NULL)
1050 ADD_NSTRING (deferred_start, deferred_len);
1051 non_printing += deferred_len;
1054 if (output_data.labelbuf != NULL
1055 && output_data.labelbuf[0] != '\0')
1057 ADD_STRING (output_data.labelbuf);
1058 output_data.labelbuf[0] = '\0';
1059 string_end_idx = bufcnt;
1061 else if (output_data.symaddr_use != addr_none)
1063 GElf_Addr symaddr = output_data.symaddr;
1064 if (output_data.symaddr_use >= addr_rel_symbolic)
1065 symaddr += addr + param_start - begin;
1067 // XXX Lookup symbol based on symaddr
1068 const char *symstr = NULL;
1070 && symcb (0 /* XXX */, 0 /* XXX */, symaddr,
1071 &output_data.labelbuf,
1072 &output_data.labelbufsize, symcbarg) == 0)
1073 symstr = output_data.labelbuf;
1075 size_t bufavail = bufsize - bufcnt;
1078 r = snprintf (&buf[bufcnt], bufavail, "# <%s>",
1080 else if (output_data.symaddr_use == addr_abs_always
1081 || output_data.symaddr_use == addr_rel_always)
1082 r = snprintf (&buf[bufcnt], bufavail, "# %#" PRIx64,
1083 (uint64_t) symaddr);
1086 if ((size_t) r >= bufavail)
1089 string_end_idx = bufcnt;
1091 output_data.symaddr_use = addr_none;
1093 if (deferred_start != NULL)
1095 ADD_STRING (color_off);
1096 non_printing += strlen (color_off);
1104 deferred_start = NULL;
1106 /* Pad according to the specified width. */
1107 while (bufcnt + prefix_size - non_printing < start_idx + width)
1112 if ((prefixes & SEGMENT_PREFIXES) != 0)
1115 assert (string_end_idx != ~0ul);
1116 bufcnt = string_end_idx;
1118 addr += param_start - begin;
1124 /* Invalid (or at least unhandled) opcode. */
1127 assert (*startp == data);
1129 ADD_STRING ("(bad)");
1130 addr += data - begin;
1133 if (bufcnt == bufsize)
1138 retval = outcb (buf, bufcnt, outcbarg);
1144 free (output_data.labelbuf);