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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdisasm/sparc/dis_sparc.c
          +++ new/usr/src/lib/libdisasm/common/dis_sparc.c
↓ open down ↓ 19 lines elided ↑ open up ↑
  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   25   */
  26   26  
  27   27  /*
  28   28   * Copyright 2007 Jason King.  All rights reserved.
  29   29   * Use is subject to license terms.
       30 + * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
  30   31   */
  31   32  
  32   33  
  33      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  34      -
  35   34  /*
  36   35   * The sparc disassembler is mostly straightforward, each instruction is
  37   36   * represented by an inst_t structure.  The inst_t definitions are organized
  38   37   * into tables.  The tables are correspond to the opcode maps documented in the
  39   38   * various sparc architecture manuals.  Each table defines the bit range of the
  40   39   * instruction whose value act as an index into the array of instructions.  A
  41   40   * table can also refer to another table if needed.  Each table also contains
  42   41   * a function pointer of type format_fcn that knows how to output the
  43   42   * instructions in the table, as well as handle any synthetic instructions
  44   43   *
↓ open down ↓ 53 lines elided ↑ open up ↑
  98   97  #include "dis_sparc.h"
  99   98  
 100   99  static const inst_t *dis_get_overlay(dis_handle_t *, const table_t *,
 101  100      uint32_t);
 102  101  static uint32_t dis_get_bits(uint32_t, int, int);
 103  102  
 104  103  #if !defined(DIS_STANDALONE)
 105  104  static void do_binary(uint32_t);
 106  105  #endif /* DIS_STANDALONE */
 107  106  
 108      -dis_handle_t *
 109      -dis_handle_create(int flags, void *data, dis_lookup_f lookup_func,
 110      -    dis_read_f read_func)
      107 +static void
      108 +dis_sparc_handle_detach(dis_handle_t *dhp)
 111  109  {
      110 +        dis_free(dhp->dh_arch_private, sizeof (dis_handle_sparc_t));
      111 +        dhp->dh_arch_private = NULL;
      112 +}
 112  113  
      114 +static int
      115 +dis_sparc_handle_attach(dis_handle_t *dhp)
      116 +{
      117 +        dis_handle_sparc_t *dhx;
      118 +
 113  119  #if !defined(DIS_STANDALONE)
 114  120          char *opt = NULL;
 115  121          char *opt2, *save, *end;
 116  122  #endif
 117      -        dis_handle_t *dhp;
 118  123  
 119      -        if ((flags & (DIS_SPARC_V8|DIS_SPARC_V9|DIS_SPARC_V9_SGI)) == 0) {
      124 +        /* Validate architecture flags */
      125 +        if ((dhp->dh_flags & (DIS_SPARC_V8|DIS_SPARC_V9|DIS_SPARC_V9_SGI))
      126 +            == 0) {
 120  127                  (void) dis_seterrno(E_DIS_INVALFLAG);
 121      -                return (NULL);
      128 +                return (-1);
 122  129          }
 123  130  
 124      -        if ((dhp = dis_zalloc(sizeof (struct dis_handle))) == NULL) {
      131 +        if ((dhx = dis_zalloc(sizeof (dis_handle_sparc_t))) == NULL) {
 125  132                  (void) dis_seterrno(E_DIS_NOMEM);
 126  133                  return (NULL);
 127  134          }
      135 +        dhx->dhx_debug = DIS_DEBUG_COMPAT;
      136 +        dhp->dh_arch_private = dhx;
 128  137  
 129      -        dhp->dh_lookup = lookup_func;
 130      -        dhp->dh_read = read_func;
 131      -        dhp->dh_flags = flags;
 132      -        dhp->dh_data = data;
 133      -        dhp->dh_debug = DIS_DEBUG_COMPAT;
 134      -
 135  138  #if !defined(DIS_STANDALONE)
 136  139  
 137  140          opt = getenv("_LIBDISASM_DEBUG");
 138  141          if (opt == NULL)
 139      -                return (dhp);
      142 +                return (0);
 140  143  
 141  144          opt2 = strdup(opt);
 142  145          if (opt2 == NULL) {
 143  146                  dis_handle_destroy(dhp);
      147 +                dis_free(dhx, sizeof (dis_handle_sparc_t));
 144  148                  (void) dis_seterrno(E_DIS_NOMEM);
 145      -                return (NULL);
      149 +                return (-1);
 146  150          }
 147  151          save = opt2;
 148  152  
 149  153          while (opt2 != NULL) {
 150  154                  end = strchr(opt2, ',');
 151  155  
 152  156                  if (end != 0)
 153  157                          *end++ = '\0';
 154  158  
 155  159                  if (strcasecmp("synth-all", opt2) == 0)
 156      -                        dhp->dh_debug |= DIS_DEBUG_SYN_ALL;
      160 +                        dhx->dhx_debug |= DIS_DEBUG_SYN_ALL;
 157  161  
 158  162                  if (strcasecmp("compat", opt2) == 0)
 159      -                        dhp->dh_debug |= DIS_DEBUG_COMPAT;
      163 +                        dhx->dhx_debug |= DIS_DEBUG_COMPAT;
 160  164  
 161  165                  if (strcasecmp("synth-none", opt2) == 0)
 162      -                        dhp->dh_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT);
      166 +                        dhx->dhx_debug &= ~(DIS_DEBUG_SYN_ALL|DIS_DEBUG_COMPAT);
 163  167  
 164  168                  if (strcasecmp("binary", opt2) == 0)
 165      -                        dhp->dh_debug |= DIS_DEBUG_PRTBIN;
      169 +                        dhx->dhx_debug |= DIS_DEBUG_PRTBIN;
 166  170  
 167  171                  if (strcasecmp("format", opt2) == 0)
 168      -                        dhp->dh_debug |= DIS_DEBUG_PRTFMT;
      172 +                        dhx->dhx_debug |= DIS_DEBUG_PRTFMT;
 169  173  
 170  174                  if (strcasecmp("all", opt2) == 0)
 171      -                        dhp->dh_debug = DIS_DEBUG_ALL;
      175 +                        dhx->dhx_debug = DIS_DEBUG_ALL;
 172  176  
 173  177                  if (strcasecmp("none", opt2) == 0)
 174      -                        dhp->dh_debug = DIS_DEBUG_NONE;
      178 +                        dhx->dhx_debug = DIS_DEBUG_NONE;
 175  179  
 176  180                  opt2 = end;
 177  181          }
 178  182          free(save);
 179  183  #endif /* DIS_STANDALONE */
 180      -        return (dhp);
      184 +        return (0);
 181  185  }
 182  186  
 183      -void
 184      -dis_handle_destroy(dis_handle_t *dhp)
      187 +/* ARGSUSED */
      188 +static int
      189 +dis_sparc_max_instrlen(dis_handle_t *dhp)
 185  190  {
 186      -        dis_free(dhp, sizeof (dis_handle_t));
      191 +        return (4);
 187  192  }
 188  193  
 189      -void
 190      -dis_set_data(dis_handle_t *dhp, void *data)
 191      -{
 192      -        dhp->dh_data = data;
 193      -}
 194      -
 195      -void
 196      -dis_flags_set(dis_handle_t *dhp, int f)
 197      -{
 198      -        dhp->dh_flags |= f;
 199      -}
 200      -
 201      -void
 202      -dis_flags_clear(dis_handle_t *dhp, int f)
 203      -{
 204      -        dhp->dh_flags &= ~f;
 205      -}
 206      -
 207  194  /* ARGSUSED */
 208      -int
 209      -dis_max_instrlen(dis_handle_t *dhp)
      195 +static int
      196 +dis_sparc_min_instrlen(dis_handle_t *dhp)
 210  197  {
 211  198          return (4);
 212  199  }
 213  200  
 214  201  /*
 215  202   * The dis_i386.c comment for this says it returns the previous instruction,
 216  203   * however, I'm fairly sure it's actually returning the _address_ of the
 217  204   * nth previous instruction.
 218  205   */
 219  206  /* ARGSUSED */
 220      -uint64_t
 221      -dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
      207 +static uint64_t
      208 +dis_sparc_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
 222  209  {
 223  210          if (n <= 0)
 224  211                  return (pc);
 225  212  
 226  213          if (pc < n)
 227  214                  return (pc);
 228  215  
 229  216          return (pc - n*4);
 230  217  }
 231  218  
 232      -int
 233      -dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
      219 +static int
      220 +dis_sparc_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf,
      221 +    size_t buflen)
 234  222  {
      223 +        dis_handle_sparc_t *dhx = dhp->dh_arch_private;
 235  224          const table_t *tp = &initial_table;
 236  225          const inst_t *inp = NULL;
 237  226  
 238  227          uint32_t instr;
 239  228          uint32_t idx = 0;
 240  229  
 241  230          if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) !=
 242  231              sizeof (instr))
 243  232                  return (-1);
 244  233  
 245      -        dhp->dh_buf    = buf;
 246      -        dhp->dh_buflen = buflen;
 247      -        dhp->dh_addr   = addr;
      234 +        dhx->dhx_buf    = buf;
      235 +        dhx->dhx_buflen = buflen;
      236 +        dhp->dh_addr    = addr;
 248  237  
 249  238          buf[0] = '\0';
 250  239  
 251  240          /* this allows sparc code to be tested on x86 */
      241 +#if !defined(DIS_STANDALONE)
 252  242          instr = BE_32(instr);
      243 +#endif /* DIS_STANDALONE */
 253  244  
 254  245  #if !defined(DIS_STANDALONE)
 255      -        if ((dhp->dh_debug & DIS_DEBUG_PRTBIN) != 0)
      246 +        if ((dhx->dhx_debug & DIS_DEBUG_PRTBIN) != 0)
 256  247                  do_binary(instr);
 257  248  #endif /* DIS_STANDALONE */
 258  249  
 259  250          /* CONSTCOND */
 260  251          while (1) {
 261  252                  idx = dis_get_bits(instr, tp->tbl_field, tp->tbl_len);
 262  253                  inp = &tp->tbl_inp[idx];
 263  254  
 264  255                  inp = dis_get_overlay(dhp, tp, idx);
 265  256  
↓ open down ↓ 64 lines elided ↑ open up ↑
 330  321  
 331  322  #if !defined(DIS_STANDALONE)
 332  323  static void
 333  324  do_binary(uint32_t instr)
 334  325  {
 335  326          (void) fprintf(stderr, "DISASM: ");
 336  327          prt_binary(instr, 32);
 337  328          (void) fprintf(stderr, "\n");
 338  329  }
 339  330  #endif /* DIS_STANDALONE */
      331 +
      332 +static int
      333 +dis_sparc_supports_flags(int flags)
      334 +{
      335 +        int archflags = flags & DIS_ARCH_MASK;
      336 +
      337 +        if (archflags == DIS_SPARC_V8 ||
      338 +            (archflags & (DIS_SPARC_V9 | DIS_SPARC_V8)) == DIS_SPARC_V9)
      339 +                return (1);
      340 +
      341 +        return (0);
      342 +}
      343 +
      344 +const dis_arch_t dis_arch_sparc = {
      345 +        dis_sparc_supports_flags,
      346 +        dis_sparc_handle_attach,
      347 +        dis_sparc_handle_detach,
      348 +        dis_sparc_disassemble,
      349 +        dis_sparc_previnstr,
      350 +        dis_sparc_min_instrlen,
      351 +        dis_sparc_max_instrlen
      352 +};
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX