Ignore:
Timestamp:
Apr 29, 2006, 3:14:27 PM (13 years ago)
Author:
gb
Message:

Write-protect handlers for stack overflow (on value/temp stacks).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/x86-exceptions.c

    r4473 r4478  
    435435}
    436436
     437
     438protection_handler
     439* protection_handlers[] = {
     440  do_spurious_wp_fault,
     441  do_soft_stack_overflow,
     442  do_soft_stack_overflow,
     443  do_soft_stack_overflow,
     444  do_hard_stack_overflow,   
     445  do_hard_stack_overflow,
     446  do_hard_stack_overflow,
     447};
     448
     449
     450/* Maybe this'll work someday.  We may have to do something to
     451   make the thread look like it's not handling an exception */
     452void
     453reset_lisp_process(ExceptionInformation *xp)
     454{
     455}
     456
     457Boolean
     458do_hard_stack_overflow(ExceptionInformation *xp, protected_area_ptr area, BytePtr addr)
     459{
     460  reset_lisp_process(xp);
     461  return false;
     462}
     463
     464
     465Boolean
     466do_spurious_wp_fault(ExceptionInformation *xp, protected_area_ptr area, BytePtr addr)
     467{
     468
     469  return false;
     470}
     471
     472Boolean
     473do_soft_stack_overflow(ExceptionInformation *xp, protected_area_ptr prot_area, BytePtr addr)
     474{
     475  /* Trying to write into a guard page on the vstack or tstack.
     476     Allocate a new stack segment, emulate stwu and stwux for the TSP, and
     477     signal an error_stack_overflow condition.
     478      */
     479  lisp_protection_kind which = prot_area->why;
     480  Boolean on_TSP = (which == kTSPsoftguard);
     481  LispObj save_rbp = xpGPR(xp,Irbp),
     482    save_vsp = xpGPR(xp,Isp),
     483    xcf,
     484    cmain = nrs_CMAIN.vcell;
     485  area *a;
     486  protected_area_ptr soft;
     487  TCR *tcr = get_tcr(false);
     488  int skip;
     489
     490  if ((fulltag_of(cmain) == fulltag_misc) &&
     491      (header_subtag(header_of(cmain)) == subtag_macptr)) {
     492    if (on_TSP) {
     493      a = tcr->ts_area;
     494    } else {
     495      a = tcr->vs_area;
     496    }
     497    soft = a->softprot;
     498    unprotect_area(soft);
     499    xcf = create_exception_callback_frame(xp);
     500    skip = callback_to_lisp(tcr, nrs_CMAIN.vcell, xp, xcf, SIGSEGV, on_TSP, 0, 0);
     501    xpGPR(xp,Irbp) = save_rbp;
     502    xpGPR(xp,Isp) = save_vsp;
     503    xpPC(xp) += skip;
     504    return true;
     505  }
     506  return false;
     507}
     508
    437509Boolean
    438510handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
    439511{
     512  BytePtr addr = (BytePtr) info->si_addr;
     513  protected_area *a = find_protected_area(addr);
     514  protection_handler *handler;
     515
     516  if (a) {
     517    handler = protection_handlers[a->why];
     518    return handler(xp, a, addr);
     519  }
    440520  return false;
    441521}
     
    875955}
    876956
    877 void
    878 restore_soft_stack_limit(unsigned stkreg)
    879 {
    880 }
    881 
    882 /* Maybe this'll work someday.  We may have to do something to
    883    make the thread look like it's not handling an exception */
    884 void
    885 reset_lisp_process(ExceptionInformation *xp)
    886 {
    887 }
     957/*
     958  Lower (move toward 0) the "end" of the soft protected area associated
     959  with a by a page, if we can.
     960*/
     961
     962void
     963
     964adjust_soft_protection_limit(area *a)
     965{
     966  char *proposed_new_soft_limit = a->softlimit - 4096;
     967  protected_area_ptr p = a->softprot;
     968 
     969  if (proposed_new_soft_limit >= (p->start+16384)) {
     970    p->end = proposed_new_soft_limit;
     971    p->protsize = p->end-p->start;
     972    a->softlimit = proposed_new_soft_limit;
     973  }
     974  protect_area(p);
     975}
     976
     977void
     978restore_soft_stack_limit(unsigned restore_tsp)
     979{
     980  TCR *tcr = get_tcr(false);
     981  area *a;
     982 
     983  if (restore_tsp) {
     984    a = tcr->ts_area;
     985  } else {
     986    a = tcr->vs_area;
     987  }
     988  adjust_soft_protection_limit(a);
     989}
     990
    888991
    889992void
Note: See TracChangeset for help on using the changeset viewer.