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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdisasm/i386/dis_i386.c
          +++ new/usr/src/lib/libdisasm/common/dis_i386.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
  25   26   */
  26   27  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   28  #include <libdisasm.h>
  30   29  #include <stdlib.h>
  31   30  #include <stdio.h>
  32   31  
  33   32  #include "dis_tables.h"
  34   33  #include "libdisasm_impl.h"
  35   34  
  36      -struct dis_handle {
  37      -        void            *dh_data;
  38      -        int             dh_flags;
  39      -        dis_lookup_f    dh_lookup;
  40      -        dis_read_f      dh_read;
  41      -        int             dh_mode;
  42      -        dis86_t         dh_dis;
  43      -        uint64_t        dh_addr;
  44      -        uint64_t        dh_end;
  45      -};
       35 +typedef struct dis_handle_i386 {
       36 +        int             dhx_mode;
       37 +        dis86_t         dhx_dis;
       38 +        uint64_t        dhx_end;
       39 +} dis_handle_i386_t;
  46   40  
  47   41  /*
  48   42   * Returns true if we are near the end of a function.  This is a cheap hack at
  49   43   * detecting NULL padding between functions.  If we're within a few bytes of the
  50   44   * next function, or past the start, then return true.
  51   45   */
  52   46  static int
  53   47  check_func(void *data)
  54   48  {
  55   49          dis_handle_t *dhp = data;
↓ open down ↓ 26 lines elided ↑ open up ↑
  82   76  }
  83   77  
  84   78  static int
  85   79  do_lookup(void *data, uint64_t addr, char *buf, size_t buflen)
  86   80  {
  87   81          dis_handle_t *dhp = data;
  88   82  
  89   83          return (dhp->dh_lookup(dhp->dh_data, addr, buf, buflen, NULL, NULL));
  90   84  }
  91   85  
  92      -dis_handle_t *
  93      -dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
  94      -    dis_read_f read_func)
       86 +static void
       87 +dis_i386_handle_detach(dis_handle_t *dhp)
  95   88  {
  96      -        dis_handle_t *dhp;
       89 +        dis_free(dhp->dh_arch_private, sizeof (dis_handle_i386_t));
       90 +        dhp->dh_arch_private = NULL;
       91 +}
  97   92  
       93 +static int
       94 +dis_i386_handle_attach(dis_handle_t *dhp)
       95 +{
       96 +        dis_handle_i386_t *dhx;
       97 +
  98   98          /*
  99   99           * Validate architecture flags
 100  100           */
 101      -        if (flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 |
      101 +        if (dhp->dh_flags & ~(DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 |
 102  102              DIS_OCTAL | DIS_NOIMMSYM)) {
 103  103                  (void) dis_seterrno(E_DIS_INVALFLAG);
 104      -                return (NULL);
      104 +                return (-1);
 105  105          }
 106  106  
 107  107          /*
 108  108           * Create and initialize the internal structure
 109  109           */
 110      -        if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
      110 +        if ((dhx = dis_zalloc(sizeof (dis_handle_i386_t))) == NULL) {
 111  111                  (void) dis_seterrno(E_DIS_NOMEM);
 112      -                return (NULL);
      112 +                return (-1);
 113  113          }
      114 +        dhp->dh_arch_private = dhx;
 114  115  
 115      -        dhp->dh_lookup = lookup_func;
 116      -        dhp->dh_read = read_func;
 117      -        dhp->dh_flags = flags;
 118      -        dhp->dh_data = data;
 119      -
 120  116          /*
 121  117           * Initialize x86-specific architecture structure
 122  118           */
 123      -        if (flags & DIS_X86_SIZE16)
 124      -                dhp->dh_mode = SIZE16;
 125      -        else if (flags & DIS_X86_SIZE64)
 126      -                dhp->dh_mode = SIZE64;
      119 +        if (dhp->dh_flags & DIS_X86_SIZE16)
      120 +                dhx->dhx_mode = SIZE16;
      121 +        else if (dhp->dh_flags & DIS_X86_SIZE64)
      122 +                dhx->dhx_mode = SIZE64;
 127  123          else
 128      -                dhp->dh_mode = SIZE32;
      124 +                dhx->dhx_mode = SIZE32;
 129  125  
 130      -        if (flags & DIS_OCTAL)
 131      -                dhp->dh_dis.d86_flags = DIS_F_OCTAL;
      126 +        if (dhp->dh_flags & DIS_OCTAL)
      127 +                dhx->dhx_dis.d86_flags = DIS_F_OCTAL;
 132  128  
 133      -        dhp->dh_dis.d86_sprintf_func = snprintf;
 134      -        dhp->dh_dis.d86_get_byte = get_byte;
 135      -        dhp->dh_dis.d86_sym_lookup = do_lookup;
 136      -        dhp->dh_dis.d86_check_func = check_func;
      129 +        dhx->dhx_dis.d86_sprintf_func = snprintf;
      130 +        dhx->dhx_dis.d86_get_byte = get_byte;
      131 +        dhx->dhx_dis.d86_sym_lookup = do_lookup;
      132 +        dhx->dhx_dis.d86_check_func = check_func;
 137  133  
 138      -        dhp->dh_dis.d86_data = dhp;
      134 +        dhx->dhx_dis.d86_data = dhp;
 139  135  
 140      -        return (dhp);
      136 +        return (0);
 141  137  }
 142  138  
 143      -int
 144      -dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
      139 +static int
      140 +dis_i386_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf,
      141 +    size_t buflen)
 145  142  {
      143 +        dis_handle_i386_t *dhx = dhp->dh_arch_private;
 146  144          dhp->dh_addr = addr;
 147  145  
 148  146          /* DIS_NOIMMSYM might not be set until now, so update */
 149  147          if (dhp->dh_flags & DIS_NOIMMSYM)
 150      -                dhp->dh_dis.d86_flags |= DIS_F_NOIMMSYM;
      148 +                dhx->dhx_dis.d86_flags |= DIS_F_NOIMMSYM;
 151  149          else
 152      -                dhp->dh_dis.d86_flags &= ~DIS_F_NOIMMSYM;
      150 +                dhx->dhx_dis.d86_flags &= ~DIS_F_NOIMMSYM;
 153  151  
 154      -        if (dtrace_disx86(&dhp->dh_dis, dhp->dh_mode) != 0)
      152 +        if (dtrace_disx86(&dhx->dhx_dis, dhx->dhx_mode) != 0)
 155  153                  return (-1);
 156  154  
 157  155          if (buf != NULL)
 158      -                dtrace_disx86_str(&dhp->dh_dis, dhp->dh_mode, addr, buf,
      156 +                dtrace_disx86_str(&dhx->dhx_dis, dhx->dhx_mode, addr, buf,
 159  157                      buflen);
 160  158  
 161  159          return (0);
 162  160  }
 163  161  
 164      -void
 165      -dis_handle_destroy(dis_handle_t *dhp)
      162 +/* ARGSUSED */
      163 +static int
      164 +dis_i386_max_instrlen(dis_handle_t *dhp)
 166  165  {
 167      -        dis_free(dhp, sizeof (dis_handle_t));
      166 +        return (15);
 168  167  }
 169  168  
 170      -void
 171      -dis_set_data(dis_handle_t *dhp, void *data)
 172      -{
 173      -        dhp->dh_data = data;
 174      -}
 175      -
 176      -void
 177      -dis_flags_set(dis_handle_t *dhp, int f)
 178      -{
 179      -        dhp->dh_flags |= f;
 180      -}
 181      -
 182      -void
 183      -dis_flags_clear(dis_handle_t *dhp, int f)
 184      -{
 185      -        dhp->dh_flags &= ~f;
 186      -}
 187      -
 188      -
 189  169  /* ARGSUSED */
 190      -int
 191      -dis_max_instrlen(dis_handle_t *dhp)
      170 +static int
      171 +dis_i386_min_instrlen(dis_handle_t *dhp)
 192  172  {
 193      -        return (15);
      173 +        return (1);
 194  174  }
 195  175  
 196  176  #define MIN(a, b)       ((a) < (b) ? (a) : (b))
 197  177  
 198  178  /*
 199  179   * Return the previous instruction.  On x86, we have no choice except to
 200  180   * disassemble everything from the start of the symbol, and stop when we have
 201  181   * reached our instruction address.  If we're not in the middle of a known
 202  182   * symbol, then we return the same address to indicate failure.
 203  183   */
 204      -uint64_t
 205      -dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
      184 +static uint64_t
      185 +dis_i386_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
 206  186  {
 207  187          uint64_t *hist, addr, start;
 208  188          int cur, nseen;
 209  189          uint64_t res = pc;
 210  190  
 211  191          if (n <= 0)
 212  192                  return (pc);
 213  193  
 214  194          if (dhp->dh_lookup(dhp->dh_data, pc, NULL, 0, &start, NULL) != 0 ||
 215  195              start == pc)
↓ open down ↓ 22 lines elided ↑ open up ↑
 238  218                   */
 239  219                  goto done;
 240  220          }
 241  221  
 242  222          res = hist[(cur + n - MIN(n, nseen)) % n];
 243  223  
 244  224  done:
 245  225          dis_free(hist, sizeof (uint64_t) * n);
 246  226          return (res);
 247  227  }
      228 +
      229 +static int
      230 +dis_i386_supports_flags(int flags)
      231 +{
      232 +        int archflags = flags & DIS_ARCH_MASK;
      233 +
      234 +        if (archflags == DIS_X86_SIZE16 || archflags == DIS_X86_SIZE32 ||
      235 +            archflags == DIS_X86_SIZE64)
      236 +                return (1);
      237 +
      238 +        return (0);
      239 +}
      240 +
      241 +dis_arch_t dis_arch_i386 = {
      242 +        dis_i386_supports_flags,
      243 +        dis_i386_handle_attach,
      244 +        dis_i386_handle_detach,
      245 +        dis_i386_disassemble,
      246 +        dis_i386_previnstr,
      247 +        dis_i386_min_instrlen,
      248 +        dis_i386_max_instrlen
      249 +};
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX