|
|
1.1 root 1: /* Print GOULD RISC instructions for GDB, the GNU debugger.
2: Copyright (C) 1986, 1987 Free Software Foundation, Inc.
3:
4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5: WARRANTY. No author or distributor accepts responsibility to anyone
6: for the consequences of using it or for whether it serves any
7: particular purpose or works at all, unless he says so in writing.
8: Refer to the GDB General Public License for full details.
9:
10: Everyone is granted permission to copy, modify and redistribute GDB,
11: but only under the conditions described in the GDB General Public
12: License. A copy of this license is supposed to have been given to you
13: along with GDB so you can know your rights and responsibilities. It
14: should be in a file named COPYING. Among other things, the copyright
15: notice and this notice must be preserved on all copies.
16:
17: In other words, go ahead and share GDB, but don't try to stop
18: anyone else from sharing it farther. Help stamp out software hoarding!
19: */
20:
21: #include <stdio.h>
22: #include <a.out.h>
23:
24: #include "defs.h"
25: #include "param.h"
26: #include "symtab.h"
27: #include "frame.h"
28: #include "opcode.h"
29:
30: /* GOULD RISC instructions are never longer than this many bytes. */
31: #define MAXLEN 4
32:
33: /* Number of elements in the opcode table. */
34: #define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
35:
36:
37: /* Print the GOULD instruction at address MEMADDR in debugged memory,
38: on STREAM. Returns length of the instruction, in bytes. */
39:
40: int
41: print_insn (memaddr, stream)
42: CORE_ADDR memaddr;
43: FILE *stream;
44: {
45: unsigned char buffer[MAXLEN];
46: register int i;
47: register char *d;
48: register int bestmask;
49: unsigned best;
50: int temp, index, bestlen;
51:
52: read_memory (memaddr, buffer, MAXLEN);
53:
54: bestmask = 0;
55: index = -1;
56: best = 0xffffffff;
57: for (i = 0; i < NOPCODES; i++)
58: {
59: register unsigned int opcode = gld_opcodes[i].opcode;
60: register unsigned int mask = gld_opcodes[i].mask;
61: register unsigned int len = gld_opcodes[i].length;
62: register unsigned int test;
63:
64: /* Get possible opcode bytes into integer */
65: test = buffer[0] << 24;
66: test |= buffer[1] << 16;
67: test |= buffer[2] << 8;
68: test |= buffer[3];
69:
70: /* Mask with opcode and see if match */
71: if ((opcode & mask) == (test & mask))
72: {
73: /* See if second or third match */
74: if (index >= 0)
75: {
76: /* Take new one if it looks good */
77: if (bestlen == MAXLEN && len == MAXLEN)
78: {
79: /* See if lower bits matched */
80: if (((bestmask & 3) == 0) &&
81: ((mask & 3) != 0))
82: {
83: bestmask = mask;
84: bestlen = len;
85: best = test;
86: index = i;
87: }
88: }
89: }
90: else
91: {
92: /* First match, save it */
93: bestmask = mask;
94: bestlen = len;
95: best = test;
96: index = i;
97: }
98: }
99: }
100:
101: /* Handle undefined instructions. */
102: if (index < 0)
103: {
104: fprintf (stream, "undefined 0%o",(buffer[0]<<8)+buffer[1]);
105: return 2;
106: }
107:
108: /* Print instruction name */
109: fprintf (stream, "%-12s", gld_opcodes[index].name);
110:
111: /* Adjust if short instruction */
112: if (gld_opcodes[index].length < 4)
113: {
114: best >>= 16;
115: i = 0;
116: }
117: else
118: {
119: i = 16;
120: }
121:
122: /* Dump out instruction arguments */
123: for (d = gld_opcodes[index].args; *d; ++d)
124: {
125: switch (*d)
126: {
127: case 'f':
128: fprintf (stream, "%d", (best >> (7 + i)) & 7);
129: break;
130: case 'r':
131: fprintf (stream, "r%d", (best >> (7 + i)) & 7);
132: break;
133: case 'R':
134: fprintf (stream, "r%d", (best >> (4 + i)) & 7);
135: break;
136: case 'b':
137: fprintf (stream, "b%d", (best >> (7 + i)) & 7);
138: break;
139: case 'B':
140: fprintf (stream, "b%d", (best >> (4 + i)) & 7);
141: break;
142: case 'v':
143: fprintf (stream, "b%d", (best >> (7 + i)) & 7);
144: break;
145: case 'V':
146: fprintf (stream, "b%d", (best >> (4 + i)) & 7);
147: break;
148: case 'X':
149: temp = (best >> 20) & 7;
150: if (temp)
151: fprintf (stream, "r%d", temp);
152: else
153: putc ('0', stream);
154: break;
155: case 'A':
156: temp = (best >> 16) & 7;
157: if (temp)
158: fprintf (stream, "(b%d)", temp);
159: break;
160: case 'S':
161: fprintf (stream, "#%d", best & 0x1f);
162: break;
163: case 'I':
164: fprintf (stream, "#%x", best & 0xffff);
165: break;
166: case 'O':
167: fprintf (stream, "%x", best & 0xffff);
168: break;
169: case 'h':
170: fprintf (stream, "%d", best & 0xfffe);
171: break;
172: case 'd':
173: fprintf (stream, "%d", best & 0xfffc);
174: break;
175: case 'T':
176: fprintf (stream, "%d", (best >> 8) & 0xff);
177: break;
178: case 'N':
179: fprintf (stream, "%d", best & 0xff);
180: break;
181: default:
182: putc (*d, stream);
183: break;
184: }
185: }
186:
187: /* Return length of instruction */
188: return (gld_opcodes[index].length);
189: }
190:
191: /*
192: * Find the number of arguments to a function.
193: */
194: findarg(frame)
195: struct frame_info frame;
196: {
197: register struct symbol *func;
198: register unsigned pc;
199:
200: #ifdef notdef
201: /* find starting address of frame function */
202: pc = get_pc_function_start (frame.pc);
203:
204: /* find function symbol info */
205: func = find_pc_function (pc);
206:
207: /* call blockframe code to look for match */
208: if (func != NULL)
209: return (func->value.block->nsyms / sizeof(int));
210: #endif
211:
212: return (-1);
213: }
214:
215: /*
216: * In the case of the NPL, the frame's norminal address is Br2 and the
217: * previous routines frame is up the stack X bytes. Finding out what
218: * 'X' is can be tricky.
219: *
220: * 1.) stored in the code function header xA(Br1).
221: * 2.) must be careful of recurssion.
222: */
223: findframe(thisframe)
224: FRAME thisframe;
225: {
226: register FRAME pointer;
227: struct frame_info frame;
228:
229: /* Setup toplevel frame structure */
230: frame.pc = read_pc();
231: frame.next_frame = 0;
232: frame.frame = read_register (SP_REGNUM); /* Br2 */
233:
234: /* Search for this frame (start at current Br2) */
235: do
236: {
237: pointer = framechain(frame);
238: frame.next_frame = frame.frame;
239: frame.frame = pointer;
240: frame.pc = FRAME_SAVED_PC(frame.next_frame);
241: }
242: while (frame.next_frame != thisframe);
243:
244: /* stop gap for now, end at __base3 */
245: if (frame.pc == 0)
246: return 0;
247:
248: return pointer;
249: }
250:
251: /*
252: * Gdb front-end and internal framechain routine.
253: * Go back up stack one level. Tricky...
254: */
255: framechain(frame)
256: register struct frame_info frame;
257: {
258: register CORE_ADDR func, prevsp;
259: register unsigned value;
260:
261: /* Get real function start address from internal frame address */
262: func = get_pc_function_start(frame.pc);
263:
264: /* If no stack given, read register Br1 "(sp)" */
265: if (!frame.frame)
266: prevsp = read_register (SP_REGNUM);
267: else
268: prevsp = frame.frame;
269:
270: /* Check function header, case #2 */
271: value = read_memory_integer (func, 4);
272: if (value)
273: {
274: /* 32bit call push value stored in function header */
275: prevsp += value;
276: }
277: else
278: {
279: /* read half-word from suabr at start of function */
280: prevsp += read_memory_integer (func + 10, 2);
281: }
282:
283: return (prevsp);
284: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.