If we can run 32 bit executables on 64 bit Windows, why can't we convert it? - wow64

WoW64 makes it possible to run 32 bit applications on 64 bit Windows. If the conversion from 32 bit instructions to 64 bit instructions can be made at runtime, why can't we convert the executable itself to 64 bit?

That is because WoW64 doesn't convert 32bit instructions to 64bit.
Your 32bit executable is run in 32 bit mode by switching your CPU to compatibility mode. There are some conversions inlined for API/driver calls, but most of the code is not converted.
*This is only true for the x86-64 architecture. The IA-64 architecture doesn't support this, so WoW actually converts your code to 64bit, but with a significant performance penalty.
*.NET code compiled to MSIL is JITted to the correct architecture. Probably the same happens with other architectures with an Intermediate Language like Java, but i'm no expert there.

Yes, Wow64 lets you run 32-bit programs but they still run in 32-bit mode - no code alterations are performed. Such automatic translation would be impossible for a native application.
The number one problem is that native applications have no annotations explaining what the code does. Just one example: the compiler compiles pointer manipulation code and uses a 32-bit register to hold this pointer value on 32-bit platform and emits bare machine code for that - the runtime will have no idea that this was a pointer and it needs to be placed in 64-bit register on 64-bit platform.
Managed environments such as Java and .NET can deal with it - the compiler emits "intermediate language" code with necessary annotations that is then compiled for the target platform before the code is first run.

Related

Can 32-bit assembly code be ran on a 64-bit processor? (Delphi)

I am writing a program in Delphi, and including a library which contains some assembly code (Pipes.pas). I am getting an access violation when I run the code which makes a call to a function called StdWndProc. The process is an assembly function which contains assembly code.
A while back I updated this code (Pipes.pas) to include unicode support and other stuff, but I didn't figure out what this assembly was doing. Any ideas on what's going wrong here?
I'm running on a 64-bit machine, could it be that this assembly is 32-bit and isn't running correctly on a 64-bit processor (the project is targeted at 32-bit build).
A 32 bit process executes 32 bit code. It doesn't matter whether that code was compiled from assembler or Delphi or some other language.
It doesn't matter whether the machine is 64 bit or 32 bit, a 32 bit process runs 32 bit code. On a 64 bit machine, a 32 bit process runs in an emulated 32 bit machine called WOW64.
Conceptually what you are attempting is possible, so the conclusion is that your code has a bug.
As David Heffernan pointed out the cause of your problem can hardly be the OS architecture.
If your code runs with no errors on 32 bit machines, but it fails to run on 64 bit ones, it could be an OS issue however. It could be caused because of the use of 32 bit-exclusive directories (like SD:\Program Files which is called SD:\Program Files(x86) on 64 bit windows for 32 bit programs), registry reflection (which causes your program to store registry data under the Wow3264Node key), or even the use of old 16 bit DLL s (that can not run under wow3264), but that is a very rare case since it is 2013...
To be able to help I need further details of how your code does not run correctly.
(Please note, that the original question is already answered, I only wanted to provide some more useful help.)

Will compiling a DLL in Delphi 7 on a 64bit OS result in a 64bit DLL?

As the title suggests!
I'm trying to get a 64bit dll
No.
Nope. Delphi 7 was released in 2002; the first AMD64 processor was released in 2003. No way Delphi 7 knows how to generate 64-bit code.
All released versions of Delphi following the 16 bit Delphi 1 emit 32 bit targets. At the moment your options are:
Wait until the upcoming 64 bit Delphi release. We anticipate this some time this year, but your port will be non-trivial.
Port to FreePascal. Again, a non-trivial port.
Port to a completely different language: even more work than porting to Free Pascal.
Carry on running 32 bit code.
Compiling a program means to translate your source files into CPU opcodes (and something more, it has to generate a executable image that can work on the OS it was designed for, respecting the OS ABI - Application Binary Interface). Each type of CPU has its own set of opcodes, and even if the Intel x86 architecture has many similarities among 16, 32 and 64 bit opcodes, there are enough differences and the ABI is anyway different.
Creating a 64 bit exe/dll means to generate 64 bit opcodes using also the new 64 bit ABI, and to do that a compiler must be written to "know" them, what a compiler can do is defined by how the compiler itself is written, not by the system it is run on. Delphi 7 compiler "doesn't know" about 64 bit CPUs and exe/dll ABI, and thereby can't generate it. This is true as well up to Delphi XE. The next version should be the first one to come with a 64 bit compiler, you can wait for it, or if you're in a hurry there are some partially compatible compilers like FPC.

What should be tested in 64-bit Delphi

Delphi with 64 bit compilation is now in Beta, but only invited beta-testers will get their hands on this version.
What should be tested by the beta testers?
Embarcadero will probably provide a tester's guide for the beta testers. But, here are some ideas:
Memory allocation, alignment, heap and stack. 32-bit could use up to 4GB (well, 3.5) of address space on a 64-bit version of Windows with the /LARGEADDRESSAWARE switch: Delphi64 should be able to use much more. Try allocating 8, 16, and 32 GB. (Even if you have less RAM, the allocation should work since it's a virtual address space.) Now read and write values into it a certain spots: check your allocation and pointers all work. Have a look at what Process Explorer reports for the app. Inspect your stack: it runs top-down, unlike the heap - what does it looks like, what addresses is it using? What does the 16-byte alignment look like? Is that alignment kept for all internal Pascal functions, or only those that call external code? In the 32-bit VCL, there were some bits of code that weren't safe for addresses larger than 2GB. Have those been fixed? Does anything break when it's allocated in, say, the 53rd GB of your program's address space? (Try allocating a huge amount, and then dynamically creating forms, controls etc - they'll probably be created with high addresses.) Does the memory manager fragment? How fast are memory moves and copies?
Compiler warnings. (This one is important.) Upgrade your programs - compile them without changes, and see what warnings / errors you get; fix any; and then fix bugs that occur even though you weren't warned. What issues did you encounter? Should the compiler have warned you, but didn't? Do you get warnings when truncating a pointer when casting to an integer? What about more complex issues: if you use the Single floating-point type, what happens? Warning, or is it silently represented as a double? What if you pass in a parameter to a method that's a different size - for example, PostMessage and you pass in a 32-bit-sized value to the handle parameter - will the compiler be smart enough to guess that if the size is wrong, your code might be wrong, even though it's often valid to pass a smaller type to a larger parameter? Under what circumstances should it do so? (Another thing: what if you pass a 64-bit pointer to a 32-bit type in a method expecting a pointer to a 64-bit type - the type safety should yell loudly, but does it? A use case for that is reading blocks from a binary file, something that could easily cause problems with the wrong-sized types.) ...etc.
Compiler warnings are probably one of the most useful tools for people who upgrade, so the compiler should produce as many as possible, in as many situations as possible, with as few false positives as possible. Remember Delphi is used by a wide range of programmers - you may know what a warning means or recognize bad code even if the compiler is silent, but anything that will help novices (or good programmers having a bad day) is important.
Custom controls & WinAPI. You probably have a few customs controls or bits of code that make heavy use of Windows APIs instead of the VCL. Are there any Windows API-specific issues?
Language compatibility. Does the old file IO code work - AssignFile, etc? RTTI? If you have an event signature with an Integer type, and an event handler is auto-created by the IDE, is it generated as Integer or a size-specific integer type depending on the platform that's currently set? What if the event is NativeInt, what then? (I've seen bugs in event handler method signature generation before, though only on the C++ side.)
Different types of application. We can assume GUI programs have been tested well. What about console and service applications?
C++Builder compatible file generation. C++Builder won't be 64-bit in XE2, but hopefully will in XE3. Delphi can produce ..hpp and .obj files for Pascal code, though. What happens in for a 64-bit platform? Can you produce those files, even though they're useless? Does the compiler generate C++-specific warnings in 64-bit mode, or does it give up and not let you do it? In 32-bit mode, is there anything you can do for 64-bit compatibility that will generate a warning building the C++ header?
Linker. Can you link .lib and .obj files created with other compilers? (I'd expect .lib yes, .obj no.) Does the linker use COFF or OMF for 64-bit - have they changed? This thread implies an ELF format. Has it changed for 32-bit too? Does this affect the DCU format, will we still get ultra-fast compiling / linking?
COM and 64-bit plugins. Are there any marshalling issues? Can you build a 64-bit plugin for Explorer now?
Calling conventions. Safecall's supposed to be the only 'calling convention' (if safecall counts...) that's still different - does it still work? Function and procedure pointers, and closures (object method pointers): do they work? What do they look like in the debug inspector? Given all calling conventions are now the same, if you mix calling conventions in your method declaration and your calling pointer, what happens? Is there any legacy stuff around that will break or does it transparently work? Does it now give you an (erroneous) warning that the types are incompatible?
Floating point math. The Delphi 64 preview said floating point would be double only. Can Delphi handle long doubles? Are there any compatibility routines for handling the old Real (48 bits, I think??) type? Does the compiler generate SSE or SSE2 code or a mix, and how good is it?
Performance. This is their first go at a 64-bit compiler; it will probably be refined over the next few releases. But are there any obvious performance problems, with:
compiling; linking; IDE insight?
Generated code: are your programs faster or slower? Is FP math faster or slower? Does inline work, and does it generate any unnecessary header/footer bits around inlined methods?
Debugging. This is probably easiest to test through the whole process of testing everything else, but how well does the 64-bit debugger work? Does it have all functionality of the 32-bit one? Do IDE debug visualiser plugins still work? What if you debug a non-Delphi 64-bit program or attach to a process, instead of running normally?
Misc Is Delphi itself compiled as a 64-bit program? If not, why not? (Are they "eating their own dogfood"?) Code inspect the new VCL (assuming the preview comes with VCL source.) What have they done to make the VCL 32/64 compatible? Are there any errors, or if you already know 64-bit code well from other IDEs, are there better approaches they could take instead?
...etc. I could keep typing for hours, but I think that's a good start though :)
I'm sure Embarcadero will provide some testing guidance. For what it's worth this is what I'd test; Mostly because it's the stuff I care about:
Small console application should work.
Allows me to allocate a 4Gb flat hunk of memory. Don't really need that, but it will be the first thing my console application tries, right after WriteLn('I''m using all 64 bits!!!!');
Can create 64bit DLL and the DLL can be imported and used from other environment.
Do some simple things and look at the generated assembler, just for kicks.
Can create Firebird 64bit compatible UDF's
I'd probably try compiling my "utility" units, because they do an fair amount of pointer manipulation, see how they work.
If the VCL works I'd put it through it's paces: create small form, put a button on it, ShowMessage.
Generally speaking the only thing I really need 64bit Delphi for is Firebird 64bit UDFs. That's minor and can be "fixed" using FPC. I assume the best testing will be done by people that actually need 64 bit delphi. And those people don't need testing suggestions.
The base foundation stuff would come first, to ensure that Delphi 64 can be used for what Delphi 32 can't be used:
compiler correctness: first and foremost, no internal errors, no incorrect code-gen
ability to compile to 64bit DLLs and stability of those
stress the memory manager: with large objects, fragmented allocation, multi-threaded allocations, etc.
multi-threading: is it stable? is it efficient? does it scale? that for core RTL functions and units, and not forgetting the reference-counted types.
floating point: does the compiler deliver proper SSE? are the maths functions properly implemented and correct? what happens if you stress the SSE register set with complex expressions?
And as a bonus, ability to accept 64bit object files from the usual C++ compilers.
Non visual stuff ... I think. There is already success from some beta testers that already ported their libraries. I don't know the preview but from the information I don't have I would assume more complex non visual scenarios currently make sense. Anyone who knows it better please correct me ...
I think the preview first allows you to setup a migration strategy, this would be my intention. The VCL ... intended to work on one code base and maybe backport your code to purepascal instead of assembler.
Mike

Converting Windows driver to 64 bit - can I use a 32-bit DLL?

My Windows driver has a .sys file and a .dll (which I'm guessing is the programming interface to the driver?). Anyway, I need to compile the driver to run on Windows 7 64-bit. I have downloaded the DDK and am able to compile everything, but my application still won't work with the new driver.
If the application is a 32-bit application, does the driver DLL need to be compiled as a 32-bit DLL, and the .sys file a 64-bit file? Or do the SYS and DLL files both need to be 64-bit?
On a 64-bit system:
driver should always be 64-bit
an application can be either 32-bit or 64-bit
a DLL used by an application (that is, a DLL an application links with) should be 32-bit for a 32-bit application and 64-bit for a 64-bit application
If a DLL is engineered to communicate with a device driver, it should be carefully written to use the same data type definitions as the driver. It's best if both the driver and the DLL avoid using data types that are defined differently for 32-bit and 64-bit (e.g. size_t) in structures that are used for communicating with each other.
However, this does not mean that the DLL should be built as a 64-bit DLL (i.e. using the x86-64 instruction set). It should use whatever instruction set the application linking to it will be using.
The DLL has to be 64 bit too.
Will try to find a reference.
Got one
Since a 64-bit program can't call a 32-bit Dynamic Link Library (DLL)
This is why no 32 bit driver works on 64 bit and why they are always separate downloads

windows service with 32 bit and 64 bit dlls

We have a windows service that uses dlls produced from a bunch of different .NET projects. One of those projects has a dependency on a dll that was compiled on 32 bit machine.
We have just moved the windows service to a 64 bit machine. By default .NET projects try to run as 64 bit assembly (because they are being run on a 64 bit machine). However, I can force individual projects to run as 32 bit assembly by specifying the Platform Target as 'x86' rather than 'Any CPU'.
My question is: do all the .NET projects need to be forced to run as a 32 bit assembly? Can 32 bit assembly and 64 bit assemblies be run together?
I think as long as you're not using native modules or anything, you're probably fine, though you can still have bugs in your code if you assume the size of a pointer, etc., anywhere.
"If you have 100% type safe managed code then you really can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR."
http://www.hanselman.com/blog/CommentView.aspx?guid=4099df2d-ef01-4f70-a7f7-829eabc36afc
If there is no unsafe code and/or references on the unmanaged dlls you can safely compile everything with the target Any CPU.
The result of compilation is then CPU agnostic - the resulting IL is JIT - compiled by the CLR on the target machine, whatever the machine will be.
If the box is a 64 bit box it will be compiled to the by the 64 bit CLR to the 64 bit instruction set and will be happily run in the native 64 bit mode

Resources