I have built a test for a driver in Windows CE 6.0 and some tests fail because memory passed in is not properly aligned.
How can I control the alignment of auto variables on the stack (not inside structures)?
Keep in mind that I cannot change this test in any way except how I build it.
Automatic variables are automatically aligned according to their natural alignment, unless you explicitly tell the compiler not to do so. So, if you need an address with 4 byte alignment, declare a 4 byte variable, like a DWORD.
There is no error message, the problem is when an unsigned byte is declared on the stack, the address is not 4-byte aligned, and I need it to be.
The exe that is built is a conformance test and I cannot change the code. When I build for windows the stack vars are 4-byte aligned, but when I build for CE they are not aligned
Related
I'm using Peter Below's PBThreadedSplashForm to display a splash window during application startup.
This component worked great for 10 years, but, since updating my Delphi to 11.2, I get an AV on the CreateWindowEx call.
This happens on Win64 platform only, on problems on Win32.
Anyone who knows what can be the cause of this?
This is one of the many issues that have surfaced in 11.2 due to the new default ASLR settings in the compiler and linker.
After a very quick glance at the source code I see this:
SetWindowLong( wnd, GWL_WNDPROC, Integer( thread.FCallstub ));
thread.FCallstub is defined as Pointer.
Just as I thought.
You see, pointers are of native size, so in 32-bit applications, pointers are 32 bits wide, while in 64-bit applications, pointers are 64 bits wide.
It was very common in the 32-bit world that pointer values were temporarily saved in Integers. This worked because a 32-bit pointer fits in a 32-bit Integer.
But in a 64-bit application, this is an obvious bug, since a 64-bit pointer doesn't fit in a 32-bit Integer. It's like taking a phone number like 5362417812 and truncating it to 17812, hoping that it will still "work".
Of course, in general, this causes bugs such as AVs and memory corruption.
However, until recently, there was a rather high probability that a pointer in a 64-bit Delphi application by "chance" didn't use its 32 upper bits (so it was like maybe $0000000000A3BE41, and so truncating it to $00A3BE41 didn't have any effect). So it seemed to work most of the time, but only by accident.
Now, recent versions of the Delphi compiler and linker enables ASLR, making such accidents much less likely.
And this is a good thing: If you have a serious bug in your code, it is better if you discover it right away and not "randomly" at your customers.
So, to fix the issue, you need to go through the code and make sure you never store a pointer in a 32-bit Integer. Instead, use a native-sized NativeInt, Pointer, LPARAM, or whatever is semantically appropriate.
(Disabling ASLR will also make it work in "many" cases by accident again, but this is a very bad approach. Your software still has a very serious bug that may manifest itself at any time.)
In your code, there is also
Integer( Pchar( FStatusMessage ))
Integer( Pchar( msg ))
I have an Ada program that was written for a specific (embedded, multi-processor, 32-bit) architecture. I'm attempting to use this same code in a simulation on 64-bit RHEL as a shared object (since there are multiple versions and I have a requirement to choose a version at runtime).
The problem I'm having is that there are several places in the code where the people who wrote it (not me...) have used Unchecked_Conversions to convert System.Addresses to 32-bit integers. Not only that, but there are multiple routines with hard-coded memory addresses. I can make minor changes to this code, but completely porting it to x86_64 isn't really an option. There are routines that handle interrupts, CPU task scheduling, etc.
This code has run fine in the past when it was statically-linked into a previous version of the simulation (consisting of Fortran/C/C++). Now, however, the main executable starts, then loads a shared object based on some inputs. This shared object then checks some other inputs and loads the appropriate Ada shared object.
Looking through the code, it's apparent that it should work fine if I can keep the logical memory addresses between 0 and 2,147,483,647 (32-bit signed int). Is there a way to either force the shared object loader to leave space in the lower ranges for the Ada code or perhaps make the Ada code "think" that it's addresses are between 0 and 2,147,483,647?
Is there a way to either force the shared object loader to leave space in the lower ranges for the Ada code
The good news is that the loader will leave the lower ranges untouched.
The bad news is that it will not load any shared object there. There is no interface you could use to influence placement of shared objects.
That said, dlopen from memory (which we implemented in our private fork of glibc) would allow you to do that. But that's not available publicly.
Your other possible options are:
if you can fit the entire process into 32-bit address space, then your solution is trivial: just build everything with -m32.
use prelink to relocate the library to desired address. Since that address should almost always be available, the loader is very likely to load the library exactly there.
link the loader with a custom mmap implementation, which detects the library of interest through some kind of side channel, and does mmap syscall with MAP_32BIT set, or
run the program in a ptrace sandbox. Such sandbox can again intercept mmap syscall, and or-in MAP_32BIT when desirable.
or perhaps make the Ada code "think" that it's addresses are between 0 and 2,147,483,647?
I don't see how that's possible. If the library stores an address of a function or a global in a 32-bit memory location, then loads that address and dereferences it ... it's going to get a 32-bit truncated address and a SIGSEGV on dereference.
In this image: https://i.imgur.com/LIImg.jpg
Under the code section it lists the first instruction as subtracting 0x28 from the stack pointer. Why would it need to subtract from a stack pointer that should be 0, right? Or does it start at the top and work down? Where in the PE headers do you specify the stack size?
The stack pointer doesn't have to be 0. In fact, and as Windows uses a flat memory model, it will have some non-zero value, big enough to allow growing downwards as stack is needed.
The action of substracting a value to the stack pointer is commonly found in the standard prologue of C functions. It allows a function to reserve stack space for local variables. Sometimes the compiler adds its own local variables to aid in some optimizations, or to help some stack checking functions linked to the program if you chose to check for stack buffer overflows at runtime.
You can see the commited and reserved stack space in a PE executable by using the DUMPBIN utility on that executable with the /HEADERS option. You can change both the reserved and commited stack size using Linker options (in Visual Studio)
Visual C++ project, Wintel-32. I have a C file that's compiled to object then linked, pretty vanilla setup. Debug configuration.
When I examine the object file with dumpbin /symbols, it tells me that my object file has numerous code ("COMDAT") sections - one per function, it seems. They all are named .text, and linker would unite them into the one large .text section in the final executable.
Function-level linking is disabled in project settings. I'm not even sure why are COMDAT's being generated in the first place.
But I've noticed in the debugger that those OBJ-level sections (functions) are not going contiguously in the executable. Between them there's some padding - several dozen bytes of int 3 instruction - obviously dead space where control is not supposed to go. The function boundaries are all aligned by 16 bytes, but there's more going on - this isn't just alignment by 16 bytes, or the padding would be much less in most cases. It's typically around 20-40 bytes, but I've seen some outliers - 11 bytes padding here, 73 there.
This has nothing to do with linker's /ALIGN option - that one deals with sections proper. And its default is 4K, definitely not what we have here.
Why this padding? And what's the algorithm for its size (definitely not mere alignment)?
If you have Edit & Continue turned on for the project, the padding you're seeing is introduced so the compiler and linker can patch the executable image rather than having to rebuild and relink it.
I am writing a program to print out a 32-bit number, and I was thinking of storing each digit on the stack, to make use of its last-in-first-off functionality. This arose the question, could I store 32 digits on the stack?
My question is, how many digits of information could I store on the stack? What is the limit of the number of things I can push onto the stack? Could I store 64 digits? 128? A number of arbitrary length?
Thanks in advance,
Rileyh
It's not actually nasm dictating this, more the linker that you use. All nasm does is create object files which can be linked together.
If you are using the ld linker from Linux, you'll most likely find that your default stack is 2M.
So, no, 32 bytes is not really going to have a massive impact on that and, even if you run out of stack, you can use something like ld --stack 4194304 to bump it up.
Depends a tiny bit on the OS and a bit more on the linker you use, but you should be fine. It's common to allocate a stack of a megabyte or more by default, so 128 bytes is nothing. Just make sure you reset the stack pointer before you return, and everything should be fine.
You can typically tell the linker to allocate a stack of a certain size as well, if you find you need more than you get by default.