|
|
1.1 ! root 1: /* $Header: /src386/STREAMS/coh.386/RCS/ker_data.c,v 2.1 93/08/09 13:35:41 bin Exp Locker: bin $ */ ! 2: /* ! 3: * This file contains definitions for the functions which support the Coherent ! 4: * internal binary-compatibility scheme. We select _SYSV3 to get some old ! 5: * definitions like makedev () visible. ! 6: */ ! 7: /* ! 8: * $Log: ker_data.c,v $ ! 9: * Revision 2.1 93/08/09 13:35:41 bin ! 10: * Kernel 82 changes ! 11: * ! 12: * Revision 2.2 93/07/26 14:55:28 nigel ! 13: * Nigel's R80 ! 14: * ! 15: */ ! 16: ! 17: #define _SYSV3 1 ! 18: ! 19: #include <common/ccompat.h> ! 20: #include <common/_tricks.h> ! 21: #include <common/_gregset.h> ! 22: #include <kernel/sigproc.h> ! 23: #include <kernel/v_types.h> ! 24: #include <sys/debug.h> ! 25: #include <string.h> ! 26: ! 27: /* ! 28: * These two pull in all the old-style trash. ! 29: */ ! 30: ! 31: #include <sys/coherent.h> ! 32: #include <sys/uproc.h> ! 33: #include <sys/proc.h> ! 34: ! 35: /* ! 36: * Stubs for the multiprocessor locking functions. ! 37: */ ! 38: ! 39: #define PROC_STATE_LOCK(proc) sphi () ! 40: #define PROC_STATE_UNLOCK(proc,pl) spl (pl) ! 41: #define PROC_ASSERT_LOCKED(proc) ((void) 0) ! 42: ! 43: ! 44: /* ! 45: * Initialize a freshly-allocated process structure to a copy of the current ! 46: * process. As a special case, if there is no current process, the new process ! 47: * is given some default values. ! 48: */ ! 49: ! 50: #if __USE_PROTO__ ! 51: void PROC_INIT (__proc_t * process) ! 52: #else ! 53: void ! 54: PROC_INIT (process) ! 55: __proc_t * process; ! 56: #endif ! 57: { ! 58: process->p_event = NULL; /* Wakeup event channel */ ! 59: process->p_alarm = 0; /* Timer for alarms */ ! 60: ! 61: process->p_utime = 0L; /* User time (HZ) */ ! 62: process->p_stime = 0L; /* System time */ ! 63: process->p_cutime = 0L; /* Sum of childs user time */ ! 64: process->p_cstime = 0L; /* Sum of childs system time */ ! 65: process->p_exit = 0; /* Exit status */ ! 66: process->p_polls = NULL; /* Enabled polls */ ! 67: ! 68: /* Poll timer */ ! 69: process->p_polltim.t_next = NULL; ! 70: process->p_polltim.t_last = NULL; ! 71: process->p_polltim.t_lbolt = 0L; ! 72: process->p_polltim.t_func = NULL; ! 73: process->p_polltim.t_farg = NULL; ! 74: ! 75: /* Alarm timer */ ! 76: process->p_alrmtim.t_next = NULL; ! 77: process->p_alrmtim.t_last = NULL; ! 78: process->p_alrmtim.t_lbolt = 0L; ! 79: process->p_alrmtim.t_func = NULL; ! 80: process->p_alrmtim.t_farg = NULL; ! 81: ! 82: process->p_prl = NULL; /* Pending record lock */ ! 83: process->p_semu = NULL; /* Semaphore undo */ ! 84: ! 85: process->p_flags = PFCORE; ! 86: process->p_state = PSRUN; ! 87: process->p_ttdev = NODEV; ! 88: ! 89: process->p_pid = 0; ! 90: ! 91: __SIGSET_EMPTY (process->p_pending_signals); ! 92: ! 93: if (SELF == NULL) { ! 94: process->p_ppid = 0; ! 95: process->p_nice = 0; ! 96: process->p_schedPri = 0; ! 97: ! 98: process->p_uid = 0; ! 99: process->p_group = 0; ! 100: process->p_ruid = 0; ! 101: process->p_rgid = 0; ! 102: ! 103: /* ! 104: * Set ttdev to null so that we do not accidentally set a tty ! 105: * for init. ! 106: */ ! 107: process->p_ttdev = makedev (0, 0); ! 108: ! 109: __SIGSET_EMPTY (process->p_signal_mask); ! 110: __SIGSET_EMPTY (process->p_queued_signals); ! 111: ! 112: /* ! 113: * The default action for the following signals is to ignore ! 114: * them. ! 115: */ ! 116: ! 117: #if _SIGNAL_MAX <= __LONG_BIT ! 118: process->p_ignored_signals._sigbits [0] = ! 119: __SIGSET_MASK (SIGCHLD) | __SIGSET_MASK (SIGPWR) | ! 120: __SIGSET_MASK (SIGWINCH) | __SIGSET_MASK (SIGURG) | ! 121: __SIGSET_MASK (SIGPOLL) | __SIGSET_MASK (SIGCONT); ! 122: #else ! 123: __SIGSET_EMPTY (process->p_ignored_signals); ! 124: __SIGSET_CLRBIT (process->p_ignored, SIGCHLD); ! 125: __SIGSET_CLRBIT (process->p_ignored, SIGPWR); ! 126: __SIGSET_CLRBIT (process->p_ignored, SIGWINCH); ! 127: __SIGSET_CLRBIT (process->p_ignored, SIGURG); ! 128: __SIGSET_CLRBIT (process->p_ignored, SIGPOLL); ! 129: __SIGSET_CLRBIT (process->p_ignored, SIGCONT); ! 130: #endif ! 131: ! 132: process->p_sigflags = 0; ! 133: } else { ! 134: process->p_ppid = SELF->p_pid; ! 135: process->p_nice = SELF->p_nice; ! 136: process->p_schedPri = SELF->p_schedPri; ! 137: ! 138: process->p_uid = SELF->p_uid; ! 139: process->p_group = SELF->p_group; ! 140: process->p_ruid = SELF->p_ruid; ! 141: process->p_rgid = SELF->p_rgid; ! 142: ! 143: process->p_ttdev = SELF->p_ttdev; ! 144: ! 145: process->p_signal_mask = SELF->p_signal_mask; ! 146: process->p_ignored_signals = SELF->p_ignored_signals; ! 147: process->p_queued_signals = SELF->p_queued_signals; ! 148: ! 149: process->p_sigflags = SELF->p_sigflags; ! 150: } ! 151: } ! 152: ! 153: ! 154: /* ! 155: * Wake a process from a sleep state, with the indicated "reason" code so that ! 156: * the process can know whether sleep was interrupted or not. ! 157: */ ! 158: ! 159: #if __USE_PROTO__ ! 160: void PROC_WAKE (__proc_t * process, int reason) ! 161: #else ! 162: void ! 163: PROC_WAKE (process, reason) ! 164: __proc_t * process; ! 165: int reason; ! 166: #endif ! 167: { ! 168: PROC_ASSERT_LOCKED (process); ! 169: ! 170: /* ! 171: * Dequeue the process from the hash list used for old-style sleep (). ! 172: */ ! 173: ! 174: process->p_lback->p_lforw = process->p_lforw; ! 175: process->p_lforw->p_lback = process->p_lback; ! 176: ! 177: /* ! 178: * Change the process state to runnable and queue the process on the ! 179: * appropriate run queue. ! 180: */ ! 181: ! 182: setrun (process); ! 183: } ! 184: ! 185: #define PROC_WAKE_SIGNAL(proc) PROC_WAKE (proc, PROCESS_SIGNALLED) ! 186: ! 187: ! 188: /* ! 189: * Internal version of sigaction (), which allows retrieval and optional ! 190: * replacement of the current signal information. ! 191: * ! 192: * Note that we take a copy of the current information in a temporary before ! 193: * trying to fiddle the new information; this allows the "act" and "oact" ! 194: * pointers to point to the same space. ! 195: */ ! 196: ! 197: #if __USE_PROTO__ ! 198: void curr_signal_action (int signal, __CONST__ __sigaction_t * act, ! 199: __sigaction_t * oact) ! 200: #else ! 201: void ! 202: curr_signal_action (signal, act, oact) ! 203: int signal; ! 204: __CONST__ __sigaction_t ! 205: * act; ! 206: __sigaction_t * oact; ! 207: #endif ! 208: { ! 209: __sigaction_t * proc_act; ! 210: ! 211: ASSERT (oact != NULL || act != NULL); ! 212: ASSERT (signal > 0 && signal <= _SIGNAL_MAX); ! 213: ! 214: proc_act = & u.u_sigact [signal - 1]; ! 215: ! 216: if (act != NULL) { ! 217: __sigmask_t mask = __SIGSET_MASK (signal); ! 218: __sigaction_t temp; ! 219: ! 220: /* ! 221: * Exchange the "action" data. ! 222: */ ! 223: ! 224: temp = * proc_act; ! 225: * proc_act = * act; ! 226: if (oact != NULL) ! 227: * oact = temp; ! 228: ! 229: /* ! 230: * The SIGILL, SIGTRAP and SIGPWR signals do not have their ! 231: * handlers reset to SIG_DFL even if the user requests this. ! 232: * Again, this is "silently enforced" so it happens at this ! 233: * layer. ! 234: */ ! 235: ! 236: #if _SIGNAL_MAX <= __LONG_BIT ! 237: if ((mask & (__SIGSET_MASK (SIGILL) | __SIGSET_MASK (SIGTRAP) | ! 238: __SIGSET_MASK (SIGPWR))) == 0) ! 239: #else ! 240: if (signal == SIGILL || signal == SIGTRAP || signal == SIGPWR) ! 241: #endif ! 242: proc_act->sa_flags &= ~ __SA_RESETHAND; ! 243: ! 244: /* ! 245: * Set the ignore flags to match handler. Note that we do not ! 246: * clear the pending signals for the current process here; ! 247: * that will happen on the way out of the system call we are ! 248: * in during the check for signals to deliver. ! 249: */ ! 250: ! 251: if (proc_act->sa_handler == SIG_IGN) ! 252: __SIGSET_ADDMASK (SELF->p_ignored_signals, signal, ! 253: mask); ! 254: else ! 255: __SIGSET_CLRMASK (SELF->p_ignored_signals, signal, ! 256: mask); ! 257: ! 258: /* ! 259: * Existing System V, Release 4 systems zero the mask if the ! 260: * signal is defaulted or ignored, so we copy them. ! 261: */ ! 262: ! 263: if (proc_act->sa_handler == SIG_IGN || ! 264: proc_act->sa_handler == SIG_DFL) ! 265: __SIGSET_EMPTY (proc_act->sa_mask); ! 266: ! 267: /* ! 268: * The default action for the following signals is for them to ! 269: * be ignored: SIGCHLD, SIGPWR, SIGWINCH, SIGURG, SIGPOLL, ! 270: * SIGCONT. ! 271: */ ! 272: ! 273: #if _SIGNAL_MAX <= __LONG_BIT ! 274: if (((__SIGSET_MASK (SIGCHLD) | __SIGSET_MASK (SIGPWR) | ! 275: __SIGSET_MASK (SIGWINCH) | __SIGSET_MASK (SIGURG) | ! 276: __SIGSET_MASK (SIGPOLL) | __SIGSET_MASK (SIGCONT)) ! 277: & mask) != 0 ! 278: #else ! 279: if ((signal == SIGCHLD || signal == SIGPWR || ! 280: signal == SIGWINCH || signal == SIGURG || ! 281: signal == SIGPOLL || signal == SIGCONT) ! 282: #endif ! 283: && proc_act->sa_handler == SIG_DFL) ! 284: __SIGSET_ADDMASK (SELF->p_ignored_signals, signal, ! 285: mask); ! 286: ! 287: if ((proc_act->sa_flags & __SA_SIGINFO) != 0) ! 288: __SIGSET_ADDMASK (SELF->p_queued_signals, signal, ! 289: mask); ! 290: } else ! 291: * oact = * proc_act; ! 292: } ! 293: ! 294: ! 295: /* ! 296: * Obtain and possibly change the current process's signal mask. Note that ! 297: * we capture the current mask to a temporary before beginning, thus allowing ! 298: * "mask" and "omask" to point to the same storage. ! 299: */ ! 300: ! 301: #if __USE_PROTO__ ! 302: void curr_signal_mask (__CONST__ __sigset_t * mask, __sigset_t * omask) ! 303: #else ! 304: void ! 305: curr_signal_mask (mask, omask) ! 306: __CONST__ __sigset_t ! 307: * mask; ! 308: __sigset_t * omask; ! 309: #endif ! 310: { ! 311: ASSERT (omask != NULL || mask != NULL); ! 312: ! 313: if (mask != NULL) { ! 314: __sigset_t temp; ! 315: ! 316: /* ! 317: * The caller of this function should arrange for collateral ! 318: * actions such as checking for newly-unmasked signals in such ! 319: * as way as to ensure that signal actions are dealt with ! 320: * promptly and to ensure that locking is not needed. ! 321: * ! 322: * For instance, at this point signals may be briefly held ! 323: * which in fact "cannot" be. We don't care about this; the ! 324: * above constraint on our callers will ensure that this has ! 325: * no effect. ! 326: */ ! 327: ! 328: temp = SELF->p_signal_mask; ! 329: SELF->p_signal_mask = * mask; ! 330: if (omask != NULL) ! 331: * omask = temp; ! 332: ! 333: /* ! 334: * SIGKILL and SIGSTOP may never be blocked or caught. Here we ! 335: * enforce the blocking part, which as the SVR4 PRM says is ! 336: * "silently enforced" by the system. ! 337: */ ! 338: ! 339: __SIGSET_CLRBIT (SELF->p_signal_mask, SIGKILL); ! 340: __SIGSET_CLRBIT (SELF->p_signal_mask, SIGSTOP); ! 341: } else ! 342: * omask = SELF->p_signal_mask; ! 343: } ! 344: ! 345: ! 346: /* ! 347: * Test the signal mask of the given process to determine whether the given ! 348: * signal is masked. ! 349: */ ! 350: ! 351: #if __USE_PROTO__ ! 352: int proc_signal_masked (__proc_t * process, int signal) ! 353: #else ! 354: int ! 355: proc_signal_masked (process, signal) ! 356: __proc_t * process; ! 357: int signal; ! 358: #endif ! 359: { ! 360: ASSERT (process != NULL && signal > 0 && signal <= _SIGNAL_MAX); ! 361: return __SIGSET_TSTBIT (process->p_signal_mask, signal); ! 362: } ! 363: ! 364: ! 365: /* ! 366: * Return a zero value if there are no signals pending, otherwise return the ! 367: * number of the first unmasked, non-ignored signal. ! 368: * ! 369: * NOTE: The code here interacts with curr_signal_action () and ! 370: * proc_send_signal () in some ways that need comment; specifically, the ! 371: * treatment of ignored signals may seem sloppy. However, the System V usage ! 372: * of allowing ignored signals to be blocked, and then caught if a handler is ! 373: * subsequently attached means that the approach of clearing pending, ignored ! 374: * signals at this point is much simpler than dealing with them at all the ! 375: * other points (arrival, unblocking, handler attach). ! 376: */ ! 377: ! 378: #if __USE_PROTO__ ! 379: int curr_signal_pending (void) ! 380: #else ! 381: int ! 382: curr_signal_pending () ! 383: #endif ! 384: { ! 385: int signo; ! 386: ! 387: /* ! 388: * If any signals have arrived, but which are not held, figure out ! 389: * what they are. This takes a little doing. ! 390: */ ! 391: ! 392: for (signo = 0 ; ! 393: signo < __ARRAY_LENGTH (SELF->p_pending_signals._sigbits) ; ! 394: signo ++) { ! 395: __sigmask_t mask; ! 396: ! 397: mask = (SELF->p_pending_signals._sigbits [signo] &= ! 398: ~ SELF->p_ignored_signals._sigbits [signo]) & ! 399: ~ SELF->p_signal_mask._sigbits [signo]; ! 400: if (mask == 0) ! 401: continue; ! 402: ! 403: /* ! 404: * There is at least one signal. Extract its number ! 405: * from the signal bits. ! 406: */ ! 407: ! 408: T_HAL(8, printf ("curr_signal_pending () = %d ", ! 409: signo * sizeof (__sigmask_t) * __CHAR_BIT + ! 410: __SIGSET_FIRSTBIT (mask))); ! 411: ! 412: return signo * sizeof (__sigmask_t) * __CHAR_BIT + ! 413: __SIGSET_FIRSTBIT (mask); ! 414: } ! 415: return 0; ! 416: } ! 417: ! 418: ! 419: #if _SIGNAL_MAX <= __LONG_BIT ! 420: /* ! 421: * For optimizing handling of job-control signals. ! 422: */ ! 423: ! 424: #define STOP_SIGNALS (__SIGSET_MASK (SIGSTOP) | __SIGSET_MASK (SIGTSTP) |\ ! 425: __SIGSET_MASK (SIGTTIN) | __SIGSET_MASK (SIGTTOU)) ! 426: #endif ! 427: ! 428: /* ! 429: * Add the given signal to the indicated process's pending-signal mask and if ! 430: * the process requires some notification (such as being woken if asleep, or ! 431: * interrupted if scheduled on another processor) then perform that. ! 432: * ! 433: * This function can only be called from base level, but we must be aware of ! 434: * the fact that process state-changes can happen at interrupt level and that ! 435: * we can be interacting with multiple processors. ! 436: */ ! 437: ! 438: #if __USE_PROTO__ ! 439: void proc_send_signal (__proc_t * process, __CONST__ __siginfo_t * siginfo) ! 440: #else ! 441: void ! 442: proc_send_signal (process, siginfo) ! 443: __proc_t * process; ! 444: __CONST__ __siginfo_t ! 445: * siginfo; ! 446: #endif ! 447: { ! 448: __sigmask_t mask; ! 449: pl_t prev_pl; ! 450: ! 451: ASSERT (process != NULL && siginfo != NULL); ! 452: ASSERT (siginfo->__si_signo > 0 && siginfo->__si_signo <= _SIGNAL_MAX); ! 453: ! 454: mask = __SIGSET_MASK (siginfo->__si_signo); ! 455: ! 456: if (siginfo->__si_signo == SIGCONT) { ! 457: /* ! 458: * When a SIGCONT is received, all pending stop signals are ! 459: * discarded and if the process is stopped, it is continued. ! 460: */ ! 461: ! 462: #if _SIGNAL_MAX <= __LONG_BIT ! 463: __SIGSET_CLRMASK (process->p_pending_signals, 0, ! 464: STOP_SIGNALS); ! 465: #else ! 466: __SIGSET_CLRBIT (process->p_pending_signals, SIGSTOP); ! 467: __SIGSET_CLRBIT (process->p_pending_signals, SIGTSTP); ! 468: __SIGSET_CLRBIT (process->p_pending_signals, SIGTTIN); ! 469: __SIGSET_CLRBIT (process->p_pending_signals, SIGTTOU); ! 470: #endif ! 471: ! 472: #ifdef PROC_IS_STOPPED ! 473: if (PROC_IS_STOPPED (process)) ! 474: PROC_CONTINUE (process); ! 475: #endif ! 476: } ! 477: ! 478: #if _SIGNAL_MAX <= __LONG_BIT ! 479: if ((mask & STOP_SIGNALS) != 0) { ! 480: #else ! 481: if (siginfo->__si_signo == SIGSTOP || ! 482: siginfo->__si_signo == SIGTSTP || ! 483: siginfo->__si_signo == SIGTTIN || ! 484: siginfo->__si_signo == SIGTTOU) { ! 485: #endif ! 486: /* ! 487: * When a stop signal is received, any pending SIGCONT signal ! 488: * is discarded. ! 489: */ ! 490: ! 491: __SIGSET_CLRBIT (process->p_pending_signals, SIGCONT); ! 492: } ! 493: ! 494: ! 495: #if 0 ! 496: if (__SIGSET_TSTMASK (process->p_queued_signals, siginfo->__si_signo, ! 497: mask) != 0) { ! 498: /* ! 499: * Reliable signal-queueing is in effect, so we must stash ! 500: * away a copy of the structure pointed at by "siginfo" so we ! 501: * can deliver the information as an additional argument to ! 502: * the signal-catching function. ! 503: */ ! 504: ASSERT ("Not implemented" == NULL); ! 505: } ! 506: #endif /* NOT IMPLEMENTED */ ! 507: ! 508: ! 509: /* ! 510: * Here we are about to modify some shared per-process state; now is a ! 511: * good time to take a lock, so we structure the code so it can be ! 512: * released. We require a basic lock for the state-change code, so we ! 513: * use that lock to cover the process-level guard as well. In a uni- ! 514: * processor system, the process-level guard is not necessary, but the ! 515: * extra area covered is small enough that it doesn't matter. ! 516: */ ! 517: ! 518: prev_pl = PROC_STATE_LOCK (process); ! 519: ! 520: __SIGSET_ADDMASK (process->p_pending_signals, ! 521: siginfo->__si_signo, mask); ! 522: ! 523: if (! __SIGSET_TSTMASK (process->p_signal_mask, ! 524: siginfo->__si_signo, mask) && ! 525: ! __SIGSET_TSTMASK (process->p_ignored_signals, ! 526: siginfo->__si_signo, mask) && ! 527: process->p_state == PSSLSIG) { ! 528: /* ! 529: * The process is sleeping and wants to be woken by ! 530: * signals, arrange for it to come out of sleep so it ! 531: * can get to user-level and process the signal. ! 532: */ ! 533: ! 534: PROC_WAKE_SIGNAL (process); ! 535: } ! 536: ! 537: PROC_STATE_UNLOCK (process, prev_pl); ! 538: ! 539: T_HAL (8, printf (" ign = %x hold = %x pend = %x ", ! 540: process->p_ignored_signals._sigbits [0], ! 541: process->p_signal_mask._sigbits [0], ! 542: process->p_pending_signals._sigbits [0])); ! 543: } ! 544: ! 545: ! 546: /* ! 547: * Obtain and/or modify the current process's miscellaneous signal-flags. The ! 548: * previous flags are returned, making "curr_signal_misc (0, 0)" the fetch. ! 549: */ ! 550: ! 551: #if __USE_PROTO__ ! 552: __sigmiscfl_t curr_signal_misc (__sigmiscfl_t clear, __sigmiscfl_t set) ! 553: #else ! 554: __sigmiscfl_t ! 555: curr_signal_misc (clear, set) ! 556: __sigmiscfl_t clear; ! 557: __sigmiscfl_t set; ! 558: #endif ! 559: { ! 560: __sigmiscfl_t temp = SELF->p_sigflags; ! 561: ! 562: SELF->p_sigflags = (temp & ~ clear) | set; ! 563: return temp; ! 564: } ! 565: ! 566: ! 567: /* ! 568: * Return the given process's miscellaneous signal information. Note that we ! 569: * don't try and deal with synchronization issues here, so whatever code tests ! 570: * this data has to find some way of being multi-processor safe (concretely, ! 571: * it means that the uses of the signal information here are not atomic at the ! 572: * system-call level). ! 573: */ ! 574: ! 575: #if __USE_PROTO__ ! 576: __sigmiscfl_t proc_signal_misc (__proc_t * process) ! 577: #else ! 578: __sigmiscfl_t ! 579: proc_signal_misc (process) ! 580: __proc_t * process; ! 581: #endif ! 582: { ! 583: return process->p_sigflags; ! 584: } ! 585: ! 586: ! 587: /* ! 588: * Remove a signal from the pending signal mask. ! 589: */ ! 590: ! 591: #if __USE_PROTO__ ! 592: void proc_unkill (__proc_t * process, int signal) ! 593: #else ! 594: void ! 595: proc_unkill (process, signal) ! 596: __proc_t * process; ! 597: int signal; ! 598: #endif ! 599: { ! 600: __SIGSET_CLRBIT (process->p_pending_signals, signal); ! 601: } ! 602: ! 603: ! 604: /* ! 605: * Perform a register dump from a gregset_t, plus any useful data from the ! 606: * current process. ! 607: */ ! 608: ! 609: #if __USE_PROTO__ ! 610: void curr_register_dump (gregset_t * regsetp) ! 611: #else ! 612: void ! 613: curr_register_dump (regsetp) ! 614: gregset_t * regsetp; ! 615: #endif ! 616: { ! 617: printf ("\neax=%x ebx=%x ecx=%x edx=%x\n", regsetp->_i386._eax, ! 618: regsetp->_i386._ebx, regsetp->_i386._ecx, regsetp->_i386._edx); ! 619: printf ("esi=%x edi=%x ebp=%x esp=%x\n", regsetp->_i386._esi, ! 620: regsetp->_i386._edi, regsetp->_i386._ebp, regsetp->_i386._esp); ! 621: printf ("cs=%x ds=%x es=%x ss=%x fs=%x gs=%x\n", ! 622: regsetp->_i386._cs, regsetp->_i386._ds, regsetp->_i386._es, ! 623: regsetp->_i386._ss, regsetp->_i386._fs, regsetp->_i386._gs); ! 624: printf ("err #%d eip=%x uesp=%x cmd=%s\n", regsetp->_i386._err, ! 625: regsetp->_i386._eip, regsetp->_i386._uesp, u.u_comm); ! 626: printf ("efl=%x ", regsetp->_i386._eflags); ! 627: ! 628: if ((regsetp->_i386._cs & R_USR) != R_USR) { ! 629: /* ! 630: * This register set is indicating something that happened in ! 631: * the kernel, so do a call backtrace. To make this a little ! 632: * more robust, we only go upwards in the stack from the frame ! 633: * where we are, so that a smashed %ebp or frame causes no ! 634: * problems. ! 635: */ ! 636: ! 637: __ulong_t * ebp = (__ulong_t *) regsetp->_i386._ebp; ! 638: __ulong_t * prev = & regsetp->_i386._ebp; ! 639: while (ebp > prev) { ! 640: printf (" -> %x", * (ebp + 1)); ! 641: ebp = (__ulong_t *) * (prev = ebp); ! 642: } ! 643: printf ("\n"); ! 644: } ! 645: } ! 646:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.