I’m trying to create some sort of poor man’s mmap() on a platform that does not support generic mmap directly (we’re talking about esp32s3). I realize that this approach will have a significant impact on performance, but nevertheless I would like to give it a try in specific places in the project. The idea is to generate code around each memory load, check the pointer value and decide if the load should happen from other address.
Pseudocode illustrating the idea:
char * mapped_file;
read(somefile, mapped_file, file_size);
char load_hook(void * ptr) {
if(ptr & 0xff000000) {
return mapped_file[ptr & 0x00ffffff];
} else {
return *ptr;
}
}
char s[] = "some data";
char * p = 0xff000002;
char load_1 = *s;
char load_2 = *p;
// load_1 will contain first byte in s[],
// load_2 will contain third byte in mapped_file
Of course load_hook should be more sophisticated and include caching procedures to be able to address large files with smaller amount of physical RAM, but the example is sufficient to illustrate the idea.
Some sort of this behaviour can be achieved with -fsanitize=kernel-address, GCC generates code to call void __asan_load*_*(void * ptr) functions that implement various out-of-bounds, use-after-free and other checks. I have successfully hijacked these calls by implementing these functions by myself and not linking to asan library.
But I can not find a way to make GCC generate code to change the load address. kasan does something like this (on x86_64):
char fn(char * p) {
char ret = *p;
return ret;
}
...
movq -24(%rbp), %rax |
movq %rax, %rdi | << injected by kasan
call __asan_load1_noabort@PLT |
movq -24(%rbp), %rax << get p pointer
movz bl(%rax), %eax << actually dereference p pointer
...
I could possibly do some dirty magic in __asan_load.. and search for pointer value in caller function frame on stack, but maybe there is a more straightforward way to achieve that?
The task is even more complicated due to lack of public documentation on ESP32 ISA, on x86 I could possibly add a custom build step and inject desired code straight into assembly text after its generation, but for ESP32 I would prefer not to mess with assembly.
I could possibly write a gcc plugin to preprocess the gimple, but the toolchain is provided by Espressif and I am not sure that all dev headers are there (at least at a first glance).
Maybe I’m moving in a completely wrong direction and you can suggest how to achieve the desired behaviour by other means?
Roman Likane is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.