Print this page
style fixes
comments; lint
unbreak dis
move fixed-size determination mostly into libdisasm
take to dis and libdisasm with an axe; does not yet compile
@@ -22,10 +22,11 @@
/*
* 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,10 +96,26 @@
(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,10 +130,12 @@
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,21 +147,21 @@
symbol = NULL;
while (addr < db.db_addr + db.db_size) {
- if (dis_disassemble(dhp, addr, buf, BUFSIZE) != 0) {
-#if defined(__sparc)
+ ret = dis_disassemble(dhp, addr, buf, BUFSIZE);
+ if (ret != 0 && insz > 0) {
/*
- * Since sparc instructions are fixed size, we
+ * 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 + 4;
+ db.db_nextaddr = addr + insz;
-#else
+ } else if (ret != 0) {
off_t next;
(void) snprintf(buf, sizeof (buf),
"*** invalid opcode ***");
@@ -161,11 +180,10 @@
db.db_nextaddr = db.db_addr +
db.db_size;
else
db.db_nextaddr = addr + next;
}
-#endif
}
/*
* Print out the line as:
*
@@ -480,11 +498,10 @@
* 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;
@@ -518,21 +535,18 @@
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);
}