Bottom of stack on wince

David Friedman dvdfrdmn at users.ess-eff.net
Sun Jul 20 06:11:40 PDT 2008


Vincent,

Will this work with WinCE 6?

David

Vincent Richomme wrote:
> David,
> 
> about the bottom of the stack,  here is a "trick" and it's really need 
> to be called like that because to get it I am accessing kernel data :
> 
> extern "C" BOOL SetKMode(BOOL bFlag);
> #define PUserKData ((LPBYTE)0xFFFFC800)
> 
> 
> int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR 
> lpCmdLine, int nCmdShow)
> {
>   BOOL bKmode = SetKMode(TRUE); //allow us to go into kernel
> 
>   DWORD dwStackBase = *(DWORD*)(*((DWORD*)(PUserKData + 0x094)) + 0x1C);
> 
>   SetKMode(bKmode); return 0;
> }
> 
> Some explanations below :
> 
> 
> Actually on all arm plateforms kernel is loaded at 0xFFFFC800 address and
> 
> typedef struct ARM_HIGH {
> 
>     ...
>     char    kStack[0x800];      // 0xFFFFC000: kernel stack
>     struct KDataStruct kdata;   // 0xFFFFC800: kernel data page
> } ARM_HIGH;
> 
> 
> As you can see kernel is the following struct and at 0x094 offset there 
> is a field called pCurThd representing a PTHREAD :
> 
> 
> struct KDataStruct {
>     LPDWORD lpvTls;         /* 0x000 Current thread local storage 
> pointer */
>     HANDLE  ahSys[NUM_SYS_HANDLES]; /* 0x004 If this moves, change 
> kapi.h */
>     char    bResched;       /* 0x084 reschedule flag */
>     char    cNest;          /* 0x085 kernel exception nesting */
>     char    bPowerOff;      /* 0x086 TRUE during "power off" processing */
>     char    bProfileOn;     /* 0x087 TRUE if profiling enabled */
>     ulong   unused;         /* 0x088 unused */
>     ulong   rsvd2;          /* 0x08c was DiffMSec */
>     PPROCESS pCurPrc;       /* 0x090 ptr to current PROCESS struct */
>     PTHREAD pCurThd;        /* 0x094 ptr to current THREAD struct */
>     DWORD   dwKCRes;        /* 0x098  */
>     ulong   handleBase;     /* 0x09c handle table base address */
>     PSECTION aSections[64]; /* 0x0a0 section table for virutal memory */
>     LPEVENT alpeIntrEvents[SYSINTR_MAX_DEVICES];/* 0x1a0 */
>     ulong   pAPIReturn;     /* 0x2a0 direct API return address for 
> kernel mode */
>     uchar   *pMap;          /* 0x2a4 ptr to MemoryMap array */
>     DWORD   dwInDebugger;   /* 0x2a8 !0 when in debugger */
>     PTHREAD pCurFPUOwner;   /* 0x2ac current FPU owner */
>     PPROCESS pCpuASIDPrc;   /* 0x2b0 current ASID proc */
>     long    nMemForPT;      /* 0x2b4 - Memory used for PageTables */
> 
>     DWORD   aPend1;         /* 0x2b8 - low (int 0-31) dword of 
> interrupts pending (must be 8-byte aligned) */
>     DWORD   aPend2;         /* 0x2bc - high (int 32-63) dword of 
> interrupts pending */
> 
>     long    alPad[16];      /* 0x2c0 - padding */
>     DWORD   aInfo[32];      /* 0x300 - misc. kernel info */
>                             /* 0x380 - interlocked api code */
>                             /* 0x400 - end */
> };  /* KDataStruct */
> 
> And finally PTHREAD with at offset 0x1C bottom of stack
> 
> struct Thread {
>     ... //
>     DWORD       dwOrigBase; /* 1C: Original stack base */
>     DWORD       dwOrigStkSize;  /* 20: Size of the original thread stack */
>     LPDWORD     tlsPtr;     /* 24: tls pointer */
>     DWORD       dwWakeupTime; /* 28: sleep count, also pending sleepcnt
> };  /* Thread */
> 
> 
> 
> 
> David Friedman a écrit :
>> Vincent Richomme wrote:
>>> Yes that what I did but I wasn't sure.
>>> Now here is the remarks I have :
>>>
>>> 1) in std.c.windows.windows windows functions are declared in their 
>>> ANSI and UNICODE version but in windows CE only Unicode version 
>>> exist(except a few exceptions) .
>>>
>>> My question is should I declare a std.c.windows.windowsce where I 
>>> could declare only Unicode version and specific functions or should I 
>>> modify std.c.windows.windows and add some global precompilation 
>>> variable, for instance UnderCE and Unicode :
>>>
>>> version(Unicode)
>>> {
>>>    export
>>>    {
>>>     BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES
>>>                               lpSecurityAttributes);
>>>    }
>>> }
>>> else
>>> {
>>>  export
>>>    {
>>>     BOOL CreateDirectoryA(LPCSTR lpPathName, 
>>> LPSECURITY_ATTRIBUTES                                  
>>> lpSecurityAttributes);
>>>    }
>>> }
>>>
>>
>> The C header included with the wince-mingw32 package defines both the 
>> A and W versions, so I do not see the need to do this.
>>
>>> and then would it be possible to keep the same logic as windows , I 
>>> mean  to be able to use short name (without A or W) in function of 
>>> encoding.
>>>
>>>
>>>
>>> version(Unicode)
>>> {
>>> alias CreateDirectoryW CreateDirectory
>>> ..
>>> .
>>> }
>>> else
>>> {
>>> alias CreateDirectoryA CreateDirectory
>>> }
>>>
>>>
>>
>> You could do this.  Actually, you may want to bring this up in the 
>> main newgroup because it applies to the desktop Windows API too.
>>
>>
>>> 2) In std.thread.d and in gc/win32, the function 
>>> os_query_stackBottom() is implemented using x86 assembler and is not 
>>> portable to other architecture.
>>> By the way why is important to know the "bottom" of stack for the 
>>> thread ? Is it a hack specific to windows and if I tell you how to 
>>> get bottom of stack on windows CE will it work ?
>>>
>>>
>>
>> The garbage collector needs to know how far back to scan from the top 
>> of the main stack.
>>
>> If there is no trick to get it under WinCE, you can adapt the guessing 
>> code from gc.gcgcc and dgccmain2.d
>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> David Friedman a écrit :
>>>> Stagiaire Baptiste et Sandrine wrote:
>>>>> Hi,
>>>>>
>>>>> I'm working on a D crosscompiler targetting arm cellphone running 
>>>>> wince and I get some trouble with the compilation of the phobos 
>>>>> library. It cannot find
>>>>> the module gcc.config.fpcls.
>>>>>
>>>>> In the configure script of phobos it appears that for some target 
>>>>> the variable
>>>>> d_use_ieee_fpsb is set. What does fpsb stand for and can we add arm 
>>>>> on the list
>>>>> of supported cpu ?
>>>>>
>>>>>
>>>>
>>>>
>>>> In the phobos configure.in script, look for this section:
>>>>
>>>> case "$target_cpu" in
>>>>     i*86|powerpc*|ppc*|x86_64 ) d_use_ieee_fpsb=1 ;;
>>>>     *) d_use_ieee_fpsb=0 ;;
>>>> esac
>>>>
>>>>
>>>> Change the second line to this:
>>>>
>>>>     i*86|powerpc*|ppc*|x86_64|arm* ) d_use_ieee_fpsb=1 ;;
>>>>
>>>> If you don't have autoconf, you can directly edit "configure".
>>>>
>>>> "fpsb" stands for "fpclass()/signbit()"
>>>>
>>>> David


More information about the D.gnu mailing list