ntgc.c (2949B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 * GC related routines 8 * 9 */ 10 #include <windows.h> 11 #include "primpl.h" 12 13 PRWord* _MD_HomeGCRegisters(PRThread* t, int isCurrent, int* np) { 14 #if defined(_X86_) 15 CONTEXT context; 16 context.ContextFlags = CONTEXT_INTEGER; 17 18 if (_PR_IS_NATIVE_THREAD(t)) { 19 context.ContextFlags |= CONTEXT_CONTROL; 20 if (GetThreadContext(t->md.handle, &context)) { 21 t->md.gcContext[0] = context.Eax; 22 t->md.gcContext[1] = context.Ebx; 23 t->md.gcContext[2] = context.Ecx; 24 t->md.gcContext[3] = context.Edx; 25 t->md.gcContext[4] = context.Esi; 26 t->md.gcContext[5] = context.Edi; 27 t->md.gcContext[6] = context.Esp; 28 t->md.gcContext[7] = context.Ebp; 29 *np = PR_NUM_GCREGS; 30 } else { 31 PR_ASSERT(0); /* XXX */ 32 } 33 } else { 34 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING 35 * 36 * This code is extremely machine dependant and completely 37 * undocumented by MS. Its only known to work experimentally. 38 * Ready for a walk on the wild * side? 39 * 40 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */ 41 42 # if !defined WIN95 // Win95 does not have fibers 43 int* fiberData = t->md.fiber_id; 44 45 /* I found these offsets by disassembling SwitchToFiber(). 46 * Are your palms sweating yet? 47 */ 48 49 /* 50 ** EAX is on the stack (ESP+0) 51 ** EDX is on the stack (ESP+4) 52 ** ECX is on the stack (ESP+8) 53 */ 54 t->md.gcContext[0] = 0; /* context.Eax */ 55 t->md.gcContext[1] = fiberData[0x2e]; /* context.Ebx */ 56 t->md.gcContext[2] = 0; /* context.Ecx */ 57 t->md.gcContext[3] = 0; /* context.Edx */ 58 t->md.gcContext[4] = fiberData[0x2d]; /* context.Esi */ 59 t->md.gcContext[5] = fiberData[0x2c]; /* context.Edi */ 60 t->md.gcContext[6] = fiberData[0x36]; /* context.Esp */ 61 t->md.gcContext[7] = fiberData[0x32]; /* context.Ebp */ 62 *np = PR_NUM_GCREGS; 63 # endif 64 } 65 return (PRWord*)&t->md.gcContext; 66 #else 67 PR_NOT_REACHED("not implemented"); 68 return NULL; 69 #endif /* defined(_X86_) */ 70 } 71 72 /* This function is not used right now, but is left as a reference. 73 * If you ever need to get the fiberID from the currently running fiber, 74 * this is it. 75 */ 76 void* GetMyFiberID() { 77 #if defined(_X86_) && !defined(__MINGW32__) 78 void* fiberData; 79 80 /* A pointer to our tib entry is found at FS:[18] 81 * At offset 10h is the fiberData pointer. The context of the 82 * fiber is stored in there. 83 */ 84 __asm { 85 mov EDX, FS:[18h] 86 mov EAX, DWORD PTR [EDX+10h] 87 mov [fiberData], EAX 88 } 89 90 return fiberData; 91 #else 92 PR_NOT_REACHED("not implemented"); 93 return NULL; 94 #endif /* defined(_X86_) */ 95 }