Print this page
BE_32 wont work in libstand mode
take to dis and libdisasm with an axe; does not yet compile

*** 25,39 **** */ /* * Copyright 2007 Jason King. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" - /* * The sparc disassembler is mostly straightforward, each instruction is * represented by an inst_t structure. The inst_t definitions are organized * into tables. The tables are correspond to the opcode maps documented in the * various sparc architecture manuals. Each table defines the bit range of the --- 25,38 ---- */ /* * Copyright 2007 Jason King. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> */ /* * The sparc disassembler is mostly straightforward, each instruction is * represented by an inst_t structure. The inst_t definitions are organized * into tables. The tables are correspond to the opcode maps documented in the * various sparc architecture manuals. Each table defines the bit range of the
*** 103,150 **** #if !defined(DIS_STANDALONE) 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) { #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) { (void) dis_seterrno(E_DIS_INVALFLAG); ! return (NULL); } ! if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == 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; - #if !defined(DIS_STANDALONE) opt = getenv("_LIBDISASM_DEBUG"); if (opt == NULL) ! return (dhp); opt2 = strdup(opt); if (opt2 == NULL) { dis_handle_destroy(dhp); (void) dis_seterrno(E_DIS_NOMEM); ! return (NULL); } save = opt2; while (opt2 != NULL) { end = strchr(opt2, ','); --- 102,154 ---- #if !defined(DIS_STANDALONE) static void do_binary(uint32_t); #endif /* DIS_STANDALONE */ ! 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 ! /* 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 (-1); } ! if ((dhx = dis_zalloc(sizeof (dis_handle_sparc_t))) == NULL) { (void) dis_seterrno(E_DIS_NOMEM); return (NULL); } + dhx->dhx_debug = DIS_DEBUG_COMPAT; + dhp->dh_arch_private = dhx; #if !defined(DIS_STANDALONE) opt = getenv("_LIBDISASM_DEBUG"); if (opt == NULL) ! 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 (-1); } save = opt2; while (opt2 != NULL) { end = strchr(opt2, ',');
*** 151,214 **** if (end != 0) *end++ = '\0'; if (strcasecmp("synth-all", opt2) == 0) ! dhp->dh_debug |= DIS_DEBUG_SYN_ALL; if (strcasecmp("compat", opt2) == 0) ! dhp->dh_debug |= DIS_DEBUG_COMPAT; if (strcasecmp("synth-none", opt2) == 0) ! dhp->dh_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT); if (strcasecmp("binary", opt2) == 0) ! dhp->dh_debug |= DIS_DEBUG_PRTBIN; if (strcasecmp("format", opt2) == 0) ! dhp->dh_debug |= DIS_DEBUG_PRTFMT; if (strcasecmp("all", opt2) == 0) ! dhp->dh_debug = DIS_DEBUG_ALL; if (strcasecmp("none", opt2) == 0) ! dhp->dh_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; - } - - void - dis_flags_clear(dis_handle_t *dhp, int f) - { - dhp->dh_flags &= ~f; - } - /* ARGSUSED */ ! int ! dis_max_instrlen(dis_handle_t *dhp) { return (4); } /* --- 155,201 ---- if (end != 0) *end++ = '\0'; if (strcasecmp("synth-all", opt2) == 0) ! dhx->dhx_debug |= DIS_DEBUG_SYN_ALL; if (strcasecmp("compat", opt2) == 0) ! dhx->dhx_debug |= DIS_DEBUG_COMPAT; if (strcasecmp("synth-none", opt2) == 0) ! dhx->dhx_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT); if (strcasecmp("binary", opt2) == 0) ! dhx->dhx_debug |= DIS_DEBUG_PRTBIN; if (strcasecmp("format", opt2) == 0) ! dhx->dhx_debug |= DIS_DEBUG_PRTFMT; if (strcasecmp("all", opt2) == 0) ! dhx->dhx_debug = DIS_DEBUG_ALL; if (strcasecmp("none", opt2) == 0) ! dhx->dhx_debug = DIS_DEBUG_NONE; opt2 = end; } free(save); #endif /* DIS_STANDALONE */ ! return (0); } ! /* ARGSUSED */ ! static int ! dis_sparc_max_instrlen(dis_handle_t *dhp) { ! return (4); } /* ARGSUSED */ ! static int ! dis_sparc_min_instrlen(dis_handle_t *dhp) { return (4); } /*
*** 215,226 **** * The dis_i386.c comment for this says it returns the previous instruction, * however, I'm fairly sure it's actually returning the _address_ of the * nth previous instruction. */ /* ARGSUSED */ ! uint64_t ! dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n) { if (n <= 0) return (pc); if (pc < n) --- 202,213 ---- * The dis_i386.c comment for this says it returns the previous instruction, * however, I'm fairly sure it's actually returning the _address_ of the * nth previous instruction. */ /* ARGSUSED */ ! static uint64_t ! dis_sparc_previnstr(dis_handle_t *dhp, uint64_t pc, int n) { if (n <= 0) return (pc); if (pc < n)
*** 227,239 **** return (pc); return (pc - n*4); } ! int ! dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen) { const table_t *tp = &initial_table; const inst_t *inp = NULL; uint32_t instr; uint32_t idx = 0; --- 214,228 ---- return (pc); return (pc - n*4); } ! 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; uint32_t instr; uint32_t idx = 0;
*** 240,260 **** if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) != sizeof (instr)) return (-1); ! dhp->dh_buf = buf; ! dhp->dh_buflen = buflen; dhp->dh_addr = addr; buf[0] = '\0'; /* this allows sparc code to be tested on x86 */ instr = BE_32(instr); #if !defined(DIS_STANDALONE) ! if ((dhp->dh_debug & DIS_DEBUG_PRTBIN) != 0) do_binary(instr); #endif /* DIS_STANDALONE */ /* CONSTCOND */ while (1) { --- 229,251 ---- if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) != sizeof (instr)) return (-1); ! 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 ((dhx->dhx_debug & DIS_DEBUG_PRTBIN) != 0) do_binary(instr); #endif /* DIS_STANDALONE */ /* CONSTCOND */ while (1) {
*** 335,339 **** --- 326,352 ---- (void) fprintf(stderr, "DISASM: "); prt_binary(instr, 32); (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 + };