Coverage Report

Created: 2025-11-13 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libcpu/i386_data.h
Line
Count
Source
1
/* Helper routines for disassembler for x86/x86-64.
2
   Copyright (C) 2007, 2008 Red Hat, Inc.
3
   This file is part of elfutils.
4
   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
5
6
   This file is free software; you can redistribute it and/or modify
7
   it under the terms of either
8
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
12
13
   or
14
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
18
19
   or both in parallel, as here.
20
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.
25
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/>.  */
29
30
#include <inttypes.h>
31
#include <stddef.h>
32
#include <stdio.h>
33
#include <stdint.h>
34
#include <libasm.h>
35
36
struct instr_enc
37
{
38
  /* The mnemonic.  Especially encoded for the optimized table.  */
39
  unsigned int mnemonic : MNEMONIC_BITS;
40
41
  /* The rep/repe prefixes.  */
42
  unsigned int rep : 1;
43
  unsigned int repe : 1;
44
45
  /* Mnemonic suffix.  */
46
  unsigned int suffix : SUFFIX_BITS;
47
48
  /* Nonzero if the instruction uses modr/m.  */
49
  unsigned int modrm : 1;
50
51
  /* 1st parameter.  */
52
  unsigned int fct1 : FCT1_BITS;
53
#ifdef STR1_BITS
54
  unsigned int str1 : STR1_BITS;
55
#endif
56
  unsigned int off1_1 : OFF1_1_BITS;
57
  unsigned int off1_2 : OFF1_2_BITS;
58
  unsigned int off1_3 : OFF1_3_BITS;
59
60
  /* 2nd parameter.  */
61
  unsigned int fct2 : FCT2_BITS;
62
#ifdef STR2_BITS
63
  unsigned int str2 : STR2_BITS;
64
#endif
65
  unsigned int off2_1 : OFF2_1_BITS;
66
  unsigned int off2_2 : OFF2_2_BITS;
67
  unsigned int off2_3 : OFF2_3_BITS;
68
69
  /* 3rd parameter.  */
70
  unsigned int fct3 : FCT3_BITS;
71
#ifdef STR3_BITS
72
  unsigned int str3 : STR3_BITS;
73
#endif
74
  unsigned int off3_1 : OFF3_1_BITS;
75
#ifdef OFF3_2_BITS
76
  unsigned int off3_2 : OFF3_2_BITS;
77
#endif
78
#ifdef OFF3_3_BITS
79
  unsigned int off3_3 : OFF3_3_BITS;
80
#endif
81
};
82
83
84
typedef int (*opfct_t) (struct output_data *);
85
86
87
static int
88
data_prefix (struct output_data *d)
89
0
{
90
0
  char ch = '\0';
91
0
  if (*d->prefixes & has_cs)
92
0
    {
93
0
      ch = 'c';
94
0
      *d->prefixes &= ~has_cs;
95
0
    }
96
0
  else if (*d->prefixes & has_ds)
97
0
    {
98
0
      ch = 'd';
99
0
      *d->prefixes &= ~has_ds;
100
0
    }
101
0
  else if (*d->prefixes & has_es)
102
0
    {
103
0
      ch = 'e';
104
0
      *d->prefixes &= ~has_es;
105
0
    }
106
0
  else if (*d->prefixes & has_fs)
107
0
    {
108
0
      ch = 'f';
109
0
      *d->prefixes &= ~has_fs;
110
0
    }
111
0
  else if (*d->prefixes & has_gs)
112
0
    {
113
0
      ch = 'g';
114
0
      *d->prefixes &= ~has_gs;
115
0
    }
116
0
  else if (*d->prefixes & has_ss)
117
0
    {
118
0
      ch = 's';
119
0
      *d->prefixes &= ~has_ss;
120
0
    }
121
0
  else
122
0
    return 0;
123
124
0
  if (*d->bufcntp + 4 > d->bufsize)
125
0
    return *d->bufcntp + 4 - d->bufsize;
126
127
0
  d->bufp[(*d->bufcntp)++] = '%';
128
0
  d->bufp[(*d->bufcntp)++] = ch;
129
0
  d->bufp[(*d->bufcntp)++] = 's';
130
0
  d->bufp[(*d->bufcntp)++] = ':';
131
132
0
  return 0;
133
0
}
Unexecuted instantiation: i386_disasm.c:data_prefix
Unexecuted instantiation: x86_64_disasm.c:data_prefix
134
135
#ifdef X86_64
136
static const char hiregs[8][4] =
137
  {
138
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
139
  };
140
static const char aregs[8][4] =
141
  {
142
    "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"
143
  };
144
static const char dregs[8][4] =
145
  {
146
    "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
147
  };
148
#else
149
static const char aregs[8][4] =
150
  {
151
    "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
152
  };
153
0
# define dregs aregs
154
#endif
155
156
static int
157
general_mod$r_m (struct output_data *d)
158
0
{
159
0
  int r = data_prefix (d);
160
0
  if (r != 0)
161
0
    return r;
162
163
0
  int prefixes = *d->prefixes;
164
0
  const uint8_t *data = &d->data[d->opoff1 / 8];
165
0
  char *bufp = d->bufp;
166
0
  size_t *bufcntp = d->bufcntp;
167
0
  size_t bufsize = d->bufsize;
168
169
0
  uint_fast8_t modrm = data[0];
170
#ifndef X86_64
171
0
  if (unlikely ((prefixes & has_addr16) != 0))
172
0
    {
173
0
      int16_t disp = 0;
174
0
      bool nodisp = false;
175
176
0
      if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80)
177
  /* 16 bit displacement.  */
178
0
  disp = read_2sbyte_unaligned (&data[1]);
179
0
      else if ((modrm & 0xc0) == 0x40)
180
  /* 8 bit displacement.  */
181
0
  disp = *(const int8_t *) &data[1];
182
0
      else if ((modrm & 0xc0) == 0)
183
0
  nodisp = true;
184
185
      char tmpbuf[sizeof ("-0x1234(%rr,%rr)")];
186
      int n;
187
0
      if ((modrm & 0xc7) == 6)
188
0
  n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx16, disp);
189
0
      else
190
0
  {
191
0
    n = 0;
192
0
    if (!nodisp)
193
0
      n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx16,
194
0
        disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
195
196
0
    if ((modrm & 0x4) == 0)
197
0
      n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%b%c,%%%ci)",
198
0
         "xp"[(modrm >> 1) & 1], "sd"[modrm & 1]);
199
0
    else
200
0
      n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%%s)",
201
0
         ((const char [4][3]) { "si", "di", "bp", "bx" })[modrm & 3]);
202
0
  }
203
204
0
      if (*bufcntp + n + 1 > bufsize)
205
0
  return *bufcntp + n + 1 - bufsize;
206
207
0
      memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
208
0
      *bufcntp += n;
209
0
    }
210
0
  else
211
0
#endif
212
0
    {
213
0
      if ((modrm & 7) != 4)
214
0
  {
215
0
    int32_t disp = 0;
216
0
    bool nodisp = false;
217
218
0
    if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80)
219
      /* 32 bit displacement.  */
220
0
      disp = read_4sbyte_unaligned (&data[1]);
221
0
    else if ((modrm & 0xc0) == 0x40)
222
      /* 8 bit displacement.  */
223
0
      disp = *(const int8_t *) &data[1];
224
0
    else if ((modrm & 0xc0) == 0)
225
0
      nodisp = true;
226
227
0
    char tmpbuf[sizeof ("-0x12345678(%rrrr)")];
228
0
    int n;
229
0
    if (nodisp)
230
0
      {
231
0
        n = snprintf (tmpbuf, sizeof (tmpbuf), "(%%%s)",
232
#ifdef X86_64
233
          (prefixes & has_rex_b) ? hiregs[modrm & 7] :
234
#endif
235
0
          aregs[modrm & 7]);
236
#ifdef X86_64
237
0
        if (prefixes & has_addr16)
238
0
    {
239
0
      if (prefixes & has_rex_b)
240
0
        tmpbuf[n++] = 'd';
241
0
      else
242
0
        tmpbuf[2] = 'e';
243
0
    }
244
#endif
245
0
      }
246
0
    else if ((modrm & 0xc7) != 5)
247
0
      {
248
0
        int p;
249
0
        n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%%n%s)",
250
0
          disp < 0 ? "-" : "", disp < 0 ? -disp : disp, &p,
251
#ifdef X86_64
252
          (prefixes & has_rex_b) ? hiregs[modrm & 7] :
253
#endif
254
0
          aregs[modrm & 7]);
255
#ifdef X86_64
256
0
        if (prefixes & has_addr16)
257
0
    {
258
0
      if (prefixes & has_rex_b)
259
0
        tmpbuf[n++] = 'd';
260
0
      else
261
0
        tmpbuf[p] = 'e';
262
0
    }
263
#endif
264
0
      }
265
0
    else
266
0
      {
267
#ifdef X86_64
268
        n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%rip)",
269
          disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
270
271
        d->symaddr_use = addr_rel_always;
272
        d->symaddr = disp;
273
#else
274
        n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx32, disp);
275
#endif
276
0
      }
277
278
0
    if (*bufcntp + n + 1 > bufsize)
279
0
      return *bufcntp + n + 1 - bufsize;
280
281
0
    memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
282
0
    *bufcntp += n;
283
0
  }
284
0
      else
285
0
  {
286
    /* SIB */
287
0
    uint_fast8_t sib = data[1];
288
0
    int32_t disp = 0;
289
0
    bool nodisp = false;
290
291
0
    if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
292
0
        || ((modrm & 0xc7) == 0x4 && (sib & 0x7) == 0x5))
293
      /* 32 bit displacement.  */
294
0
      disp = read_4sbyte_unaligned (&data[2]);
295
0
    else if ((modrm & 0xc0) == 0x40)
296
      /* 8 bit displacement.  */
297
0
      disp = *(const int8_t *) &data[2];
298
0
    else
299
0
      nodisp = true;
300
301
0
    char tmpbuf[sizeof ("-0x12345678(%rrrr,%rrrr,N)")];
302
0
    char *cp = tmpbuf;
303
0
    int n;
304
0
    if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25
305
#ifdef X86_64
306
0
        || (prefixes & has_rex_x) != 0
307
#endif
308
0
        )
309
0
      {
310
0
        if (!nodisp)
311
0
    {
312
0
      n = snprintf (cp, sizeof (tmpbuf), "%s0x%" PRIx32,
313
0
        disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
314
0
      cp += n;
315
0
    }
316
317
0
        *cp++ = '(';
318
319
0
        if ((modrm & 0xc7) != 0x4 || (sib & 0x7) != 0x5)
320
0
    {
321
0
      *cp++ = '%';
322
0
      cp = stpcpy (cp,
323
#ifdef X86_64
324
0
             (prefixes & has_rex_b) ? hiregs[sib & 7] :
325
0
             (prefixes & has_addr16) ? dregs[sib & 7] :
326
#endif
327
0
             aregs[sib & 7]);
328
#ifdef X86_64
329
0
      if ((prefixes & (has_rex_b | has_addr16))
330
0
          == (has_rex_b | has_addr16))
331
0
        *cp++ = 'd';
332
#endif
333
0
    }
334
335
0
        if ((sib & 0x38) != 0x20
336
#ifdef X86_64
337
0
      || (prefixes & has_rex_x) != 0
338
#endif
339
0
      )
340
0
    {
341
0
      *cp++ = ',';
342
0
      *cp++ = '%';
343
0
      cp = stpcpy (cp,
344
#ifdef X86_64
345
0
             (prefixes & has_rex_x)
346
0
             ? hiregs[(sib >> 3) & 7] :
347
0
             (prefixes & has_addr16)
348
0
             ? dregs[(sib >> 3) & 7] :
349
#endif
350
0
             aregs[(sib >> 3) & 7]);
351
#ifdef X86_64
352
0
      if ((prefixes & (has_rex_b | has_addr16))
353
0
          == (has_rex_b | has_addr16))
354
0
        *cp++ = 'd';
355
#endif
356
357
0
      *cp++ = ',';
358
0
      *cp++ = '0' + (1 << (sib >> 6));
359
0
    }
360
361
0
        *cp++ = ')';
362
0
      }
363
0
    else
364
0
      {
365
0
        assert (! nodisp);
366
#ifdef X86_64
367
0
        if ((prefixes & has_addr16) == 0)
368
0
    n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx64,
369
0
            (int64_t) disp);
370
0
        else
371
0
#endif
372
0
    n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx32, disp);
373
0
        cp += n;
374
0
      }
375
376
0
    if (*bufcntp + (cp - tmpbuf) > bufsize)
377
0
      return *bufcntp + (cp - tmpbuf) - bufsize;
378
379
0
    memcpy (&bufp[*bufcntp], tmpbuf, cp - tmpbuf);
380
0
    *bufcntp += cp - tmpbuf;
381
0
  }
382
0
    }
383
0
  return 0;
384
0
}
Unexecuted instantiation: i386_disasm.c:general_mod$r_m
Unexecuted instantiation: x86_64_disasm.c:general_mod$r_m
385
386
387
static int
388
FCT_MOD$R_M (struct output_data *d)
389
0
{
390
0
  assert (d->opoff1 % 8 == 0);
391
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
392
0
  if ((modrm & 0xc0) == 0xc0)
393
0
    {
394
0
      assert (d->opoff1 / 8 == d->opoff2 / 8);
395
0
      assert (d->opoff2 % 8 == 5);
396
      //uint_fast8_t byte = d->data[d->opoff2 / 8] & 7;
397
0
      uint_fast8_t byte = modrm & 7;
398
399
0
      size_t *bufcntp = d->bufcntp;
400
0
      char *buf = d->bufp + *bufcntp;
401
0
      size_t avail = d->bufsize - *bufcntp;
402
0
      int needed;
403
0
      if (*d->prefixes & (has_rep | has_repne))
404
0
  needed = snprintf (buf, avail, "%%%s", dregs[byte]);
405
0
      else
406
0
  needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte);
407
0
      if ((size_t) needed > avail)
408
0
  return needed - avail;
409
0
      *bufcntp += needed;
410
0
      return 0;
411
0
    }
412
413
0
  return general_mod$r_m (d);
414
0
}
Unexecuted instantiation: i386_disasm.c:FCT_MOD$R_M
Unexecuted instantiation: x86_64_disasm.c:FCT_MOD$R_M
415
416
417
static int
418
FCT_Mod$R_m (struct output_data *d)
419
0
{
420
0
  assert (d->opoff1 % 8 == 0);
421
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
422
0
  if ((modrm & 0xc0) == 0xc0)
423
0
    {
424
0
      assert (d->opoff1 / 8 == d->opoff2 / 8);
425
0
      assert (d->opoff2 % 8 == 5);
426
      //uint_fast8_t byte = data[opoff2 / 8] & 7;
427
0
      uint_fast8_t byte = modrm & 7;
428
429
0
      size_t *bufcntp = d->bufcntp;
430
0
      size_t avail = d->bufsize - *bufcntp;
431
0
      int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8,
432
0
           byte);
433
0
      if ((size_t) needed > avail)
434
0
  return needed - avail;
435
0
      *d->bufcntp += needed;
436
0
      return 0;
437
0
    }
438
439
0
  return general_mod$r_m (d);
440
0
}
Unexecuted instantiation: i386_disasm.c:FCT_Mod$R_m
Unexecuted instantiation: x86_64_disasm.c:FCT_Mod$R_m
441
442
static int
443
generic_abs (struct output_data *d, const char *absstring
444
#ifdef X86_64
445
       , int abslen
446
#else
447
0
# define abslen 4
448
#endif
449
       )
450
0
{
451
0
  int r = data_prefix (d);
452
0
  if (r != 0)
453
0
    return r;
454
455
0
  assert (d->opoff1 % 8 == 0);
456
0
  assert (d->opoff1 / 8 == 1);
457
0
  if (*d->param_start + abslen > d->end)
458
0
    return -1;
459
0
  *d->param_start += abslen;
460
#ifndef X86_64
461
  uint32_t absval;
462
# define ABSPRIFMT PRIx32
463
#else
464
  uint64_t absval;
465
# define ABSPRIFMT PRIx64
466
0
  if (abslen == 8)
467
0
    absval = read_8ubyte_unaligned (&d->data[1]);
468
0
  else
469
0
#endif
470
0
    absval = read_4ubyte_unaligned (&d->data[1]);
471
0
  size_t *bufcntp = d->bufcntp;
472
0
  size_t avail = d->bufsize - *bufcntp;
473
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT,
474
0
       absstring, absval);
475
0
  if ((size_t) needed > avail)
476
0
    return needed - avail;
477
0
  *bufcntp += needed;
478
0
  return 0;
479
0
}
Unexecuted instantiation: i386_disasm.c:generic_abs
Unexecuted instantiation: x86_64_disasm.c:generic_abs
480
481
482
static int
483
FCT_absval (struct output_data *d)
484
0
{
485
0
  return generic_abs (d, "$"
486
#ifdef X86_64
487
          , 4
488
#endif
489
0
          );
490
0
}
Unexecuted instantiation: i386_disasm.c:FCT_absval
Unexecuted instantiation: x86_64_disasm.c:FCT_absval
491
492
static int
493
FCT_abs (struct output_data *d)
494
0
{
495
0
  return generic_abs (d, ""
496
#ifdef X86_64
497
          , 8
498
#endif
499
0
          );
500
0
}
Unexecuted instantiation: i386_disasm.c:FCT_abs
Unexecuted instantiation: x86_64_disasm.c:FCT_abs
501
502
static int
503
FCT_ax (struct output_data *d)
504
0
{
505
0
  int is_16bit = (*d->prefixes & has_data16) != 0;
506
507
0
  size_t *bufcntp = d->bufcntp;
508
0
  char *bufp = d->bufp;
509
0
  size_t bufsize = d->bufsize;
510
511
0
  if (*bufcntp + 4 - is_16bit > bufsize)
512
0
    return *bufcntp + 4 - is_16bit - bufsize;
513
514
0
  bufp[(*bufcntp)++] = '%';
515
0
  if (! is_16bit)
516
0
    bufp[(*bufcntp)++] = (
517
#ifdef X86_64
518
0
        (*d->prefixes & has_rex_w) ? 'r' :
519
#endif
520
0
        'e');
521
0
  bufp[(*bufcntp)++] = 'a';
522
0
  bufp[(*bufcntp)++] = 'x';
523
524
0
  return 0;
525
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ax
Unexecuted instantiation: x86_64_disasm.c:FCT_ax
526
527
528
static int
529
FCT_ax$w (struct output_data *d)
530
0
{
531
0
  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
532
0
    return FCT_ax (d);
533
534
0
  size_t *bufcntp = d->bufcntp;
535
0
  char *bufp = d->bufp;
536
0
  size_t bufsize = d->bufsize;
537
538
0
  if (*bufcntp + 3 > bufsize)
539
0
    return *bufcntp + 3 - bufsize;
540
541
0
  bufp[(*bufcntp)++] = '%';
542
0
  bufp[(*bufcntp)++] = 'a';
543
0
  bufp[(*bufcntp)++] = 'l';
544
545
0
  return 0;
546
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ax$w
Unexecuted instantiation: x86_64_disasm.c:FCT_ax$w
547
548
549
static int
550
__attribute__ ((noinline))
551
FCT_crdb (struct output_data *d, const char *regstr)
552
0
{
553
0
  if (*d->prefixes & has_data16)
554
0
    return -1;
555
556
0
  size_t *bufcntp = d->bufcntp;
557
558
  // XXX If this assert is true, use absolute offset below
559
0
  assert (d->opoff1 / 8 == 2);
560
0
  assert (d->opoff1 % 8 == 2);
561
0
  size_t avail = d->bufsize - *bufcntp;
562
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%%s%" PRIx32,
563
0
       regstr, (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7);
564
0
  if ((size_t) needed > avail)
565
0
    return needed - avail;
566
0
  *bufcntp += needed;
567
0
  return 0;
568
0
}
Unexecuted instantiation: i386_disasm.c:FCT_crdb
Unexecuted instantiation: x86_64_disasm.c:FCT_crdb
569
570
571
static int
572
FCT_ccc (struct output_data *d)
573
0
{
574
0
  return FCT_crdb (d, "cr");
575
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ccc
Unexecuted instantiation: x86_64_disasm.c:FCT_ccc
576
577
578
static int
579
FCT_ddd (struct output_data *d)
580
0
{
581
0
  return FCT_crdb (d, "db");
582
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ddd
Unexecuted instantiation: x86_64_disasm.c:FCT_ddd
583
584
585
static int
586
FCT_disp8 (struct output_data *d)
587
0
{
588
0
  assert (d->opoff1 % 8 == 0);
589
0
  if (*d->param_start >= d->end)
590
0
    return -1;
591
0
  int32_t offset = *(const int8_t *) (*d->param_start)++;
592
593
0
  size_t *bufcntp = d->bufcntp;
594
0
  size_t avail = d->bufsize - *bufcntp;
595
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
596
0
       (uint32_t) (d->addr + (*d->param_start - d->data)
597
0
             + offset));
598
0
  if ((size_t) needed > avail)
599
0
    return needed - avail;
600
0
  *bufcntp += needed;
601
0
  return 0;
602
0
}
Unexecuted instantiation: i386_disasm.c:FCT_disp8
Unexecuted instantiation: x86_64_disasm.c:FCT_disp8
603
604
605
static int
606
__attribute__ ((noinline))
607
FCT_ds_xx (struct output_data *d, const char *reg)
608
0
{
609
0
  int prefix = *d->prefixes & SEGMENT_PREFIXES;
610
611
0
  if (prefix == 0)
612
0
    *d->prefixes |= prefix = has_ds;
613
  /* Make sure only one bit is set.  */
614
0
  else if ((prefix - 1) & prefix)
615
0
    return -1;
616
617
0
  int r = data_prefix (d);
618
619
0
  assert ((*d->prefixes & prefix) == 0);
620
621
0
  if (r != 0)
622
0
    return r;
623
624
0
  size_t *bufcntp = d->bufcntp;
625
0
  size_t avail = d->bufsize - *bufcntp;
626
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)",
627
#ifdef X86_64
628
       *d->prefixes & idx_addr16 ? "e" : "r",
629
#else
630
       *d->prefixes & idx_addr16 ? "" : "e",
631
#endif
632
0
       reg);
633
0
  if ((size_t) needed > avail)
634
0
    return (size_t) needed - avail;
635
0
  *bufcntp += needed;
636
637
0
  return 0;
638
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ds_xx
Unexecuted instantiation: x86_64_disasm.c:FCT_ds_xx
639
640
641
static int
642
FCT_ds_bx (struct output_data *d)
643
0
{
644
0
  return FCT_ds_xx (d, "bx");
645
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ds_bx
Unexecuted instantiation: x86_64_disasm.c:FCT_ds_bx
646
647
648
static int
649
FCT_ds_si (struct output_data *d)
650
0
{
651
0
  return FCT_ds_xx (d, "si");
652
0
}
Unexecuted instantiation: i386_disasm.c:FCT_ds_si
Unexecuted instantiation: x86_64_disasm.c:FCT_ds_si
653
654
655
static int
656
FCT_dx (struct output_data *d)
657
0
{
658
0
  size_t *bufcntp = d->bufcntp;
659
660
0
  if (*bufcntp + 7 > d->bufsize)
661
0
    return *bufcntp + 7 - d->bufsize;
662
663
0
  memcpy (&d->bufp[*bufcntp], "(%dx)", 5);
664
0
  *bufcntp += 5;
665
666
0
  return 0;
667
0
}
Unexecuted instantiation: i386_disasm.c:FCT_dx
Unexecuted instantiation: x86_64_disasm.c:FCT_dx
668
669
670
static int
671
FCT_es_di (struct output_data *d)
672
0
{
673
0
  size_t *bufcntp = d->bufcntp;
674
0
  size_t avail = d->bufsize - *bufcntp;
675
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)",
676
#ifdef X86_64
677
       *d->prefixes & idx_addr16 ? "e" : "r"
678
#else
679
       *d->prefixes & idx_addr16 ? "" : "e"
680
#endif
681
0
       );
682
0
  if ((size_t) needed > avail)
683
0
    return (size_t) needed - avail;
684
0
  *bufcntp += needed;
685
686
0
  return 0;
687
0
}
Unexecuted instantiation: i386_disasm.c:FCT_es_di
Unexecuted instantiation: x86_64_disasm.c:FCT_es_di
688
689
690
static int
691
FCT_imm (struct output_data *d)
692
0
{
693
0
  size_t *bufcntp = d->bufcntp;
694
0
  size_t avail = d->bufsize - *bufcntp;
695
0
  int needed;
696
0
  if (*d->prefixes & has_data16)
697
0
    {
698
0
      if (*d->param_start + 2 > d->end)
699
0
  return -1;
700
0
      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
701
0
      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
702
0
    }
703
0
  else
704
0
    {
705
0
      if (*d->param_start + 4 > d->end)
706
0
  return -1;
707
0
      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
708
#ifdef X86_64
709
0
      if (*d->prefixes & has_rex_w)
710
0
  needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
711
         (int64_t) word);
712
0
      else
713
0
#endif
714
0
  needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
715
0
    }
716
0
  if ((size_t) needed > avail)
717
0
    return (size_t) needed - avail;
718
0
  *bufcntp += needed;
719
0
  return 0;
720
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imm
Unexecuted instantiation: x86_64_disasm.c:FCT_imm
721
722
723
static int
724
FCT_imm$w (struct output_data *d)
725
0
{
726
0
  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
727
0
    return FCT_imm (d);
728
729
0
  size_t *bufcntp = d->bufcntp;
730
0
  size_t avail = d->bufsize - *bufcntp;
731
0
  if (*d->param_start>= d->end)
732
0
    return -1;
733
0
  uint_fast8_t word = *(*d->param_start)++;
734
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word);
735
0
  if ((size_t) needed > avail)
736
0
    return (size_t) needed - avail;
737
0
  *bufcntp += needed;
738
0
  return 0;
739
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imm$w
Unexecuted instantiation: x86_64_disasm.c:FCT_imm$w
740
741
742
#ifdef X86_64
743
static int
744
FCT_imm64$w (struct output_data *d)
745
0
{
746
0
  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) == 0
747
0
      || (*d->prefixes & has_data16) != 0)
748
0
    return FCT_imm$w (d);
749
750
0
  size_t *bufcntp = d->bufcntp;
751
0
  size_t avail = d->bufsize - *bufcntp;
752
0
  int needed;
753
0
  if (*d->prefixes & has_rex_w)
754
0
    {
755
0
      if (*d->param_start + 8 > d->end)
756
0
  return -1;
757
0
      uint64_t word = read_8ubyte_unaligned_inc (*d->param_start);
758
0
      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, word);
759
0
    }
760
0
  else
761
0
    {
762
0
      if (*d->param_start + 4 > d->end)
763
0
  return -1;
764
0
      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
765
0
      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
766
0
    }
767
0
  if ((size_t) needed > avail)
768
0
    return (size_t) needed - avail;
769
0
  *bufcntp += needed;
770
0
  return 0;
771
0
}
772
#endif
773
774
775
static int
776
FCT_imms (struct output_data *d)
777
0
{
778
0
  size_t *bufcntp = d->bufcntp;
779
0
  size_t avail = d->bufsize - *bufcntp;
780
0
  if (*d->param_start>= d->end)
781
0
    return -1;
782
0
  int8_t byte = *(*d->param_start)++;
783
#ifdef X86_64
784
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
785
       (int64_t) byte);
786
#else
787
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
788
       (int32_t) byte);
789
#endif
790
0
  if ((size_t) needed > avail)
791
0
    return (size_t) needed - avail;
792
0
  *bufcntp += needed;
793
0
  return 0;
794
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imms
Unexecuted instantiation: x86_64_disasm.c:FCT_imms
795
796
797
static int
798
FCT_imm$s (struct output_data *d)
799
0
{
800
0
  uint_fast8_t opcode = d->data[d->opoff2 / 8];
801
0
  size_t *bufcntp = d->bufcntp;
802
0
  size_t avail = d->bufsize - *bufcntp;
803
0
  if ((opcode & 2) != 0)
804
0
    return FCT_imms (d);
805
806
0
  if ((*d->prefixes & has_data16) == 0)
807
0
    {
808
0
      if (*d->param_start + 4 > d->end)
809
0
  return -1;
810
0
      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
811
#ifdef X86_64
812
      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
813
           (int64_t) word);
814
#else
815
      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
816
#endif
817
0
      if ((size_t) needed > avail)
818
0
  return (size_t) needed - avail;
819
0
      *bufcntp += needed;
820
0
    }
821
0
  else
822
0
    {
823
0
      if (*d->param_start + 2 > d->end)
824
0
  return -1;
825
0
      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
826
0
      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
827
0
      if ((size_t) needed > avail)
828
0
  return (size_t) needed - avail;
829
0
      *bufcntp += needed;
830
0
    }
831
0
  return 0;
832
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imm$s
Unexecuted instantiation: x86_64_disasm.c:FCT_imm$s
833
834
835
static int
836
FCT_imm16 (struct output_data *d)
837
0
{
838
0
  if (*d->param_start + 2 > d->end)
839
0
    return -1;
840
0
  uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
841
0
  size_t *bufcntp = d->bufcntp;
842
0
  size_t avail = d->bufsize - *bufcntp;
843
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
844
0
  if ((size_t) needed > avail)
845
0
    return (size_t) needed - avail;
846
0
  *bufcntp += needed;
847
0
  return 0;
848
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imm16
Unexecuted instantiation: x86_64_disasm.c:FCT_imm16
849
850
851
static int
852
FCT_imms8 (struct output_data *d)
853
0
{
854
0
  size_t *bufcntp = d->bufcntp;
855
0
  size_t avail = d->bufsize - *bufcntp;
856
0
  if (*d->param_start >= d->end)
857
0
    return -1;
858
0
  int_fast8_t byte = *(*d->param_start)++;
859
0
  int needed;
860
#ifdef X86_64
861
0
  if (*d->prefixes & has_rex_w)
862
0
    needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
863
           (int64_t) byte);
864
0
  else
865
0
#endif
866
0
    needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
867
0
           (int32_t) byte);
868
0
  if ((size_t) needed > avail)
869
0
    return (size_t) needed - avail;
870
0
  *bufcntp += needed;
871
0
  return 0;
872
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imms8
Unexecuted instantiation: x86_64_disasm.c:FCT_imms8
873
874
875
static int
876
FCT_imm8 (struct output_data *d)
877
0
{
878
0
  size_t *bufcntp = d->bufcntp;
879
0
  size_t avail = d->bufsize - *bufcntp;
880
0
  if (*d->param_start >= d->end)
881
0
    return -1;
882
0
  uint_fast8_t byte = *(*d->param_start)++;
883
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
884
0
       (uint32_t) byte);
885
0
  if ((size_t) needed > avail)
886
0
    return (size_t) needed - avail;
887
0
  *bufcntp += needed;
888
0
  return 0;
889
0
}
Unexecuted instantiation: i386_disasm.c:FCT_imm8
Unexecuted instantiation: x86_64_disasm.c:FCT_imm8
890
891
892
static int
893
FCT_rel (struct output_data *d)
894
0
{
895
0
  size_t *bufcntp = d->bufcntp;
896
0
  size_t avail = d->bufsize - *bufcntp;
897
0
  if (*d->param_start + 4 > d->end)
898
0
    return -1;
899
0
  int32_t rel = read_4sbyte_unaligned_inc (*d->param_start);
900
#ifdef X86_64
901
  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64,
902
       (uint64_t) (d->addr + rel
903
             + (*d->param_start - d->data)));
904
#else
905
  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
906
       (uint32_t) (d->addr + rel
907
             + (*d->param_start - d->data)));
908
#endif
909
0
  if ((size_t) needed > avail)
910
0
    return (size_t) needed - avail;
911
0
  *bufcntp += needed;
912
0
  return 0;
913
0
}
Unexecuted instantiation: i386_disasm.c:FCT_rel
Unexecuted instantiation: x86_64_disasm.c:FCT_rel
914
915
916
static int
917
FCT_mmxreg (struct output_data *d)
918
0
{
919
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
920
0
  assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
921
0
  byte = (byte >> (5 - d->opoff1 % 8)) & 7;
922
0
  size_t *bufcntp =  d->bufcntp;
923
0
  size_t avail = d->bufsize - *bufcntp;
924
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte);
925
0
  if ((size_t) needed > avail)
926
0
    return needed - avail;
927
0
  *bufcntp += needed;
928
0
  return 0;
929
0
}
Unexecuted instantiation: i386_disasm.c:FCT_mmxreg
Unexecuted instantiation: x86_64_disasm.c:FCT_mmxreg
930
931
932
static int
933
FCT_mod$r_m (struct output_data *d)
934
0
{
935
0
  assert (d->opoff1 % 8 == 0);
936
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
937
0
  if ((modrm & 0xc0) == 0xc0)
938
0
    {
939
0
      int prefixes = *d->prefixes;
940
0
      if (prefixes & has_addr16)
941
0
  return -1;
942
943
0
      int is_16bit = (prefixes & has_data16) != 0;
944
945
0
      size_t *bufcntp = d->bufcntp;
946
0
      char *bufp = d->bufp;
947
0
      if (*bufcntp + 5 - is_16bit > d->bufsize)
948
0
  return *bufcntp + 5 - is_16bit - d->bufsize;
949
0
      bufp[(*bufcntp)++] = '%';
950
951
0
      char *cp;
952
#ifdef X86_64
953
0
      if ((prefixes & has_rex_b) != 0 && !is_16bit)
954
0
  {
955
0
    cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
956
0
    if ((prefixes & has_rex_w) == 0)
957
0
      *cp++ = 'd';
958
0
  }
959
0
      else
960
0
#endif
961
0
  {
962
0
    cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
963
#ifdef X86_64
964
0
    if ((prefixes & has_rex_w) != 0)
965
0
      bufp[*bufcntp] = 'r';
966
#endif
967
0
  }
968
0
      *bufcntp = cp - bufp;
969
0
      return 0;
970
0
    }
971
972
0
  return general_mod$r_m (d);
973
0
}
Unexecuted instantiation: i386_disasm.c:FCT_mod$r_m
Unexecuted instantiation: x86_64_disasm.c:FCT_mod$r_m
974
975
976
#ifndef X86_64
977
static int
978
FCT_moda$r_m (struct output_data *d)
979
0
{
980
0
  assert (d->opoff1 % 8 == 0);
981
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
982
0
  if ((modrm & 0xc0) == 0xc0)
983
0
    {
984
0
      if (*d->prefixes & has_addr16)
985
0
  return -1;
986
987
0
      size_t *bufcntp = d->bufcntp;
988
0
      if (*bufcntp + 3 > d->bufsize)
989
0
  return *bufcntp + 3 - d->bufsize;
990
991
0
      memcpy (&d->bufp[*bufcntp], "???", 3);
992
0
      *bufcntp += 3;
993
994
0
      return 0;
995
0
    }
996
997
0
  return general_mod$r_m (d);
998
0
}
999
#endif
1000
1001
1002
#ifdef X86_64
1003
static const char rex_8bit[8][3] =
1004
  {
1005
    [0] = "a", [1] = "c", [2] = "d", [3] = "b",
1006
    [4] = "sp", [5] = "bp", [6] = "si", [7] = "di"
1007
  };
1008
#endif
1009
1010
1011
static int
1012
FCT_mod$r_m$w (struct output_data *d)
1013
0
{
1014
0
  assert (d->opoff1 % 8 == 0);
1015
0
  const uint8_t *data = d->data;
1016
0
  uint_fast8_t modrm = data[d->opoff1 / 8];
1017
0
  if ((modrm & 0xc0) == 0xc0)
1018
0
    {
1019
0
      int prefixes = *d->prefixes;
1020
1021
0
      if (prefixes & has_addr16)
1022
0
  return -1;
1023
1024
0
      size_t *bufcntp = d->bufcntp;
1025
0
      char *bufp = d->bufp;
1026
0
      if (*bufcntp + 5 > d->bufsize)
1027
0
  return *bufcntp + 5 - d->bufsize;
1028
1029
0
      if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0)
1030
0
  {
1031
0
    bufp[(*bufcntp)++] = '%';
1032
1033
#ifdef X86_64
1034
0
    if (prefixes & has_rex)
1035
0
      {
1036
0
        if (prefixes & has_rex_r)
1037
0
    *bufcntp += snprintf (bufp + *bufcntp, d->bufsize - *bufcntp,
1038
0
              "r%db", 8 + (modrm & 7));
1039
0
        else
1040
0
    {
1041
0
      char *cp = stpcpy (bufp + *bufcntp, hiregs[modrm & 7]);
1042
0
      *cp++ = 'l';
1043
0
      *bufcntp = cp - bufp;
1044
0
    }
1045
0
      }
1046
0
    else
1047
0
#endif
1048
0
      {
1049
0
        bufp[(*bufcntp)++] = "acdb"[modrm & 3];
1050
0
        bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
1051
0
      }
1052
0
  }
1053
0
      else
1054
0
  {
1055
0
    int is_16bit = (prefixes & has_data16) != 0;
1056
1057
0
    bufp[(*bufcntp)++] = '%';
1058
1059
0
    char *cp;
1060
#ifdef X86_64
1061
0
    if ((prefixes & has_rex_b) != 0 && !is_16bit)
1062
0
      {
1063
0
        cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
1064
0
        if ((prefixes & has_rex_w) == 0)
1065
0
    *cp++ = 'd';
1066
0
      }
1067
0
    else
1068
0
#endif
1069
0
      {
1070
0
        cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
1071
#ifdef X86_64
1072
0
        if ((prefixes & has_rex_w) != 0)
1073
0
    bufp[*bufcntp] = 'r';
1074
#endif
1075
0
      }
1076
0
    *bufcntp = cp - bufp;
1077
0
  }
1078
0
      return 0;
1079
0
    }
1080
1081
0
  return general_mod$r_m (d);
1082
0
}
Unexecuted instantiation: i386_disasm.c:FCT_mod$r_m$w
Unexecuted instantiation: x86_64_disasm.c:FCT_mod$r_m$w
1083
1084
1085
static int
1086
FCT_mod$8r_m (struct output_data *d)
1087
0
{
1088
0
  assert (d->opoff1 % 8 == 0);
1089
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
1090
0
  if ((modrm & 0xc0) == 0xc0)
1091
0
    {
1092
0
      size_t *bufcntp = d->bufcntp;
1093
0
      char *bufp = d->bufp;
1094
0
      if (*bufcntp + 3 > d->bufsize)
1095
0
  return *bufcntp + 3 - d->bufsize;
1096
0
      bufp[(*bufcntp)++] = '%';
1097
0
      bufp[(*bufcntp)++] = "acdb"[modrm & 3];
1098
0
      bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
1099
0
      return 0;
1100
0
    }
1101
1102
0
  return general_mod$r_m (d);
1103
0
}
Unexecuted instantiation: i386_disasm.c:FCT_mod$8r_m
Unexecuted instantiation: x86_64_disasm.c:FCT_mod$8r_m
1104
1105
1106
static int
1107
FCT_mod$16r_m (struct output_data *d)
1108
0
{
1109
0
  assert (d->opoff1 % 8 == 0);
1110
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
1111
0
  if ((modrm & 0xc0) == 0xc0)
1112
0
    {
1113
0
      assert (d->opoff1 / 8 == d->opoff2 / 8);
1114
      //uint_fast8_t byte = data[opoff2 / 8] & 7;
1115
0
      uint_fast8_t byte = modrm & 7;
1116
1117
0
      size_t *bufcntp = d->bufcntp;
1118
0
      if (*bufcntp + 3 > d->bufsize)
1119
0
  return *bufcntp + 3 - d->bufsize;
1120
0
      d->bufp[(*bufcntp)++] = '%';
1121
0
      memcpy (&d->bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1);
1122
0
      *bufcntp += 2;
1123
0
      return 0;
1124
0
    }
1125
1126
0
  return general_mod$r_m (d);
1127
0
}
Unexecuted instantiation: i386_disasm.c:FCT_mod$16r_m
Unexecuted instantiation: x86_64_disasm.c:FCT_mod$16r_m
1128
1129
1130
#ifdef X86_64
1131
static int
1132
FCT_mod$64r_m (struct output_data *d)
1133
0
{
1134
0
  assert (d->opoff1 % 8 == 0);
1135
0
  uint_fast8_t modrm = d->data[d->opoff1 / 8];
1136
0
  if ((modrm & 0xc0) == 0xc0)
1137
0
    {
1138
0
      assert (d->opoff1 / 8 == d->opoff2 / 8);
1139
      //uint_fast8_t byte = data[opoff2 / 8] & 7;
1140
0
      uint_fast8_t byte = modrm & 7;
1141
1142
0
      size_t *bufcntp = d->bufcntp;
1143
0
      if (*bufcntp + 4 > d->bufsize)
1144
0
  return *bufcntp + 4 - d->bufsize;
1145
0
      char *cp = &d->bufp[*bufcntp];
1146
0
      *cp++ = '%';
1147
0
      cp = stpcpy (cp,
1148
0
       (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]);
1149
0
      *bufcntp = cp - d->bufp;
1150
0
      return 0;
1151
0
    }
1152
1153
0
  return general_mod$r_m (d);
1154
0
}
1155
#else
1156
#define FCT_mod$64r_m FCT_mod$r_m
1157
#endif
1158
1159
1160
static int
1161
FCT_reg (struct output_data *d)
1162
0
{
1163
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1164
0
  assert (d->opoff1 % 8 + 3 <= 8);
1165
0
  byte >>= 8 - (d->opoff1 % 8 + 3);
1166
0
  byte &= 7;
1167
0
  int is_16bit = (*d->prefixes & has_data16) != 0;
1168
0
  size_t *bufcntp = d->bufcntp;
1169
0
  if (*bufcntp + 5 > d->bufsize)
1170
0
    return *bufcntp + 5 - d->bufsize;
1171
0
  d->bufp[(*bufcntp)++] = '%';
1172
#ifdef X86_64
1173
0
  if ((*d->prefixes & has_rex_r) != 0 && !is_16bit)
1174
0
    {
1175
0
      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
1176
0
          8 + byte);
1177
0
      if ((*d->prefixes & has_rex_w) == 0)
1178
0
  d->bufp[(*bufcntp)++] = 'd';
1179
0
    }
1180
0
  else
1181
0
#endif
1182
0
    {
1183
0
      memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit);
1184
#ifdef X86_64
1185
0
      if ((*d->prefixes & has_rex_w) != 0 && !is_16bit)
1186
0
  d->bufp[*bufcntp] = 'r';
1187
#endif
1188
0
      *bufcntp += 3 - is_16bit;
1189
0
    }
1190
0
  return 0;
1191
0
}
Unexecuted instantiation: i386_disasm.c:FCT_reg
Unexecuted instantiation: x86_64_disasm.c:FCT_reg
1192
1193
1194
#ifdef X86_64
1195
static int
1196
FCT_oreg (struct output_data *d)
1197
0
{
1198
  /* Special form where register comes from opcode.  The rex.B bit is used,
1199
     rex.R and rex.X are ignored.  */
1200
0
  int save_prefixes = *d->prefixes;
1201
1202
0
  *d->prefixes = ((save_prefixes & ~has_rex_r)
1203
0
      | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
1204
1205
0
  int r = FCT_reg (d);
1206
1207
0
  *d->prefixes = save_prefixes;
1208
1209
0
  return r;
1210
0
}
1211
#endif
1212
1213
1214
static int
1215
FCT_reg64 (struct output_data *d)
1216
0
{
1217
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1218
0
  assert (d->opoff1 % 8 + 3 <= 8);
1219
0
  byte >>= 8 - (d->opoff1 % 8 + 3);
1220
0
  byte &= 7;
1221
0
  if ((*d->prefixes & has_data16) != 0)
1222
0
    return -1;
1223
0
  size_t *bufcntp = d->bufcntp;
1224
0
  if (*bufcntp + 5 > d->bufsize)
1225
0
    return *bufcntp + 5 - d->bufsize;
1226
0
  d->bufp[(*bufcntp)++] = '%';
1227
#ifdef X86_64
1228
0
  if ((*d->prefixes & has_rex_r) != 0)
1229
0
    {
1230
0
      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
1231
0
          8 + byte);
1232
0
      if ((*d->prefixes & has_rex_w) == 0)
1233
0
  d->bufp[(*bufcntp)++] = 'd';
1234
0
    }
1235
0
  else
1236
0
#endif
1237
0
    {
1238
0
      memcpy (&d->bufp[*bufcntp], aregs[byte], 3);
1239
0
      *bufcntp += 3;
1240
0
    }
1241
0
  return 0;
1242
0
}
Unexecuted instantiation: i386_disasm.c:FCT_reg64
Unexecuted instantiation: x86_64_disasm.c:FCT_reg64
1243
1244
1245
static int
1246
FCT_reg$w (struct output_data *d)
1247
0
{
1248
0
  if (d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7))))
1249
0
    return FCT_reg (d);
1250
1251
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1252
0
  assert (d->opoff1 % 8 + 3 <= 8);
1253
0
  byte >>= 8 - (d->opoff1 % 8 + 3);
1254
0
  byte &= 7;
1255
1256
0
  size_t *bufcntp = d->bufcntp;
1257
0
  if (*bufcntp + 4 > d->bufsize)
1258
0
    return *bufcntp + 4 - d->bufsize;
1259
1260
0
  d->bufp[(*bufcntp)++] = '%';
1261
1262
#ifdef X86_64
1263
0
  if (*d->prefixes & has_rex)
1264
0
    {
1265
0
      if (*d->prefixes & has_rex_r)
1266
0
  *bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp,
1267
0
            "r%db", 8 + byte);
1268
0
      else
1269
0
  {
1270
0
    char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]);
1271
0
    *cp++ = 'l';
1272
0
    *bufcntp = cp - d->bufp;
1273
0
  }
1274
0
    }
1275
0
  else
1276
0
#endif
1277
0
    {
1278
0
      d->bufp[(*bufcntp)++] = "acdb"[byte & 3];
1279
0
      d->bufp[(*bufcntp)++] = "lh"[byte >> 2];
1280
0
    }
1281
0
  return 0;
1282
0
}
Unexecuted instantiation: i386_disasm.c:FCT_reg$w
Unexecuted instantiation: x86_64_disasm.c:FCT_reg$w
1283
1284
1285
#ifdef X86_64
1286
static int
1287
FCT_oreg$w (struct output_data *d)
1288
0
{
1289
  /* Special form where register comes from opcode.  The rex.B bit is used,
1290
     rex.R and rex.X are ignored.  */
1291
0
  int save_prefixes = *d->prefixes;
1292
1293
0
  *d->prefixes = ((save_prefixes & ~has_rex_r)
1294
0
      | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
1295
1296
0
  int r = FCT_reg$w (d);
1297
1298
0
  *d->prefixes = save_prefixes;
1299
1300
0
  return r;
1301
0
}
1302
#endif
1303
1304
1305
static int
1306
FCT_freg (struct output_data *d)
1307
0
{
1308
0
  assert (d->opoff1 / 8 == 1);
1309
0
  assert (d->opoff1 % 8 == 5);
1310
0
  size_t *bufcntp = d->bufcntp;
1311
0
  size_t avail = d->bufsize - *bufcntp;
1312
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%st(%" PRIx32 ")",
1313
0
       (uint32_t) (d->data[1] & 7));
1314
0
  if ((size_t) needed > avail)
1315
0
    return (size_t) needed - avail;
1316
0
  *bufcntp += needed;
1317
0
  return 0;
1318
0
}
Unexecuted instantiation: i386_disasm.c:FCT_freg
Unexecuted instantiation: x86_64_disasm.c:FCT_freg
1319
1320
1321
#ifndef X86_64
1322
static int
1323
FCT_reg16 (struct output_data *d)
1324
0
{
1325
0
  if (*d->prefixes & has_data16)
1326
0
    return -1;
1327
1328
0
  *d->prefixes |= has_data16;
1329
0
  return FCT_reg (d);
1330
0
}
1331
#endif
1332
1333
1334
static int
1335
FCT_sel (struct output_data *d)
1336
0
{
1337
0
  assert (d->opoff1 % 8 == 0);
1338
0
  assert (d->opoff1 / 8 == 5);
1339
0
  if (*d->param_start + 2 >= d->end)
1340
0
    return -1;
1341
0
  *d->param_start += 2;
1342
0
  uint16_t absval = read_2ubyte_unaligned (&d->data[5]);
1343
1344
0
  size_t *bufcntp = d->bufcntp;
1345
0
  size_t avail = d->bufsize - *bufcntp;
1346
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, absval);
1347
0
  if ((size_t) needed > avail)
1348
0
    return needed - avail;
1349
0
  *bufcntp += needed;
1350
0
  return 0;
1351
0
}
Unexecuted instantiation: i386_disasm.c:FCT_sel
Unexecuted instantiation: x86_64_disasm.c:FCT_sel
1352
1353
1354
static int
1355
FCT_sreg2 (struct output_data *d)
1356
0
{
1357
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1358
0
  assert (d->opoff1 % 8 + 3 <= 8);
1359
0
  byte >>= 8 - (d->opoff1 % 8 + 2);
1360
1361
0
  size_t *bufcntp = d->bufcntp;
1362
0
  char *bufp = d->bufp;
1363
0
  if (*bufcntp + 3 > d->bufsize)
1364
0
    return *bufcntp + 3 - d->bufsize;
1365
1366
0
  bufp[(*bufcntp)++] = '%';
1367
0
  bufp[(*bufcntp)++] = "ecsd"[byte & 3];
1368
0
  bufp[(*bufcntp)++] = 's';
1369
1370
0
  return 0;
1371
0
}
Unexecuted instantiation: i386_disasm.c:FCT_sreg2
Unexecuted instantiation: x86_64_disasm.c:FCT_sreg2
1372
1373
1374
static int
1375
FCT_sreg3 (struct output_data *d)
1376
0
{
1377
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1378
0
  assert (d->opoff1 % 8 + 4 <= 8);
1379
0
  byte >>= 8 - (d->opoff1 % 8 + 3);
1380
1381
0
  if ((byte & 7) >= 6)
1382
0
    return -1;
1383
1384
0
  size_t *bufcntp = d->bufcntp;
1385
0
  char *bufp = d->bufp;
1386
0
  if (*bufcntp + 3 > d->bufsize)
1387
0
    return *bufcntp + 3 - d->bufsize;
1388
1389
0
  bufp[(*bufcntp)++] = '%';
1390
0
  bufp[(*bufcntp)++] = "ecsdfg"[byte & 7];
1391
0
  bufp[(*bufcntp)++] = 's';
1392
1393
0
  return 0;
1394
0
}
Unexecuted instantiation: i386_disasm.c:FCT_sreg3
Unexecuted instantiation: x86_64_disasm.c:FCT_sreg3
1395
1396
1397
static int
1398
FCT_string (struct output_data *d __attribute__ ((unused)))
1399
0
{
1400
0
  return 0;
1401
0
}
Unexecuted instantiation: i386_disasm.c:FCT_string
Unexecuted instantiation: x86_64_disasm.c:FCT_string
1402
1403
1404
static int
1405
FCT_xmmreg (struct output_data *d)
1406
0
{
1407
0
  uint_fast8_t byte = d->data[d->opoff1 / 8];
1408
0
  assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
1409
0
  byte = (byte >> (5 - d->opoff1 % 8)) & 7;
1410
1411
0
  size_t *bufcntp = d->bufcntp;
1412
0
  size_t avail = d->bufsize - *bufcntp;
1413
0
  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte);
1414
0
  if ((size_t) needed > avail)
1415
0
    return needed - avail;
1416
0
  *bufcntp += needed;
1417
0
  return 0;
1418
0
}
Unexecuted instantiation: i386_disasm.c:FCT_xmmreg
Unexecuted instantiation: x86_64_disasm.c:FCT_xmmreg