diff options
author | Joshua M. Clulow <josh@sysmgr.org> | 2015-01-20 20:27:53 -0500 |
---|---|---|
committer | Dan McDonald <danmcd@omniti.com> | 2015-01-23 22:17:34 -0500 |
commit | f7184619589931c4b827180c213074c470f08a8f (patch) | |
tree | b8594d45bca78fc4eddbc8a0d35061dc23e8ba8b /usr/src/cmd | |
parent | 22253b45e469decdb988b799c90598f2652597cd (diff) | |
download | illumos-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.c | 34 | ||||
-rw-r--r-- | usr/src/cmd/dis/dis_target.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/dis/dis_target.h | 2 |
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 *); /* |