summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2015-01-26 12:53:40 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2015-01-26 12:53:40 +0000
commit6d28d28825ce8837a909f5155a527518b07b1926 (patch)
tree737c7936ffd4a511cd7d9ae34ecddb4e98d291f5 /usr/src
parentc0e498928e0811212fda8b3b7090689d16618028 (diff)
parentb045990893825c31e176b319ae8cc4ef32115d17 (diff)
downloadillumos-joyent-6d28d28825ce8837a909f5155a527518b07b1926.tar.gz
[illumos-gate merge]
commit b045990893825c31e176b319ae8cc4ef32115d17 5552 libsun_sas leaks devids commit f7184619589931c4b827180c213074c470f08a8f 3317 dis(1) should support cross-target disassembly
Diffstat (limited to 'usr/src')
-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
-rw-r--r--usr/src/lib/libdisasm/Makefile.com69
-rw-r--r--usr/src/lib/libdisasm/Makefile.targ5
-rw-r--r--usr/src/lib/libdisasm/amd64/Makefile3
-rw-r--r--usr/src/lib/libdisasm/common/dis_i386.c (renamed from usr/src/lib/libdisasm/i386/dis_i386.c)152
-rw-r--r--usr/src/lib/libdisasm/common/dis_sparc.c (renamed from usr/src/lib/libdisasm/sparc/dis_sparc.c)130
-rw-r--r--usr/src/lib/libdisasm/common/dis_sparc.h (renamed from usr/src/lib/libdisasm/sparc/dis_sparc.h)18
-rw-r--r--usr/src/lib/libdisasm/common/dis_sparc_fmt.c (renamed from usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c)182
-rw-r--r--usr/src/lib/libdisasm/common/dis_sparc_fmt.h (renamed from usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h)2
-rw-r--r--usr/src/lib/libdisasm/common/dis_sparc_instr.c (renamed from usr/src/lib/libdisasm/sparc/instr.c)0
-rw-r--r--usr/src/lib/libdisasm/common/libdisasm.c156
-rw-r--r--usr/src/lib/libdisasm/common/libdisasm.h27
-rw-r--r--usr/src/lib/libdisasm/common/libdisasm_impl.h29
-rw-r--r--usr/src/lib/libdisasm/common/linktest_stand.c6
-rw-r--r--usr/src/lib/libdisasm/common/mapfile-vers1
-rw-r--r--usr/src/lib/libdisasm/i386/Makefile3
-rw-r--r--usr/src/lib/sun_sas/common/devtree_device_disco.c12
19 files changed, 530 insertions, 303 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 *);
/*
diff --git a/usr/src/lib/libdisasm/Makefile.com b/usr/src/lib/libdisasm/Makefile.com
index 32614b2262..5e5c520fd4 100644
--- a/usr/src/lib/libdisasm/Makefile.com
+++ b/usr/src/lib/libdisasm/Makefile.com
@@ -21,6 +21,8 @@
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
+# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -29,9 +31,6 @@
# for use by kmdb and as a normal library. We use $(CURTYPE) to indicate the
# current flavor being built.
#
-# The SPARC library is built from the closed gate. This Makefile is shared
-# between both environments, so all paths must be absolute.
-#
LIBRARY= libdisasm.a
STANDLIBRARY= libstanddisasm.so
@@ -45,32 +44,46 @@ CURTYPE= library
COMDIR= $(SRC)/lib/libdisasm/common
#
-# Architecture-dependent files common to both versions of libdisasm
+# Architecture-independent files
#
-OBJECTS_common_i386 = dis_i386.o dis_tables.o
-OBJECTS_common_sparc = dis_sparc.o instr.o dis_sparc_fmt.o
-
-SRCS_common_i386 = $(ISASRCDIR)/dis_i386.c $(SRC)/common/dis/i386/dis_tables.c
-SRCS_common_sparc = $(ISASRCDIR)/dis_sparc.c $(ISASRCDIR)/instr.c \
- $(ISASRCDIR)/dis_sparc_fmt.c
+SRCS_common= $(COMDIR)/libdisasm.c
+OBJECTS_common= libdisasm.o
#
-# Architecture-independent files common to both version of libdisasm
+# Architecture-dependent disassembly files
#
-OBJECTS_common_common = libdisasm.o
-SRC_common_common = $(OBJECTS_common_common:%.o=$(COMDIR)/%.c)
+SRCS_i386= $(COMDIR)/dis_i386.c \
+ $(SRC)/common/dis/i386/dis_tables.c
+SRCS_sparc= $(COMDIR)/dis_sparc.c \
+ $(COMDIR)/dis_sparc_fmt.c \
+ $(COMDIR)/dis_sparc_instr.c
+OBJECTS_i386= dis_i386.o \
+ dis_tables.o
+OBJECTS_sparc= dis_sparc.o \
+ dis_sparc_fmt.o \
+ dis_sparc_instr.o
-OBJECTS= \
- $(OBJECTS_common_$(MACH)) \
- $(OBJECTS_common_common)
+#
+# We build the regular shared library with support for all architectures.
+# The standalone version should only contain code for the native
+# architecture to reduce the memory footprint of kmdb.
+#
+OBJECTS_library= $(OBJECTS_common) \
+ $(OBJECTS_i386) \
+ $(OBJECTS_sparc)
+OBJECTS_standalone= $(OBJECTS_common) \
+ $(OBJECTS_$(MACH))
+OBJECTS= $(OBJECTS_$(CURTYPE))
include $(SRC)/lib/Makefile.lib
-SRCS= \
- $(SRCS_$(CURTYPE)) \
- $(SRCS_common_$(MACH)) \
- $(SRCS_common_common)
+SRCS_library= $(SRCS_common) \
+ $(SRCS_i386) \
+ $(SRCS_sparc)
+SRCS_standalone= $(SRCS_common) \
+ $(SRCS_$(MACH))
+SRCS= $(SRCS_$(CURTYPE))
#
# Used to verify that the standalone doesn't have any unexpected external
@@ -108,22 +121,12 @@ CERRWARN += -_gcc=-Wno-uninitialized
# doesn't get it.
DTS_ERRNO=
-# We need to rename some standard functions so we can easily implement them
-# in consumers.
-STAND_RENAMED_FUNCS= \
- snprintf
-
-CPPFLAGS_standalone = -DDIS_STANDALONE $(STAND_RENAMED_FUNCS:%=-D%=mdb_%) \
- -Dvsnprintf=mdb_iob_vsnprintf -I$(SRC)/cmd/mdb/common
+CPPFLAGS_standalone = -DDIS_STANDALONE -I$(SRC)/cmd/mdb/common
CPPFLAGS_library = -D_REENTRANT
CPPFLAGS += -I$(COMDIR) $(CPPFLAGS_$(CURTYPE))
-#
-# For x86, we have to link to sources in usr/src/common
-#
-CPPFLAGS_dis_i386 = -I$(SRC)/common/dis/i386 -DDIS_TEXT
-CPPFLAGS_dis_sparc =
-CPPFLAGS += $(CPPFLAGS_dis_$(MACH))
+# For the x86 disassembler we have to include sources from usr/src/common
+CPPFLAGS += -I$(SRC)/common/dis/i386 -DDIS_TEXT
CFLAGS_standalone = $(STAND_FLAGS_32)
CFLAGS_common =
diff --git a/usr/src/lib/libdisasm/Makefile.targ b/usr/src/lib/libdisasm/Makefile.targ
index 2354fc811e..e9f2c11268 100644
--- a/usr/src/lib/libdisasm/Makefile.targ
+++ b/usr/src/lib/libdisasm/Makefile.targ
@@ -22,8 +22,6 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
#
# We build each flavor in a separate make invocation to improve clarity(!) in
@@ -31,9 +29,6 @@
# flavor they're supposed to build. This causes the correct set of source
# files and compiler and linker flags to be selected.
#
-# The SPARC library is built from the closed gate. This Makefile is shared
-# between both environments, so all paths must be absolute.
-#
install: $(TYPES:%=install.%)
diff --git a/usr/src/lib/libdisasm/amd64/Makefile b/usr/src/lib/libdisasm/amd64/Makefile
index f53089a463..25c1eb86e8 100644
--- a/usr/src/lib/libdisasm/amd64/Makefile
+++ b/usr/src/lib/libdisasm/amd64/Makefile
@@ -22,7 +22,6 @@
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
ISASRCDIR=../$(MACH)/
@@ -35,3 +34,5 @@ INSTALL_DEPS_library = $(ROOTLINKS64) $(ROOTLINT64) $(ROOTLIBS64)
INSTALL_DEPS_standalone = $(ROOTLIBS64)
include ../Makefile.targ
+
+C99MODE = $(C99_ENABLE)
diff --git a/usr/src/lib/libdisasm/i386/dis_i386.c b/usr/src/lib/libdisasm/common/dis_i386.c
index a970cc76fb..c0653351fa 100644
--- a/usr/src/lib/libdisasm/i386/dis_i386.c
+++ b/usr/src/lib/libdisasm/common/dis_i386.c
@@ -22,25 +22,20 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <libdisasm.h>
-#include <stdlib.h>
-#include <stdio.h>
#include "dis_tables.h"
#include "libdisasm_impl.h"
-struct dis_handle {
- void *dh_data;
- int dh_flags;
- dis_lookup_f dh_lookup;
- dis_read_f dh_read;
- int dh_mode;
- dis86_t dh_dis;
- uint64_t dh_addr;
- uint64_t dh_end;
-};
+typedef struct dis_handle_i386 {
+ int dhx_mode;
+ dis86_t dhx_dis;
+ uint64_t dhx_end;
+} dis_handle_i386_t;
/*
* Returns true if we are near the end of a function. This is a cheap hack at
@@ -87,120 +82,104 @@ do_lookup(void *data, uint64_t addr, char *buf, size_t buflen)
return (dhp->dh_lookup(dhp->dh_data, addr, buf, buflen, NULL, NULL));
}
-dis_handle_t *
-dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
- dis_read_f read_func)
+static void
+dis_i386_handle_detach(dis_handle_t *dhp)
+{
+ dis_free(dhp->dh_arch_private, sizeof (dis_handle_i386_t));
+ dhp->dh_arch_private = NULL;
+}
+
+static int
+dis_i386_handle_attach(dis_handle_t *dhp)
{
- dis_handle_t *dhp;
+ dis_handle_i386_t *dhx;
/*
* Validate architecture flags
*/
- if (flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 |
+ if (dhp->dh_flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 |
DIS_OCTAL | DIS_NOIMMSYM)) {
(void) dis_seterrno(E_DIS_INVALFLAG);
- return (NULL);
+ return (-1);
}
/*
* Create and initialize the internal structure
*/
- if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
+ if ((dhx = dis_zalloc(sizeof (dis_handle_i386_t))) == NULL) {
(void) dis_seterrno(E_DIS_NOMEM);
- return (NULL);
+ return (-1);
}
-
- dhp->dh_lookup = lookup_func;
- dhp->dh_read = read_func;
- dhp->dh_flags = flags;
- dhp->dh_data = data;
+ dhp->dh_arch_private = dhx;
/*
* Initialize x86-specific architecture structure
*/
- if (flags & DIS_X86_SIZE16)
- dhp->dh_mode = SIZE16;
- else if (flags & DIS_X86_SIZE64)
- dhp->dh_mode = SIZE64;
+ if (dhp->dh_flags & DIS_X86_SIZE16)
+ dhx->dhx_mode = SIZE16;
+ else if (dhp->dh_flags & DIS_X86_SIZE64)
+ dhx->dhx_mode = SIZE64;
else
- dhp->dh_mode = SIZE32;
+ dhx->dhx_mode = SIZE32;
- if (flags & DIS_OCTAL)
- dhp->dh_dis.d86_flags = DIS_F_OCTAL;
+ if (dhp->dh_flags & DIS_OCTAL)
+ dhx->dhx_dis.d86_flags = DIS_F_OCTAL;
- dhp->dh_dis.d86_sprintf_func = snprintf;
- dhp->dh_dis.d86_get_byte = get_byte;
- dhp->dh_dis.d86_sym_lookup = do_lookup;
- dhp->dh_dis.d86_check_func = check_func;
+ dhx->dhx_dis.d86_sprintf_func = dis_snprintf;
+ dhx->dhx_dis.d86_get_byte = get_byte;
+ dhx->dhx_dis.d86_sym_lookup = do_lookup;
+ dhx->dhx_dis.d86_check_func = check_func;
- dhp->dh_dis.d86_data = dhp;
+ dhx->dhx_dis.d86_data = dhp;
- return (dhp);
+ return (0);
}
-int
-dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
+static int
+dis_i386_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf,
+ size_t buflen)
{
+ dis_handle_i386_t *dhx = dhp->dh_arch_private;
dhp->dh_addr = addr;
/* DIS_NOIMMSYM might not be set until now, so update */
if (dhp->dh_flags & DIS_NOIMMSYM)
- dhp->dh_dis.d86_flags |= DIS_F_NOIMMSYM;
+ dhx->dhx_dis.d86_flags |= DIS_F_NOIMMSYM;
else
- dhp->dh_dis.d86_flags &= ~DIS_F_NOIMMSYM;
+ dhx->dhx_dis.d86_flags &= ~DIS_F_NOIMMSYM;
- if (dtrace_disx86(&dhp->dh_dis, dhp->dh_mode) != 0)
+ if (dtrace_disx86(&dhx->dhx_dis, dhx->dhx_mode) != 0)
return (-1);
if (buf != NULL)
- dtrace_disx86_str(&dhp->dh_dis, dhp->dh_mode, addr, buf,
+ dtrace_disx86_str(&dhx->dhx_dis, dhx->dhx_mode, addr, buf,
buflen);
return (0);
}
-void
-dis_handle_destroy(dis_handle_t *dhp)
-{
- dis_free(dhp, sizeof (dis_handle_t));
-}
-
-void
-dis_set_data(dis_handle_t *dhp, void *data)
-{
- dhp->dh_data = data;
-}
-
-void
-dis_flags_set(dis_handle_t *dhp, int f)
-{
- dhp->dh_flags |= f;
-}
-
-void
-dis_flags_clear(dis_handle_t *dhp, int f)
+/* ARGSUSED */
+static int
+dis_i386_max_instrlen(dis_handle_t *dhp)
{
- dhp->dh_flags &= ~f;
+ return (15);
}
-
/* ARGSUSED */
-int
-dis_max_instrlen(dis_handle_t *dhp)
+static int
+dis_i386_min_instrlen(dis_handle_t *dhp)
{
- return (15);
+ return (1);
}
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
/*
* Return the previous instruction. On x86, we have no choice except to
* disassemble everything from the start of the symbol, and stop when we have
* reached our instruction address. If we're not in the middle of a known
* symbol, then we return the same address to indicate failure.
*/
-uint64_t
-dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
+static uint64_t
+dis_i386_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
{
uint64_t *hist, addr, start;
int cur, nseen;
@@ -244,11 +223,34 @@ done:
return (res);
}
-int
-dis_instrlen(dis_handle_t *dhp, uint64_t pc)
+static int
+dis_i386_supports_flags(int flags)
+{
+ int archflags = flags & DIS_ARCH_MASK;
+
+ if (archflags == DIS_X86_SIZE16 || archflags == DIS_X86_SIZE32 ||
+ archflags == DIS_X86_SIZE64)
+ return (1);
+
+ return (0);
+}
+
+static int
+dis_i386_instrlen(dis_handle_t *dhp, uint64_t pc)
{
if (dis_disassemble(dhp, pc, NULL, 0) != 0)
return (-1);
return (dhp->dh_addr - pc);
}
+
+dis_arch_t dis_arch_i386 = {
+ dis_i386_supports_flags,
+ dis_i386_handle_attach,
+ dis_i386_handle_detach,
+ dis_i386_disassemble,
+ dis_i386_previnstr,
+ dis_i386_min_instrlen,
+ dis_i386_max_instrlen,
+ dis_i386_instrlen,
+};
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc.c b/usr/src/lib/libdisasm/common/dis_sparc.c
index 70f4ee549b..8334241f24 100644
--- a/usr/src/lib/libdisasm/sparc/dis_sparc.c
+++ b/usr/src/lib/libdisasm/common/dis_sparc.c
@@ -27,6 +27,7 @@
/*
* Copyright 2007 Jason King. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
*/
/*
@@ -102,44 +103,49 @@ static uint32_t dis_get_bits(uint32_t, int, int);
static void do_binary(uint32_t);
#endif /* DIS_STANDALONE */
-dis_handle_t *
-dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
- dis_read_f read_func)
+static void
+dis_sparc_handle_detach(dis_handle_t *dhp)
+{
+ dis_free(dhp->dh_arch_private, sizeof (dis_handle_sparc_t));
+ dhp->dh_arch_private = NULL;
+}
+
+static int
+dis_sparc_handle_attach(dis_handle_t *dhp)
{
+ dis_handle_sparc_t *dhx;
#if !defined(DIS_STANDALONE)
char *opt = NULL;
char *opt2, *save, *end;
#endif
- dis_handle_t *dhp;
- if ((flags & (DIS_SPARC_V8|DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0) {
+ /* Validate architecture flags */
+ if ((dhp->dh_flags & (DIS_SPARC_V8|DIS_SPARC_V9|DIS_SPARC_V9_SGI))
+ == 0) {
(void) dis_seterrno(E_DIS_INVALFLAG);
- return (NULL);
+ return (-1);
}
- if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
+ if ((dhx = dis_zalloc(sizeof (dis_handle_sparc_t))) == NULL) {
(void) dis_seterrno(E_DIS_NOMEM);
return (NULL);
}
-
- dhp->dh_lookup = lookup_func;
- dhp->dh_read = read_func;
- dhp->dh_flags = flags;
- dhp->dh_data = data;
- dhp->dh_debug = DIS_DEBUG_COMPAT;
+ dhx->dhx_debug = DIS_DEBUG_COMPAT;
+ dhp->dh_arch_private = dhx;
#if !defined(DIS_STANDALONE)
opt = getenv("_LIBDISASM_DEBUG");
if (opt == NULL)
- return (dhp);
+ return (0);
opt2 = strdup(opt);
if (opt2 == NULL) {
dis_handle_destroy(dhp);
+ dis_free(dhx, sizeof (dis_handle_sparc_t));
(void) dis_seterrno(E_DIS_NOMEM);
- return (NULL);
+ return (-1);
}
save = opt2;
@@ -150,60 +156,43 @@ dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
*end++ = '\0';
if (strcasecmp("synth-all", opt2) == 0)
- dhp->dh_debug |= DIS_DEBUG_SYN_ALL;
+ dhx->dhx_debug |= DIS_DEBUG_SYN_ALL;
if (strcasecmp("compat", opt2) == 0)
- dhp->dh_debug |= DIS_DEBUG_COMPAT;
+ dhx->dhx_debug |= DIS_DEBUG_COMPAT;
if (strcasecmp("synth-none", opt2) == 0)
- dhp->dh_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT);
+ dhx->dhx_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT);
if (strcasecmp("binary", opt2) == 0)
- dhp->dh_debug |= DIS_DEBUG_PRTBIN;
+ dhx->dhx_debug |= DIS_DEBUG_PRTBIN;
if (strcasecmp("format", opt2) == 0)
- dhp->dh_debug |= DIS_DEBUG_PRTFMT;
+ dhx->dhx_debug |= DIS_DEBUG_PRTFMT;
if (strcasecmp("all", opt2) == 0)
- dhp->dh_debug = DIS_DEBUG_ALL;
+ dhx->dhx_debug = DIS_DEBUG_ALL;
if (strcasecmp("none", opt2) == 0)
- dhp->dh_debug = DIS_DEBUG_NONE;
+ dhx->dhx_debug = DIS_DEBUG_NONE;
opt2 = end;
}
free(save);
#endif /* DIS_STANDALONE */
- return (dhp);
-}
-
-void
-dis_handle_destroy(dis_handle_t *dhp)
-{
- dis_free(dhp, sizeof (dis_handle_t));
-}
-
-void
-dis_set_data(dis_handle_t *dhp, void *data)
-{
- dhp->dh_data = data;
-}
-
-void
-dis_flags_set(dis_handle_t *dhp, int f)
-{
- dhp->dh_flags |= f;
+ return (0);
}
-void
-dis_flags_clear(dis_handle_t *dhp, int f)
+/* ARGSUSED */
+static int
+dis_sparc_max_instrlen(dis_handle_t *dhp)
{
- dhp->dh_flags &= ~f;
+ return (4);
}
/* ARGSUSED */
-int
-dis_max_instrlen(dis_handle_t *dhp)
+static int
+dis_sparc_min_instrlen(dis_handle_t *dhp)
{
return (4);
}
@@ -214,8 +203,8 @@ dis_max_instrlen(dis_handle_t *dhp)
* nth previous instruction.
*/
/* ARGSUSED */
-uint64_t
-dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
+static uint64_t
+dis_sparc_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
{
if (n <= 0)
return (pc);
@@ -227,15 +216,17 @@ dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
}
/* ARGSUSED */
-int
-dis_instrlen(dis_handle_t *dhp, uint64_t pc)
+static int
+dis_sparc_instrlen(dis_handle_t *dhp, uint64_t pc)
{
return (4);
}
-int
-dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
+static int
+dis_sparc_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf,
+ size_t buflen)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
const table_t *tp = &initial_table;
const inst_t *inp = NULL;
@@ -246,17 +237,19 @@ dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
sizeof (instr))
return (-1);
- dhp->dh_buf = buf;
- dhp->dh_buflen = buflen;
- dhp->dh_addr = addr;
+ dhx->dhx_buf = buf;
+ dhx->dhx_buflen = buflen;
+ dhp->dh_addr = addr;
buf[0] = '\0';
/* this allows sparc code to be tested on x86 */
+#if !defined(DIS_STANDALONE)
instr = BE_32(instr);
+#endif /* DIS_STANDALONE */
#if !defined(DIS_STANDALONE)
- if ((dhp->dh_debug & DIS_DEBUG_PRTBIN) != 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTBIN) != 0)
do_binary(instr);
#endif /* DIS_STANDALONE */
@@ -284,7 +277,7 @@ dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
error:
- (void) snprintf(buf, buflen,
+ (void) dis_snprintf(buf, buflen,
((dhp->dh_flags & DIS_OCTAL) != 0) ? "0%011lo" : "0x%08lx",
instr);
@@ -341,3 +334,26 @@ do_binary(uint32_t instr)
(void) fprintf(stderr, "\n");
}
#endif /* DIS_STANDALONE */
+
+static int
+dis_sparc_supports_flags(int flags)
+{
+ int archflags = flags & DIS_ARCH_MASK;
+
+ if (archflags == DIS_SPARC_V8 ||
+ (archflags & (DIS_SPARC_V9 | DIS_SPARC_V8)) == DIS_SPARC_V9)
+ return (1);
+
+ return (0);
+}
+
+const dis_arch_t dis_arch_sparc = {
+ dis_sparc_supports_flags,
+ dis_sparc_handle_attach,
+ dis_sparc_handle_detach,
+ dis_sparc_disassemble,
+ dis_sparc_previnstr,
+ dis_sparc_min_instrlen,
+ dis_sparc_max_instrlen,
+ dis_sparc_instrlen
+};
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc.h b/usr/src/lib/libdisasm/common/dis_sparc.h
index 8ebeda18b7..b11eea8593 100644
--- a/usr/src/lib/libdisasm/sparc/dis_sparc.h
+++ b/usr/src/lib/libdisasm/common/dis_sparc.h
@@ -33,8 +33,6 @@
#ifndef _DIS_SPARC_H
#define _DIS_SPARC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -49,17 +47,11 @@ extern "C" {
#define DIS_DEBUG_ALL DIS_DEBUG_SYN_ALL|DIS_DEBUG_PRTBIN|DIS_DEBUG_PRTFMT
-struct dis_handle {
- void *dh_data;
- dis_lookup_f dh_lookup;
- dis_read_f dh_read;
- int dh_flags;
-
- char *dh_buf;
- size_t dh_buflen;
- uint64_t dh_addr;
- int dh_debug;
-};
+typedef struct dis_handle_sparc {
+ char *dhx_buf;
+ size_t dhx_buflen;
+ int dhx_debug;
+} dis_handle_sparc_t;
/* different types of things we can have in inst_t */
#define INST_NONE 0x00
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c b/usr/src/lib/libdisasm/common/dis_sparc_fmt.c
index 56e36e6d3c..017c056477 100644
--- a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.c
+++ b/usr/src/lib/libdisasm/common/dis_sparc_fmt.c
@@ -27,6 +27,7 @@
/*
* Copyright 2009 Jason King. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
*/
@@ -48,8 +49,6 @@ extern int strcmp(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern size_t strlcat(char *, const char *, size_t);
extern size_t strlcpy(char *, const char *, size_t);
-extern int snprintf(char *, size_t, const char *, ...);
-extern int vsnprintf(char *, size_t, const char *, va_list);
/*
* This file has the functions that do all the dirty work of outputting the
@@ -698,6 +697,7 @@ prt_binary(uint32_t val, int bitlen)
int
fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int32_t disp;
@@ -705,7 +705,7 @@ fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f1.op, 2);
prt_field("disp30", f->f1.disp30, 30);
}
@@ -718,13 +718,13 @@ fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
(disp < 0) ? "-" : "+",
(disp < 0) ? (-disp) : disp);
- (void) strlcat(dhp->dh_buf, " <", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, " <", dhx->dhx_buflen);
- curlen = strlen(dhp->dh_buf);
+ curlen = strlen(dhx->dhx_buf);
dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
- dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL,
+ dhx->dhx_buf + curlen, dhx->dhx_buflen - curlen - 1, NULL,
NULL);
- (void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ">", dhx->dhx_buflen);
return (0);
@@ -733,9 +733,10 @@ fmt_call(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f2.op, 2);
prt_field("op2", f->f2.op2, 3);
prt_field("rd", f->f2.rd, 5);
@@ -771,6 +772,7 @@ fmt_sethi(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
const char *name = inp->in_data.in_def.in_name;
const char *r = NULL;
const char *annul = "";
@@ -785,7 +787,7 @@ fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
uint32_t flags = inp->in_data.in_def.in_flags;
int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f2.op, 2);
prt_field("op2", f->f2.op2, 3);
@@ -816,7 +818,7 @@ fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
}
if (f->f2b.op2 == 0x01 && idx == 0x00 && f->f2b.p == 1 &&
- f->f2b.cc == 0x02 && ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0)) {
+ f->f2b.cc == 0x02 && ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) != 0)) {
name = "iprefetch";
flags = FLG_RS1(REG_NONE)|FLG_DISP(DISP19);
}
@@ -854,12 +856,12 @@ fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if (f->f2b.p == 0) {
pred = ",pn";
} else {
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0)
pred = ",pt";
}
}
- (void) snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
+ (void) dis_snprintf(buf, sizeof (buf), "%s%s%s", name, annul, pred);
prt_name(dhp, buf, 1);
@@ -888,11 +890,11 @@ fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
break;
}
- curlen = strlen(dhp->dh_buf);
+ curlen = strlen(dhx->dhx_buf);
dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int64_t)disp,
- dhp->dh_buf + curlen, dhp->dh_buflen - curlen - 1, NULL, NULL);
+ dhx->dhx_buf + curlen, dhx->dhx_buflen - curlen - 1, NULL, NULL);
- (void) strlcat(dhp->dh_buf, ">", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ">", dhx->dhx_buflen);
return (0);
}
@@ -915,13 +917,14 @@ fmt_branch(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
static int
fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char *asistr = NULL;
int noasi = 0;
asistr = get_asi_name(f->f3.asi);
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT)) != 0) {
if (f->f3.op3 == 0x3c && f->f3.i == 0) {
if (f->f3.asi == 0x80) {
noasi = 1;
@@ -952,7 +955,7 @@ fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
bprintf(dhp, "[%s]", reg_names[f->f3.rs1]);
if (noasi == 0) {
- (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
prt_asi(dhp, instr);
}
@@ -999,6 +1002,7 @@ fmt_cas(dis_handle_t *dhp, uint32_t instr, const char *name)
int
fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char *regstr = NULL;
const char *asistr = NULL;
@@ -1006,7 +1010,7 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
const char *iname = inp->in_data.in_def.in_name;
uint32_t flags = inp->in_data.in_def.in_flags;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3.op, 2);
prt_field("op3", f->f3.op3, 6);
prt_field("rs1", f->f3.rs1, 5);
@@ -1029,16 +1033,16 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
prt_address(dhp, instr, 0);
if (idx == 0x3d) {
- (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
prt_asi(dhp, instr);
}
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
/* fcn field is the same as rd */
if (prefetch_str[f->f3.rd] != NULL)
- (void) strlcat(dhp->dh_buf, prefetch_str[f->f3.rd],
- dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, prefetch_str[f->f3.rd],
+ dhx->dhx_buflen);
else
prt_imm(dhp, f->f3.rd, 0);
@@ -1059,18 +1063,18 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
switch (idx) {
case 0x00:
/* ld */
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
iname = "lduw";
break;
case 0x03:
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
iname = "ldtw";
break;
case 0x04:
/* stw */
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
iname = "stuw";
if ((dhp->dh_flags & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
@@ -1108,7 +1112,7 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
break;
case 0x07:
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
iname = "sttw";
break;
@@ -1127,14 +1131,14 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x13:
/* ldtwa */
- if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
+ if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) &&
((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
iname = "ldtwa";
break;
case 0x17:
/* sttwa */
- if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) &&
+ if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) &&
((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
iname = "sttwa";
break;
@@ -1212,25 +1216,25 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if ((flags & FLG_STORE) != 0) {
if (regstr[0] != '\0') {
- (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
}
prt_address(dhp, instr, 0);
if ((flags & FLG_ASI) != 0) {
- (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
prt_asi(dhp, instr);
}
} else {
prt_address(dhp, instr, 0);
if ((flags & FLG_ASI) != 0) {
- (void) strlcat(dhp->dh_buf, " ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, " ", dhx->dhx_buflen);
prt_asi(dhp, instr);
}
if (regstr[0] != '\0') {
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
- (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
+ (void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
}
}
@@ -1243,10 +1247,11 @@ fmt_ls(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
static int
fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int flags = FLG_P1(REG_CP)|FLG_P2(REG_CP)|FLG_NOIMM|FLG_P3(REG_CP);
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->fcp.op, 2);
prt_field("op3", f->fcp.op3, 6);
prt_field("opc", f->fcp.opc, 9);
@@ -1258,7 +1263,7 @@ fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
prt_name(dhp, inp->in_data.in_def.in_name, 1);
prt_imm(dhp, f->fcp.opc, 0);
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
(void) prt_aluargs(dhp, instr, flags);
return (0);
@@ -1267,6 +1272,7 @@ fmt_cpop(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
static int
dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
const char *psr_str = "%psr";
const char *wim_str = "%wim";
const char *tbr_str = "%tbr";
@@ -1392,7 +1398,7 @@ dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
}
/* synth: mov */
- if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ if ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
== 0)
break;
@@ -1464,12 +1470,12 @@ dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
IMM_SIGNED);
else
- (void) strlcat(dhp->dh_buf,
- reg_names[f->f3.rs2], dhp->dh_buflen);
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf,
+ reg_names[f->f3.rs2], dhx->dhx_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
}
- (void) strlcat(dhp->dh_buf, regstr, dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, regstr, dhx->dhx_buflen);
}
return (0);
@@ -1479,6 +1485,7 @@ dis_fmt_rdwr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
@@ -1497,7 +1504,7 @@ fmt_trap(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
return (-1);
p_rs1 = ((f->ftcc.rs1 != 0) ||
- ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
+ ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0));
if (f->ftcc.i == 0) {
p_t = (f->f3.rs2 != 0 || p_rs1 == 0);
@@ -1555,10 +1562,11 @@ prt_shift(dis_handle_t *dhp, uint32_t instr, const inst_t *inp)
static int
prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
const char *name = inp->in_data.in_def.in_name;
ifmt_t *f = (ifmt_t *)&instr;
- if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
+ if (f->f3.rd == 15 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0))
name = "call";
if (f->f3.rd == 0) {
@@ -1583,7 +1591,7 @@ prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if (f->f3.rd == 0)
return (0);
- if (f->f3.rd == 15 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0))
+ if (f->f3.rd == 15 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0))
return (0);
bprintf(dhp, ", %s", reg_names[f->f3.rd]);
@@ -1594,13 +1602,14 @@ prt_jmpl(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char *name = inp->in_data.in_def.in_name;
int flags = inp->in_data.in_def.in_flags;
int arg = 0;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3.op, 2);
prt_field("op3", f->f3.op3, 6);
prt_field("rs1", f->f3.rs1, 5);
@@ -1623,7 +1632,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x00:
/* add */
- if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
break;
if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
@@ -1644,11 +1653,11 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x02:
/* or */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
- if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) != 0) {
if (f->f3.rs1 == f->f3.rd) {
name = "bset";
flags = FLG_P1(REG_NONE);
@@ -1674,7 +1683,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x04:
/* sub */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
@@ -1690,7 +1699,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
break;
}
- if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
break;
if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
@@ -1711,7 +1720,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x07:
/* xnor */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
@@ -1737,7 +1746,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x10:
/* addcc */
- if ((dhp->dh_debug & DIS_DEBUG_SYN_ALL) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_SYN_ALL) == 0)
break;
if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
@@ -1761,11 +1770,11 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if (f->f3.rd != 0)
break;
- if ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
+ if ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL))
== 0)
break;
- if (((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0) &&
+ if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0) &&
((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0))
break;
@@ -1777,7 +1786,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x12:
/* orcc */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
@@ -1798,7 +1807,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x14:
/* subcc */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
@@ -1808,7 +1817,7 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
break;
}
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0)
break;
if (f->f3.rs1 == f->f3.rd && f->f3.i == 1 &&
@@ -1868,14 +1877,14 @@ fmt_alu(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
case 0x3c:
case 0x3d:
/* save / restore */
- if ((dhp->dh_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
+ if ((dhx->dhx_debug & (DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT))
== 0)
break;
if (f->f3.rs1 != 0 || f->f3.rs2 != 0 || f->f3.rd != 0)
break;
- if (f->f3.i != 0 && ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0))
+ if (f->f3.i != 0 && ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0))
break;
prt_name(dhp, name, 0);
@@ -1919,10 +1928,11 @@ fmt_trap_ret(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char **regs = NULL;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3c.op, 2);
prt_field("op3", f->f3c.op3, 6);
prt_field("cond", f->f3c.cond, 4);
@@ -1953,8 +1963,8 @@ fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if (f->f3c.i == 1)
prt_imm(dhp, sign_extend(f->f3c.simm11, 11), IMM_SIGNED);
else
- (void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
- dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, reg_names[f->f3.rs2],
+ dhx->dhx_buflen);
bprintf(dhp, ", %s", reg_names[f->f3.rd]);
@@ -1965,6 +1975,7 @@ fmt_movcc(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
prt_name(dhp, inp->in_data.in_def.in_name, 1);
@@ -1974,8 +1985,8 @@ fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
if (f->f3d.i == 1)
prt_imm(dhp, sign_extend(f->f3d.simm10, 10), IMM_SIGNED);
else
- (void) strlcat(dhp->dh_buf, reg_names[f->f3.rs2],
- dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, reg_names[f->f3.rs2],
+ dhx->dhx_buflen);
bprintf(dhp, ", %s", reg_names[f->f3.rd]);
@@ -1986,12 +1997,13 @@ fmt_movr(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_fpop1(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int flags = inp->in_data.in_def.in_flags;
flags |= FLG_NOIMM;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3.op, 2);
prt_field("op3", f->f3.op3, 6);
prt_field("opf", f->fcmp.opf, 9);
@@ -2019,6 +2031,7 @@ fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
"a", "e", "ue", "ge", "uge", "le", "ule", "o"
};
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char *ccstr = "";
char name[15];
@@ -2028,13 +2041,13 @@ fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
idx == 0x55 || idx == 0x56 || idx == 0x57);
int is_fmov = (idx & 0x3f);
int is_v9 = ((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0);
- int is_compat = ((dhp->dh_debug & DIS_DEBUG_COMPAT) != 0);
+ int is_compat = ((dhx->dhx_debug & DIS_DEBUG_COMPAT) != 0);
int p_cc = 0;
is_fmov = (is_fmov == 0x1 || is_fmov == 0x2 || is_fmov == 0x3);
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3.op, 2);
prt_field("op3", f->f3.op3, 6);
prt_field("opf", f->fcmp.opf, 9);
@@ -2104,10 +2117,11 @@ fmt_fpop2(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
int
fmt_vis(dis_handle_t *dhp, uint32_t instr, const inst_t *inp, int idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int flags = inp->in_data.in_def.in_flags;
- if ((dhp->dh_debug & DIS_DEBUG_PRTFMT) != 0) {
+ if ((dhx->dhx_debug & DIS_DEBUG_PRTFMT) != 0) {
prt_field("op", f->f3.op, 2);
prt_field("op3", f->f3.op3, 6);
prt_field("opf", f->fcmp.opf, 9);
@@ -2251,6 +2265,7 @@ prt_imm(dis_handle_t *dhp, uint32_t val, int format)
static const char *
get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
const char *regname = NULL;
switch (regset) {
@@ -2263,7 +2278,7 @@ get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
break;
case REG_FPD:
- if (((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0) ||
+ if (((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0) ||
((dhp->dh_flags & (DIS_SPARC_V9|DIS_SPARC_V9_SGI)) != 0))
regname = fdreg_names[idx];
else
@@ -2272,7 +2287,7 @@ get_regname(dis_handle_t *dhp, int regset, uint32_t idx)
break;
case REG_FPQ:
- if ((dhp->dh_debug & DIS_DEBUG_COMPAT) == 0)
+ if ((dhx->dhx_debug & DIS_DEBUG_COMPAT) == 0)
regname = fqreg_names[idx];
else
regname = freg_names[idx];
@@ -2350,11 +2365,12 @@ prt_asi(dis_handle_t *dhp, uint32_t instr)
static void
prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
int32_t simm13;
int octal = ((dhp->dh_flags & DIS_OCTAL) != 0);
- int p1 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
- int p2 = ((dhp->dh_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
+ int p1 = ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
+ int p2 = ((dhx->dhx_debug & (DIS_DEBUG_COMPAT|DIS_DEBUG_SYN_ALL)) == 0);
if (f->f3a.i == 0) {
p1 |= ((f->f3a.rs1 != 0) || f->f3.rs2 == 0);
@@ -2421,6 +2437,7 @@ prt_address(dis_handle_t *dhp, uint32_t instr, int nobrackets)
static void
prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
ifmt_t *f = (ifmt_t *)&instr;
const char *r1, *r2, *r3;
int p1, p2, p3;
@@ -2447,30 +2464,30 @@ prt_aluargs(dis_handle_t *dhp, uint32_t instr, uint32_t flags)
opf = f->fcmp.opf;
if ((opf == 0x151) || (opf == 0x152)) {
- (void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, r3, dhx->dhx_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
p3 = 0;
}
if (p1 != 0) {
- (void) strlcat(dhp->dh_buf, r1, dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, r1, dhx->dhx_buflen);
if (p2 != 0 || p3 != 0)
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
}
if (p2 != 0) {
if (f->f3.i == 0 || ((flags & FLG_NOIMM) != 0))
- (void) strlcat(dhp->dh_buf, r2, dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, r2, dhx->dhx_buflen);
else
prt_imm(dhp, sign_extend(f->f3a.simm13, 13),
IMM_SIGNED);
if (p3 != 0)
- (void) strlcat(dhp->dh_buf, ", ", dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, ", ", dhx->dhx_buflen);
}
if (p3 != 0)
- (void) strlcat(dhp->dh_buf, r3, dhp->dh_buflen);
+ (void) strlcat(dhx->dhx_buf, r3, dhx->dhx_buflen);
}
static const char *
@@ -2742,13 +2759,14 @@ get_asi_name(uint8_t asi)
static void
bprintf(dis_handle_t *dhp, const char *fmt, ...)
{
+ dis_handle_sparc_t *dhx = dhp->dh_arch_private;
size_t curlen;
va_list ap;
- curlen = strlen(dhp->dh_buf);
+ curlen = strlen(dhx->dhx_buf);
va_start(ap, fmt);
- (void) vsnprintf(dhp->dh_buf + curlen, dhp->dh_buflen - curlen, fmt,
- ap);
+ (void) dis_vsnprintf(dhx->dhx_buf + curlen, dhx->dhx_buflen -
+ curlen, fmt, ap);
va_end(ap);
}
diff --git a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h b/usr/src/lib/libdisasm/common/dis_sparc_fmt.h
index 4630c8114e..fbd8ecad8f 100644
--- a/usr/src/lib/libdisasm/sparc/dis_sparc_fmt.h
+++ b/usr/src/lib/libdisasm/common/dis_sparc_fmt.h
@@ -29,8 +29,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef _DIS_SPARC_FMT_H
#define _DIS_SPARC_FMT_H
diff --git a/usr/src/lib/libdisasm/sparc/instr.c b/usr/src/lib/libdisasm/common/dis_sparc_instr.c
index aa357837a0..aa357837a0 100644
--- a/usr/src/lib/libdisasm/sparc/instr.c
+++ b/usr/src/lib/libdisasm/common/dis_sparc_instr.c
diff --git a/usr/src/lib/libdisasm/common/libdisasm.c b/usr/src/lib/libdisasm/common/libdisasm.c
index 197c2c34df..7f040a04b8 100644
--- a/usr/src/lib/libdisasm/common/libdisasm.c
+++ b/usr/src/lib/libdisasm/common/libdisasm.c
@@ -22,19 +22,48 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <libdisasm.h>
#include <stdlib.h>
#ifdef DIS_STANDALONE
#include <mdb/mdb_modapi.h>
+#define _MDB
+#include <mdb/mdb_io.h>
+#else
+#include <stdio.h>
#endif
+#include "libdisasm_impl.h"
+
static int _dis_errno;
/*
+ * If we're building the standalone library, then we only want to
+ * include support for disassembly of the native architecture.
+ * The regular shared library should include support for all
+ * architectures.
+ */
+#if !defined(DIS_STANDALONE) || defined(__i386) || defined(__amd64)
+extern dis_arch_t dis_arch_i386;
+#endif
+#if !defined(DIS_STANDALONE) || defined(__sparc)
+extern dis_arch_t dis_arch_sparc;
+#endif
+
+static dis_arch_t *dis_archs[] = {
+#if !defined(DIS_STANDALONE) || defined(__i386) || defined(__amd64)
+ &dis_arch_i386,
+#endif
+#if !defined(DIS_STANDALONE) || defined(__sparc)
+ &dis_arch_sparc,
+#endif
+ NULL
+};
+
+/*
* For the standalone library, we need to link against mdb's malloc/free.
* Otherwise, use the standard malloc/free.
*/
@@ -86,7 +115,130 @@ dis_strerror(int error)
return ("out of memory");
case E_DIS_INVALFLAG:
return ("invalid flags for this architecture");
+ case E_DIS_UNSUPARCH:
+ return ("unsupported machine architecture");
default:
return ("unknown error");
}
}
+
+void
+dis_set_data(dis_handle_t *dhp, void *data)
+{
+ dhp->dh_data = data;
+}
+
+void
+dis_flags_set(dis_handle_t *dhp, int f)
+{
+ dhp->dh_flags |= f;
+}
+
+void
+dis_flags_clear(dis_handle_t *dhp, int f)
+{
+ dhp->dh_flags &= ~f;
+}
+
+void
+dis_handle_destroy(dis_handle_t *dhp)
+{
+ dhp->dh_arch->da_handle_detach(dhp);
+ dis_free(dhp, sizeof (dis_handle_t));
+}
+
+dis_handle_t *
+dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
+ dis_read_f read_func)
+{
+ dis_handle_t *dhp;
+ dis_arch_t *arch = NULL;
+ int i;
+
+ /* Select an architecture based on flags */
+ for (i = 0; dis_archs[i] != NULL; i++) {
+ if (dis_archs[i]->da_supports_flags(flags)) {
+ arch = dis_archs[i];
+ break;
+ }
+ }
+ if (arch == NULL) {
+ (void) dis_seterrno(E_DIS_UNSUPARCH);
+ return (NULL);
+ }
+
+ if ((dhp = dis_zalloc(sizeof (dis_handle_t))) == NULL) {
+ (void) dis_seterrno(E_DIS_NOMEM);
+ return (NULL);
+ }
+ dhp->dh_arch = arch;
+ dhp->dh_lookup = lookup_func;
+ dhp->dh_read = read_func;
+ dhp->dh_flags = flags;
+ dhp->dh_data = data;
+
+ /*
+ * Allow the architecture-specific code to allocate
+ * its private data.
+ */
+ if (arch->da_handle_attach(dhp) != 0) {
+ dis_free(dhp, sizeof (dis_handle_t));
+ /* dis errno already set */
+ return (NULL);
+ }
+
+ return (dhp);
+}
+
+int
+dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
+{
+ return (dhp->dh_arch->da_disassemble(dhp, addr, buf, buflen));
+}
+
+uint64_t
+dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
+{
+ return (dhp->dh_arch->da_previnstr(dhp, pc, n));
+}
+
+int
+dis_min_instrlen(dis_handle_t *dhp)
+{
+ return (dhp->dh_arch->da_min_instrlen(dhp));
+}
+
+int
+dis_max_instrlen(dis_handle_t *dhp)
+{
+ return (dhp->dh_arch->da_max_instrlen(dhp));
+}
+
+int
+dis_instrlen(dis_handle_t *dhp, uint64_t pc)
+{
+ return (dhp->dh_arch->da_instrlen(dhp, pc));
+}
+
+int
+dis_vsnprintf(char *restrict s, size_t n, const char *restrict format,
+ va_list args)
+{
+#ifdef DIS_STANDALONE
+ return (mdb_iob_vsnprintf(s, n, format, args));
+#else
+ return (vsnprintf(s, n, format, args));
+#endif
+}
+
+int
+dis_snprintf(char *restrict s, size_t n, const char *restrict format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ n = dis_vsnprintf(s, n, format, args);
+ va_end(args);
+
+ return (n);
+}
diff --git a/usr/src/lib/libdisasm/common/libdisasm.h b/usr/src/lib/libdisasm/common/libdisasm.h
index 3329d565f5..3d4d5f6957 100644
--- a/usr/src/lib/libdisasm/common/libdisasm.h
+++ b/usr/src/lib/libdisasm/common/libdisasm.h
@@ -22,6 +22,7 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
*/
#ifndef _LIBDISASM_H
@@ -38,19 +39,23 @@ typedef struct dis_handle dis_handle_t;
#define DIS_DEFAULT 0x0
/* SPARC disassembler flags */
-#define DIS_SPARC_V8 0x01
-#define DIS_SPARC_V9 0x02
-#define DIS_SPARC_V9_SGI 0x04
-#define DIS_SPARC_V9_OPL 0x08
+#define DIS_SPARC_V8 0x001
+#define DIS_SPARC_V9 0x002
+#define DIS_SPARC_V9_SGI 0x004
+#define DIS_SPARC_V9_OPL 0x008
-/* x86 diassembler flags (mutually exclusive) */
-#define DIS_X86_SIZE16 0x08
-#define DIS_X86_SIZE32 0x10
-#define DIS_X86_SIZE64 0x20
+/* x86 diassembler flags */
+#define DIS_X86_SIZE16 0x100
+#define DIS_X86_SIZE32 0x010
+#define DIS_X86_SIZE64 0x020
/* generic disassembler flags */
-#define DIS_OCTAL 0x40
-#define DIS_NOIMMSYM 0x80
+#define DIS_OCTAL 0x040
+#define DIS_NOIMMSYM 0x080
+
+#define DIS_ARCH_MASK (DIS_SPARC_V8 | \
+ DIS_SPARC_V9 | DIS_SPARC_V9_SGI | DIS_SPARC_V9_OPL | \
+ DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64)
typedef int (*dis_lookup_f)(void *, uint64_t, char *, size_t, uint64_t *,
size_t *);
@@ -65,11 +70,13 @@ extern void dis_set_data(dis_handle_t *, void *);
extern void dis_flags_set(dis_handle_t *, int f);
extern void dis_flags_clear(dis_handle_t *, int f);
extern int dis_max_instrlen(dis_handle_t *);
+extern int dis_min_instrlen(dis_handle_t *);
extern int dis_instrlen(dis_handle_t *, uint64_t);
/* libdisasm errors */
#define E_DIS_NOMEM 1 /* Out of memory */
#define E_DIS_INVALFLAG 2 /* Invalid flag for this architecture */
+#define E_DIS_UNSUPARCH 3 /* Unsupported architecture */
extern int dis_errno(void);
extern const char *dis_strerror(int);
diff --git a/usr/src/lib/libdisasm/common/libdisasm_impl.h b/usr/src/lib/libdisasm/common/libdisasm_impl.h
index c31c24fe6a..a00c880076 100644
--- a/usr/src/lib/libdisasm/common/libdisasm_impl.h
+++ b/usr/src/lib/libdisasm/common/libdisasm_impl.h
@@ -22,21 +22,48 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _LIBDISASM_IMPL_H
#define _LIBDISASM_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
+#include <stdarg.h>
+#include <sys/sysmacros.h>
#ifdef __cplusplus
extern "C" {
#endif
+typedef struct dis_arch {
+ int (*da_supports_flags)(int);
+ int (*da_handle_attach)(dis_handle_t *);
+ void (*da_handle_detach)(dis_handle_t *);
+ int (*da_disassemble)(dis_handle_t *, uint64_t, char *, size_t);
+ uint64_t (*da_previnstr)(dis_handle_t *, uint64_t, int n);
+ int (*da_min_instrlen)(dis_handle_t *);
+ int (*da_max_instrlen)(dis_handle_t *);
+ int (*da_instrlen)(dis_handle_t *, uint64_t);
+} dis_arch_t;
+
+struct dis_handle {
+ void *dh_data;
+ int dh_flags;
+ dis_lookup_f dh_lookup;
+ dis_read_f dh_read;
+ uint64_t dh_addr;
+
+ dis_arch_t *dh_arch;
+ void *dh_arch_private;
+};
+
extern int dis_seterrno(int);
extern void *dis_zalloc(size_t);
extern void dis_free(void *, size_t);
+extern int dis_vsnprintf(char *restrict, size_t, const char *restrict, va_list);
+extern int dis_snprintf(char *restrict, size_t, const char *restrict, ...);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libdisasm/common/linktest_stand.c b/usr/src/lib/libdisasm/common/linktest_stand.c
index 36466b24fa..ce0d99f15a 100644
--- a/usr/src/lib/libdisasm/common/linktest_stand.c
+++ b/usr/src/lib/libdisasm/common/linktest_stand.c
@@ -24,16 +24,14 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This file is used to verify that the standalone's external dependencies
* haven't changed in a way that'll break things that use it.
*/
void mdb_free(void) {}
-void snprintf(void) {}
-void vsnprintf(void) {}
+void mdb_snprintf(void) {}
+void mdb_iob_vsnprintf(void) {}
void mdb_zalloc(void) {}
void strcmp(void) {}
void strlen(void) {}
diff --git a/usr/src/lib/libdisasm/common/mapfile-vers b/usr/src/lib/libdisasm/common/mapfile-vers
index 8261e04067..e7a5f9a170 100644
--- a/usr/src/lib/libdisasm/common/mapfile-vers
+++ b/usr/src/lib/libdisasm/common/mapfile-vers
@@ -46,6 +46,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
dis_handle_destroy;
dis_instrlen;
dis_max_instrlen;
+ dis_min_instrlen;
dis_previnstr;
dis_set_data;
dis_flags_set;
diff --git a/usr/src/lib/libdisasm/i386/Makefile b/usr/src/lib/libdisasm/i386/Makefile
index 8d0d4453a2..cba80ba7be 100644
--- a/usr/src/lib/libdisasm/i386/Makefile
+++ b/usr/src/lib/libdisasm/i386/Makefile
@@ -22,7 +22,6 @@
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
ISASRCDIR=.
@@ -34,3 +33,5 @@ INSTALL_DEPS_library = $(ROOTLINKS) $(ROOTLINT) $(ROOTLIBS)
INSTALL_DEPS_standalone = $(ROOTLIBS)
include ../Makefile.targ
+
+C99MODE = $(C99_ENABLE)
diff --git a/usr/src/lib/sun_sas/common/devtree_device_disco.c b/usr/src/lib/sun_sas/common/devtree_device_disco.c
index 3e8ad260b9..90fb546051 100644
--- a/usr/src/lib/sun_sas/common/devtree_device_disco.c
+++ b/usr/src/lib/sun_sas/common/devtree_device_disco.c
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <sun_sas.h>
@@ -587,19 +588,22 @@ get_attached_devices_info(di_node_t node, struct sun_sas_port *port_ptr)
guidStr = devid_to_guid(devid);
if (guidStr != NULL) {
(void) strlcpy(mapping_ptr->entry.LUID.buffer,
- guidStr, 256);
+ guidStr,
+ sizeof (mapping_ptr->entry.LUID.buffer));
devid_free_guid(guidStr);
} else {
/*
* Note:
* if logical unit associated page 83 id
* descriptor is not avaialble for the device
- * devid_to_guid returns NULl with errno 0.
+ * devid_to_guid returns NULL with errno 0.
*/
log(LOG_DEBUG, ROUTINE,
"failed to get devid guid on (%s) : %s",
devpath, strerror(errno));
}
+
+ devid_free(devid);
} else {
/*
* device may not support proper page 83 id descriptor.
@@ -1005,7 +1009,7 @@ get_attached_paths_info(di_path_t path, struct sun_sas_port *port_ptr)
* Note:
* if logical unit associated page 83 id
* descriptor is not avaialble for the device
- * devid_to_guid returns NULl with errno 0.
+ * devid_to_guid returns NULL with errno 0.
*/
log(LOG_DEBUG, ROUTINE,
"failed to get devid guid on (%s)",
@@ -1015,6 +1019,8 @@ get_attached_paths_info(di_path_t path, struct sun_sas_port *port_ptr)
"(missing device path)",
strerror(errno));
}
+
+ devid_free(devid);
} else {
/*
* device may not support proper page 83 id descriptor.