Changeset 10916


Ignore:
Timestamp:
Sep 29, 2008, 8:31:15 AM (11 years ago)
Author:
gb
Message:

setup_tcr_extra_segment() for win32. (Note that it looked like
we were calling setup_tcr_extra_segment() twice on X8632, but
I may have misread something.)

This seems to work (at least on 32-bit OSes); the version of GDB I'm
using on Win32 seems to have trouble stepping through code that reads
from/writes to %gs, but the code works when not stepped through.

Will need a free_tcr_extra_segment(), hopefully soon.

File:
1 edited

Legend:

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

    r10889 r10916  
    963963
    964964#ifdef WINDOWS
     965bitvector ldt_entries_in_use = NULL;
     966HANDLE ldt_lock;
     967
     968typedef struct {
     969  DWORD offset;
     970  DWORD size;
     971  LDT_ENTRY entry;
     972} win32_ldt_info;
     973
     974
     975int WINAPI (*NtQueryInformationProcess)(HANDLE,DWORD,VOID*,DWORD,DWORD*);
     976int WINAPI (*NtSetInformationProcess)(HANDLE,DWORD,VOID*,DWORD);
     977
     978void
     979init_win32_ldt()
     980{
     981  HANDLE hNtdll;
     982  int status = 0xc0000002;
     983  win32_ldt_info info;
     984  DWORD nret;
     985 
     986
     987  ldt_entries_in_use=malloc(8192/8);
     988  zero_bits(ldt_entries_in_use,8192);
     989  ldt_lock = CreateMutex(NULL,0,NULL);
     990
     991  hNtdll = LoadLibrary("ntdll.dll");
     992  NtQueryInformationProcess = (void*)GetProcAddress(hNtdll, "NtQueryInformationProcess");
     993  NtSetInformationProcess = (void*)GetProcAddress(hNtdll, "NtSetInformationProcess");
     994  if (NtQueryInformationProcess != NULL) {
     995    info.offset = 0;
     996    info.size = sizeof(LDT_ENTRY);
     997    status = NtQueryInformationProcess(GetCurrentProcess(),10,&info,sizeof(info),&nret);
     998  }
     999
     1000  if (status) {
     1001    fprintf(stderr, "This application can't run under this OS version\n");
     1002    _exit(1);
     1003  }
     1004}
     1005
    9651006void
    9661007setup_tcr_extra_segment(TCR *tcr)
    9671008{
     1009  int i, status;
     1010  DWORD nret;
     1011  win32_ldt_info info;
     1012  LDT_ENTRY *entry = &(info.entry);
     1013  DWORD *words = (DWORD *)entry, tcraddr = (DWORD)tcr;
     1014
     1015
     1016  WaitForSingleObject(ldt_lock,INFINITE);
     1017
     1018  for (i = 0; i < 8192; i++) {
     1019    if (!ref_bit(ldt_entries_in_use,i)) {
     1020      info.offset = i << 3;
     1021      info.size = sizeof(LDT_ENTRY);
     1022      words[0] = 0;
     1023      words[1] = 0;
     1024      status = NtQueryInformationProcess(GetCurrentProcess(),10,&info,sizeof(info),&nret);
     1025      if (status == 0) {
     1026        if ((info.size == 0) ||
     1027            ((words[0] == 0) && (words[1] == 0))) {
     1028          break;
     1029        }
     1030      }
     1031    }
     1032  }
     1033  if (i == 8192) {
     1034    ReleaseMutex(ldt_lock);
     1035    fprintf(stderr, "All 8192 ldt entries in use ?\n");
     1036    _exit(1);
     1037  }
     1038  set_bit(ldt_entries_in_use,i);
     1039  words[0] = 0;
     1040  words[1] = 0;
     1041  entry->LimitLow = sizeof(TCR);
     1042  entry->BaseLow = tcraddr & 0xffff;
     1043  entry->HighWord.Bits.BaseMid = (tcraddr >> 16) & 0xff;
     1044  entry->HighWord.Bits.BaseHi = (tcraddr >> 24);
     1045  entry->HighWord.Bits.Pres = 1;
     1046  entry->HighWord.Bits.Default_Big = 1;
     1047  entry->HighWord.Bits.Type = 16 | 2; /* read-write data */
     1048  entry->HighWord.Bits.Dpl = 3; /* for use by the great unwashed */
     1049  info.size = sizeof(LDT_ENTRY);
     1050  status = NtSetInformationProcess(GetCurrentProcess(),10,&info,sizeof(info));
     1051  if (status != 0) {
     1052    ReleaseMutex(ldt_lock);
     1053    FBug(NULL, "can't set LDT entry %d, status = 0x%x", i, status);
     1054  }
     1055#if 1
     1056  /* Sanity check */
     1057  info.offset = i << 3;
     1058  info.size = sizeof(LDT_ENTRY);
     1059  words[0] = 0;
     1060  words[0] = 0;
     1061  NtQueryInformationProcess(GetCurrentProcess(),10,&info,sizeof(info),&nret);
     1062  if (((entry->BaseLow)|((entry->HighWord.Bits.BaseMid)<<16)|((entry->HighWord.Bits.BaseHi)<<24)) != tcraddr) {
     1063    Bug(NULL, "you blew it: bad address in ldt entry\n");
     1064  }
     1065#endif
     1066  tcr->ldt_selector = (i << 3) | 7;
     1067  ReleaseMutex(ldt_lock);
    9681068}
    9691069
     
    9721072{
    9731073}
    974 
    9751074
    9761075#endif
     
    9991098#else /* no TLS */
    10001099  TCR *tcr = allocate_tcr();
    1001 #ifdef X8632
    1002   setup_tcr_extra_segment(tcr);
    1003 #endif
    10041100#endif
    10051101
Note: See TracChangeset for help on using the changeset viewer.