Print this page
saveargs: let disasm do the lifting


  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2007 Jason King.  All rights reserved.
  29  * Use is subject to license terms.
  30  */
  31 
  32 
  33 #pragma ident   "%Z%%M% %I%     %E% SMI"
  34 
  35 /*
  36  * The sparc disassembler is mostly straightforward, each instruction is
  37  * represented by an inst_t structure.  The inst_t definitions are organized
  38  * into tables.  The tables are correspond to the opcode maps documented in the
  39  * various sparc architecture manuals.  Each table defines the bit range of the
  40  * instruction whose value act as an index into the array of instructions.  A
  41  * table can also refer to another table if needed.  Each table also contains
  42  * a function pointer of type format_fcn that knows how to output the
  43  * instructions in the table, as well as handle any synthetic instructions
  44  *
  45  * Unfortunately, the changes from sparcv8 -> sparcv9 not only include new
  46  * instructions, they sometimes renamed or just reused the same instruction to
  47  * do different operations (i.e. the sparcv8 coprocessor instructions).  To
  48  * accommodate this, each table can define an overlay table.  The overlay table
  49  * is a list of (table index, architecture, new instruction definition) values.
  50  *
  51  *
  52  * Traversal starts with the first table,
  53  *   get index value from the instruction
  54  *   if an relevant overlay entry exists for this index,


 213 
 214 /*
 215  * The dis_i386.c comment for this says it returns the previous instruction,
 216  * however, I'm fairly sure it's actually returning the _address_ of the
 217  * nth previous instruction.
 218  */
 219 /* ARGSUSED */
 220 uint64_t
 221 dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
 222 {
 223         if (n <= 0)
 224                 return (pc);
 225 
 226         if (pc < n)
 227                 return (pc);
 228 
 229         return (pc - n*4);
 230 }
 231 
 232 int






 233 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
 234 {
 235         const table_t *tp = &initial_table;
 236         const inst_t *inp = NULL;
 237 
 238         uint32_t instr;
 239         uint32_t idx = 0;
 240 
 241         if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) !=
 242             sizeof (instr))
 243                 return (-1);
 244 
 245         dhp->dh_buf    = buf;
 246         dhp->dh_buflen = buflen;
 247         dhp->dh_addr   = addr;
 248 
 249         buf[0] = '\0';
 250 
 251         /* this allows sparc code to be tested on x86 */
 252         instr = BE_32(instr);




  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2007 Jason King.  All rights reserved.
  29  * Use is subject to license terms.
  30  */
  31 



  32 /*
  33  * The sparc disassembler is mostly straightforward, each instruction is
  34  * represented by an inst_t structure.  The inst_t definitions are organized
  35  * into tables.  The tables are correspond to the opcode maps documented in the
  36  * various sparc architecture manuals.  Each table defines the bit range of the
  37  * instruction whose value act as an index into the array of instructions.  A
  38  * table can also refer to another table if needed.  Each table also contains
  39  * a function pointer of type format_fcn that knows how to output the
  40  * instructions in the table, as well as handle any synthetic instructions
  41  *
  42  * Unfortunately, the changes from sparcv8 -> sparcv9 not only include new
  43  * instructions, they sometimes renamed or just reused the same instruction to
  44  * do different operations (i.e. the sparcv8 coprocessor instructions).  To
  45  * accommodate this, each table can define an overlay table.  The overlay table
  46  * is a list of (table index, architecture, new instruction definition) values.
  47  *
  48  *
  49  * Traversal starts with the first table,
  50  *   get index value from the instruction
  51  *   if an relevant overlay entry exists for this index,


 210 
 211 /*
 212  * The dis_i386.c comment for this says it returns the previous instruction,
 213  * however, I'm fairly sure it's actually returning the _address_ of the
 214  * nth previous instruction.
 215  */
 216 /* ARGSUSED */
 217 uint64_t
 218 dis_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
 219 {
 220         if (n <= 0)
 221                 return (pc);
 222 
 223         if (pc < n)
 224                 return (pc);
 225 
 226         return (pc - n*4);
 227 }
 228 
 229 int
 230 dis_instrlen(dis_handle_t *dhp, uint64_t pc)
 231 {
 232         return (4);
 233 }
 234 
 235 int
 236 dis_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
 237 {
 238         const table_t *tp = &initial_table;
 239         const inst_t *inp = NULL;
 240 
 241         uint32_t instr;
 242         uint32_t idx = 0;
 243 
 244         if (dhp->dh_read(dhp->dh_data, addr, &instr, sizeof (instr)) !=
 245             sizeof (instr))
 246                 return (-1);
 247 
 248         dhp->dh_buf    = buf;
 249         dhp->dh_buflen = buflen;
 250         dhp->dh_addr   = addr;
 251 
 252         buf[0] = '\0';
 253 
 254         /* this allows sparc code to be tested on x86 */
 255         instr = BE_32(instr);