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);
|