1 /*  $NetBSD: db_disasm.c,v 1.19 2007/02/28 04:21:53 thorpej Exp $   */
2 
3 /*-
4  * Copyright (c) 1991, 1993
5  *  The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Ralph Campbell.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *  from: @(#)kadb.c    8.1 (Berkeley) 6/10/93
35  */
36 
37 #include <stdio.h>
38 #include <stdint.h>
39 #include <stdarg.h>
40 #include <stdbool.h>
41 #include <sys/cdefs.h>
42 
43 #include <sys/types.h>
44 #include "mips_opcode.h"
45 
46 
47 // #include <sys/systm.h>
48 // #include <sys/param.h>
49 
50 // #include <machine/reg.h>
51 // #include <machine/cpu.h>
52 /*#include <machine/param.h>*/
53 // #include <machine/db_machdep.h>
54 
55 // #include <ddb/db_interface.h>
56 // #include <ddb/db_output.h>
57 // #include <ddb/db_extern.h>
58 // #include <ddb/db_sym.h>
59 
60 #define __unused __attribute__((__unused__))
61 
62 static char *sprintf_buffer;
63 static int sprintf_buf_len;
64 
65 
66 typedef uint32_t db_addr_t;
67 static void db_printf(const char* fmt, ...);
68 
69 static const char * const op_name[64] = {
70 /* 0 */ "spec", "bcond","j  ",    "jal",  "beq",  "bne",  "blez", "bgtz",
71 /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori",  "xori", "lui",
72 /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
73 /*24 */ "daddi","daddiu","ldl", "ldr",  "op34", "op35", "op36", "op37",
74 /*32 */ "lb ",   "lh ",   "lwl",  "lw ",   "lbu",  "lhu",  "lwr",  "lwu",
75 /*40 */ "sb ",   "sh ",   "swl",  "sw ",   "sdl",  "sdr",  "swr",  "cache",
76 /*48 */ "ll ",   "lwc1", "lwc2", "lwc3", "lld",  "ldc1", "ldc2", "ld ",
77 /*56 */ "sc ",   "swc1", "swc2", "swc3", "scd",  "sdc1", "sdc2", "sd "
78 };
79 
80 static const char * const spec_name[64] = {
81 /* 0 */ "sll",  "spec01","srl", "sra",  "sllv", "spec05","srlv","srav",
82 /* 8 */ "jr",   "jalr", "movz","movn","syscall","break","spec16","sync",
83 /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
84 /*24 */ "mult", "multu","div",  "divu", "dmult","dmultu","ddiv","ddivu",
85 /*32 */ "add",  "addu", "sub",  "subu", "and",  "or ",   "xor",  "nor",
86 /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
87 /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
88 /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
89 };
90 
91 static const char * const spec2_name[64] = {     /* QED RM4650, R5000, etc. */
92 /* 0x00 */ "madd", "maddu", "mul", "spec3", "msub", "msubu", "rsrv6", "rsrv7",
93 /* 0x08 */ "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv",
94 /* 0x10 */ "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv",
95 /* 0x18 */ "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv",
96 /* 0x20 */ "clz",  "clo",  "rsrv", "rsrv", "dclz", "dclo", "rsrv", "rsrv",
97 /* 0x28 */ "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv",
98 /* 0x30 */ "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv", "rsrv",
99 /* 0x38 */ "rsrv", "rsrv", "rsrv", "resv", "rsrv", "rsrv", "rsrv", "sdbbp"
100 };
101 
102 static const char * const bcond_name[32] = {
103 /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
104 /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
105 /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
106 /*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
107 };
108 
109 static const char * const cop1_name[64] = {
110 /* 0 */ "fadd",  "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
111 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
112 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
113 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
114 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
115 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
116 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
117     "fcmp.ole","fcmp.ule",
118 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
119     "fcmp.le","fcmp.ngt"
120 };
121 
122 static const char * const fmt_name[16] = {
123     "s",    "d",    "e",    "fmt3",
124     "w",    "fmt5", "fmt6", "fmt7",
125     "fmt8", "fmt9", "fmta", "fmtb",
126     "fmtc", "fmtd", "fmte", "fmtf"
127 };
128 
129 #if defined(__mips_n32) || defined(__mips_n64)
130 static char * const reg_name[32] = {
131     "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
132     "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
133     "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
134     "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
135 };
136 #else
137 
138 static char * alt_arm_reg_name[32] = {  // hacked names for comparison with ARM code
139     "zero", "at",   "r0",   "r1",   "r2",   "r3",   "r4",   "r5",
140     "r6",   "r7",   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",
141     "r14",  "r15",  "at2",  "cmp",  "s4",   "s5",   "s6",   "s7",
142     "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
143 };
144 
145 static char * mips_reg_name[32] = {
146     "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
147     "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
148     "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
149     "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
150 };
151 
152 static char ** reg_name =  &mips_reg_name[0];
153 
154 #endif /* __mips_n32 || __mips_n64 */
155 
156 static const char * const c0_opname[64] = {
157     "c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
158     "tlbp",  "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
159     "rfe",   "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
160     "eret",  "c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
161     "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
162     "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
163     "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
164     "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
165 };
166 
167 static const char * const c0_reg[32] = {
168     "index",    "random",   "tlblo0",  "tlblo1",
169     "context",  "pagemask", "wired",   "cp0r7",
170     "badvaddr", "count",    "tlbhi",   "compare",
171     "status",   "cause",    "epc",     "prid",
172     "config",   "lladdr",   "watchlo", "watchhi",
173     "xcontext", "cp0r21",   "cp0r22",  "debug",
174     "depc",     "perfcnt",  "ecc",     "cacheerr",
175     "taglo",    "taghi",    "errepc",  "desave"
176 };
177 
178 static void print_addr(db_addr_t);
179 db_addr_t mips_disassem(db_addr_t loc, char *di_buffer, int alt_dis_format);
180 
181 
182 /*
183  * Disassemble instruction 'insn' nominally at 'loc'.
184  * 'loc' may in fact contain a breakpoint instruction.
185  */
186 static db_addr_t
db_disasm_insn(int insn,db_addr_t loc,bool altfmt __unused)187 db_disasm_insn(int insn, db_addr_t loc, bool altfmt __unused)
188 {
189     bool bdslot = false;
190     InstFmt i;
191 
192     i.word = insn;
193 
194     switch (i.JType.op) {
195     case OP_SPECIAL:
196         if (i.word == 0) {
197             db_printf("nop");
198             break;
199         }
200         if (i.word == 0x0080) {
201             db_printf("NIY");
202             break;
203         }
204         if (i.word == 0x00c0) {
205             db_printf("NOT IMPL");
206             break;
207         }
208         /* Special cases --------------------------------------------------
209          * "addu" is a "move" only in 32-bit mode.  What's the correct
210          * answer - never decode addu/daddu as "move"?
211          */
212         if ( (i.RType.func == OP_ADDU && i.RType.rt == 0)  ||
213              (i.RType.func == OP_OR   && i.RType.rt == 0) ) {
214             db_printf("move\t%s,%s",
215                 reg_name[i.RType.rd],
216                 reg_name[i.RType.rs]);
217             break;
218         }
219         // mips32r2, rotr & rotrv
220         if (i.RType.func == OP_SRL && (i.RType.rs & 1) == 1) {
221             db_printf("rotr\t%s,%s,%d", reg_name[i.RType.rd],
222                 reg_name[i.RType.rt], i.RType.shamt);
223             break;
224         }
225         if (i.RType.func == OP_SRLV && (i.RType.shamt & 1) == 1) {
226             db_printf("rotrv\t%s,%s,%s", reg_name[i.RType.rd],
227                 reg_name[i.RType.rt], reg_name[i.RType.rs]);
228             break;
229         }
230 
231 
232         db_printf("%s", spec_name[i.RType.func]);
233         switch (i.RType.func) {
234         case OP_SLL:
235         case OP_SRL:
236         case OP_SRA:
237         case OP_DSLL:
238 
239         case OP_DSRL:
240         case OP_DSRA:
241         case OP_DSLL32:
242         case OP_DSRL32:
243         case OP_DSRA32:
244             db_printf("\t%s,%s,%d",
245                 reg_name[i.RType.rd],
246                 reg_name[i.RType.rt],
247                 i.RType.shamt);
248             break;
249 
250         case OP_SLLV:
251         case OP_SRLV:
252         case OP_SRAV:
253         case OP_DSLLV:
254         case OP_DSRLV:
255         case OP_DSRAV:
256             db_printf("\t%s,%s,%s",
257                 reg_name[i.RType.rd],
258                 reg_name[i.RType.rt],
259                 reg_name[i.RType.rs]);
260             break;
261 
262         case OP_MFHI:
263         case OP_MFLO:
264             db_printf("\t%s", reg_name[i.RType.rd]);
265             break;
266 
267         case OP_JR:
268         case OP_JALR:
269             db_printf("\t%s", reg_name[i.RType.rs]);
270             bdslot = true;
271             break;
272         case OP_MTLO:
273         case OP_MTHI:
274             db_printf("\t%s", reg_name[i.RType.rs]);
275             break;
276 
277         case OP_MULT:
278         case OP_MULTU:
279         case OP_DMULT:
280         case OP_DMULTU:
281         case OP_DIV:
282         case OP_DIVU:
283         case OP_DDIV:
284         case OP_DDIVU:
285             db_printf("\t%s,%s",
286                 reg_name[i.RType.rs],
287                 reg_name[i.RType.rt]);
288             break;
289 
290 
291         case OP_SYSCALL:
292         case OP_SYNC:
293             break;
294 
295         case OP_BREAK:
296             db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
297             break;
298 
299         default:
300             db_printf("\t%s,%s,%s",
301                 reg_name[i.RType.rd],
302                 reg_name[i.RType.rs],
303                 reg_name[i.RType.rt]);
304         }
305         break;
306 
307     case OP_SPECIAL2:
308         if (i.RType.func == OP_MUL)
309             db_printf("%s\t%s,%s,%s",
310                 spec2_name[i.RType.func & 0x3f],
311                     reg_name[i.RType.rd],
312                     reg_name[i.RType.rs],
313                     reg_name[i.RType.rt]);
314         else
315             db_printf("%s\t%s,%s",
316                 spec2_name[i.RType.func & 0x3f],
317                     reg_name[i.RType.rs],
318                     reg_name[i.RType.rt]);
319 
320         break;
321 
322     case OP_SPECIAL3:
323         if (i.RType.func == OP_EXT)
324             db_printf("ext\t%s,%s,%d,%d",
325                     reg_name[i.RType.rt],
326                     reg_name[i.RType.rs],
327                     i.RType.shamt,
328                     i.RType.rd+1);
329         else if (i.RType.func == OP_INS)
330             db_printf("ins\t%s,%s,%d,%d",
331                     reg_name[i.RType.rt],
332                     reg_name[i.RType.rs],
333                     i.RType.shamt,
334                     i.RType.rd-i.RType.shamt+1);
335         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_WSBH)
336             db_printf("wsbh\t%s,%s",
337                 reg_name[i.RType.rd],
338                 reg_name[i.RType.rt]);
339         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_SEB)
340             db_printf("seb\t%s,%s",
341                 reg_name[i.RType.rd],
342                 reg_name[i.RType.rt]);
343         else if (i.RType.func == OP_BSHFL && i.RType.shamt == OP_SEH)
344             db_printf("seh\t%s,%s",
345                 reg_name[i.RType.rd],
346                 reg_name[i.RType.rt]);
347         else
348             db_printf("Unknown");
349         break;
350 
351     case OP_BCOND:
352         db_printf("%s\t%s,", bcond_name[i.IType.rt],
353             reg_name[i.IType.rs]);
354         goto pr_displ;
355 
356     case OP_BLEZ:
357     case OP_BLEZL:
358     case OP_BGTZ:
359     case OP_BGTZL:
360         db_printf("%s\t%s,", op_name[i.IType.op],
361             reg_name[i.IType.rs]);
362         goto pr_displ;
363 
364     case OP_BEQ:
365     case OP_BEQL:
366         if (i.IType.rs == 0 && i.IType.rt == 0) {
367             db_printf("b  \t");
368             goto pr_displ;
369         }
370         /* FALLTHROUGH */
371     case OP_BNE:
372     case OP_BNEL:
373         db_printf("%s\t%s,%s,", op_name[i.IType.op],
374             reg_name[i.IType.rs],
375             reg_name[i.IType.rt]);
376     pr_displ:
377         print_addr(loc + 4 + ((short)i.IType.imm << 2));
378         bdslot = true;
379         break;
380 
381     case OP_COP0:
382         switch (i.RType.rs) {
383         case OP_BCx:
384         case OP_BCy:
385 
386             db_printf("bc0%c\t",
387                 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
388             goto pr_displ;
389 
390         case OP_MT:
391             db_printf("mtc0\t%s,%s",
392                 reg_name[i.RType.rt],
393                 c0_reg[i.RType.rd]);
394             break;
395 
396         case OP_DMT:
397             db_printf("dmtc0\t%s,%s",
398                 reg_name[i.RType.rt],
399                 c0_reg[i.RType.rd]);
400             break;
401 
402         case OP_MF:
403             db_printf("mfc0\t%s,%s",
404                 reg_name[i.RType.rt],
405                 c0_reg[i.RType.rd]);
406             break;
407 
408         case OP_DMF:
409             db_printf("dmfc0\t%s,%s",
410                 reg_name[i.RType.rt],
411                 c0_reg[i.RType.rd]);
412             break;
413 
414         default:
415             db_printf("%s", c0_opname[i.FRType.func]);
416         }
417         break;
418 
419     case OP_COP1:
420         switch (i.RType.rs) {
421         case OP_BCx:
422         case OP_BCy:
423             db_printf("bc1%c\t",
424                 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
425             goto pr_displ;
426 
427         case OP_MT:
428             db_printf("mtc1\t%s,f%d",
429                 reg_name[i.RType.rt],
430                 i.RType.rd);
431             break;
432 
433         case OP_MF:
434             db_printf("mfc1\t%s,f%d",
435                 reg_name[i.RType.rt],
436                 i.RType.rd);
437             break;
438 
439         case OP_CT:
440             db_printf("ctc1\t%s,f%d",
441                 reg_name[i.RType.rt],
442                 i.RType.rd);
443             break;
444 
445         case OP_CF:
446             db_printf("cfc1\t%s,f%d",
447                 reg_name[i.RType.rt],
448                 i.RType.rd);
449             break;
450 
451         default:
452             db_printf("%s.%s\tf%d,f%d,f%d",
453                 cop1_name[i.FRType.func],
454                 fmt_name[i.FRType.fmt],
455                 i.FRType.fd, i.FRType.fs, i.FRType.ft);
456         }
457         break;
458 
459     case OP_J:
460     case OP_JAL:
461         db_printf("%s\t", op_name[i.JType.op]);
462         print_addr((loc & 0xF0000000) | (i.JType.target << 2));
463         bdslot = true;
464         break;
465 
466     case OP_LWC1:
467     case OP_SWC1:
468         db_printf("%s\tf%d,", op_name[i.IType.op],
469             i.IType.rt);
470         goto loadstore;
471 
472     case OP_LB:
473     case OP_LH:
474     case OP_LW:
475     case OP_LD:
476     case OP_LBU:
477     case OP_LHU:
478     case OP_LWU:
479     case OP_SB:
480     case OP_SH:
481     case OP_SW:
482     case OP_SD:
483         db_printf("%s\t%s,", op_name[i.IType.op],
484             reg_name[i.IType.rt]);
485     loadstore:
486         db_printf("%d(%s)", (short)i.IType.imm,
487             reg_name[i.IType.rs]);
488         break;
489 
490     case OP_ORI:
491     case OP_XORI:
492         if (i.IType.rs == 0) {
493             db_printf("li\t%s,0x%x",
494                 reg_name[i.IType.rt],
495                 i.IType.imm);
496             break;
497         }
498         /* FALLTHROUGH */
499     case OP_ANDI:
500         db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
501             reg_name[i.IType.rt],
502             reg_name[i.IType.rs],
503             i.IType.imm);
504         break;
505 
506     case OP_LUI:
507         db_printf("%s\t%s,0x%x", op_name[i.IType.op],
508             reg_name[i.IType.rt],
509             i.IType.imm);
510         break;
511 
512     case OP_CACHE:
513         db_printf("%s\t0x%x,0x%x(%s)",
514             op_name[i.IType.op],
515             i.IType.rt,
516             i.IType.imm,
517             reg_name[i.IType.rs]);
518         break;
519 
520     case OP_ADDI:
521     case OP_DADDI:
522     case OP_ADDIU:
523     case OP_DADDIU:
524         if (i.IType.rs == 0) {
525             db_printf("li\t%s,%d",
526                 reg_name[i.IType.rt],
527                 (short)i.IType.imm);
528             break;
529         }
530         /* FALLTHROUGH */
531     default:
532         db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
533             reg_name[i.IType.rt],
534             reg_name[i.IType.rs],
535             (short)i.IType.imm);
536     }
537     // db_printf("\n");
538     // if (bdslot) {
539     //     db_printf("   bd: ");
540     //     mips_disassem(loc+4);
541     //     return (loc + 8);
542     // }
543     return (loc + 4);
544 }
545 
546 static void
print_addr(db_addr_t loc)547 print_addr(db_addr_t loc)
548 {
549     db_printf("0x%08x", loc);
550 }
551 
552 
553 
db_printf(const char * fmt,...)554 static void db_printf(const char* fmt, ...)
555 {
556     int cnt;
557     va_list argp;
558     va_start(argp, fmt);
559     if (sprintf_buffer) {
560         cnt = vsnprintf(sprintf_buffer, sprintf_buf_len, fmt, argp);
561         sprintf_buffer += cnt;
562         sprintf_buf_len -= cnt;
563     } else {
564         vprintf(fmt, argp);
565     }
566     va_end(argp);
567 }
568 
569 
570 /*
571  * Disassemble instruction at 'loc'.
572  * Return address of start of next instruction.
573  * Since this function is used by 'examine' and by 'step'
574  * "next instruction" does NOT mean the next instruction to
575  * be executed but the 'linear' next instruction.
576  */
577 db_addr_t
mips_disassem(db_addr_t loc,char * di_buffer,int alt_dis_format)578 mips_disassem(db_addr_t loc, char *di_buffer, int alt_dis_format)
579 {
580     u_int32_t instr;
581 
582     if (alt_dis_format) {   // use ARM register names for disassembly
583         reg_name = &alt_arm_reg_name[0];
584     }
585 
586     sprintf_buffer = di_buffer;     // quick 'n' dirty printf() vs sprintf()
587     sprintf_buf_len = 39;           // should be passed in
588 
589     instr =  *(u_int32_t *)loc;
590     return (db_disasm_insn(instr, loc, false));
591 }
592 
593