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