Ignore:
Timestamp:
Aug 26, 2008, 3:24:37 AM (11 years ago)
Author:
gb
Message:

Merge changes from branches/win64.

As well as the expected low-level exception/suspend/interrupt stuff,
these changes also include changes to [f]printf format strings. Note
that on win64, a 'long' is 32-bits wide, which complicates matters:

  • an address (viewed as an integer) or a natural-sized integer isn't

(portably) a long, and so can't be printed with %l.

  • an address (viewed as an integer) or a natural-sized integer isn't

(portably) a long long, and so can't be printed with %ll.

  • an address (viewed as an integer) or a natural-sized integer can be

portably printed with '%p', but implementations differ as to whether
or not '%p' prepends a gratuitous '0x' to the hex address. (Linux
does, other current platforms seem not to.)

The approach that seems to work is to cast arguments to natural, then
to u64_t, then use %ll. That approach probably isn't taken consistently
(yet), so some debugging information printed by the kernel may be
incorrect.

File:
1 edited

Legend:

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

    r10492 r10565  
    3838#include <sys/syslog.h>
    3939#endif
    40 
     40#ifdef WINDOWS
     41#include <windows.h>
     42#include <winternl.h>
     43#include <ntstatus.h>
     44#endif
    4145
    4246int
     
    767771}
    768772
    769 #ifdef WINDOWS
    770773Boolean
    771774handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
    772775{
    773 }
    774 
    775 Boolean
    776 handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
    777 {
    778 }
    779 #else
    780 Boolean
    781 handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
    782 {
    783776#ifdef FREEBSD
    784777  BytePtr addr = (BytePtr) xp->uc_mcontext.mc_addr;
    785778#else
     779#ifdef WINDOWS
     780  BytePtr addr = NULL;          /* FIX THIS */
     781#else
    786782  BytePtr addr = (BytePtr) info->si_addr;
     783#endif
    787784#endif
    788785
     
    822819handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
    823820{
    824   int code = info->si_code, skip;
     821  int code,skip;
    825822  LispObj  xcf, cmain = nrs_CMAIN.vcell,
    826823    save_vsp = xpGPR(xp,Isp);
     
    830827  LispObj save_ebp = xpGPR(xp,Iebp);
    831828#endif
     829#ifdef WINDOWS
     830  code = info->ExceptionCode;
     831#else
     832  code = info->si_code;
     833#endif 
    832834
    833835  if ((fulltag_of(cmain) == fulltag_misc) &&
     
    847849  }
    848850}
    849 #endif
     851
    850852
    851853Boolean
     
    950952}
    951953
    952 #ifdef WINDOWS
    953 Boolean
    954 handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr, int old_valence)
    955 {
    956 }
    957 #else
    958954Boolean
    959955handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr, int old_valence)
     
    995991          {
    996992            char msg[512];
    997              
     993
    998994            get_lisp_string(xpGPR(context,Iarg_z),msg, sizeof(msg)-1);
    999995            lisp_Debugger(context, info, debug_entry_dbg, false, msg);
    1000996          }
    1001           return true;
    1002            
     997          return true;
     998         
    1003999        default:
    10041000          return handle_error(tcr, context);
     
    11071103  }
    11081104}
    1109 #endif
     1105
    11101106
    11111107/*
     
    11231119  tcr->valence = TCR_STATE_EXCEPTION_WAIT;
    11241120
     1121#ifdef WINDOWS
     1122  if (tcr->flags & (1<<TCR_FLAG_BIT_PENDING_SUSPEND)) {
     1123    CLR_TCR_FLAG(tcr, TCR_FLAG_BIT_PENDING_SUSPEND);
     1124    SEM_RAISE(tcr->suspend);
     1125    SEM_WAIT_FOREVER(tcr->resume);
     1126  }
     1127#else
    11251128  ALLOW_EXCEPTIONS(context);
     1129#endif
    11261130  return old_valence;
    11271131
     
    13061310#endif
    13071311
    1308 #ifdef WINDOWS
    1309 LispObj *
    1310 copy_ucontext(ExceptionInformation *context, LispObj *current, copy_ucontext_last_arg_t fp)
    1311 {
    1312 }
    1313 #else
     1312#ifndef WINDOWS
    13141313LispObj *
    13151314copy_ucontext(ExceptionInformation *context, LispObj *current, copy_ucontext_last_arg_t fp)
     
    13321331#endif
    13331332
     1333
    13341334LispObj *
    13351335find_foreign_rsp(LispObj rsp, area *foreign_area, TCR *tcr)
     
    13541354#endif
    13551355
     1356#ifndef WINDOWS
    13561357void
    13571358handle_signal_on_foreign_stack(TCR *tcr,
     
    13991400  switch_to_foreign_stack(foreign_rsp,handler,signum,info_copy,xp);
    14001401}
    1401 
    1402 
     1402#endif
     1403
     1404
     1405#ifndef WINDOWS
    14031406#ifndef USE_SIGALTSTACK
    14041407void
     
    14521455}
    14531456#endif
     1457#endif
    14541458
    14551459Boolean
     
    14631467
    14641468#ifdef WINDOWS
    1465 void
    1466 interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
    1467 {
    1468 }
    1469 #else
     1469extern LONG restore_win64_context(ExceptionInformation *, TCR *, int;);
     1470#endif
     1471
    14701472void
    14711473interrupt_handler (int signum, siginfo_t *info, ExceptionInformation *context)
     
    14751477#endif
    14761478  TCR *tcr = get_interrupt_tcr(false);
     1479  int old_valence = tcr->valence;
     1480
    14771481  if (tcr) {
    14781482    if ((TCR_INTERRUPT_LEVEL(tcr) < 0) ||
     
    14851489        ! stack_pointer_on_vstack_p(xpGPR(context,Iebp), tcr)) {
    14861490#endif
    1487       tcr->interrupt_pending = (1L << (nbits_in_word - 1L));
     1491      tcr->interrupt_pending = (((natural) 1)<< (nbits_in_word - ((natural)1)));
    14881492    } else {
    14891493      LispObj cmain = nrs_CMAIN.vcell;
     
    14961500
    14971501        xframe_list xframe_link;
    1498         int old_valence;
    14991502        signed_natural alloc_displacement = 0;
    15001503        LispObj
     
    15311534        tcr->flags |= old_foreign_exception;
    15321535        unlock_exception_lock_in_handler(tcr);
     1536#ifndef WINDOWS
    15331537        exit_signal_handler(tcr, old_valence);
     1538#endif
    15341539      }
    15351540    }
     
    15401545  }
    15411546#endif
     1547#ifdef WINDOWS
     1548  restore_win64_context(context,tcr,old_valence);
     1549#else
    15421550  SIGRETURN(context);
    1543 }
    1544 #endif
    1545 
     1551#endif
     1552}
     1553
     1554
     1555#ifndef WINDOWS
    15461556#ifndef USE_SIGALTSTACK
    15471557void
     
    15961606
    15971607#endif
    1598 
    1599 #ifdef WINDOWS
    1600 void
    1601 install_signal_handler(int signo, void * handler)
    1602 {
    1603 }
    1604 #else
     1608#endif
     1609
     1610#ifndef WINDOWS
    16051611void
    16061612install_signal_handler(int signo, void * handler)
     
    16301636
    16311637#ifdef WINDOWS
     1638BOOL
     1639ControlEventHandler(DWORD event)
     1640{
     1641  switch(event) {
     1642  case CTRL_C_EVENT:
     1643    lisp_global(INTFLAG) = (1 << fixnumshift);
     1644    return TRUE;
     1645    break;
     1646  default:
     1647    return FALSE;
     1648  }
     1649}
     1650
     1651int
     1652map_windows_exception_code_to_posix_signal(DWORD code)
     1653{
     1654  switch (code) {
     1655  case EXCEPTION_ACCESS_VIOLATION:
     1656    return SIGSEGV;
     1657  case EXCEPTION_FLT_DENORMAL_OPERAND:
     1658  case EXCEPTION_FLT_DIVIDE_BY_ZERO:
     1659  case EXCEPTION_FLT_INEXACT_RESULT:
     1660  case EXCEPTION_FLT_INVALID_OPERATION:
     1661  case EXCEPTION_FLT_OVERFLOW:
     1662  case EXCEPTION_FLT_STACK_CHECK:
     1663  case EXCEPTION_FLT_UNDERFLOW:
     1664  case EXCEPTION_INT_DIVIDE_BY_ZERO:
     1665  case EXCEPTION_INT_OVERFLOW:
     1666    return SIGFPE;
     1667  case EXCEPTION_PRIV_INSTRUCTION:
     1668  case EXCEPTION_ILLEGAL_INSTRUCTION:
     1669    return SIGILL;
     1670  case EXCEPTION_IN_PAGE_ERROR:
     1671    return SIGBUS;
     1672  case DBG_PRINTEXCEPTION_C:
     1673    return DBG_PRINTEXCEPTION_C;
     1674  default:
     1675    return -1;
     1676  }
     1677}
     1678
     1679
     1680LONG
     1681windows_exception_handler(EXCEPTION_POINTERS *exception_pointers)
     1682{
     1683  TCR *tcr = get_tcr(false);
     1684  DWORD code = exception_pointers->ExceptionRecord->ExceptionCode;
     1685  int old_valence, signal_number;
     1686  ExceptionInformation *context = exception_pointers->ContextRecord;
     1687  siginfo_t *info = exception_pointers->ExceptionRecord;
     1688  xframe_list xframes;
     1689
     1690  old_valence = prepare_to_wait_for_exception_lock(tcr, context);
     1691  wait_for_exception_lock_in_handler(tcr, context, &xframes);
     1692
     1693  signal_number = map_windows_exception_code_to_posix_signal(code);
     1694 
     1695  if (!handle_exception(signal_number, info, context, tcr, old_valence)) {
     1696    char msg[512];
     1697    Boolean foreign = (old_valence != TCR_STATE_LISP);
     1698
     1699    snprintf(msg, sizeof(msg), "Unhandled exception %d (windows code 0x%x) at 0x%Ix, context->regs at 0x%Ix", signal_number, code, xpPC(context), (natural)xpGPRvector(context));
     1700   
     1701    if (lisp_Debugger(context, info, signal_number,  foreign, msg)) {
     1702      SET_TCR_FLAG(tcr,TCR_FLAG_BIT_PROPAGATE_EXCEPTION);
     1703    }
     1704  }
     1705  unlock_exception_lock_in_handler(tcr);
     1706  return restore_win64_context(context, tcr, old_valence);
     1707}
     1708
     1709LONG windows_switch_to_foreign_stack(LispObj, void*, void*);
     1710
     1711LONG
     1712handle_windows_exception_on_foreign_stack(TCR *tcr,
     1713                                          CONTEXT *context,
     1714                                          void *handler,
     1715                                          EXCEPTION_POINTERS *original_ep)
     1716{
     1717  LispObj foreign_rsp =
     1718    (LispObj) find_foreign_rsp(xpGPR(context,Isp), tcr->cs_area, tcr);
     1719  CONTEXT *new_context;
     1720  siginfo_t *new_info;
     1721  EXCEPTION_POINTERS *new_ep;
     1722
     1723  new_context = ((CONTEXT *)(foreign_rsp&~15))-1;
     1724  *new_context = *context;
     1725  foreign_rsp = (LispObj)new_context;
     1726  new_info = ((siginfo_t *)(foreign_rsp&~15))-1;
     1727  *new_info = *original_ep->ExceptionRecord;
     1728  foreign_rsp = (LispObj)new_info;
     1729  new_ep = ((EXCEPTION_POINTERS *)(foreign_rsp&~15))-1;
     1730  foreign_rsp = (LispObj)new_ep & ~15;
     1731  new_ep->ContextRecord = new_context;
     1732  new_ep->ExceptionRecord = new_info;
     1733  return windows_switch_to_foreign_stack(foreign_rsp,handler,new_ep);
     1734}
     1735
     1736LONG
     1737windows_arbstack_exception_handler(EXCEPTION_POINTERS *exception_pointers)
     1738{
     1739  DWORD code = exception_pointers->ExceptionRecord->ExceptionCode;
     1740 
     1741  if ((code & 0x80000000L) == 0) {
     1742    return EXCEPTION_CONTINUE_SEARCH;
     1743  } else {
     1744    TCR *tcr = get_interrupt_tcr(false);
     1745    area *vs = tcr->vs_area;
     1746    BytePtr current_sp = (BytePtr) current_stack_pointer();
     1747    struct _TEB *teb = NtCurrentTeb();
     1748   
     1749    if ((current_sp >= vs->low) &&
     1750        (current_sp < vs->high)) {
     1751      return
     1752        handle_windows_exception_on_foreign_stack(tcr,
     1753                                                  exception_pointers->ContextRecord,
     1754                                                  windows_exception_handler,
     1755                                                  exception_pointers);
     1756    }
     1757    return windows_exception_handler(exception_pointers);
     1758  }
     1759}
     1760
     1761
    16321762void
    16331763install_pmcl_exception_handlers()
    16341764{
     1765  AddVectoredExceptionHandler(1,windows_arbstack_exception_handler);
    16351766}
    16361767#else
     
    16731804#endif
    16741805
     1806#ifndef WINDOWS
    16751807#ifndef USE_SIGALTSTACK
    16761808void
     
    17281860                                 );
    17291861}
    1730 
     1862#endif
    17311863#endif
    17321864
     
    17401872quit_handler(int signum, siginfo_t *info, ExceptionInformation *xp)
    17411873{
     1874#ifdef DARWIN_GS_HACK
     1875  Boolean gs_was_tcr = ensure_gs_pthread();
     1876#endif
    17421877  TCR *tcr = get_tcr(false);
    17431878  area *a;
     
    17681903#endif
    17691904
     1905#ifndef WINDOWS
    17701906#ifndef USE_SIGALTSTACK
    17711907void
     
    18241960}
    18251961#endif
     1962#endif
    18261963
    18271964#ifdef USE_SIGALTSTACK
     
    19342071#ifdef X8664
    19352072opcode load_allocptr_reg_from_tcr_save_allocptr_instruction[] =
    1936   {0x65,0x48,0x8b,0x1c,0x25,0xd8,0x00,0x00,0x00};
     2073#ifdef WINDOWS
     2074  {0x49,0x8b,0x9b,0xd8,0x00,0x00,0x00}
     2075#else
     2076  {0x65,0x48,0x8b,0x1c,0x25,0xd8,0x00,0x00,0x00}
     2077#endif
     2078;
    19372079opcode compare_allocptr_reg_to_tcr_save_allocbase_instruction[] =
    1938   {0x65,0x48,0x3b,0x1c,0x25,0xe0,0x00,0x00,0x00};
     2080#ifdef WINDOWS
     2081  {0x49,0x3b,0x9b,0xe0,0x00,0x00,0x00}
     2082#else
     2083  {0x65,0x48,0x3b,0x1c,0x25,0xe0,0x00,0x00,0x00}
     2084#endif
     2085
     2086;
    19392087opcode branch_around_alloc_trap_instruction[] =
    19402088  {0x7f,0x02};
     
    19422090  {0xcd,0xc5};
    19432091opcode clear_tcr_save_allocptr_tag_instruction[] =
    1944   {0x65,0x80,0x24,0x25,0xd8,0x00,0x00,0x00,0xf0};
     2092#ifdef WINDOWS
     2093  {0x41,0x80,0xa3,0xd8,0x00,0x00,0x00,0xf0}
     2094#else
     2095  {0x65,0x80,0x24,0x25,0xd8,0x00,0x00,0x00,0xf0}
     2096#endif
     2097;
    19452098opcode set_allocptr_header_instruction[] =
    19462099  {0x48,0x89,0x43,0xf3};
     2100
    19472101
    19482102alloc_instruction_id
     
    19532107  case 0x7f: return ID_branch_around_alloc_trap_instruction;
    19542108  case 0x48: return ID_set_allocptr_header_instruction;
     2109#ifdef WINDOWS
     2110  case 0x41: return ID_clear_tcr_save_allocptr_tag_instruction;
     2111  case 0x49:
     2112    switch(program_counter[1]) {
     2113    case 0x8b: return ID_load_allocptr_reg_from_tcr_save_allocptr_instruction;
     2114    case 0x3b: return ID_compare_allocptr_reg_to_tcr_save_allocbase_instruction;
     2115    }
     2116#else
    19552117  case 0x65:
    19562118    switch(program_counter[1]) {
     
    19622124      }
    19632125    }
     2126#endif
     2127  default: break;
    19642128  }
    19652129  return ID_unrecognized_alloc_instruction;
     
    19972161}
    19982162#endif     
    1999 #ifdef WINDOWS 
    2000 void
    2001 pc_luser_xp(ExceptionInformation *xp, TCR *tcr, signed_natural *interrupt_displacement)
    2002 {
    2003 }
    2004 #else
     2163
    20052164void
    20062165pc_luser_xp(ExceptionInformation *xp, TCR *tcr, signed_natural *interrupt_displacement)
     
    20302189    switch(state) {
    20312190    case ID_set_allocptr_header_instruction:
    2032       /* We were consing a vector and we won.  Set the header of the
    2033          new vector (in the allocptr register) to the header in
    2034          %eax/%rax and skip over this instruction, then fall into the
    2035          next case. */
     2191      /* We were consing a vector and we won.  Set the header of the new vector
     2192         (in the allocptr register) to the header in %rax and skip over this
     2193         instruction, then fall into the next case. */
    20362194      new_vector = xpGPR(xp,Iallocptr);
    20372195      deref(new_vector,0) = xpGPR(xp,Iimm0);
     
    20672225         attempt. */
    20682226      {
    2069         int flags = (int)xpGPR(xp,Iflags);
     2227        int flags = (int)eflags_register(xp);
    20702228       
    20712229        if ((!(flags & (1 << X86_ZERO_FLAG_BIT))) &&
     
    21092267      }
    21102268      break;
     2269    default:
     2270      break;
    21112271    }
    21122272    return;
     
    21212281      if ((program_counter < &egc_store_node_conditional_success_test) ||
    21222282          ((program_counter == &egc_store_node_conditional_success_test) &&
    2123            !(xpGPR(xp, Iflags) & (1 << X86_ZERO_FLAG_BIT)))) {
     2283           !(eflags_register(xp) & (1 << X86_ZERO_FLAG_BIT)))) {
    21242284        /* Back up the PC, try again */
    21252285        xpPC(xp) = (LispObj) &egc_store_node_conditional;
     
    21842344  }
    21852345}
    2186 #endif
     2346
    21872347
    21882348void
Note: See TracChangeset for help on using the changeset viewer.