Print this page
take to dis and libdisasm with an axe; does not yet compile

*** 20,50 **** */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" - #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; ! }; /* * Returns true if we are near the end of a function. This is a cheap hack at * detecting NULL padding between functions. If we're within a few bytes of the * next function, or past the start, then return true. --- 20,44 ---- */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> */ #include <libdisasm.h> #include <stdlib.h> #include <stdio.h> #include "dis_tables.h" #include "libdisasm_impl.h" ! 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 * detecting NULL padding between functions. If we're within a few bytes of the * next function, or past the start, then return true.
*** 87,198 **** dis_handle_t *dhp = data; 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) { ! dis_handle_t *dhp; /* * Validate architecture flags */ ! if (flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 | DIS_OCTAL | DIS_NOIMMSYM)) { (void) dis_seterrno(E_DIS_INVALFLAG); ! return (NULL); } /* * Create and initialize the internal structure */ ! 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; - /* * Initialize x86-specific architecture structure */ ! if (flags & DIS_X86_SIZE16) ! dhp->dh_mode = SIZE16; ! else if (flags & DIS_X86_SIZE64) ! dhp->dh_mode = SIZE64; else ! dhp->dh_mode = SIZE32; ! if (flags & DIS_OCTAL) ! dhp->dh_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; ! dhp->dh_dis.d86_data = dhp; ! return (dhp); } ! int ! dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen) { 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; else ! dhp->dh_dis.d86_flags &= ~DIS_F_NOIMMSYM; ! if (dtrace_disx86(&dhp->dh_dis, dhp->dh_mode) != 0) return (-1); if (buf != NULL) ! dtrace_disx86_str(&dhp->dh_dis, dhp->dh_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) - { - dhp->dh_flags &= ~f; - } - - /* ARGSUSED */ ! int ! dis_max_instrlen(dis_handle_t *dhp) { ! return (15); } #define MIN(a, b) ((a) < (b) ? (a) : (b)) /* --- 81,178 ---- dis_handle_t *dhp = data; return (dhp->dh_lookup(dhp->dh_data, addr, buf, buflen, NULL, NULL)); } ! 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_i386_t *dhx; + /* * Validate architecture flags */ ! if (dhp->dh_flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 | DIS_OCTAL | DIS_NOIMMSYM)) { (void) dis_seterrno(E_DIS_INVALFLAG); ! return (-1); } /* * Create and initialize the internal structure */ ! if ((dhx = dis_zalloc(sizeof (dis_handle_i386_t))) == NULL) { (void) dis_seterrno(E_DIS_NOMEM); ! return (-1); } + dhp->dh_arch_private = dhx; /* * Initialize x86-specific architecture structure */ ! if (dhp->dh_flags & DIS_X86_SIZE16) ! dhx->dhx_mode = SIZE16; ! else if (dhp->dh_flags & DIS_X86_SIZE64) ! dhx->dhx_mode = SIZE64; else ! dhx->dhx_mode = SIZE32; ! if (dhp->dh_flags & DIS_OCTAL) ! dhx->dhx_dis.d86_flags = DIS_F_OCTAL; ! dhx->dhx_dis.d86_sprintf_func = 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; ! dhx->dhx_dis.d86_data = dhp; ! return (0); } ! 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) ! dhx->dhx_dis.d86_flags |= DIS_F_NOIMMSYM; else ! dhx->dhx_dis.d86_flags &= ~DIS_F_NOIMMSYM; ! if (dtrace_disx86(&dhx->dhx_dis, dhx->dhx_mode) != 0) return (-1); if (buf != NULL) ! dtrace_disx86_str(&dhx->dhx_dis, dhx->dhx_mode, addr, buf, buflen); return (0); } ! /* ARGSUSED */ ! static int ! dis_i386_max_instrlen(dis_handle_t *dhp) { ! return (15); } /* ARGSUSED */ ! static int ! dis_i386_min_instrlen(dis_handle_t *dhp) { ! return (1); } #define MIN(a, b) ((a) < (b) ? (a) : (b)) /*
*** 199,210 **** * 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) { uint64_t *hist, addr, start; int cur, nseen; uint64_t res = pc; --- 179,190 ---- * 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. */ ! static uint64_t ! dis_i386_previnstr(dis_handle_t *dhp, uint64_t pc, int n) { uint64_t *hist, addr, start; int cur, nseen; uint64_t res = pc;
*** 243,247 **** --- 223,249 ---- done: dis_free(hist, sizeof (uint64_t) * n); return (res); } + + 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); + } + + 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 + };