Annotation of 43BSDReno/contrib/emacs-18.55/gdb/m-isi.h, revision 1.1.1.1

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"); }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.