Print this page
3317 dis(1) should support cross-target disassembly

*** 22,31 **** --- 22,32 ---- /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2011 Jason King. All rights reserved. + * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> */ #include <ctype.h> #include <getopt.h> #include <stdio.h>
*** 95,104 **** --- 96,121 ---- (void) snprintf(buf, buflen, "%s+0x%x", symbol, offset); } } /* + * Determine if we are on an architecture with fixed-size instructions, + * and if so, what size they are. + */ + static int + insn_size(dis_handle_t *dhp) + { + int min = dis_min_instrlen(dhp); + int max = dis_max_instrlen(dhp); + + if (min == max) + return (min); + + return (0); + } + + /* * The main disassembly routine. Given a fixed-sized buffer and starting * address, disassemble the data using the supplied target and libdisasm handle. */ void dis_data(dis_tgt_t *tgt, dis_handle_t *dhp, uint64_t addr, void *data,
*** 113,122 **** --- 130,141 ---- int i; int bytesperline; size_t symsize; int isfunc; size_t symwidth = 0; + int ret; + int insz = insn_size(dhp); db.db_tgt = tgt; db.db_data = data; db.db_addr = addr; db.db_size = datalen;
*** 128,148 **** symbol = NULL; while (addr < db.db_addr + db.db_size) { ! if (dis_disassemble(dhp, addr, buf, BUFSIZE) != 0) { ! #if defined(__sparc) /* ! * Since sparc instructions are fixed size, we * always know the address of the next instruction */ (void) snprintf(buf, sizeof (buf), "*** invalid opcode ***"); ! db.db_nextaddr = addr + 4; ! #else off_t next; (void) snprintf(buf, sizeof (buf), "*** invalid opcode ***"); --- 147,167 ---- symbol = NULL; while (addr < db.db_addr + db.db_size) { ! ret = dis_disassemble(dhp, addr, buf, BUFSIZE); ! if (ret != 0 && insz > 0) { /* ! * Since we know instructions are fixed size, we * always know the address of the next instruction */ (void) snprintf(buf, sizeof (buf), "*** invalid opcode ***"); ! db.db_nextaddr = addr + insz; ! } else if (ret != 0) { off_t next; (void) snprintf(buf, sizeof (buf), "*** invalid opcode ***");
*** 161,171 **** db.db_nextaddr = db.db_addr + db.db_size; else db.db_nextaddr = addr + next; } - #endif } /* * Print out the line as: * --- 180,189 ----
*** 480,490 **** * we should be able to disassemble targets from different * architectures. For now, we only support objects as the * native machine type. */ switch (ehdr.e_machine) { - #ifdef __sparc case EM_SPARC: if (ehdr.e_ident[EI_CLASS] != ELFCLASS32 || ehdr.e_ident[EI_DATA] != ELFDATA2MSB) { warn("invalid E_IDENT field for SPARC object"); return; --- 498,507 ----
*** 518,538 **** return; } g_flags |= DIS_SPARC_V9 | DIS_SPARC_V9_SGI; break; - #endif /* __sparc */ - #if defined(__i386) || defined(__amd64) case EM_386: g_flags |= DIS_X86_SIZE32; break; case EM_AMD64: g_flags |= DIS_X86_SIZE64; break; - #endif /* __i386 || __amd64 */ default: die("%s: unsupported ELF machine 0x%x", filename, ehdr.e_machine); } --- 535,552 ----