diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-01-26 12:53:40 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2015-01-26 12:53:40 +0000 |
| commit | 6d28d28825ce8837a909f5155a527518b07b1926 (patch) | |
| tree | 737c7936ffd4a511cd7d9ae34ecddb4e98d291f5 /usr/src | |
| parent | c0e498928e0811212fda8b3b7090689d16618028 (diff) | |
| parent | b045990893825c31e176b319ae8cc4ef32115d17 (diff) | |
| download | illumos-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')
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. |
