|
|
1.1 root 1: /*
2: Date: Thu, 2 Apr 87 00:02:42 EST
3: From: [email protected] (Charles R. LaBrec)
4: Message-Id: <[email protected]>
5: To: [email protected]
6: Subject: gdb for ISI Optimum V
7:
8: Here is an m-isi-ov.h file for gdb version 2.1. It supports the 68881
9: registers, and tracks down the function prologue (since the ISI cc
10: puts it at the end of the function and branches to it if not
11: optimizing). Also included are diffs to core.c, findvar.c, and
12: inflow.c, since the original code assumed that registers are an int in
13: the user struct, which isn't the case for 68020's with 68881's (and
14: not using the NEW_SUN_PTRACE). I have not fixed the bugs associated
15: with the other direction (writing registers back to the user struct).
16: I have also included a diff that turns m68k-pinsn.c into isi-pinsn.c,
17: which is needed since the 3.05 release of as does not understand
18: floating point ops, and it compiles incorrectly under "cc -20"
19:
20: I have used gdb for a while now, and it seems to work relatively well,
21: but I do not guarantee that it is perfect. The more that use it, the
22: faster the bugs will get shaken out. One bug I know of is not in gdb,
23: but in the assembler. It seems to screw up the .stabs of variables.
24: For externs, this is not important since gdb uses the global symbol
25: value, but for statics, this makes gdb unable to find them. I am
26: currently trying to track it down.
27:
28: As an aside, I notice that only global functions are used as symbols
29: to print as relative addresses, i.e. "<function + offset>", and not
30: static functions, which end up printing as large offsets from the last
31: global one. Would there be a problem if static functions were also
32: recorded as misc functions in read_dbx_symtab?
33:
34: Charles LaBrec
35: crl @ maxwell.physics.purdue.edu
36:
37: Definitions to make GDB run on a ISI Optimum V (3.05) under 4.2bsd.
38:
39: Copyright (C) 1987 Free Software Foundation, Inc.
40:
41: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
42: WARRANTY. No author or distributor accepts responsibility to anyone
43: for the consequences of using it or for whether it serves any
44: particular purpose or works at all, unless he says so in writing.
45: Refer to the GDB General Public License for full details.
46:
47: Everyone is granted permission to copy, modify and redistribute GDB,
48: but only under the conditions described in the GDB General Public
49: License. A copy of this license is supposed to have been given to you
50: along with GDB so you can know your rights and responsibilities. It
51: should be in a file named COPYING. Among other things, the copyright
52: notice and this notice must be preserved on all copies.
53:
54: In other words, go ahead and share GDB, but don't try to stop
55: anyone else from sharing it farther. Help stamp out software hoarding!
56: */
57:
58:
59: /* Identify this machine */
60: #ifndef ISI68K
61: #define ISI68K
62: #endif
63:
64: /* Define this if the C compiler puts an underscore at the front
65: of external names before giving them to the linker. */
66:
67: #define NAMES_HAVE_UNDERSCORE
68:
69: /* Debugger information will be in DBX format. */
70:
71: #define READ_DBX_FORMAT
72:
73: /* Offset from address of function to start of its code.
74: Zero on most machines. */
75:
76: #define FUNCTION_START_OFFSET 0
77:
78: /* Advance PC across any function entry prologue instructions
79: to reach some "real" code. */
80:
81: #define SKIP_PROLOGUE(pc) \
82: { register int op = read_memory_integer (pc, 2); \
83: if (op == 0047126) \
84: pc += 4; /* Skip link #word */ \
85: else if (op == 0044016) \
86: pc += 6; /* Skip link #long */ \
87: else if (op == 0060000) \
88: pc += 4; /* Skip bra #word */ \
89: else if (op == 00600377) \
90: pc += 6; /* skip bra #long */ \
91: else if ((op & 0177400) == 0060000) \
92: pc += 2; /* skip bra #char */ \
93: }
94:
95:
96: /* Immediately after a function call, return the saved pc.
97: Can't always go through the frames for this because on some machines
98: the new frame is not set up until the new function executes
99: some instructions. */
100:
101: #define SAVED_PC_AFTER_CALL(frame) \
102: read_memory_integer (read_register (SP_REGNUM), 4)
103:
104: /* This is the amount to subtract from u.u_ar0
105: to get the offset in the core file of the register values. */
106:
107: #define KERNEL_U_ADDR 0x10800000
108:
109: /* Address of end of stack space. */
110:
111: #define STACK_END_ADDR 0x10000000
112:
113: /* Stack grows downward. */
114:
115: #define INNER_THAN <
116:
117: /* Sequence of bytes for breakpoint instruction. */
118:
119: #define BREAKPOINT {0x4e, 0x4f}
120:
121: /* Data segment starts at etext rounded up to DATAROUND in {N,Z}MAGIC files */
122:
123: #define DATAROUND 0x20000
124: #define N_DATADDR(hdr) (hdr.a_magic != OMAGIC ? \
125: (hdr.a_text + DATAROUND) & ~(DATAROUND-1) : hdr.a_text)
126:
127: /* Text segment starts at sizeof (struct exec) in {N,Z}MAGIC files */
128:
129: #define N_TXTADDR(hdr) (hdr.a_magic != OMAGIC ? sizeof (struct exec) : 0)
130:
131: /* Amount PC must be decremented by after a breakpoint.
132: This is often the number of bytes in BREAKPOINT
133: but not always.
134: On the ISI, the kernel resets the pc to the trap instr */
135:
136: #define DECR_PC_AFTER_BREAK 0
137:
138: /* Nonzero if instruction at PC is a return instruction. */
139:
140: #define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
141:
142: /* Return 1 if P points to an invalid floating point value. */
143:
144: #define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
145:
146: /* Say how long registers are. */
147:
148: #define REGISTER_TYPE long
149:
150: /* Number of machine registers */
151:
152: #define NUM_REGS 29
153:
154: /* Initializer for an array of names of registers.
155: There should be NUM_REGS strings in this initializer. */
156:
157: #define REGISTER_NAMES \
158: {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
159: "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
160: "ps", "pc", \
161: "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
162: "fpcontrol", "fpstatus", "fpiaddr" }
163:
164: /* Register numbers of various important registers.
165: Note that some of these values are "real" register numbers,
166: and correspond to the general registers of the machine,
167: and some are "phony" register numbers which are too large
168: to be actual register numbers as far as the user is concerned
169: but do serve to get the desired values when passed to read_register. */
170:
171: #define FP_REGNUM 14 /* Contains address of executing stack frame */
172: #define SP_REGNUM 15 /* Contains address of top of stack */
173: #define PS_REGNUM 16 /* Contains processor status */
174: #define PC_REGNUM 17 /* Contains program counter */
175: #define FP0_REGNUM 18 /* Floating point register 0 */
176: #define FPC_REGNUM 26 /* 68881 control register */
177:
178: #ifdef BSD43_ISI40D
179: #define BLOCKFUDGE 0x400000
180: #else
181: #define BLOCKFUDGE 0
182: #endif
183: #define REGISTER_U_ADDR(addr, blockend, regno) \
184: { blockend -= BLOCKFUDGE; \
185: if (regno < 2) addr = blockend - 0x18 + regno * 4; \
186: else if (regno < 8) addr = blockend - 0x54 + regno * 4; \
187: else if (regno < 10) addr = blockend - 0x30 + regno * 4;\
188: else if (regno < 15) addr = blockend - 0x5c + regno * 4;\
189: else if (regno < 16) addr = blockend - 0x1c; \
190: else if (regno < 18) addr = blockend - 0x44 + regno * 4;\
191: else if (regno < 26) addr = (int) ((struct user *)0)->u_68881_regs \
192: + (regno - 18) * 12; \
193: else if (regno < 29) addr = (int) ((struct user *)0)->u_68881_regs \
194: + 8 * 12 + (regno - 26) * 4; \
195: }
196:
197: /* Total amount of space needed to store our copies of the machine's
198: register state, the array `registers'. */
199: #define REGISTER_BYTES (16*4+8*12+8+20)
200:
201: /* Index within `registers' of the first byte of the space for
202: register N. */
203:
204: #define REGISTER_BYTE(N) \
205: ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
206: : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
207: : (N) * 4)
208:
209: /* Number of bytes of storage in the actual machine representation
210: for register N. On the 68000, all regs are 4 bytes
211: except the floating point regs which are 12 bytes. */
212:
213: #define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
214:
215: /* Number of bytes of storage in the program's representation
216: for register N. On the 68000, all regs are 4 bytes
217: except the floating point regs which are 8-byte doubles. */
218:
219: #define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
220:
221: /* Largest value REGISTER_RAW_SIZE can have. */
222:
223: #define MAX_REGISTER_RAW_SIZE 12
224:
225: /* Largest value REGISTER_VIRTUAL_SIZE can have. */
226:
227: #define MAX_REGISTER_VIRTUAL_SIZE 8
228:
229: /* Nonzero if register N requires conversion
230: from raw format to virtual format. */
231:
232: #define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
233:
234: /* Convert data from raw format for register REGNUM
235: to virtual format for register REGNUM. */
236:
237: #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
238: { if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
239: convert_from_68881 ((FROM), (TO)); \
240: else \
241: bcopy ((FROM), (TO), 4); }
242:
243: /* Convert data from virtual format for register REGNUM
244: to raw format for register REGNUM. */
245:
246: #define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
247: { if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
248: convert_to_68881 ((FROM), (TO)); \
249: else \
250: bcopy ((FROM), (TO), 4); }
251:
252: /* Return the GDB type object for the "standard" data type
253: of data in register N. */
254:
255: #define REGISTER_VIRTUAL_TYPE(N) \
256: (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
257:
258: /* Extract from an array REGBUF containing the (raw) register state
259: a function return value of type TYPE, and copy that, in virtual format,
260: into VALBUF. */
261:
262: #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
263: bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
264:
265: /* Write into appropriate registers a function return value
266: of type TYPE, given in virtual format. */
267:
268: #define STORE_RETURN_VALUE(TYPE,VALBUF) \
269: write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
270:
271: /* Extract from an array REGBUF containing the (raw) register state
272: the address in which a function should return its structure value,
273: as a CORE_ADDR (or an expression that can be used as one). */
274:
275: #define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
276:
277: /* Describe the pointer in each stack frame to the previous stack frame
278: (its caller). */
279:
280: /* FRAME_CHAIN takes a frame's nominal address
281: and produces the frame's chain-pointer.
282:
283: FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
284: and produces the nominal address of the caller frame.
285:
286: However, if FRAME_CHAIN_VALID returns zero,
287: it means the given frame is the outermost one and has no caller.
288: In that case, FRAME_CHAIN_COMBINE is not used. */
289:
290: /* In the case of the ISI, the frame's nominal address
291: is the address of a 4-byte word containing the calling frame's address. */
292:
293: #define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
294:
295: #define FRAME_CHAIN_VALID(chain, thisframe) \
296: (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
297:
298: #define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
299:
300: /* Define other aspects of the stack frame. */
301:
302: #define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
303:
304: #define FRAME_ARGS_ADDRESS(fi) (fi.frame)
305:
306: #define FRAME_LOCALS_ADDRESS(fi) (fi.frame)
307:
308: /* Return number of args passed to a frame.
309: Can return -1, meaning no way to tell. */
310:
311: #define FRAME_NUM_ARGS(val, fi) \
312: { register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
313: register int insn = 0177777 & read_memory_integer (pc, 2); \
314: val = 0; \
315: if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
316: val = read_memory_integer (pc + 2, 2); \
317: else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
318: || (insn & 0170777) == 0050117) /* addqw */ \
319: { val = (insn >> 9) & 7; if (val == 0) val = 8; } \
320: else if (insn == 0157774) /* addal #WW, sp */ \
321: val = read_memory_integer (pc + 2, 4); \
322: val >>= 2; }
323:
324: /* Return number of bytes at start of arglist that are not really args. */
325:
326: #define FRAME_ARGS_SKIP 8
327:
328: /* Put here the code to store, into a struct frame_saved_regs,
329: the addresses of the saved registers of frame described by FRAME_INFO.
330: This includes special registers such as pc and fp saved in special
331: ways in the stack frame. sp is even more special:
332: the address we return for it IS the sp for the next frame. */
333:
334: #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
335: { register int regnum; \
336: register int regmask; \
337: register CORE_ADDR next_addr; \
338: register CORE_ADDR pc; \
339: register int insn; \
340: register int offset; \
341: bzero (&frame_saved_regs, sizeof frame_saved_regs); \
342: if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
343: && (frame_info).pc <= (frame_info).frame) \
344: { next_addr = (frame_info).frame; \
345: pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
346: else \
347: { pc = get_pc_function_start ((frame_info).pc); \
348: /* Verify we have a link a6 instruction next, \
349: or a branch followed by a link a6 instruction; \
350: if not we lose. If we win, find the address above the saved \
351: regs using the amount of storage from the link instruction. */\
352: retry: \
353: insn = read_memory_integer (pc, 2); \
354: if (insn == 044016) \
355: next_addr = (frame_info).frame - read_memory_integer (pc += 2, 4), pc+=4; \
356: else if (insn == 047126) \
357: next_addr = (frame_info).frame - read_memory_integer (pc += 2, 2), pc+=2; \
358: else if ((insn & 0177400) == 060000) /* bra insn */ \
359: { offset = insn & 0377; \
360: pc += 2; /* advance past bra */ \
361: if (offset == 0) /* bra #word */ \
362: offset = read_memory_integer (pc, 2), pc += 2; \
363: else if (offset == 0377) /* bra #long */ \
364: offset = read_memory_integer (pc, 4), pc += 4; \
365: pc += offset; \
366: goto retry; \
367: } else goto lose; \
368: /* If have an addal #-n, sp next, adjust next_addr. */ \
369: if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
370: next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
371: } \
372: /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
373: insn = read_memory_integer (pc, 2), pc += 2; \
374: regmask = read_memory_integer (pc, 2); \
375: if ((insn & 0177760) == 022700) /* movl rn, (sp) */ \
376: (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr; \
377: else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */ \
378: (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \
379: else if (insn == 0044327) /* moveml mask, (sp) */ \
380: { pc += 2; \
381: /* Regmask's low bit is for register 0, the first written */ \
382: next_addr -= 4; \
383: for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
384: if (regmask & 1) \
385: (frame_saved_regs).regs[regnum] = (next_addr += 4); \
386: } else if (insn == 0044347) /* moveml mask, -(sp) */ \
387: { pc += 2; \
388: /* Regmask's low bit is for register 15, the first pushed */ \
389: for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
390: if (regmask & 1) \
391: (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
392: /* clrw -(sp); movw ccr,-(sp) may follow. */ \
393: if (read_memory_integer (pc, 2) == 041147 \
394: && read_memory_integer (pc+2, 2) == 042347) \
395: (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
396: lose: ; \
397: (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
398: (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
399: (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
400: }
401:
402: /* Compensate for lack of `vprintf' function. */
403: #define vprintf(format, ap) _doprnt (format, ap, stdout)
404:
405: /* Things needed for making the inferior call functions. */
406:
407: /* Push an empty stack frame, to record the current PC, etc. */
408:
409: #define PUSH_DUMMY_FRAME \
410: { register CORE_ADDR sp = read_register (SP_REGNUM); \
411: register int regnum; \
412: char raw_buffer[12]; \
413: sp = push_word (sp, read_register (PC_REGNUM)); \
414: sp = push_word (sp, read_register (FP_REGNUM)); \
415: write_register (FP_REGNUM, sp); \
416: for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
417: { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
418: sp = push_bytes (sp, raw_buffer, 12); } \
419: for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
420: sp = push_word (sp, read_register (regnum)); \
421: sp = push_word (sp, read_register (PS_REGNUM)); \
422: write_register (SP_REGNUM, sp); }
423:
424: /* Discard from the stack the innermost frame, restoring all registers. */
425:
426: #define POP_FRAME \
427: { register CORE_ADDR fp = read_register (FP_REGNUM); \
428: register int regnum; \
429: struct frame_saved_regs fsr; \
430: struct frame_info fi; \
431: char raw_buffer[12]; \
432: fi = get_frame_info (fp); \
433: get_frame_saved_regs (&fi, &fsr); \
434: for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
435: if (fsr.regs[regnum]) \
436: { read_memory (fsr.regs[regnum], raw_buffer, 12); \
437: write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
438: for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
439: if (fsr.regs[regnum]) \
440: write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
441: if (fsr.regs[PS_REGNUM]) \
442: write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
443: write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
444: write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
445: write_register (SP_REGNUM, fp + 8); \
446: }
447:
448: /* This sequence of words is the instructions
449: fmovem #<f0-f7>,-(sp)
450: moveml 0xfffc,-(sp)
451: clrw -(sp)
452: movew ccr,-(sp)
453: /..* The arguments are pushed at this point by GDB;
454: no code is needed in the dummy for this.
455: The CALL_DUMMY_START_OFFSET gives the position of
456: the following jsr instruction. *../
457: jsr @#32323232
458: addl #69696969,sp
459: bpt
460: nop
461: Note this is 24 bytes.
462: We actually start executing at the jsr, since the pushing of the
463: registers is done by PUSH_DUMMY_FRAME. If this were real code,
464: the arguments for the function called by the jsr would be pushed
465: between the moveml and the jsr, and we could allow it to execute through.
466: But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
467: and we cannot allow the moveml to push the registers again lest they be
468: taken for the arguments. */
469:
470: #define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
471:
472: #define CALL_DUMMY_LENGTH 28
473:
474: #define CALL_DUMMY_START_OFFSET 12
475:
476: /* Insert the specified number of args and function address
477: into a call sequence of the above form stored at DUMMYNAME. */
478:
479: #define FIX_CALL_DUMMY(dummyname, fun, nargs) \
480: { *(int *)((char *) dummyname + 20) = nargs * 4; \
481: *(int *)((char *) dummyname + 14) = fun; }
482:
483: /* Interface definitions for kernel debugger KDB. */
484:
485: /* Map machine fault codes into signal numbers.
486: First subtract 0, divide by 4, then index in a table.
487: Faults for which the entry in this table is 0
488: are not handled by KDB; the program's own trap handler
489: gets to handle then. */
490:
491: #define FAULT_CODE_ORIGIN 0
492: #define FAULT_CODE_UNITS 4
493: #define FAULT_TABLE \
494: { 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
495: 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
496: 0, 0, 0, 0, 0, 0, 0, 0, \
497: SIGILL }
498:
499: /* Start running with a stack stretching from BEG to END.
500: BEG and END should be symbols meaningful to the assembler.
501: This is used only for kdb. */
502:
503: #define INIT_STACK(beg, end) \
504: { asm (".globl end"); \
505: asm ("movl $ end, sp"); \
506: asm ("clrl fp"); }
507:
508: /* Push the frame pointer register on the stack. */
509: #define PUSH_FRAME_PTR \
510: asm ("movel fp, -(sp)");
511:
512: /* Copy the top-of-stack to the frame pointer register. */
513: #define POP_FRAME_PTR \
514: asm ("movl (sp), fp");
515:
516: /* After KDB is entered by a fault, push all registers
517: that GDB thinks about (all NUM_REGS of them),
518: so that they appear in order of ascending GDB register number.
519: The fault code will be on the stack beyond the last register. */
520:
521: #define PUSH_REGISTERS \
522: { asm ("clrw -(sp)"); \
523: asm ("pea 10(sp)"); \
524: asm ("movem $ 0xfffe,-(sp)"); }
525:
526: /* Assuming the registers (including processor status) have been
527: pushed on the stack in order of ascending GDB register number,
528: restore them and return to the address in the saved PC register. */
529:
530: #define POP_REGISTERS \
531: { asm ("subil $8,28(sp)"); \
532: asm ("movem (sp),$ 0xffff"); \
533: asm ("rte"); }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.