Merge branch 'nasm-2.09.xx'
[platform/upstream/nasm.git] / disasm.c
1 /* ----------------------------------------------------------------------- *
2  *   
3  *   Copyright 1996-2010 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *     
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33
34 /* 
35  * disasm.c   where all the _work_ gets done in the Netwide Disassembler
36  */
37
38 #include "compiler.h"
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <limits.h>
43 #include <inttypes.h>
44
45 #include "nasm.h"
46 #include "disasm.h"
47 #include "sync.h"
48 #include "insns.h"
49 #include "tables.h"
50 #include "regdis.h"
51
52 /*
53  * Flags that go into the `segment' field of `insn' structures
54  * during disassembly.
55  */
56 #define SEG_RELATIVE      1
57 #define SEG_32BIT         2
58 #define SEG_RMREG         4
59 #define SEG_DISP8         8
60 #define SEG_DISP16       16
61 #define SEG_DISP32       32
62 #define SEG_NODISP       64
63 #define SEG_SIGNED      128
64 #define SEG_64BIT       256
65
66 /*
67  * Prefix information
68  */
69 struct prefix_info {
70     uint8_t osize;              /* Operand size */
71     uint8_t asize;              /* Address size */
72     uint8_t osp;                /* Operand size prefix present */
73     uint8_t asp;                /* Address size prefix present */
74     uint8_t rep;                /* Rep prefix present */
75     uint8_t seg;                /* Segment override prefix present */
76     uint8_t wait;               /* WAIT "prefix" present */
77     uint8_t lock;               /* Lock prefix present */
78     uint8_t vex[3];             /* VEX prefix present */
79     uint8_t vex_c;              /* VEX "class" (VEX, XOP, ...) */
80     uint8_t vex_m;              /* VEX.M field */
81     uint8_t vex_v;
82     uint8_t vex_lp;             /* VEX.LP fields */
83     uint32_t rex;               /* REX prefix present */
84 };
85
86 #define getu8(x) (*(uint8_t *)(x))
87 #if X86_MEMORY
88 /* Littleendian CPU which can handle unaligned references */
89 #define getu16(x) (*(uint16_t *)(x))
90 #define getu32(x) (*(uint32_t *)(x))
91 #define getu64(x) (*(uint64_t *)(x))
92 #else
93 static uint16_t getu16(uint8_t *data)
94 {
95     return (uint16_t)data[0] + ((uint16_t)data[1] << 8);
96 }
97 static uint32_t getu32(uint8_t *data)
98 {
99     return (uint32_t)getu16(data) + ((uint32_t)getu16(data+2) << 16);
100 }
101 static uint64_t getu64(uint8_t *data)
102 {
103     return (uint64_t)getu32(data) + ((uint64_t)getu32(data+4) << 32);
104 }
105 #endif
106
107 #define gets8(x) ((int8_t)getu8(x))
108 #define gets16(x) ((int16_t)getu16(x))
109 #define gets32(x) ((int32_t)getu32(x))
110 #define gets64(x) ((int64_t)getu64(x))
111
112 /* Important: regval must already have been adjusted for rex extensions */
113 static enum reg_enum whichreg(opflags_t regflags, int regval, int rex)
114 {
115     if (!(regflags & (REGISTER|REGMEM)))
116         return 0;               /* Registers not permissible?! */
117
118     regflags |= REGISTER;
119
120     if (!(REG_AL & ~regflags))
121         return R_AL;
122     if (!(REG_AX & ~regflags))
123         return R_AX;
124     if (!(REG_EAX & ~regflags))
125         return R_EAX;
126     if (!(REG_RAX & ~regflags))
127         return R_RAX;
128     if (!(REG_DL & ~regflags))
129         return R_DL;
130     if (!(REG_DX & ~regflags))
131         return R_DX;
132     if (!(REG_EDX & ~regflags))
133         return R_EDX;
134     if (!(REG_RDX & ~regflags))
135         return R_RDX;
136     if (!(REG_CL & ~regflags))
137         return R_CL;
138     if (!(REG_CX & ~regflags))
139         return R_CX;
140     if (!(REG_ECX & ~regflags))
141         return R_ECX;
142     if (!(REG_RCX & ~regflags))
143         return R_RCX;
144     if (!(FPU0 & ~regflags))
145         return R_ST0;
146     if (!(XMM0 & ~regflags))
147         return R_XMM0;
148     if (!(YMM0 & ~regflags))
149         return R_YMM0;
150     if (!(REG_CS & ~regflags))
151         return (regval == 1) ? R_CS : 0;
152     if (!(REG_DESS & ~regflags))
153         return (regval == 0 || regval == 2
154                 || regval == 3 ? nasm_rd_sreg[regval] : 0);
155     if (!(REG_FSGS & ~regflags))
156         return (regval == 4 || regval == 5 ? nasm_rd_sreg[regval] : 0);
157     if (!(REG_SEG67 & ~regflags))
158         return (regval == 6 || regval == 7 ? nasm_rd_sreg[regval] : 0);
159
160     /* All the entries below look up regval in an 16-entry array */
161     if (regval < 0 || regval > 15)
162         return 0;
163
164     if (!(REG8 & ~regflags)) {
165         if (rex & (REX_P|REX_NH))
166             return nasm_rd_reg8_rex[regval];
167         else
168             return nasm_rd_reg8[regval];
169     }
170     if (!(REG16 & ~regflags))
171         return nasm_rd_reg16[regval];
172     if (!(REG32 & ~regflags))
173         return nasm_rd_reg32[regval];
174     if (!(REG64 & ~regflags))
175         return nasm_rd_reg64[regval];
176     if (!(REG_SREG & ~regflags))
177         return nasm_rd_sreg[regval & 7]; /* Ignore REX */
178     if (!(REG_CREG & ~regflags))
179         return nasm_rd_creg[regval];
180     if (!(REG_DREG & ~regflags))
181         return nasm_rd_dreg[regval];
182     if (!(REG_TREG & ~regflags)) {
183         if (regval > 7)
184             return 0;           /* TR registers are ill-defined with rex */
185         return nasm_rd_treg[regval];
186     }
187     if (!(FPUREG & ~regflags))
188         return nasm_rd_fpureg[regval & 7]; /* Ignore REX */
189     if (!(MMXREG & ~regflags))
190         return nasm_rd_mmxreg[regval & 7]; /* Ignore REX */
191     if (!(XMMREG & ~regflags))
192         return nasm_rd_xmmreg[regval];
193     if (!(YMMREG & ~regflags))
194         return nasm_rd_ymmreg[regval];
195
196     return 0;
197 }
198
199 /*
200  * Process a DREX suffix
201  */
202 static uint8_t *do_drex(uint8_t *data, insn *ins)
203 {
204     uint8_t drex = *data++;
205     operand *dst = &ins->oprs[ins->drexdst];
206
207     if ((drex & 8) != ((ins->rex & REX_OC) ? 8 : 0))
208         return NULL;    /* OC0 mismatch */
209     ins->rex = (ins->rex & ~7) | (drex & 7);
210
211     dst->segment = SEG_RMREG;
212     dst->basereg = drex >> 4;
213     return data;
214 }
215
216
217 /*
218  * Process an effective address (ModRM) specification.
219  */
220 static uint8_t *do_ea(uint8_t *data, int modrm, int asize,
221                       int segsize, enum ea_type type,
222                       operand *op, insn *ins)
223 {
224     int mod, rm, scale, index, base;
225     int rex;
226     uint8_t sib = 0;
227
228     mod = (modrm >> 6) & 03;
229     rm = modrm & 07;
230
231     if (mod != 3 && asize != 16 && rm == 4)
232         sib = *data++;
233
234     if (ins->rex & REX_D) {
235         data = do_drex(data, ins);
236         if (!data)
237             return NULL;
238     }
239     rex = ins->rex;
240
241     if (mod == 3) {             /* pure register version */
242         op->basereg = rm+(rex & REX_B ? 8 : 0);
243         op->segment |= SEG_RMREG;
244         return data;
245     }
246
247     op->disp_size = 0;
248     op->eaflags = 0;
249
250     if (asize == 16) {
251         /*
252          * <mod> specifies the displacement size (none, byte or
253          * word), and <rm> specifies the register combination.
254          * Exception: mod=0,rm=6 does not specify [BP] as one might
255          * expect, but instead specifies [disp16].
256          */
257
258         if (type != EA_SCALAR)
259             return NULL;
260
261         op->indexreg = op->basereg = -1;
262         op->scale = 1;          /* always, in 16 bits */
263         switch (rm) {
264         case 0:
265             op->basereg = R_BX;
266             op->indexreg = R_SI;
267             break;
268         case 1:
269             op->basereg = R_BX;
270             op->indexreg = R_DI;
271             break;
272         case 2:
273             op->basereg = R_BP;
274             op->indexreg = R_SI;
275             break;
276         case 3:
277             op->basereg = R_BP;
278             op->indexreg = R_DI;
279             break;
280         case 4:
281             op->basereg = R_SI;
282             break;
283         case 5:
284             op->basereg = R_DI;
285             break;
286         case 6:
287             op->basereg = R_BP;
288             break;
289         case 7:
290             op->basereg = R_BX;
291             break;
292         }
293         if (rm == 6 && mod == 0) {      /* special case */
294             op->basereg = -1;
295             if (segsize != 16)
296                 op->disp_size = 16;
297             mod = 2;            /* fake disp16 */
298         }
299         switch (mod) {
300         case 0:
301             op->segment |= SEG_NODISP;
302             break;
303         case 1:
304             op->segment |= SEG_DISP8;
305             op->offset = (int8_t)*data++;
306             break;
307         case 2:
308             op->segment |= SEG_DISP16;
309             op->offset = *data++;
310             op->offset |= ((unsigned)*data++) << 8;
311             break;
312         }
313         return data;
314     } else {
315         /*
316          * Once again, <mod> specifies displacement size (this time
317          * none, byte or *dword*), while <rm> specifies the base
318          * register. Again, [EBP] is missing, replaced by a pure
319          * disp32 (this time that's mod=0,rm=*5*) in 32-bit mode,
320          * and RIP-relative addressing in 64-bit mode.
321          *
322          * However, rm=4
323          * indicates not a single base register, but instead the
324          * presence of a SIB byte...
325          */
326         int a64 = asize == 64;
327
328         op->indexreg = -1;
329
330         if (a64)
331             op->basereg = nasm_rd_reg64[rm | ((rex & REX_B) ? 8 : 0)];
332         else
333             op->basereg = nasm_rd_reg32[rm | ((rex & REX_B) ? 8 : 0)];
334
335         if (rm == 5 && mod == 0) {
336             if (segsize == 64) {
337                 op->eaflags |= EAF_REL;
338                 op->segment |= SEG_RELATIVE;
339                 mod = 2;        /* fake disp32 */
340             }
341
342             if (asize != 64)
343                 op->disp_size = asize;
344
345             op->basereg = -1;
346             mod = 2;            /* fake disp32 */
347         }
348
349
350         if (rm == 4) {          /* process SIB */
351             scale = (sib >> 6) & 03;
352             index = (sib >> 3) & 07;
353             base = sib & 07;
354
355             op->scale = 1 << scale;
356
357             if (index == 4 && !(rex & REX_X))
358                 op->indexreg = -1; /* ESP/RSP cannot be an index */
359             else if (type == EA_XMMVSIB)
360                 op->indexreg = nasm_rd_xmmreg[index | ((rex & REX_X) ? 8 : 0)];
361             else if (type == EA_YMMVSIB)
362                 op->indexreg = nasm_rd_ymmreg[index | ((rex & REX_X) ? 8 : 0)];
363             else if (a64)
364                 op->indexreg = nasm_rd_reg64[index | ((rex & REX_X) ? 8 : 0)];
365             else
366                 op->indexreg = nasm_rd_reg32[index | ((rex & REX_X) ? 8 : 0)];
367
368             if (base == 5 && mod == 0) {
369                 op->basereg = -1;
370                 mod = 2;        /* Fake disp32 */
371             } else if (a64)
372                 op->basereg = nasm_rd_reg64[base | ((rex & REX_B) ? 8 : 0)];
373             else
374                 op->basereg = nasm_rd_reg32[base | ((rex & REX_B) ? 8 : 0)];
375
376             if (segsize == 16)
377                 op->disp_size = 32;
378         } else if (type != EA_SCALAR) {
379             /* Can't have VSIB without SIB */
380             return NULL;
381         }
382
383         switch (mod) {
384         case 0:
385             op->segment |= SEG_NODISP;
386             break;
387         case 1:
388             op->segment |= SEG_DISP8;
389             op->offset = gets8(data);
390             data++;
391             break;
392         case 2:
393             op->segment |= SEG_DISP32;
394             op->offset = gets32(data);
395             data += 4;
396             break;
397         }
398         return data;
399     }
400 }
401
402 /*
403  * Determine whether the instruction template in t corresponds to the data
404  * stream in data. Return the number of bytes matched if so.
405  */
406 #define case4(x) case (x): case (x)+1: case (x)+2: case (x)+3
407
408 static int matches(const struct itemplate *t, uint8_t *data,
409                    const struct prefix_info *prefix, int segsize, insn *ins)
410 {
411     uint8_t *r = (uint8_t *)(t->code);
412     uint8_t *origdata = data;
413     bool a_used = false, o_used = false;
414     enum prefixes drep = 0;
415     enum prefixes dwait = 0;
416     uint8_t lock = prefix->lock;
417     int osize = prefix->osize;
418     int asize = prefix->asize;
419     int i, c;
420     int op1, op2;
421     struct operand *opx, *opy;
422     uint8_t opex = 0;
423     int s_field_for = -1;       /* No 144/154 series code encountered */
424     bool vex_ok = false;
425     int regmask = (segsize == 64) ? 15 : 7;
426     enum ea_type eat = EA_SCALAR;
427
428     for (i = 0; i < MAX_OPERANDS; i++) {
429         ins->oprs[i].segment = ins->oprs[i].disp_size =
430             (segsize == 64 ? SEG_64BIT : segsize == 32 ? SEG_32BIT : 0);
431     }
432     ins->condition = -1;
433     ins->rex = prefix->rex;
434     memset(ins->prefixes, 0, sizeof ins->prefixes);
435
436     if (t->flags & (segsize == 64 ? IF_NOLONG : IF_LONG))
437         return false;
438
439     if (prefix->rep == 0xF2)
440         drep = P_REPNE;
441     else if (prefix->rep == 0xF3)
442         drep = P_REP;
443
444     dwait = prefix->wait ? P_WAIT : 0;
445
446     while ((c = *r++) != 0) {
447         op1 = (c & 3) + ((opex & 1) << 2);
448         op2 = ((c >> 3) & 3) + ((opex & 2) << 1);
449         opx = &ins->oprs[op1];
450         opy = &ins->oprs[op2];
451         opex = 0;
452
453         switch (c) {
454         case 01:
455         case 02:
456         case 03:
457         case 04:
458             while (c--)
459                 if (*r++ != *data++)
460                     return false;
461             break;
462
463         case 05:
464         case 06:
465         case 07:
466             opex = c;
467             break;
468
469         case4(010):
470         {
471             int t = *r++, d = *data++;
472             if (d < t || d > t + 7)
473                 return false;
474             else {
475                 opx->basereg = (d-t)+
476                     (ins->rex & REX_B ? 8 : 0);
477                 opx->segment |= SEG_RMREG;
478             }
479             break;
480         }
481
482         case4(014):
483         case4(0274):
484             opx->offset = (int8_t)*data++;
485             opx->segment |= SEG_SIGNED;
486             break;
487
488         case4(020):
489             opx->offset = *data++;
490             break;
491
492         case4(024):
493             opx->offset = *data++;
494             break;
495
496         case4(030):
497             opx->offset = getu16(data);
498             data += 2;
499             break;
500
501         case4(034):
502             if (osize == 32) {
503                 opx->offset = getu32(data);
504                 data += 4;
505             } else {
506                 opx->offset = getu16(data);
507                 data += 2;
508             }
509             if (segsize != asize)
510                 opx->disp_size = asize;
511             break;
512
513         case4(040):
514         case4(0254):
515             opx->offset = getu32(data);
516             data += 4;
517             break;
518
519         case4(044):
520             switch (asize) {
521             case 16:
522                 opx->offset = getu16(data);
523                 data += 2;
524                 if (segsize != 16)
525                     opx->disp_size = 16;
526                 break;
527             case 32:
528                 opx->offset = getu32(data);
529                 data += 4;
530                 if (segsize == 16)
531                     opx->disp_size = 32;
532                 break;
533             case 64:
534                 opx->offset = getu64(data);
535                 opx->disp_size = 64;
536                 data += 8;
537                 break;
538             }
539             break;
540
541         case4(050):
542             opx->offset = gets8(data++);
543             opx->segment |= SEG_RELATIVE;
544             break;
545
546         case4(054):
547             opx->offset = getu64(data);
548             data += 8;
549             break;
550
551         case4(060):
552             opx->offset = gets16(data);
553             data += 2;
554             opx->segment |= SEG_RELATIVE;
555             opx->segment &= ~SEG_32BIT;
556             break;
557
558         case4(064):
559             opx->segment |= SEG_RELATIVE;
560             if (osize == 16) {
561                 opx->offset = gets16(data);
562                 data += 2;
563                 opx->segment &= ~(SEG_32BIT|SEG_64BIT);
564             } else if (osize == 32) {
565                 opx->offset = gets32(data);
566                 data += 4;
567                 opx->segment &= ~SEG_64BIT;
568                 opx->segment |= SEG_32BIT;
569             }
570             if (segsize != osize) {
571                 opx->type =
572                     (opx->type & ~SIZE_MASK)
573                     | ((osize == 16) ? BITS16 : BITS32);
574             }
575             break;
576
577         case4(070):
578             opx->offset = gets32(data);
579             data += 4;
580             opx->segment |= SEG_32BIT | SEG_RELATIVE;
581             break;
582
583         case4(0100):
584         case4(0110):
585         case4(0120):
586         case4(0130):
587         {
588             int modrm = *data++;
589             opx->segment |= SEG_RMREG;
590             data = do_ea(data, modrm, asize, segsize, eat, opy, ins);
591             if (!data)
592                 return false;
593             opx->basereg = ((modrm >> 3) & 7) + (ins->rex & REX_R ? 8 : 0);
594             break;
595         }
596
597         case4(0140):
598             if (s_field_for == op1) {
599                 opx->offset = gets8(data);
600                 data++;
601             } else {
602                 opx->offset = getu16(data);
603                 data += 2;
604             }
605             break;
606
607         case4(0144):
608         case4(0154):
609             s_field_for = (*data & 0x02) ? op1 : -1;
610             if ((*data++ & ~0x02) != *r++)
611                 return false;
612             break;
613
614         case4(0150):
615             if (s_field_for == op1) {
616                 opx->offset = gets8(data);
617                 data++;
618             } else {
619                 opx->offset = getu32(data);
620                 data += 4;
621             }
622             break;
623
624         case4(0160):
625             ins->rex |= REX_D;
626             ins->drexdst = op1;
627             break;
628
629         case4(0164):
630             ins->rex |= REX_D|REX_OC;
631             ins->drexdst = op1;
632             break;
633
634         case 0171:
635             data = do_drex(data, ins);
636             if (!data)
637                 return false;
638             break;
639
640         case 0172:
641         {
642             uint8_t ximm = *data++;
643             c = *r++;
644             ins->oprs[c >> 3].basereg = (ximm >> 4) & regmask;
645             ins->oprs[c >> 3].segment |= SEG_RMREG;
646             ins->oprs[c & 7].offset = ximm & 15;
647         }
648         break;
649
650         case 0173:
651         {
652             uint8_t ximm = *data++;
653             c = *r++;
654
655             if ((c ^ ximm) & 15)
656                 return false;
657
658             ins->oprs[c >> 4].basereg = (ximm >> 4) & regmask;
659             ins->oprs[c >> 4].segment |= SEG_RMREG;
660         }
661         break;
662
663         case 0174:
664         {
665             uint8_t ximm = *data++;
666             c = *r++;
667
668             ins->oprs[c].basereg = (ximm >> 4) & regmask;
669             ins->oprs[c].segment |= SEG_RMREG;
670         }
671         break;
672
673         case4(0200):
674         case4(0204):
675         case4(0210):
676         case4(0214):
677         case4(0220):
678         case4(0224):
679         case4(0230):
680         case4(0234):
681         {
682             int modrm = *data++;
683             if (((modrm >> 3) & 07) != (c & 07))
684                 return false;   /* spare field doesn't match up */
685             data = do_ea(data, modrm, asize, segsize, eat, opy, ins);
686             if (!data)
687                 return false;
688             break;
689         }
690
691         case4(0250):
692             if (s_field_for == op1) {
693                 opx->offset = gets8(data);
694                 data++;
695             } else {
696                 opx->offset = gets32(data);
697                 data += 4;
698             }
699             break;
700
701         case4(0260):
702         case 0270:
703         {
704             int vexm   = *r++;
705             int vexwlp = *r++;
706
707             ins->rex |= REX_V;
708             if ((prefix->rex & (REX_V|REX_D|REX_P)) != REX_V)
709                 return false;
710
711             if ((vexm & 0x1f) != prefix->vex_m)
712                 return false;
713
714             switch (vexwlp & 060) {
715             case 000:
716                 if (prefix->rex & REX_W)
717                     return false;
718                 break;
719             case 020:
720                 if (!(prefix->rex & REX_W))
721                     return false;
722                 ins->rex &= ~REX_W;
723                 break;
724             case 040:           /* VEX.W is a don't care */
725                 ins->rex &= ~REX_W;
726                 break;
727             case 060:
728                 break;
729             }
730
731             /* The 010 bit of vexwlp is set if VEX.L is ignored */
732             if ((vexwlp ^ prefix->vex_lp) & ((vexwlp & 010) ? 03 : 07))
733                 return false;
734
735             if (c == 0270) {
736                 if (prefix->vex_v != 0)
737                     return false;
738             } else {
739                 opx->segment |= SEG_RMREG;
740                 opx->basereg = prefix->vex_v;
741             }
742             vex_ok = true;
743             break;
744         }
745
746         case 0310:
747             if (asize != 16)
748                 return false;
749             else
750                 a_used = true;
751             break;
752
753         case 0311:
754             if (asize != 32)
755                 return false;
756             else
757                 a_used = true;
758             break;
759
760         case 0312:
761             if (asize != segsize)
762                 return false;
763             else
764                 a_used = true;
765             break;
766
767         case 0313:
768             if (asize != 64)
769                 return false;
770             else
771                 a_used = true;
772             break;
773
774         case 0314:
775             if (prefix->rex & REX_B)
776                 return false;
777             break;
778
779         case 0315:
780             if (prefix->rex & REX_X)
781                 return false;
782             break;
783
784         case 0316:
785             if (prefix->rex & REX_R)
786                 return false;
787             break;
788
789         case 0317:
790             if (prefix->rex & REX_W)
791                 return false;
792             break;
793
794         case 0320:
795             if (osize != 16)
796                 return false;
797             else
798                 o_used = true;
799             break;
800
801         case 0321:
802             if (osize != 32)
803                 return false;
804             else
805                 o_used = true;
806             break;
807
808         case 0322:
809             if (osize != (segsize == 16) ? 16 : 32)
810                 return false;
811             else
812                 o_used = true;
813             break;
814
815         case 0323:
816             ins->rex |= REX_W;  /* 64-bit only instruction */
817             osize = 64;
818             o_used = true;
819             break;
820
821         case 0324:
822             if (osize != 64)
823                 return false;
824             o_used = true;
825             break;
826
827         case 0325:
828             ins->rex |= REX_NH;
829             break;
830
831         case 0330:
832         {
833             int t = *r++, d = *data++;
834             if (d < t || d > t + 15)
835                 return false;
836             else
837                 ins->condition = d - t;
838             break;
839         }
840
841         case 0331:
842             if (prefix->rep)
843                 return false;
844             break;
845
846         case 0332:
847             if (prefix->rep != 0xF2)
848                 return false;
849             drep = 0;
850             break;
851
852         case 0333:
853             if (prefix->rep != 0xF3)
854                 return false;
855             drep = 0;
856             break;
857
858         case 0334:
859             if (lock) {
860                 ins->rex |= REX_R;
861                 lock = 0;
862             }
863             break;
864
865         case 0335:
866             if (drep == P_REP)
867                 drep = P_REPE;
868             break;
869
870         case 0336:
871         case 0337:
872             break;
873
874         case 0340:
875             return false;
876
877         case 0341:
878             if (prefix->wait != 0x9B)
879                 return false;
880             dwait = 0;
881             break;
882
883         case4(0344):
884             ins->oprs[0].basereg = (*data++ >> 3) & 7;
885             break;
886
887         case 0360:
888             if (prefix->osp || prefix->rep)
889                 return false;
890             break;
891
892         case 0361:
893             if (!prefix->osp || prefix->rep)
894                 return false;
895             o_used = true;
896             break;
897
898         case 0362:
899             if (prefix->osp || prefix->rep != 0xf2)
900                 return false;
901             drep = 0;
902             break;
903
904         case 0363:
905             if (prefix->osp || prefix->rep != 0xf3)
906                 return false;
907             drep = 0;
908             break;
909
910         case 0364:
911             if (prefix->osp)
912                 return false;
913             break;
914
915         case 0365:
916             if (prefix->asp)
917                 return false;
918             break;
919
920         case 0366:
921             if (!prefix->osp)
922                 return false;
923             o_used = true;
924             break;
925
926         case 0367:
927             if (!prefix->asp)
928                 return false;
929             a_used = true;
930             break;
931
932         case 0374:
933             eat = EA_XMMVSIB;
934             break;
935
936         case 0375:
937             eat = EA_YMMVSIB;
938             break;
939
940         default:
941             return false;       /* Unknown code */
942         }
943     }
944
945     if (!vex_ok && (ins->rex & REX_V))
946         return false;
947
948     /* REX cannot be combined with DREX or VEX */
949     if ((ins->rex & (REX_D|REX_V)) && (prefix->rex & REX_P))
950         return false;
951
952     /*
953      * Check for unused rep or a/o prefixes.
954      */
955     for (i = 0; i < t->operands; i++) {
956         if (ins->oprs[i].segment != SEG_RMREG)
957             a_used = true;
958     }
959
960     if (lock) {
961         if (ins->prefixes[PPS_LREP])
962             return false;
963         ins->prefixes[PPS_LREP] = P_LOCK;
964     }
965     if (drep) {
966         if (ins->prefixes[PPS_LREP])
967             return false;
968         ins->prefixes[PPS_LREP] = drep;
969     }
970     ins->prefixes[PPS_WAIT] = dwait;
971     if (!o_used) {
972         if (osize != ((segsize == 16) ? 16 : 32)) {
973             enum prefixes pfx = 0;
974
975             switch (osize) {
976             case 16:
977                 pfx = P_O16;
978                 break;
979             case 32:
980                 pfx = P_O32;
981                 break;
982             case 64:
983                 pfx = P_O64;
984                 break;
985             }
986
987             if (ins->prefixes[PPS_OSIZE])
988                 return false;
989             ins->prefixes[PPS_OSIZE] = pfx;
990         }
991     }
992     if (!a_used && asize != segsize) {
993         if (ins->prefixes[PPS_ASIZE])
994             return false;
995         ins->prefixes[PPS_ASIZE] = asize == 16 ? P_A16 : P_A32;
996     }
997
998     /* Fix: check for redundant REX prefixes */
999
1000     return data - origdata;
1001 }
1002
1003 /* Condition names for disassembly, sorted by x86 code */
1004 static const char * const condition_name[16] = {
1005     "o", "no", "c", "nc", "z", "nz", "na", "a",
1006     "s", "ns", "pe", "po", "l", "nl", "ng", "g"
1007 };
1008
1009 int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
1010             int32_t offset, int autosync, uint32_t prefer)
1011 {
1012     const struct itemplate * const *p, * const *best_p;
1013     const struct disasm_index *ix;
1014     uint8_t *dp;
1015     int length, best_length = 0;
1016     char *segover;
1017     int i, slen, colon, n;
1018     uint8_t *origdata;
1019     int works;
1020     insn tmp_ins, ins;
1021     uint32_t goodness, best;
1022     int best_pref;
1023     struct prefix_info prefix;
1024     bool end_prefix;
1025
1026     memset(&ins, 0, sizeof ins);
1027
1028     /*
1029      * Scan for prefixes.
1030      */
1031     memset(&prefix, 0, sizeof prefix);
1032     prefix.asize = segsize;
1033     prefix.osize = (segsize == 64) ? 32 : segsize;
1034     segover = NULL;
1035     origdata = data;
1036
1037     ix = itable;
1038
1039     end_prefix = false;
1040     while (!end_prefix) {
1041         switch (*data) {
1042         case 0xF2:
1043         case 0xF3:
1044             prefix.rep = *data++;
1045             break;
1046
1047         case 0x9B:
1048             prefix.wait = *data++;
1049             break;
1050
1051         case 0xF0:
1052             prefix.lock = *data++;
1053             break;
1054
1055         case 0x2E:
1056             segover = "cs", prefix.seg = *data++;
1057             break;
1058         case 0x36:
1059             segover = "ss", prefix.seg = *data++;
1060             break;
1061         case 0x3E:
1062             segover = "ds", prefix.seg = *data++;
1063             break;
1064         case 0x26:
1065             segover = "es", prefix.seg = *data++;
1066             break;
1067         case 0x64:
1068             segover = "fs", prefix.seg = *data++;
1069             break;
1070         case 0x65:
1071             segover = "gs", prefix.seg = *data++;
1072             break;
1073
1074         case 0x66:
1075             prefix.osize = (segsize == 16) ? 32 : 16;
1076             prefix.osp = *data++;
1077             break;
1078         case 0x67:
1079             prefix.asize = (segsize == 32) ? 16 : 32;
1080             prefix.asp = *data++;
1081             break;
1082
1083         case 0xC4:
1084         case 0xC5:
1085             if (segsize == 64 || (data[1] & 0xc0) == 0xc0) {
1086                 prefix.vex[0] = *data++;
1087                 prefix.vex[1] = *data++;
1088
1089                 prefix.rex = REX_V;
1090                 prefix.vex_c = RV_VEX;
1091
1092                 if (prefix.vex[0] == 0xc4) {
1093                     prefix.vex[2] = *data++;
1094                     prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */
1095                     prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W;
1096                     prefix.vex_m = prefix.vex[1] & 0x1f;
1097                     prefix.vex_v = (~prefix.vex[2] >> 3) & 15;
1098                     prefix.vex_lp = prefix.vex[2] & 7;
1099                 } else {
1100                     prefix.rex |= (~prefix.vex[1] >> (7-2)) & REX_R;
1101                     prefix.vex_m = 1;
1102                     prefix.vex_v = (~prefix.vex[1] >> 3) & 15;
1103                     prefix.vex_lp = prefix.vex[1] & 7;
1104                 }
1105
1106                 ix = itable_vex[RV_VEX][prefix.vex_m][prefix.vex_lp & 3];
1107             }
1108             end_prefix = true;
1109             break;
1110
1111         case 0x8F:
1112             if ((data[1] & 030) != 0 &&
1113                 (segsize == 64 || (data[1] & 0xc0) == 0xc0)) {
1114                 prefix.vex[0] = *data++;
1115                 prefix.vex[1] = *data++;
1116                 prefix.vex[2] = *data++;
1117
1118                 prefix.rex = REX_V;
1119                 prefix.vex_c = RV_XOP;
1120
1121                 prefix.rex |= (~prefix.vex[1] >> 5) & 7; /* REX_RXB */
1122                 prefix.rex |= (prefix.vex[2] >> (7-3)) & REX_W;
1123                 prefix.vex_m = prefix.vex[1] & 0x1f;
1124                 prefix.vex_v = (~prefix.vex[2] >> 3) & 15;
1125                 prefix.vex_lp = prefix.vex[2] & 7;
1126
1127                 ix = itable_vex[RV_XOP][prefix.vex_m][prefix.vex_lp & 3];
1128             }
1129             end_prefix = true;
1130             break;
1131
1132         case REX_P + 0x0:
1133         case REX_P + 0x1:
1134         case REX_P + 0x2:
1135         case REX_P + 0x3:
1136         case REX_P + 0x4:
1137         case REX_P + 0x5:
1138         case REX_P + 0x6:
1139         case REX_P + 0x7:
1140         case REX_P + 0x8:
1141         case REX_P + 0x9:
1142         case REX_P + 0xA:
1143         case REX_P + 0xB:
1144         case REX_P + 0xC:
1145         case REX_P + 0xD:
1146         case REX_P + 0xE:
1147         case REX_P + 0xF:
1148             if (segsize == 64) {
1149                 prefix.rex = *data++;
1150                 if (prefix.rex & REX_W)
1151                     prefix.osize = 64;
1152             }
1153             end_prefix = true;
1154             break;
1155
1156         default:
1157             end_prefix = true;
1158             break;
1159         }
1160     }
1161
1162     best = -1;                  /* Worst possible */
1163     best_p = NULL;
1164     best_pref = INT_MAX;
1165
1166     if (!ix)
1167         return 0;               /* No instruction table at all... */
1168
1169     dp = data;
1170     ix += *dp++;
1171     while (ix->n == -1) {
1172         ix = (const struct disasm_index *)ix->p + *dp++;
1173     }
1174
1175     p = (const struct itemplate * const *)ix->p;
1176     for (n = ix->n; n; n--, p++) {
1177         if ((length = matches(*p, data, &prefix, segsize, &tmp_ins))) {
1178             works = true;
1179             /*
1180              * Final check to make sure the types of r/m match up.
1181              * XXX: Need to make sure this is actually correct.
1182              */
1183             for (i = 0; i < (*p)->operands; i++) {
1184                 if (!((*p)->opd[i] & SAME_AS) &&
1185                     (
1186                         /* If it's a mem-only EA but we have a
1187                            register, die. */
1188                         ((tmp_ins.oprs[i].segment & SEG_RMREG) &&
1189                          is_class(MEMORY, (*p)->opd[i])) ||
1190                         /* If it's a reg-only EA but we have a memory
1191                            ref, die. */
1192                         (!(tmp_ins.oprs[i].segment & SEG_RMREG) &&
1193                          !(REG_EA & ~(*p)->opd[i]) &&
1194                          !((*p)->opd[i] & REG_SMASK)) ||
1195                         /* Register type mismatch (eg FS vs REG_DESS):
1196                            die. */
1197                         ((((*p)->opd[i] & (REGISTER | FPUREG)) ||
1198                           (tmp_ins.oprs[i].segment & SEG_RMREG)) &&
1199                          !whichreg((*p)->opd[i],
1200                                    tmp_ins.oprs[i].basereg, tmp_ins.rex))
1201                         )) {
1202                     works = false;
1203                     break;
1204                 }
1205             }
1206
1207             /*
1208              * Note: we always prefer instructions which incorporate
1209              * prefixes in the instructions themselves.  This is to allow
1210              * e.g. PAUSE to be preferred to REP NOP, and deal with
1211              * MMX/SSE instructions where prefixes are used to select
1212              * between MMX and SSE register sets or outright opcode
1213              * selection.
1214              */
1215             if (works) {
1216                 int i, nprefix;
1217                 goodness = ((*p)->flags & IF_PFMASK) ^ prefer;
1218                 nprefix = 0;
1219                 for (i = 0; i < MAXPREFIX; i++)
1220                     if (tmp_ins.prefixes[i])
1221                         nprefix++;
1222                 if (nprefix < best_pref ||
1223                     (nprefix == best_pref && goodness < best)) {
1224                     /* This is the best one found so far */
1225                     best = goodness;
1226                     best_p = p;
1227                     best_pref = nprefix;
1228                     best_length = length;
1229                     ins = tmp_ins;
1230                 }
1231             }
1232         }
1233     }
1234
1235     if (!best_p)
1236         return 0;               /* no instruction was matched */
1237
1238     /* Pick the best match */
1239     p = best_p;
1240     length = best_length;
1241
1242     slen = 0;
1243
1244     /* TODO: snprintf returns the value that the string would have if
1245      *      the buffer were long enough, and not the actual length of
1246      *      the returned string, so each instance of using the return
1247      *      value of snprintf should actually be checked to assure that
1248      *      the return value is "sane."  Maybe a macro wrapper could
1249      *      be used for that purpose.
1250      */
1251     for (i = 0; i < MAXPREFIX; i++) {
1252         const char *prefix = prefix_name(ins.prefixes[i]);
1253         if (prefix)
1254             slen += snprintf(output+slen, outbufsize-slen, "%s ", prefix);
1255     }
1256
1257     i = (*p)->opcode;
1258     if (i >= FIRST_COND_OPCODE)
1259         slen += snprintf(output + slen, outbufsize - slen, "%s%s",
1260                          nasm_insn_names[i], condition_name[ins.condition]);
1261     else
1262         slen += snprintf(output + slen, outbufsize - slen, "%s",
1263                          nasm_insn_names[i]);
1264
1265     colon = false;
1266     length += data - origdata;  /* fix up for prefixes */
1267     for (i = 0; i < (*p)->operands; i++) {
1268         opflags_t t = (*p)->opd[i];
1269         const operand *o = &ins.oprs[i];
1270         int64_t offs;
1271
1272         if (t & SAME_AS) {
1273             o = &ins.oprs[t & ~SAME_AS];
1274             t = (*p)->opd[t & ~SAME_AS];
1275         }
1276
1277         output[slen++] = (colon ? ':' : i == 0 ? ' ' : ',');
1278
1279         offs = o->offset;
1280         if (o->segment & SEG_RELATIVE) {
1281             offs += offset + length;
1282             /*
1283              * sort out wraparound
1284              */
1285             if (!(o->segment & (SEG_32BIT|SEG_64BIT)))
1286                 offs &= 0xffff;
1287             else if (segsize != 64)
1288                 offs &= 0xffffffff;
1289
1290             /*
1291              * add sync marker, if autosync is on
1292              */
1293             if (autosync)
1294                 add_sync(offs, 0L);
1295         }
1296
1297         if (t & COLON)
1298             colon = true;
1299         else
1300             colon = false;
1301
1302         if ((t & (REGISTER | FPUREG)) ||
1303             (o->segment & SEG_RMREG)) {
1304             enum reg_enum reg;
1305             reg = whichreg(t, o->basereg, ins.rex);
1306             if (t & TO)
1307                 slen += snprintf(output + slen, outbufsize - slen, "to ");
1308             slen += snprintf(output + slen, outbufsize - slen, "%s",
1309                              nasm_reg_names[reg-EXPR_REG_START]);
1310         } else if (!(UNITY & ~t)) {
1311             output[slen++] = '1';
1312         } else if (t & IMMEDIATE) {
1313             if (t & BITS8) {
1314                 slen +=
1315                     snprintf(output + slen, outbufsize - slen, "byte ");
1316                 if (o->segment & SEG_SIGNED) {
1317                     if (offs < 0) {
1318                         offs *= -1;
1319                         output[slen++] = '-';
1320                     } else
1321                         output[slen++] = '+';
1322                 }
1323             } else if (t & BITS16) {
1324                 slen +=
1325                     snprintf(output + slen, outbufsize - slen, "word ");
1326             } else if (t & BITS32) {
1327                 slen +=
1328                     snprintf(output + slen, outbufsize - slen, "dword ");
1329             } else if (t & BITS64) {
1330                 slen +=
1331                     snprintf(output + slen, outbufsize - slen, "qword ");
1332             } else if (t & NEAR) {
1333                 slen +=
1334                     snprintf(output + slen, outbufsize - slen, "near ");
1335             } else if (t & SHORT) {
1336                 slen +=
1337                     snprintf(output + slen, outbufsize - slen, "short ");
1338             }
1339             slen +=
1340                 snprintf(output + slen, outbufsize - slen, "0x%"PRIx64"",
1341                          offs);
1342         } else if (!(MEM_OFFS & ~t)) {
1343             slen +=
1344                 snprintf(output + slen, outbufsize - slen,
1345                          "[%s%s%s0x%"PRIx64"]",
1346                          (segover ? segover : ""),
1347                          (segover ? ":" : ""),
1348                          (o->disp_size == 64 ? "qword " :
1349                           o->disp_size == 32 ? "dword " :
1350                           o->disp_size == 16 ? "word " : ""), offs);
1351             segover = NULL;
1352         } else if (is_class(REGMEM, t)) {
1353             int started = false;
1354             if (t & BITS8)
1355                 slen +=
1356                     snprintf(output + slen, outbufsize - slen, "byte ");
1357             if (t & BITS16)
1358                 slen +=
1359                     snprintf(output + slen, outbufsize - slen, "word ");
1360             if (t & BITS32)
1361                 slen +=
1362                     snprintf(output + slen, outbufsize - slen, "dword ");
1363             if (t & BITS64)
1364                 slen +=
1365                     snprintf(output + slen, outbufsize - slen, "qword ");
1366             if (t & BITS80)
1367                 slen +=
1368                     snprintf(output + slen, outbufsize - slen, "tword ");
1369             if (t & BITS128)
1370                 slen +=
1371                     snprintf(output + slen, outbufsize - slen, "oword ");
1372             if (t & BITS256)
1373                 slen +=
1374                     snprintf(output + slen, outbufsize - slen, "yword ");
1375             if (t & FAR)
1376                 slen += snprintf(output + slen, outbufsize - slen, "far ");
1377             if (t & NEAR)
1378                 slen +=
1379                     snprintf(output + slen, outbufsize - slen, "near ");
1380             output[slen++] = '[';
1381             if (o->disp_size)
1382                 slen += snprintf(output + slen, outbufsize - slen, "%s",
1383                                  (o->disp_size == 64 ? "qword " :
1384                                   o->disp_size == 32 ? "dword " :
1385                                   o->disp_size == 16 ? "word " :
1386                                   ""));
1387             if (o->eaflags & EAF_REL)
1388                 slen += snprintf(output + slen, outbufsize - slen, "rel ");
1389             if (segover) {
1390                 slen +=
1391                     snprintf(output + slen, outbufsize - slen, "%s:",
1392                              segover);
1393                 segover = NULL;
1394             }
1395             if (o->basereg != -1) {
1396                 slen += snprintf(output + slen, outbufsize - slen, "%s",
1397                                  nasm_reg_names[(o->basereg-EXPR_REG_START)]);
1398                 started = true;
1399             }
1400             if (o->indexreg != -1) {
1401                 if (started)
1402                     output[slen++] = '+';
1403                 slen += snprintf(output + slen, outbufsize - slen, "%s",
1404                                  nasm_reg_names[(o->indexreg-EXPR_REG_START)]);
1405                 if (o->scale > 1)
1406                     slen +=
1407                         snprintf(output + slen, outbufsize - slen, "*%d",
1408                                  o->scale);
1409                 started = true;
1410             }
1411
1412
1413             if (o->segment & SEG_DISP8) {
1414                 const char *prefix;
1415                 uint8_t offset = offs;
1416                 if ((int8_t)offset < 0) {
1417                     prefix = "-";
1418                     offset = -offset;
1419                 } else {
1420                     prefix = "+";
1421                 }
1422                 slen +=
1423                     snprintf(output + slen, outbufsize - slen, "%s0x%"PRIx8"",
1424                              prefix, offset);
1425             } else if (o->segment & SEG_DISP16) {
1426                 const char *prefix;
1427                 uint16_t offset = offs;
1428                 if ((int16_t)offset < 0 && started) {
1429                     offset = -offset;
1430                     prefix = "-";
1431                 } else {
1432                     prefix = started ? "+" : "";
1433                 }
1434                 slen +=
1435                     snprintf(output + slen, outbufsize - slen,
1436                              "%s0x%"PRIx16"", prefix, offset);
1437             } else if (o->segment & SEG_DISP32) {
1438                 if (prefix.asize == 64) {
1439                     const char *prefix;
1440                     uint64_t offset = (int64_t)(int32_t)offs;
1441                     if ((int32_t)offs < 0 && started) {
1442                         offset = -offset;
1443                         prefix = "-";
1444                     } else {
1445                         prefix = started ? "+" : "";
1446                     }
1447                     slen +=
1448                         snprintf(output + slen, outbufsize - slen,
1449                                  "%s0x%"PRIx64"", prefix, offset);
1450                 } else {
1451                     const char *prefix;
1452                     uint32_t offset = offs;
1453                     if ((int32_t) offset < 0 && started) {
1454                         offset = -offset;
1455                         prefix = "-";
1456                     } else {
1457                         prefix = started ? "+" : "";
1458                     }
1459                     slen +=
1460                         snprintf(output + slen, outbufsize - slen,
1461                                  "%s0x%"PRIx32"", prefix, offset);
1462                 }
1463             }
1464             output[slen++] = ']';
1465         } else {
1466             slen +=
1467                 snprintf(output + slen, outbufsize - slen, "<operand%d>",
1468                          i);
1469         }
1470     }
1471     output[slen] = '\0';
1472     if (segover) {              /* unused segment override */
1473         char *p = output;
1474         int count = slen + 1;
1475         while (count--)
1476             p[count + 3] = p[count];
1477         strncpy(output, segover, 2);
1478         output[2] = ' ';
1479     }
1480     return length;
1481 }
1482
1483 /*
1484  * This is called when we don't have a complete instruction.  If it
1485  * is a standalone *single-byte* prefix show it as such, otherwise
1486  * print it as a literal.
1487  */
1488 int32_t eatbyte(uint8_t *data, char *output, int outbufsize, int segsize)
1489 {
1490     uint8_t byte = *data;
1491     const char *str = NULL;
1492     
1493     switch (byte) {
1494     case 0xF2:
1495         str = "repne";
1496         break;
1497     case 0xF3:
1498         str = "rep";
1499         break;
1500     case 0x9B:
1501         str = "wait";
1502         break;
1503     case 0xF0:
1504         str = "lock";
1505         break;
1506     case 0x2E:
1507         str = "cs";
1508         break;
1509     case 0x36:
1510         str = "ss";
1511         break;
1512     case 0x3E:
1513         str = "ss";
1514         break;
1515     case 0x26:
1516         str = "es";
1517         break;
1518     case 0x64:
1519         str = "fs";
1520         break;
1521     case 0x65:
1522         str = "gs";
1523         break;
1524     case 0x66:
1525         str = (segsize == 16) ? "o32" : "o16";
1526         break;
1527     case 0x67:
1528         str = (segsize == 32) ? "a16" : "a32";
1529         break;
1530     case REX_P + 0x0:
1531     case REX_P + 0x1:
1532     case REX_P + 0x2:
1533     case REX_P + 0x3:
1534     case REX_P + 0x4:
1535     case REX_P + 0x5:
1536     case REX_P + 0x6:
1537     case REX_P + 0x7:
1538     case REX_P + 0x8:
1539     case REX_P + 0x9:
1540     case REX_P + 0xA:
1541     case REX_P + 0xB:
1542     case REX_P + 0xC:
1543     case REX_P + 0xD:
1544     case REX_P + 0xE:
1545     case REX_P + 0xF:
1546         if (segsize == 64) {
1547             snprintf(output, outbufsize, "rex%s%s%s%s%s",
1548                      (byte == REX_P) ? "" : ".",
1549                      (byte & REX_W) ? "w" : "",
1550                      (byte & REX_R) ? "r" : "",
1551                      (byte & REX_X) ? "x" : "",
1552                      (byte & REX_B) ? "b" : "");
1553             break;
1554         }
1555         /* else fall through */
1556     default:
1557         snprintf(output, outbufsize, "db 0x%02x", byte);
1558         break;
1559     }
1560
1561     if (str)
1562         snprintf(output, outbufsize, "%s", str);
1563
1564     return 1;
1565 }