Re[6]: [Gc]: mingw32ce patch

Ivan Maidanski ivmai at mail.ru
Wed Sep 30 23:29:04 PDT 2009


Hi!

"Vincent R." <forumer at smartmobili.com> wrote:
> Ok so now here is the explanation about how to get stack address, on wince
> 5.x, kernel is 
> a structure declared like this (example below is for arm but mips and x86
> are very similar)
> 
> *****************************************************
> ARM ARCHITECTURE(nkarm.h)
> *****************************************************
> #define PUserKData ((LPBYTE)0xFFFFC800)
> typedef struct Thread THREAD;
> typedef THREAD *PTHREAD;
> 
> struct KDataStruct {
>     LPDWORD lpvTls;         /* 0x000 Current thread local storage pointer
> */
>     ...
>     PPROCESS pCurPrc;       /* 0x090 ptr to current PROCESS struct */
>     PTHREAD pCurThd;        /* 0x094 ptr to current THREAD struct */
>     ...
> };  /* KDataStruct */
> 
> /* High memory layout
>  *  0xFFFFC800 - KDataStruct
>  */
> 
> So on arm kernel is ALWAYS loaded at address 0xFFFFC800 and from it you
> can get a pointer
> to the current thread structure (PTHREAD pCurThd) defined as shown below :
> 
> struct Thread {
>     ...
>     DWORD       dwOrigBase; /* 0x1C: Original stack base */
>     ...
> };

Where is it defined?

Just to refine, dwOrigBase == ~sp at thread start (dwOrigBase is not stack minimum), right?

> 
> So now you should understand the formula I gave in my previous email :
> 
> DWORD dwStackBase2 = *(DWORD*)(*((DWORD*)(PUserKData + 0x094)) + 0x1C);

Yes.

> 
> We are deferencing PUserKData + 0x094 = pCurThd (pointer to PTHREAD) then
> we add
> 0x1C to get the dwOrigBase field.
> 
> So finally here is the final method for all architectures
> 
> #if _WIN32_WCE <= 0x502

This not clear, do you think it's not working for all WinCE 5.x versions?
And what's minimal version (you are sure it work and could test on)? I think if we set 5.0, it would be good.

I'd like to use runtime version detection (compiled once, run on every version).

> extern "C" BOOL		
> SetKMode(BOOL bFlag);

Thread-local, as I can see.

> void *os_query_stackBase()

You mean GC_get_stack_base(), right?

> {
> DWORD dwStackBase;
> BOOL bKmode;
> 
> LPBYTE PUserKData = 0x00005800; //address for all arch. except on arm
> DWORD dwThreadOffset;
> 
> if defined(__arm__) || defined(__thumb__) || defined(SHx)
> PUserKData = (LPBYTE)0xFFFFC800;
> dwThreadOffset = 0x094;
> #else
> 
> #if defined(_MIPS_)
> dwThreadOffset = 0x2c0;
> #endif
> 
> #if defined(x86)
> dwThreadOffset = 0x098;
> #endif
> 
> bKmode = SetKMode(TRUE);
> dwStackBase = *(cast(DWORD*) (*(cast(DWORD*)(PUserKData + dwThreadOffset
> )) +
> 0x1C));
> SetKMode(bKmode);
> 
> return cast(void *)dwStackBase;
> }
> #endif

Looks better to me.

> 
> I am sure it works on arm platform (device and emulator) now I need to
> test on x86 and 
> to do that I will ask cegcc maintainer that have that kind of device.
> In the same time I could see if there is something similar with 6.x
> kernels but it will be
> hard for me to test.

There is a person on the ML using GC for WinCE 6.0 standard and custom builds:
http://thread.gmane.org/gmane.comp.programming.garbage-collection.boehmgc/3260

> 
> Regards
> 
> Vincent Richomme

Bye.


More information about the Gc mailing list