We have been building 32 bit drivers using mingw32 in a msys environment. We recently downloaded and installed a snapshot build mingw-w64-bin_i686-mingw_20090121. And other than a header pathing issue, and a couple other minor hiccups, things seemed to be ok.
However, when we go to link our final output we have a problem.
Our problem now is that there does not appear to be a 64 bit version of ntoskrnl (or a 32 bit in this package). I looked in our install tree (/home/engr/tools/generic-i386-winxp64 -- which happens to be a networked drive under mingw) in mingw/lib64. I'm making an assumption that this library is automatically listed in the paths to be searched for libraries. I do see a lib64/libhal.a.
Any help is appreciated.
Here is the output. gcc is actually a shell which invokes bin/x86_64-pc-mingw32-gcc.exe when it sees the -m64 flag.
gcc -shared -L/home/engr/tmp/bhawley/generic-i386-winxp/LicenseMgr/22.214.171.124/lib -L/home/engr/tmp/bhawley/generic-i386-winxp/Libraries/126.96.36.199/lib -L/home/engr/support/generic-i386-winxp/LicenseMgr/188.8.131.52/lib -L/home/engr/support/generic-i386-winxp/Libraries/184.108.40.206/lib -L/home/engr/support/generic-i386-winxp/w32compat/pthread/lib -m64 -shared -Wl,--entry,_DriverEntry@8 -nostartfiles -nostdlib -static-libgcc /home/engr/tmp/bhawley/generic-i386-winxp/LicenseMgr/220.127.116.11/llmdrv/generic-i386-winxp-entry.o_K64 /home/engr/tmp/bhawley/generic-i386-winxp/LicenseMgr/18.104.22.168/llmdrv/llmdrv.o_K64 /home/engr/tmp/bhawley/generic-i386-winxp/LicenseMgr/22.214.171.124/llmdrv/version.o_K64 -o /home/engr/tmp/bhawley/generic-i386-winxp/LicenseMgr/126.96.36.199/drv/llmdrv_K64.sys -lLicenseMgr_K64 -lbase_K64 -lntoskrnl -lhal -lgcc
using 64bit compiler
v:/tools/generic-i386-winxp64/bin/../lib/gcc/x86_64-pc-mingw32/4.4.0/../../../../x86_64-pc-mingw32/bin/ld.exe: cannot find -lntoskrnl
collect2: ld returned 1 exit status
We had since added a -L/home/engr/tools/generic-i386-winxp64/mingw/lib to the flags. However, since no library was there, it still could not be found.
When we copied the libntoskrnl.a from the mingw win32 project, it found the library but gave us lots of undefined symbols such as:
e:\projects\current\bhawley_Base_Libraries\libraries\base/HashTable.c:945: undefined reference to `_imp__ExAllocatePoolWithTag'
I'm not surprised, I guess, since I wouldn't expect the 32 bit libraries to work with a 64 bit build.
Curiously, running ranlib on the library file
now makes ld complain that there is no index and that ranlib needs to be run.
v:/tools/generic-i386-winxp64/mingw/lib64/libntoskrnl.a: could not read symbols: Archive has no index; run ranlib to add one
Well, at the moment we don't have the DDK package include for 32-bit and not for 64-bit.
But if you need for 32-bit (and/or 64-bit) an import library you can use the gendef tool (to be found in our experimental tree) to generate the corresponding .def files. By them you can generate those import-libraries.
PS: If you have working .def files, please let us know.
I'm very much a novice when it comes to the windows builds (hence my reason for using msys and mingw).
What I have is whatever comes in the mingw32 package and the packages you have available. The 32 bit libraries were already present in the mingw32 project although one of them did need to be tweaked for the correct signature.
I also have a hal.def and ntoskrnl.def which either came with the mingw32 package or which I came across subsequently because of the aforementioned glitch in the 32 bit libraries that had to be fixed.
Are you saying that with the ntoskrnl.def I can generate a 64 bit .a that can be used for linking 64 bit binaries?
If so, please tell this novice how to go about it.
You have to run the gendef tool against the 64-bit library to generate a 64-bit def file. From that, you can easily generate the 64-bit .a file, and we'll gladly accept your generated .def file into our repository so that we can provide .a files for it in future releases.
Please keep in mind I know nothing of the gendef, and very little of the import/export windows stuff, def files, dlls, etc. I'm a unix guy and work with .a's and .so's.
Are you saying to run gendef against the 64 bit libraries in the Windows DDK?
Can you provide an example, or point me to a documentation for gendef?
All I have are the .def files along with the 32 bit libraries, the contents of which look something like:
I added the file ntoskrnl.def to our 64-bit libraries. So when we have added it to our makefile, it will be available.
The Feb 08 build has the ntoskrnl.def file in the ../lib/ directory. So, I ran
../../bin/x86_64-pc-mingw32-dlltool.exe --def ntoskrnl.def --output-lib libntoskrnl.a
and put it in the lib64 directory. I'm assuming that was the correct thing to do, since I think this was a multi-lib build and the lib directory contains the 32 bit binaries. However, I still have to explicitly add the lib64 path to the -L options. Am I missing something here?
$ x86_64-pc-mingw32-gcc -print-search-dirs
I appreciate the efforts. I apologize for being so naive and unhelpful.
How can I tell when it is available?
On a related but different note, could you or nitestrike contact me 'off-forum' for how I might be able to contribute to/support your efforts.
Take any automated build starting tomorrow or the next day. It'll get picked up with the daily builds.
We still have some undefined symbols. While the ntoskrnl.def contains a variety of spinlock functions:
The following are no where to be found.
c:/tmp/bhawley/generic-i386-winxp/Libraries/188.8.131.52/lib/libbase_K64.a(pal__windows.o_K64):pal__windows.c:(.text+0x1129): undefined reference to `_imp__KeAcquireSpinLock'
c:/tmp/bhawley/generic-i386-winxp/Libraries/184.108.40.206/lib/libbase_K64.a(pal__windows.o_K64):pal__windows.c:(.text+0x11d8): undefined reference to `_imp__KeAcquireSpinLock'
c:/tmp/bhawley/generic-i386-winxp/Libraries/220.127.116.11/lib/libbase_K64.a(pal__windows.o_K64):pal__windows.c:(.text+0x135b): undefined reference to `_imp__KeQuerySystemTime'
c:/tmp/bhawley/generic-i386-winxp/Libraries/18.104.22.168/lib/libbase_K64.a(pal__windows.o_K64):pal__windows.c:(.text+0x1417): undefined reference to `_imp__KeInitializeSpinLock'
c:/tmp/bhawley/generic-i386-winxp/Libraries/22.214.171.124/lib/libbase_K64.a(pal__windows.o_K64):pal__windows.c:(.text+0x14e5): undefined reference to `_imp__KeAcquireSpinLock'
Looking at my 32 bit def files:
$ fgrep KeAcquireSpinLock *.def
Makes me think that perhaps of some these should be getting picked up from libhal.a.
For what its worth here are the others and where they are defined:
$ fgrep KeQuerySystemTime *.def
$ fgrep KeInitializeSpinLock *.def
Well, it seems that for 64-bit the API it doesn't exist anymore. I can't find e.g the export of KeQuerySystemTime for 64-bit
Sadly I have no further documentation about this
I looked at the latest online DDK reference, and KeQuerySystemTime is not there...however, the KeAcquireSpinLock, and KeInitializeSpinLock are present.
It is relatively easy for me to do something other than SystemTime, but I can't easily substitute something for a spin lock.
This online reference for the current DDK has KeQuerySystemTime, I just didn't see it the first time I looked. But maybe there is a different DDK that isn't readily obvious to me that you are referring to that does not contain it.
This subsection discussing 64bit issues in the DDK does not indicate that functions listed earlier in the reference guide are not available in 64 bit mode.
Perhaps those macro's were simply ReactOS's way of implementing the windows ddk so existing code would compile.
Could be that this is ReactOS specific, but I have about this doubts. It seems so, that at least on XP64 (and Vista64) those exports aren't present in ntoskrnl, nor in hal. But I try to clarify this.
Another question I have. How are you signing your 64-bit driver? AFAIK are XP64 and for sure Vista64 needing signed drivers, otherwise it rejects to use them, or do I misunderstood here something?
I have some people checking into the signing.
But I'm completely dumbfounded that KeInitializeSpinLock and KeAcquireSpinLock would be removed from the API, but KeReleaseSpinLock would still be present...
Perhaps there is a header in win64 that changes KeInitializeSpinLock to something else, but I haven't found it in the windows ddk include files.
Signing is needed for windows 2008. But not for windows XP.
I'm willing to do whatever I can to help.
The 6001 DDK and documentation does not indicate support for these being removed, nor do the header files have any special macros for 64 bit in the case of the spinlock routines.
What am I not finding that you are, and what can I do to help.
The KeInitializeSpinLock is a method just present as inline
try the following implementation
*SpinLock = 0;
it should work
I will look at adding that to the ddk header files under a _MINGW64_ ifdef (I think thats the correct one).
But what about KeAcquireSpinLock?
I'm still puzzled why KeReleaseSpinLock would be in the DDK but Acquire would not.
Well, KeAcquireSpinLock should be something like this:
#define KeAcquireSpinLock(SpinLock, OldIrql) \
*(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)
I read the parts in ddk documentations now too. And there seems to be no hint that those methods are deprecated, but this means not that there must be such a export in ntoskernl, hal, ...
A define is possible, too. In fact is pretty often common in msdn documentation, that the describe the macro alias, but not the real method name. E.g. for Ascii and Unicode versions of functions, The talk about CreateFile, but not that the physical method behind are CreateFileA and CreateFileW. So I think that the headers from ReactOS are reasonable.
Yes, I quite agree. Many of the Ex.... are #defined to the Ke variants.
With more digging in different DDK's have found some #defines for some architecture variants, which cover these. I should have seen them in the first place, but was working under a different set of assumptions for what was defined by the compiler (i.e. IA64, etc).
Is _MINGW64_ the proper ifdef under which to bring these macros into the mingw header file(s)?
Thanks for your help.
The proper macro to be used for architecture stuff is __x86_64__. The __MINGW64__ is defined by gcc by targeting w64, so it would be fine at the moment, too. If there will be IA64, then it would be false, because it would be also __MINGW64__ but the architecture define would be __ia64__ IIRC
Just to close the loop and leave something usable for anyone following this thread in the future...here is what I got to work. It would probably be better in the w32api ntddk.h (and hence the undefs would not be needed) but I don't know if they want it.
// the w32api does not have the #defines to reflect the changes in wdm
// for 64 bit...specifically the following appear to have become
// #defines in the wdm.h
#define KeInitializeSpinLock(SpinLock) *SpinLock = 0
#define KeAcquireSpinLock(SpinLock, OldIrql) \
*(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)
#define KI_USER_SHARED_DATA 0xFFFFF78000000000ULL
#define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA)
#define SharedInterruptTime (KI_USER_SHARED_DATA + 0x8)
#define SharedSystemTime (KI_USER_SHARED_DATA + 0x14)
#define SharedTickCount (KI_USER_SHARED_DATA + 0x320)
#define KeQueryInterruptTime() *((volatile ULONG64 *)(SharedInterruptTime))
#define KeQuerySystemTime(CurrentCount) \
*((PULONG64)(CurrentCount)) = *((volatile ULONG64 *)(SharedSystemTime))
#define KeQueryTickCount(CurrentCount) \
*((PULONG64)(CurrentCount)) = *((volatile ULONG64 *)(SharedTickCount))
#endif // AMD64