The following code doesn't work as intended but hopefully illustrates my attempt:
long foo (int a, int b) {
return a + b;
}
void call_foo_from_stack (void) {
/* reserve space on the stack to store foo's code */
char code[sizeof(*foo)];
/* have a pointer to the beginning of the code */
long (*fooptr)(int, int) = (long (*)(int, int)) code;
/* copy foo's code to the stack */
memcpy(code, foo, sizeof(*foo));
/* execute foo from the stack */
fooptr(3, 5);
}
Obviously, sizeof(*foo)
doesn't return the size of the code of the foo()
function.
I am aware that executing the stack is restricted on some CPUs (or at least if a restriction flag is set). Apart from GCC's nested functions that can eventually be stored on the stack, is there a way to do that in standard C?
If you need to measure the size of a function, have the compiler/linker output a map file and you can calculate function size based off of that information.
On Linux, you cannot do this because the stack memory region is NOT not executable.
You can read something on ELF.
There are lots of ways that trying to do this can go wrong, but it can and has been done. This is one of the ways that buffer overflow attacks have worked -- write in a small malicious program for what is likely the architecture of the target computer along with code and/or data that is likely to get the processor to end up executing the malicious code and hope for the worst.
There have also been less evil uses of this, but it generally is restricted by the OS and/or CPU. Some CPUs can't allow this at all since the code and stack memory are in different address spaces.
One thing that you will need to account for if you do want to do this is that the code that you write into the stack space will need to be compiled (or if written as assembly or machine code, written as) position independent code or you will have to make sure that it ends up at a certain address (and that it was written/compiled to expect this).
I don't think that the C standard says anything about this.
As others have said, it's not possible to do this in a standard way - what you end up with will be platform-specific: CPU because of the way opcodes are structured (relative vs. absolute references), OS because you'll likely need to set page protection to be allowed to execute from stack. Furthermore, it's compiler-dependent: there's no standard-and-guaranteed way to get the size of a function.
If you really do have a good use-case, like the flash reprogramming RBerteig mentions, be prepared to mess with linker scripts, verify disassembly, and know you're writing very non-standard and unportable code :)
A valid use case for this kind of thing is an embedded system that is generally running out of FLASH memory, but is required to be able to reprogram itself in the field. To do this, a portion of the code must run from some other memory device (in my case the FLASH device itself could not erase and program one page while allowing reads from any other page, but there are devices that can do that), and there was enough RAM in the system to hold both the flash writer and the new application image to be written.
We wrote the necessary FLASH programming function in C, but used
#pragma
directives to have it placed in a distinct.text
segment from the rest of the code. In linker control file, we had the linker define global symbols for the start and end of that segment, and had it located at a base address in the RAM, while placing the generated code in a load region that was located in the FLASH along with the initialization data for the.data
segment and the pure read-only.rodata
segment; the base address in the FLASH was computed and defined as a global symbol as well.At run time, when the application update feature was exercised, we read the new application image into its buffer (and did all the sanity checks that should be done to make sure it actually was an application image for this device). We then copied the update kernel out of its dormant location in FLASH to its linked location in RAM (using the global symbols defined by the linker), then called it just like any other function. We didn't have to do anything special at the call site (not even a function pointer) because as far as the linker was concerned it was located in RAM the whole time. The fact that during normal operation that particular piece of RAM had a very different purpose was not important to the linker.
That said, all of the machinery that made this possible is either outside the scope of the standard, or solidly implementation defined behavior. The standard doesn't care how code gets loaded into memory before it is executed. It just says that the system can execute code.
Your OS shouldn't let you do that easily. There shouldn't be any memory with both write and execute permissions, and specially the stack has many different protections (see ExecShield, OpenWall patches, ...). IIRC, Selinux also includes stack execution restrictions. You'll have to find a way to do one or more of: