summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorJoshua M. Clulow <josh@sysmgr.org>2015-01-20 20:27:53 -0500
committerDan McDonald <danmcd@omniti.com>2015-01-23 22:17:34 -0500
commitf7184619589931c4b827180c213074c470f08a8f (patch)
treeb8594d45bca78fc4eddbc8a0d35061dc23e8ba8b /usr/src/cmd
parent22253b45e469decdb988b799c90598f2652597cd (diff)
downloadillumos-gate-f7184619589931c4b827180c213074c470f08a8f.tar.gz
3317 dis(1) should support cross-target disassembly
Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Joshua M. Clulow <josh@sysmgr.org> Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net> Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/dis/dis_main.c34
-rw-r--r--usr/src/cmd/dis/dis_target.c2
-rw-r--r--usr/src/cmd/dis/dis_target.h2
3 files changed, 24 insertions, 14 deletions
diff --git a/usr/src/cmd/dis/dis_main.c b/usr/src/cmd/dis/dis_main.c
index 2a01f92cf6..62a39de2bf 100644
--- a/usr/src/cmd/dis/dis_main.c
+++ b/usr/src/cmd/dis/dis_main.c
@@ -24,6 +24,7 @@
* Use is subject to license terms.
*
* Copyright 2011 Jason King. All rights reserved.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
*/
#include <ctype.h>
@@ -97,6 +98,22 @@ getsymname(uint64_t addr, const char *symbol, off_t offset, char *buf,
}
/*
+ * 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.
*/
@@ -115,6 +132,8 @@ dis_data(dis_tgt_t *tgt, dis_handle_t *dhp, uint64_t addr, void *data,
size_t symsize;
int isfunc;
size_t symwidth = 0;
+ int ret;
+ int insz = insn_size(dhp);
db.db_tgt = tgt;
db.db_data = data;
@@ -130,17 +149,17 @@ dis_data(dis_tgt_t *tgt, dis_handle_t *dhp, uint64_t addr, void *data,
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),
@@ -163,7 +182,6 @@ dis_data(dis_tgt_t *tgt, dis_handle_t *dhp, uint64_t addr, void *data,
else
db.db_nextaddr = addr + next;
}
-#endif
}
/*
@@ -482,7 +500,6 @@ dis_file(const char *filename)
* 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) {
@@ -520,9 +537,7 @@ dis_file(const char *filename)
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;
@@ -530,7 +545,6 @@ dis_file(const char *filename)
case EM_AMD64:
g_flags |= DIS_X86_SIZE64;
break;
-#endif /* __i386 || __amd64 */
default:
die("%s: unsupported ELF machine 0x%x", filename,
diff --git a/usr/src/cmd/dis/dis_target.c b/usr/src/cmd/dis/dis_target.c
index ec951665bc..37ab5cc3bc 100644
--- a/usr/src/cmd/dis/dis_target.c
+++ b/usr/src/cmd/dis/dis_target.c
@@ -726,7 +726,6 @@ dis_tgt_lookup(dis_tgt_t *tgt, uint64_t addr, off_t *offset, int cache_result,
return (sym->se_name);
}
-#if !defined(__sparc)
/*
* Given an address, return the starting offset of the next symbol in the file.
* Only needed on variable length instruction architectures.
@@ -746,7 +745,6 @@ dis_tgt_next_symbol(dis_tgt_t *tgt, uint64_t addr)
return (0);
}
-#endif
/*
* Iterate over all sections in the target, executing the given callback for
diff --git a/usr/src/cmd/dis/dis_target.h b/usr/src/cmd/dis/dis_target.h
index c6d13ab8dc..fa6c14c378 100644
--- a/usr/src/cmd/dis/dis_target.h
+++ b/usr/src/cmd/dis/dis_target.h
@@ -54,9 +54,7 @@ const char *dis_find_section(dis_tgt_t *, uint64_t, off_t *);
const char *dis_tgt_name(dis_tgt_t *);
const char *dis_tgt_member(dis_tgt_t *);
void dis_tgt_ehdr(dis_tgt_t *, GElf_Ehdr *);
-#if !defined(__sparc)
off_t dis_tgt_next_symbol(dis_tgt_t *, uint64_t);
-#endif
dis_tgt_t *dis_tgt_next(dis_tgt_t *);
/*