Ignore:
Timestamp:
Jan 31, 2011, 11:17:18 PM (8 years ago)
Author:
rme
Message:

Merge shrink-tcr branch. This enables the 32-bit Windows lisp to run
on 64-bit Windows.

On 32-bit x86 ports, we expect to use a segment register to point to a
block of thread-local data called the TCR (thread context record).
This has always been kind of a bother on 32-bit Windows: we have been
using a kludge that allows us to use the %es segment register
(conditionalized on WIN32_ES_HACK).

Unfortunately, 64-bit Windows doesn't support using an LDT. This is
why the 32-bit lisp wouldn't run on 64-bit Windows.

The new scheme is to use some of the TlsSlots? (part of the Windows
TEB) for the most important parts of the TCR, and to introduce an "aux
vector" for the remaining TCR slots. Since %fs points to the TEB, we
can make this work. We reserve the last 34 (of 64) slots for our use,
and will die if we don't get them.

Microsoft's documentation says not to access the TlsSlots? directly
(you're supposed to use TlsGetValue/TlsSetValue?), so we're treading on
undocumented ground. Frankly, we've done worse.

This change introduces some ugliness. In lisp kernel C files, there's
a TCR_AUX(tcr) macro that expands to "tcr->aux" on win32, and to "tcr"
elsewhere.

If lisp or lap code has a pointer to a TCR, it's necessary to subtract
off target::tcr-bias (which on Windows/x86 is #xe10, the offset from
%fs to the TlsSlots? in the Windows TEB). We also sometimes have to load
target::tcr.aux to get at data which has been moved there.

These changes should only affect Windows/x86. The story on the other
platforms is just the same as before.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-constants32.s

    r13952 r14619  
    4747define(`rcontext_reg',`fs')
    4848       
    49         ifdef(`WINDOWS',`
    50 undefine(`rcontext_reg')       
    51 define(`rcontext_reg',`es')
    52         ')
    53                
    5449define(`rcontext',`%rcontext_reg:$1')
    5550
     
    485480        _ends
    486481
     482ifdef(`WIN_32',`
     483TCR_BIAS = 0xe10 + (4 * 30)     /* last 34 words of TlsSlots */
     484',`
    487485TCR_BIAS = 0
    488                
     486')
     487
     488ifdef(`WIN_32',`
     489        _struct(tcr,TCR_BIAS)
     490         _node(linear)          /* our linear (non-segment-based) address. */
     491         _word(aux)             /* pointer to tcr_aux struct, see below */
     492         _node(valence)         /* odd when in foreign code */
     493         _word(node_regs_mask)
     494         _node(save_allocbase)
     495         _node(save_allocptr)
     496         _node(last_allocptr)
     497         _node(catch_top)       /* top catch frame */
     498         _node(db_link)         /* special binding chain head */
     499         _node(tlb_limit)
     500         _node(tlb_pointer)     /* Consider using tcr+N as tlb_pointer */
     501         _node(ffi_exception)   /* mxcsr exception bits from ff-call */
     502         _node(foreign_sp)      /* Saved foreign SP when in lisp code */
     503         _node(interrupt_pending)
     504         _node(next_method_context)
     505         _node(next_tsp)
     506         _node(safe_ref_address)
     507         _node(save_tsp)        /* TSP when in foreign code */
     508         _node(save_vsp)        /* VSP when in foreign code */
     509         _node(save_ebp)        /* lisp EBP when in foreign code */
     510         _node(ts_area)         /* tstack area pointer */
     511         _node(vs_area)         /* vstack area pointer */
     512         _node(xframe)          /* per-thread exception frame list */
     513         _node(unwinding)
     514         _node(flags)     
     515         _node(foreign_mxcsr)
     516         _word(lisp_mxcsr)
     517         _word(pending_exception_context)
     518         _word(unboxed0)
     519         _word(unboxed1)
     520         _node(save0)           /* spill area for node registers... */
     521         _node(save1)           /* ...must be 16-byte aligned */
     522         _node(save2)
     523         _node(save3)
     524        _ends
     525
     526        _struct(tcr_aux,0)
     527         _word(bytes_allocated)
     528         _word(bytes_allocated_high)
     529         _node(cs_area)         /* cstack area pointer */
     530         _node(cs_limit)        /* cstack overflow limit */
     531         _node(log2_allocation_quantum)
     532         _node(errno_loc)       /* per-thread  errno location */
     533         _node(osid)            /* OS thread id */
     534         _node(foreign_exception_status)
     535         _node(native_thread_info)
     536         _node(native_thread_id)
     537         _node(reset_completion)
     538         _node(activate)
     539         _node(gc_context)
     540         _node(termination_semaphore)
     541         _node(shutdown_count)
     542         _node(suspend_count)
     543         _node(suspend_context)
     544         _node(suspend)         /* semaphore for suspension notify */
     545         _node(resume)          /* sempahore for resumption notify */
     546         _word(allocated)
     547         _word(pending_io_info)
     548         _word(io_datum)
     549         _node(next)            /* in doubly-linked list */
     550         _node(prev)            /* in doubly-linked list */
     551        _ends
     552',`
    489553/*  Thread context record.  */
    490554
     
    551615         _word(io_datum)
    552616        _ends
     617')
    553618
    554619        _struct(win32_context,0)
Note: See TracChangeset for help on using the changeset viewer.