Bottom of stack on wince

Vincent Richomme forumer at smartmobili.com
Sun Jul 20 07:44:41 PDT 2008


Yes it works at least on WM5 and WM6.
I have only tested on emulator but if you like I could test on a real 
device very soon.
Just notice that this trick works only for ARM platforms because wince 
is loaded at a different address with other cpu.

Version(Wince)
{
  Version(Arm)
  {

  }
}
By the way it could be interesting to declare a Wince variable :

In target-ver-syms:

*wince*|*cegcc*|*mingw32ce*) d_os_versym=Win32 ; d_windows=1 ; d_wince=1 ;;
...

I will send you a patch asap about modifications we had to do in order 
to compile gdc on wince platforms.






David Friedman a écrit :
> 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