]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ppc/db_disasm.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / osfmk / ppc / db_disasm.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31
32/*
33 * Instruction disassembler.
34 */
35
36#include <mach/boolean.h>
37#include <machine/db_machdep.h>
38
39#include <ddb/db_access.h>
40#include <ddb/db_sym.h>
41#include <ddb/db_output.h>
42
43#include <kern/task.h>
44#include <kern/misc_protos.h>
45
46#include "ppc_disasm.h"
47
48db_addr_t db_disasm_pc, db_disasm_symaddr;
49boolean_t db_disasm_print_symaddr;
50
51/*
52 * Disassemble instruction at 'loc'. 'altfmt' specifies an
53 * (optional) alternate format. Return address of start of
54 * next instruction.
55 */
56db_addr_t
57db_disasm(
58 db_addr_t loc,
59 boolean_t altfmt,
60 task_t task)
61{
62 int inst;
63 char *p;
64
65 inst = db_get_task_value(loc, 4, FALSE, task);
66 db_disasm_pc = loc;
67 db_disasm_print_symaddr = FALSE;
68 p = in(inst);
69 db_printf("%s", p);
70 if (db_disasm_print_symaddr) {
71 db_printf(" <");
72 db_task_printsym(db_disasm_symaddr, DB_STGY_ANY, task);
73 db_printf(">");
74 }
55e303ae 75 db_printf("\n"); /* Make sure we have a new line for multiline displays */
1c79356b
A
76 dis_done();
77 return (loc+4);
78}
79
80/*
81 * Given four bytes of instruction (stored as an int, not an
82 * array of characters), compute if the instruction reads
83 * memory.
84 */
85int
86db_inst_load(
87 unsigned long insw)
88{
89#if 1
90 db_printf("db_inst_load: coming soon in a debugger near you!\n");
91 return 0;
92#else
93 unsigned char insb, bits;
94
95 insb = insw & 0xff;
96 insw >>= 8;
97 bits = db_ldstrtab[insb];
98 if (!(bits & DBLS_LOAD))
99 return (0);
100 while (1) {
101 switch (bits & DBLS_MODS) {
102 case 0:
103 return (1);
104 case DBLS_MODRM:
105 insb = insw & 0xff;
106 return ((insb & 0xc0) != 0xc0);
107 case DBLS_SECOND|DBLS_MODRM:
108 insb = insw & 0xff;
109 return ((insb & 0xc0) != 0xc0 ? 2 : 0);
110 case DBLS_SECOND:
111 return (2);
112 case DBLS_ESCAPE:
113 insb = insw & 0xff;
114 insw >>= 8;
115 bits = db_ldstrtab0f[insb];
116 break;
117 case DBLS_SWREG:
118 return (db_inst_swreg(TRUE, insw, insb));
119 default:
120 panic ("db_inst_load: unknown mod bits");
121 }
122 }
123#endif
124}
125
126/*
127 * Given four bytes of instruction (stored as an int, not an
128 * array of characters), compute if the instruction writes
129 * memory.
130 */
131int
132db_inst_store(
133 unsigned long insw)
134{
135#if 1
136 db_printf("db_inst_store: coming soon in a debugger near you!\n");
137 return 0;
138#else
139 unsigned char insb, bits;
140
141 insb = insw & 0xff;
142 insw >>= 8;
143 bits = db_ldstrtab[insb];
144 if (!(bits & DBLS_STORE))
145 return (0);
146 while (1) {
147 switch (bits & DBLS_MODS) {
148 case 0:
149 return (1);
150 case DBLS_MODRM:
151 insb = insw & 0xff;
152 return ((insb & 0xc0) != 0xc0);
153 case DBLS_SECOND|DBLS_MODRM:
154 insb = insw & 0xff;
155 return ((insb & 0xc0) != 0xc0 ? 2 : 0);
156 case DBLS_SECOND:
157 return (2);
158 case DBLS_ESCAPE:
159 insb = insw & 0xff;
160 insw >>= 8;
161 bits = db_ldstrtab0f[insb];
162 break;
163 case DBLS_SWREG:
164 return (db_inst_swreg(FALSE, insw, insb));
165 default:
166 panic ("db_inst_store: unknown mod bits");
167 }
168 }
169#endif
170}
171
172/*
173 * Extra routines for the automatically generated disassembler
174 */
175char *
176hex(
177 bits n)
178{
179 char *p;
180
181 if (n < 10)
182 return dec(n);
183 p = dis_alloc(11);
184 sprintf(p, "0x%lx", n);
185 return p;
186}
187
188char *
189dec(
190 bits n)
191{
192 char *p = dis_alloc(11);
193 sprintf(p, "%lu", n);
194 return p;
195}
196
197char *
198brdispl(
199 bits displ,
200 bits nbits)
201{
202 int sign, extended;
203
204 sign = 1 << (nbits - 1);
205 extended = (displ & sign ? displ - (sign << 1) : displ);
206 db_disasm_symaddr = db_disasm_pc + (extended << 2);
207 db_disasm_print_symaddr = TRUE;
208 return hex(extended << 2);
209}
210
211char *
212mbz(
213 bits n)
214{
215 return n ? "[reserved bits not zero]" : "";
216}
217
218size_t db_disasm_string_size = 0;
219#define DB_DISASM_STRING_MAXSIZE 4096
220char db_disasm_string[DB_DISASM_STRING_MAXSIZE];
221
222void *db_disasm_malloc(size_t size); /* forward */
223void *
224db_disasm_malloc(
225 size_t size)
226{
227 void * new_buf;
228
229 if (db_disasm_string_size + size <= DB_DISASM_STRING_MAXSIZE) {
230 new_buf = (void *) (db_disasm_string + db_disasm_string_size);
231 db_disasm_string_size += size;
232 return new_buf;
233 }
234 db_printf("db_disasm_malloc(size=%d) failed: %d left !\n",
235 size,
236 DB_DISASM_STRING_MAXSIZE - db_disasm_string_size);
237 return (void *) 0;
238}