gdb-3.5
[deliverable/binutils-gdb.git] / gdb / m-altos.h
CommitLineData
4187119d 1/* Definitions to make GDB run on an Altos 3068 (m68k running SVR2)
2 Copyright (C) 1987,1989 Free Software Foundation, Inc.
7b4ac7e1 3
4187119d 4This file is part of GDB.
5
6GDB is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GDB is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GDB; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
7b4ac7e1 19
4187119d 20/* The altos support would make a good base for a port to other USGR2 systems
21 (like the 3b1 and the Convergent miniframe). */
22
23/* This is only needed in one file, but it's cleaner to put it here than
24 putting in more #ifdef's. */
25#include <sys/page.h>
26#include <sys/net.h>
27
28#ifndef ALTOS
29#define ALTOS
30#endif
3bf57d21 31
e91b87a3 32#define USG
33
4187119d 34/* Define the bit, byte, and word ordering of the machine. */
35#define BITS_BIG_ENDIAN
36#define BYTES_BIG_ENDIAN
37#define WORDS_BIG_ENDIAN
3bf57d21 38
39/* Get rid of any system-imposed stack limit if possible. */
40
4187119d 41/*#define SET_STACK_LIMIT_HUGE*/
42
43#define HAVE_TERMIO
44
45#define CBREAK XTABS /* It takes all kinds... */
46
47/*
48 * #define FLOATING_POINT if you have 68881
49 * This hasn't been tested
50 */
51
52/*#define FLOATING_POINT*/
53/*#undef FLOATING_POINT*/
54
55#ifndef __GNUC__
56#undef USE_GAS
57#define ALTOS_AS
58#else
59#define USE_GAS
60#endif
61
62#ifndef R_OK
63#define R_OK 4
64#define W_OK 2
65#define X_OK 1
66#define F_OK 0
67#endif
68
69#ifndef MAXPATHLEN
70#define MAXPATHLEN (1024)
71#endif
72
73/* Motorola assembly format */
74#if !defined(USE_GAS) && !defined(ALTOS)
75#define MOTOROLA
76#endif
77
78/* Get sys/wait.h ie. from a Sun and edit it a little (mc68000 to m68k) */
79#define HAVE_WAIT_STRUCT
3bf57d21 80
7b4ac7e1 81/* Define this if the C compiler puts an underscore at the front
82 of external names before giving them to the linker. */
83
4187119d 84#undef NAMES_HAVE_UNDERSCORE
7b4ac7e1 85
4187119d 86/* Exec files and symbol tables are in COFF format */
7b4ac7e1 87
4187119d 88#define COFF_FORMAT
89#define COFF_NO_LONG_FILE_NAMES
90#define vfork fork
7b4ac7e1 91
92/* Offset from address of function to start of its code.
93 Zero on most machines. */
94
95#define FUNCTION_START_OFFSET 0
96
97/* Advance PC across any function entry prologue instructions
98 to reach some "real" code. */
99
100#define SKIP_PROLOGUE(pc) \
101{ register int op = read_memory_integer (pc, 2); \
4187119d 102 if (op == 0047126) \
7b4ac7e1 103 pc += 4; /* Skip link #word */ \
4187119d 104 else if (op == 0044016) \
7b4ac7e1 105 pc += 6; /* Skip link #long */ \
4187119d 106 else if (op == 0060000) \
107 pc += 4; /* Skip bra #word */ \
108 else if (op == 00600377) \
109 pc += 6; /* skip bra #long */ \
110 else if ((op & 0177400) == 0060000) \
111 pc += 2; /* skip bra #char */ \
7b4ac7e1 112}
113
7b4ac7e1 114/* Immediately after a function call, return the saved pc.
4187119d 115 Can't always go through the frames for this because on some machines
7b4ac7e1 116 the new frame is not set up until the new function executes
117 some instructions. */
118
119#define SAVED_PC_AFTER_CALL(frame) \
120read_memory_integer (read_register (SP_REGNUM), 4)
121
122/* This is the amount to subtract from u.u_ar0
4187119d 123 to get the offset in the core file of the register values. */
7b4ac7e1 124
4187119d 125#define KERNEL_U_ADDR 0x1fbf000
7b4ac7e1 126
127/* Address of end of stack space. */
128
4187119d 129/*#define STACK_END_ADDR (0xffffff)*/
130#define STACK_END_ADDR (0x1000000)
7b4ac7e1 131
132/* Stack grows downward. */
133
134#define INNER_THAN <
135
136/* Sequence of bytes for breakpoint instruction. */
137
4187119d 138#define BREAKPOINT {0x4e, 0x4e}
7b4ac7e1 139
140/* Amount PC must be decremented by after a breakpoint.
141 This is often the number of bytes in BREAKPOINT
4187119d 142 but not always.
143 On the Altos, the kernel resets the pc to the trap instr */
7b4ac7e1 144
4187119d 145#define DECR_PC_AFTER_BREAK 0
7b4ac7e1 146
147/* Nonzero if instruction at PC is a return instruction. */
148
3bf57d21 149#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
7b4ac7e1 150
151/* Return 1 if P points to an invalid floating point value. */
152
4187119d 153#define INVALID_FLOAT(p, len) (*((int *) (p)) == -1) /* Just a first guess; not checked */
7b4ac7e1 154
e91b87a3 155/* Largest integer type */
156#define LONGEST long
157
158/* Name of the builtin type for the LONGEST type above. */
159#define BUILTIN_TYPE_LONGEST builtin_type_long
160
3bf57d21 161/* Say how long (ordinary) registers are. */
7b4ac7e1 162
163#define REGISTER_TYPE long
164
165/* Number of machine registers */
166
4187119d 167#ifdef FLOATING_POINT
168#define NUM_REGS 31
169#else
170#define NUM_REGS 18
171#endif
7b4ac7e1 172
173/* Initializer for an array of names of registers.
174 There should be NUM_REGS strings in this initializer. */
175
4187119d 176#ifdef FLOATING_POINT
7b4ac7e1 177#define REGISTER_NAMES \
178 {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
e91b87a3 179 "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
7b4ac7e1 180 "ps", "pc", \
181 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
4187119d 182 "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" \
183 }
184#else
185#define REGISTER_NAMES \
186 {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
187 "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
188 "ps", "pc", \
189 }
190#endif
7b4ac7e1 191
192/* Register numbers of various important registers.
193 Note that some of these values are "real" register numbers,
194 and correspond to the general registers of the machine,
195 and some are "phony" register numbers which are too large
196 to be actual register numbers as far as the user is concerned
197 but do serve to get the desired values when passed to read_register. */
198
199#define FP_REGNUM 14 /* Contains address of executing stack frame */
200#define SP_REGNUM 15 /* Contains address of top of stack */
201#define PS_REGNUM 16 /* Contains processor status */
202#define PC_REGNUM 17 /* Contains program counter */
203#define FP0_REGNUM 18 /* Floating point register 0 */
204#define FPC_REGNUM 26 /* 68881 control register */
7b4ac7e1 205
206/* Total amount of space needed to store our copies of the machine's
207 register state, the array `registers'. */
4187119d 208#define REGISTER_BYTES (16*4+8*12+8+20)
7b4ac7e1 209
210/* Index within `registers' of the first byte of the space for
211 register N. */
212
213#define REGISTER_BYTE(N) \
214 ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
215 : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
216 : (N) * 4)
217
218/* Number of bytes of storage in the actual machine representation
219 for register N. On the 68000, all regs are 4 bytes
220 except the floating point regs which are 12 bytes. */
4187119d 221/* Note that the unsigned cast here forces the result of the
222 subtractiion to very high positive values if N < FP0_REGNUM */
7b4ac7e1 223
224#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
225
226/* Number of bytes of storage in the program's representation
227 for register N. On the 68000, all regs are 4 bytes
228 except the floating point regs which are 8-byte doubles. */
229
230#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
231
4187119d 232#define REGISTER_U_ADDR(addr, blockend, regno) \
233{ if (regno <= SP_REGNUM) \
234 addr = blockend + regno * 4; \
235 else if (regno == PS_REGNUM) \
236 addr = blockend + regno * 4 + 4; \
237 else if (regno == PC_REGNUM) \
238 addr = blockend + regno * 4 + 2; \
239}
240
7b4ac7e1 241/* Largest value REGISTER_RAW_SIZE can have. */
242
243#define MAX_REGISTER_RAW_SIZE 12
244
245/* Largest value REGISTER_VIRTUAL_SIZE can have. */
246
247#define MAX_REGISTER_VIRTUAL_SIZE 8
248
249/* Nonzero if register N requires conversion
250 from raw format to virtual format. */
251
252#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
253
254/* Convert data from raw format for register REGNUM
255 to virtual format for register REGNUM. */
256
257#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
258{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
259 convert_from_68881 ((FROM), (TO)); \
260 else \
261 bcopy ((FROM), (TO), 4); }
262
263/* Convert data from virtual format for register REGNUM
264 to raw format for register REGNUM. */
265
266#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
267{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
268 convert_to_68881 ((FROM), (TO)); \
269 else \
270 bcopy ((FROM), (TO), 4); }
271
272/* Return the GDB type object for the "standard" data type
273 of data in register N. */
274
275#define REGISTER_VIRTUAL_TYPE(N) \
276 (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
277
e91b87a3 278/* Store the address of the place in which to copy the structure the
279 subroutine will return. This is called from call_function. */
280
281#define STORE_STRUCT_RETURN(ADDR, SP) \
282 { write_register (9, (ADDR)); }
283
7b4ac7e1 284/* Extract from an array REGBUF containing the (raw) register state
285 a function return value of type TYPE, and copy that, in virtual format,
286 into VALBUF. */
287
288#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
289 bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
290
291/* Write into appropriate registers a function return value
292 of type TYPE, given in virtual format. */
293
294#define STORE_RETURN_VALUE(TYPE,VALBUF) \
295 write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
296
297/* Extract from an array REGBUF containing the (raw) register state
298 the address in which a function should return its structure value,
299 as a CORE_ADDR (or an expression that can be used as one). */
300
301#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
3bf57d21 302
e91b87a3 303#define REGISTER_ADDR(u_ar0, regno) \
304 (((regno) < PS_REGNUM) \
305 ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)]) \
306 : (((regno) == PS_REGNUM) \
307 ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS)) \
308 : (&((struct exception_stack *) (u_ar0))->e_PC)))
309
310#define FP_REGISTER_ADDR(u, regno) \
311 (((char *) \
312 (((regno) < FPC_REGNUM) \
313 ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
314 : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))) \
315 - ((char *) (& u)))
7b4ac7e1 316\f
317/* Describe the pointer in each stack frame to the previous stack frame
318 (its caller). */
319
320/* FRAME_CHAIN takes a frame's nominal address
321 and produces the frame's chain-pointer.
322
323 FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
324 and produces the nominal address of the caller frame.
325
326 However, if FRAME_CHAIN_VALID returns zero,
327 it means the given frame is the outermost one and has no caller.
328 In that case, FRAME_CHAIN_COMBINE is not used. */
329
4187119d 330/* In the case of the Altos, the frame's nominal address
7b4ac7e1 331 is the address of a 4-byte word containing the calling frame's address. */
332
4187119d 333#define FRAME_CHAIN(thisframe) \
334 (outside_startup_file ((thisframe)->pc) ? \
335 read_memory_integer ((thisframe)->frame, 4) :\
336 0)
7b4ac7e1 337
338#define FRAME_CHAIN_VALID(chain, thisframe) \
4187119d 339 (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
7b4ac7e1 340
341#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
342
343/* Define other aspects of the stack frame. */
344
4187119d 345/* A macro that tells us whether the function invocation represented
346 by FI does not have a frame on the stack associated with it. If it
347 does not, FRAMELESS is set to 1, else 0. */
348#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
349 FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS)
350
e91b87a3 351#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
7b4ac7e1 352
e91b87a3 353#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
7b4ac7e1 354
e91b87a3 355#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
7b4ac7e1 356
3bf57d21 357/* Set VAL to the number of args passed to frame described by FI.
358 Can set VAL to -1, meaning no way to tell. */
7b4ac7e1 359
4187119d 360/* Return number of args passed to a frame.
361 Can return -1, meaning no way to tell. */
362
3bf57d21 363/* We can't tell how many args there are
4187119d 364 now that the (gnu) C compiler delays popping them.
365 Perhaps we could tell if we use the Altos cc, but I'm not sure
366 COFF_FORMAT is the right conditional */
367
368#ifdef COFF_FORMAT
3bf57d21 369
4187119d 370#define FRAME_NUM_ARGS(val, fi) (val = -1)
3bf57d21 371#if 0
7b4ac7e1 372#define FRAME_NUM_ARGS(val, fi) \
4187119d 373{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
7b4ac7e1 374 register int insn = 0177777 & read_memory_integer (pc, 2); \
375 val = 0; \
376 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
377 val = read_memory_integer (pc + 2, 2); \
378 else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
379 || (insn & 0170777) == 0050117) /* addqw */ \
380 { val = (insn >> 9) & 7; if (val == 0) val = 8; } \
381 else if (insn == 0157774) /* addal #WW, sp */ \
382 val = read_memory_integer (pc + 2, 4); \
383 val >>= 2; }
3bf57d21 384#endif
7b4ac7e1 385
386/* Return number of bytes at start of arglist that are not really args. */
387
388#define FRAME_ARGS_SKIP 8
389
390/* Put here the code to store, into a struct frame_saved_regs,
391 the addresses of the saved registers of frame described by FRAME_INFO.
392 This includes special registers such as pc and fp saved in special
393 ways in the stack frame. sp is even more special:
394 the address we return for it IS the sp for the next frame. */
395
396#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
397{ register int regnum; \
398 register int regmask; \
399 register CORE_ADDR next_addr; \
400 register CORE_ADDR pc; \
3bf57d21 401 int nextinsn; \
7b4ac7e1 402 bzero (&frame_saved_regs, sizeof frame_saved_regs); \
e91b87a3 403 if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
404 && (frame_info)->pc <= (frame_info)->frame) \
405 { next_addr = (frame_info)->frame; \
406 pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
7b4ac7e1 407 else \
e91b87a3 408 { pc = get_pc_function_start ((frame_info)->pc); \
3bf57d21 409 /* Verify we have a link a6 instruction next; \
7b4ac7e1 410 if not we lose. If we win, find the address above the saved \
411 regs using the amount of storage from the link instruction. */\
3bf57d21 412 if (044016 == read_memory_integer (pc, 2)) \
e91b87a3 413 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
3bf57d21 414 else if (047126 == read_memory_integer (pc, 2)) \
e91b87a3 415 next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
3bf57d21 416 else goto lose; \
7b4ac7e1 417 /* If have an addal #-n, sp next, adjust next_addr. */ \
418 if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
419 next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
420 } \
421 /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
3bf57d21 422 regmask = read_memory_integer (pc + 2, 2); \
423 /* But before that can come an fmovem. Check for it. */ \
424 nextinsn = 0xffff & read_memory_integer (pc, 2); \
425 if (0xf227 == nextinsn \
426 && (regmask & 0xff00) == 0xe000) \
427 { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
428 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
429 if (regmask & 1) \
430 (frame_saved_regs).regs[regnum] = (next_addr -= 12); \
431 regmask = read_memory_integer (pc + 2, 2); } \
432 if (0044327 == read_memory_integer (pc, 2)) \
433 { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
7b4ac7e1 434 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
435 if (regmask & 1) \
3bf57d21 436 (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
437 else if (0044347 == read_memory_integer (pc, 2)) \
438 { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
7b4ac7e1 439 for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
440 if (regmask & 1) \
441 (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
4187119d 442 else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) \
3bf57d21 443 { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
444 (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
445 /* fmovemx to index of sp may follow. */ \
446 regmask = read_memory_integer (pc + 2, 2); \
447 nextinsn = 0xffff & read_memory_integer (pc, 2); \
448 if (0xf236 == nextinsn \
449 && (regmask & 0xff00) == 0xf000) \
450 { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
451 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
452 if (regmask & 1) \
453 (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
454 regmask = read_memory_integer (pc + 2, 2); } \
7b4ac7e1 455 /* clrw -(sp); movw ccr,-(sp) may follow. */ \
3bf57d21 456 if (0x426742e7 == read_memory_integer (pc, 4)) \
7b4ac7e1 457 (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
458 lose: ; \
e91b87a3 459 (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8; \
460 (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame; \
461 (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4; \
7b4ac7e1 462}
463\f
4187119d 464#if 0
465{ register int regnum; \
466 register int regmask; \
467 register CORE_ADDR next_addr; \
468 register CORE_ADDR pc; \
469 int nextinsn; \
470 bzero (&frame_saved_regs, sizeof frame_saved_regs); \
471 if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
472 && (frame_info).pc <= (frame_info).frame) \
473 { next_addr = (frame_info).frame; \
474 pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
475 else \
476 { pc = get_pc_function_start ((frame_info).pc); \
477 /* Verify we have a link a6 instruction next; \
478 if not we lose. If we win, find the address above the saved \
479 regs using the amount of storage from the link instruction. */\
480 if (044016 == read_memory_integer (pc, 2)) \
481 next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \
482 else if (047126 == read_memory_integer (pc, 2)) \
483 next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \
484 else goto lose; \
485 /* If have an addal #-n, sp next, adjust next_addr. */ \
486 if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
487 next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
488 } \
489 /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
490 regmask = read_memory_integer (pc + 2, 2); \
491 /* But before that can come an fmovem. Check for it. */ \
492 nextinsn = 0xffff & read_memory_integer (pc, 2); \
493 if (0xf227 == nextinsn \
494 && (regmask & 0xff00) == 0xe000) \
495 { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
496 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
497 if (regmask & 1) \
498 (frame_saved_regs).regs[regnum] = (next_addr -= 12); \
499 regmask = read_memory_integer (pc + 2, 2); } \
500 if (0044327 == read_memory_integer (pc, 2)) \
501 { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
502 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
503 if (regmask & 1) \
504 (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
505 else if (0044347 == read_memory_integer (pc, 2)) \
506 { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
507 for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
508 if (regmask & 1) \
509 (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
510 else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \
511 { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
512 (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
513 /* fmovemx to index of sp may follow. */ \
514 regmask = read_memory_integer (pc + 2, 2); \
515 nextinsn = 0xffff & read_memory_integer (pc, 2); \
516 if (0xf236 == nextinsn \
517 && (regmask & 0xff00) == 0xf000) \
518 { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
519 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
520 if (regmask & 1) \
521 (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
522 regmask = read_memory_integer (pc + 2, 2); } \
523 /* clrw -(sp); movw ccr,-(sp) may follow. */ \
524 if (0x426742e7 == read_memory_integer (pc, 4)) \
525 (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
526 lose: ; \
527 (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
528 (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
529 (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
530}
531#endif
532#if 0
533#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
534{ register int regnum; \
535 register int regmask; \
536 register CORE_ADDR next_addr; \
537 register CORE_ADDR pc; \
538 register int insn; \
539 register int offset; \
540 bzero (&frame_saved_regs, sizeof frame_saved_regs); \
541 if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
542 && (frame_info).pc <= (frame_info).frame) \
543 { next_addr = (frame_info).frame; \
544 pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
545 else \
546 { pc = get_pc_function_start ((frame_info).pc); \
547 /* Verify we have a link a6 instruction next, \
548 or a branch followed by a link a6 instruction; \
549 if not we lose. If we win, find the address above the saved \
550 regs using the amount of storage from the link instruction. */\
551retry: \
552 insn = read_memory_integer (pc, 2); \
553 if (insn == 044016) \
554 next_addr = (frame_info).frame - read_memory_integer (pc += 2, 4), pc+=4; \
555 else if (insn == 047126) \
556 next_addr = (frame_info).frame - read_memory_integer (pc += 2, 2), pc+=2; \
557 else if ((insn & 0177400) == 060000) /* bra insn */ \
558 { offset = insn & 0377; \
559 pc += 2; /* advance past bra */ \
560 if (offset == 0) /* bra #word */ \
561 offset = read_memory_integer (pc, 2), pc += 2; \
562 else if (offset == 0377) /* bra #long */ \
563 offset = read_memory_integer (pc, 4), pc += 4; \
564 pc += offset; \
565 goto retry; \
566 } else goto lose; \
567 /* If have an addal #-n, sp next, adjust next_addr. */ \
568 if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
569 next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
570 } \
571 /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
572 insn = read_memory_integer (pc, 2), pc += 2; \
573 regmask = read_memory_integer (pc, 2); \
574 if ((insn & 0177760) == 022700) /* movl rn, (sp) */ \
575 (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr; \
576 else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */ \
577 (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \
578 else if (insn == 0044327) /* moveml mask, (sp) */ \
579 { pc += 2; \
580 /* Regmask's low bit is for register 0, the first written */ \
581 next_addr -= 4; \
582 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
583 if (regmask & 1) \
584 (frame_saved_regs).regs[regnum] = (next_addr += 4); \
585 } else if (insn == 0044347) /* moveml mask, -(sp) */ \
586 { pc += 2; \
587 /* Regmask's low bit is for register 15, the first pushed */ \
588 for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
589 if (regmask & 1) \
590 (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
591 /* clrw -(sp); movw ccr,-(sp) may follow. */ \
592 if (read_memory_integer (pc, 2) == 041147 \
593 && read_memory_integer (pc+2, 2) == 042347) \
594 (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
595 lose: ; \
596 (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
597 (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
598 (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
599}
600#endif
601#else
602#define FRAME_NUM_ARGS(val, fi) (val = -1)
603#endif
604\f
7b4ac7e1 605/* Things needed for making the inferior call functions. */
606
607/* Push an empty stack frame, to record the current PC, etc. */
608
609#define PUSH_DUMMY_FRAME \
610{ register CORE_ADDR sp = read_register (SP_REGNUM); \
611 register int regnum; \
612 char raw_buffer[12]; \
613 sp = push_word (sp, read_register (PC_REGNUM)); \
614 sp = push_word (sp, read_register (FP_REGNUM)); \
615 write_register (FP_REGNUM, sp); \
616 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
617 { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
618 sp = push_bytes (sp, raw_buffer, 12); } \
619 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
620 sp = push_word (sp, read_register (regnum)); \
621 sp = push_word (sp, read_register (PS_REGNUM)); \
622 write_register (SP_REGNUM, sp); }
623
3bf57d21 624/* Discard from the stack the innermost frame,
625 restoring all saved registers. */
7b4ac7e1 626
627#define POP_FRAME \
4187119d 628{ register FRAME frame = get_current_frame (); \
629 register CORE_ADDR fp; \
630 register int regnum; \
631 struct frame_saved_regs fsr; \
632 struct frame_info *fi; \
633 char raw_buffer[12]; \
634 fi = get_frame_info (frame); \
635 fp = fi->frame; \
636 get_frame_saved_regs (fi, &fsr); \
637 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
638 if (fsr.regs[regnum]) \
639 { read_memory (fsr.regs[regnum], raw_buffer, 12); \
7b4ac7e1 640 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
4187119d 641 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
642 if (fsr.regs[regnum]) \
7b4ac7e1 643 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
4187119d 644 if (fsr.regs[PS_REGNUM]) \
7b4ac7e1 645 write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
4187119d 646 write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
647 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
648 write_register (SP_REGNUM, fp + 8); \
649 flush_cached_frames (); \
650 set_current_frame (create_new_frame (read_register (FP_REGNUM), \
651 read_pc ())); }
7b4ac7e1 652
653/* This sequence of words is the instructions
3bf57d21 654 fmovem 0xff,-(sp)
7b4ac7e1 655 moveml 0xfffc,-(sp)
656 clrw -(sp)
657 movew ccr,-(sp)
658 /..* The arguments are pushed at this point by GDB;
659 no code is needed in the dummy for this.
660 The CALL_DUMMY_START_OFFSET gives the position of
661 the following jsr instruction. *../
4187119d 662 jsr @#32323232
7b4ac7e1 663 addl #69696969,sp
e91b87a3 664 bpt
7b4ac7e1 665 nop
3bf57d21 666Note this is 28 bytes.
7b4ac7e1 667We actually start executing at the jsr, since the pushing of the
668registers is done by PUSH_DUMMY_FRAME. If this were real code,
669the arguments for the function called by the jsr would be pushed
670between the moveml and the jsr, and we could allow it to execute through.
671But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
672and we cannot allow the moveml to push the registers again lest they be
673taken for the arguments. */
674
4187119d 675#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4e4e71}
7b4ac7e1 676
677#define CALL_DUMMY_LENGTH 28
678
679#define CALL_DUMMY_START_OFFSET 12
680
681/* Insert the specified number of args and function address
682 into a call sequence of the above form stored at DUMMYNAME. */
683
e91b87a3 684#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \
7b4ac7e1 685{ *(int *)((char *) dummyname + 20) = nargs * 4; \
686 *(int *)((char *) dummyname + 14) = fun; }
687\f
688/* Interface definitions for kernel debugger KDB. */
689
690/* Map machine fault codes into signal numbers.
691 First subtract 0, divide by 4, then index in a table.
692 Faults for which the entry in this table is 0
693 are not handled by KDB; the program's own trap handler
694 gets to handle then. */
695
696#define FAULT_CODE_ORIGIN 0
697#define FAULT_CODE_UNITS 4
698#define FAULT_TABLE \
699{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
700 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
701 0, 0, 0, 0, 0, 0, 0, 0, \
702 SIGILL }
703
704/* Start running with a stack stretching from BEG to END.
705 BEG and END should be symbols meaningful to the assembler.
706 This is used only for kdb. */
707
4187119d 708#ifdef MOTOROLA
709#define INIT_STACK(beg, end) \
710{ asm (".globl end"); \
711 asm ("move.l $ end, sp"); \
712 asm ("clr.l fp"); }
713#else
714#ifdef ALTOS_AS
715#define INIT_STACK(beg, end) \
716{ asm ("global end"); \
717 asm ("mov.l &end,%sp"); \
718 asm ("clr.l %fp"); }
719#else
7b4ac7e1 720#define INIT_STACK(beg, end) \
721{ asm (".globl end"); \
e91b87a3 722 asm ("movel $ end, sp"); \
723 asm ("clrl fp"); }
4187119d 724#endif
725#endif
7b4ac7e1 726
727/* Push the frame pointer register on the stack. */
4187119d 728#ifdef MOTOROLA
729#define PUSH_FRAME_PTR \
730 asm ("move.l fp, -(sp)");
731#else
732#ifdef ALTOS_AS
733#define PUSH_FRAME_PTR \
734 asm ("mov.l %fp, -(%sp)");
735#else
7b4ac7e1 736#define PUSH_FRAME_PTR \
e91b87a3 737 asm ("movel fp, -(sp)");
4187119d 738#endif
739#endif
7b4ac7e1 740
741/* Copy the top-of-stack to the frame pointer register. */
4187119d 742#ifdef MOTOROLA
743#define POP_FRAME_PTR \
744 asm ("move.l (sp), fp");
745#else
746#ifdef ALTOS_AS
747#define POP_FRAME_PTR \
748 asm ("mov.l (%sp), %fp");
749#else
7b4ac7e1 750#define POP_FRAME_PTR \
e91b87a3 751 asm ("movl (sp), fp");
4187119d 752#endif
753#endif
7b4ac7e1 754
755/* After KDB is entered by a fault, push all registers
756 that GDB thinks about (all NUM_REGS of them),
757 so that they appear in order of ascending GDB register number.
758 The fault code will be on the stack beyond the last register. */
759
4187119d 760#ifdef MOTOROLA
761#define PUSH_REGISTERS \
762{ asm ("clr.w -(sp)"); \
763 asm ("pea (10,sp)"); \
764 asm ("movem $ 0xfffe,-(sp)"); }
765#else
766#ifdef ALTOS_AS
767#define PUSH_REGISTERS \
768{ asm ("clr.w -(%sp)"); \
769 asm ("pea (10,%sp)"); \
770 asm ("movm.l &0xfffe,-(%sp)"); }
771#else
7b4ac7e1 772#define PUSH_REGISTERS \
773{ asm ("clrw -(sp)"); \
e91b87a3 774 asm ("pea 10(sp)"); \
775 asm ("movem $ 0xfffe,-(sp)"); }
4187119d 776#endif
777#endif
7b4ac7e1 778
779/* Assuming the registers (including processor status) have been
780 pushed on the stack in order of ascending GDB register number,
781 restore them and return to the address in the saved PC register. */
782
4187119d 783#ifdef MOTOROLA
7b4ac7e1 784#define POP_REGISTERS \
4187119d 785{ asm ("subi.l $8,28(sp)"); \
e91b87a3 786 asm ("movem (sp),$ 0xffff"); \
7b4ac7e1 787 asm ("rte"); }
4187119d 788#else
789#ifdef ALTOS_AS
790#define POP_REGISTERS \
791{ asm ("sub.l &8,28(%sp)"); \
792 asm ("movem (%sp),&0xffff"); \
793 asm ("rte"); }
794#else
795#define POP_REGISTERS \
796{ asm ("subil $8,28(sp)"); \
797 asm ("movem (sp),$ 0xffff"); \
e91b87a3 798 asm ("rte"); }
4187119d 799#endif
800#endif
e91b87a3 801
This page took 0.074329 seconds and 4 git commands to generate.