Any examples on working with memory executables?

TimLee
Posts: 8
Joined: Tue May 29, 2018 7:21 pm

Any examples on working with memory executables?

Postby TimLee » Thu Jul 11, 2019 5:29 pm

Hi,

I'm trying to execute a bit bunch of pre-compiled binary on the device. The code seems like reads okay, and the content is correct as well, I've also move the memory to IRAM, which I think is executable. But the code crashes with InstrFetchProhibited, which is quite confusing here. What might be the cause of the error?

here's the code to load the binary

Code: Select all


     void *data;
     //size_t alloc;
     //MP_PLAT_ALLOC_EXEC(len, &data, &alloc);
     data = malloc(len);
     read_bytes(reader, data, len);

     void *iram_data = heap_caps_realloc(data,len,MALLOC_CAP_EXEC);
     free(data);
     char* entry = iram_data+28;
     printf("func start %p from %p,content is ",entry,iram_data);
     for(int i =0;i<10;i++)
    {
        printf("%02x ",*(entry+i));
    }

and this is the crash info.
len number is 336
func start 0x3ffececc from 0x3ffeceb0,content is 36 41 00 38 02 a1 f7 ff 42 23 rc loaded 0x3f95bf30
point 1
point 2
point 3
point 4
point 5
Guru Meditation Error: Core 0 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x3ffececc PS : 0x00060630 A0 : 0x800dc6e0 A1 : 0x3ffc9130
A2 : 0x3f95be90 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
A6 : 0x3ffececc A7 : 0x00000000 A8 : 0x800e02f5 A9 : 0x3ffc9110
A10 : 0x3f95bf00 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001a EXCCAUSE: 0x00000014
EXCVADDR: 0x3ffececc LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffe

Backtrace: 0x3ffececc:0x3ffc9130 0x400dc6dd:0x3ffc9160 0x400dc70a:0x3ffc9180 0x400e6e5f:0x3ffc91a0 0x400e6ed6:0x3ffc9230 0x400e722e:0x3ffc9260 0x400dd063:0x3ffc9340 0x400e9be8:0x3ffc9380 0x400e04f8:0x3ffc9420 0x400dc6dd:0x3ffc9480 0x400dc70a:0x3ffc94a0 0x40101c6e:0x3ffc94c0 0x40101eb0:0x3ffc9560 0x400ef635:0x3ffc95a0

the location where it crashes PC seems exactly equals the location I realloc for execution, And this is the disassembly of the code where it starts.
0000002c <init>:
2c: 004136 entry a1, 32
2f: 0238 l32i.n a3, a2, 0
31: fff7a1 l32r a10, 10 <header+0x10>
34: 2a2342 l32i a4, a3, 168
37: 1238 l32i.n a3, a2, 4
Which I believe is the same with the code it loaded" func start 0x3ffececc from 0x3ffeceb0,content is 36 41 00 38 02 a1 f7 ff 42 23 rc loaded 0x3f95bf30"
If there are any linker problem I would expect it crashes after the entrance of the function, but looks like it did crashes in before enter the function, what might be the cause here?


TimLee
Posts: 8
Joined: Tue May 29, 2018 7:21 pm

Re: Any examples on working with memory executables?

Postby TimLee » Thu Jul 11, 2019 7:09 pm

Didn't noticed that,Thx very much :)

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Any examples on working with memory executables?

Postby jcsbanks » Fri Jul 12, 2019 9:22 am

I think your problem is reading 8 bit char from IRAM which requires 32 bit access.

I did write and use something to load functions to IRAM and execute them and it worked but it had more limitations than perhaps the elf loader mentioned by WiFive.

I wanted something that could process buffers at native speeds instead of scripting languages. It copies/aligns a byte array into IRAM and defines and calls the function pointer. Two source buffers are passed by means of start/end pointers, and another pointer to the result which is returned as either 32 bits or a buffer.

The executable had a custom 2 * 4 byte header with offset to the code and size of the result.

I'm casting returns from malloc because it is part of a larger task/script processing loop in a .cpp file.

The project above linked by WiFive (you are way better than Google BTW ;) ) is probably far more elegant and flexible.

Code: Select all

			//copy exe from DRAM to IRAM with 32 bit alignment
			//exe should be padded to 4 byte alignment, first 4 bytes are offset to entry point, second 4 bytes are size to malloc for result
			uint32_t* dest = (uint32_t*)heap_caps_malloc(((ram_bin_end - ram_bin_start) + 3) & 0xFFFFFFFC, MALLOC_CAP_EXEC);
			if (!dest) {
				ESP_LOGE(TAG, "unable to malloc exec dest!");
				break;
			}
			for (uint16_t i = 0; i < ram_bin_end - ram_bin_start; i += 4){
				dest[i>>2] = ram_bin_start[i] + (ram_bin_start[i + 1] << 8) + (ram_bin_start[i + 2] << 16) + (ram_bin_start[i + 3] << 24);
			}
			
			//first 32 bits are offset to entry point
			uint32_t func = (uint32_t)dest + dest[0];
			
			//second 32 bits are the size of the result
			//this function is responsible for malloc/free of result_start
			uint32_t result_size = dest[1];
			if (result_size){
				result_start = (uint8_t*)malloc(result_size);
				if (!result_start){
					ESP_LOGE(TAG, "failed to malloc for result");
					break;
				}	
			}

			uint32_t result = ((uint32_t(*)(uint8_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*))func)(data0_start, data0_end, data1_start, data1_end, result_start);

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Any examples on working with memory executables?

Postby jcsbanks » Fri Jul 12, 2019 9:37 am

I'm curious about the free(data) after realloc in the original post. Should it be there or have I misundertsood?

TimLee
Posts: 8
Joined: Tue May 29, 2018 7:21 pm

Re: Any examples on working with memory executables?

Postby TimLee » Fri Jul 12, 2019 6:44 pm

Yeps, that's exactly the problem here looks like. I've tried to align the data in IRAM and seems it works somehow, but not quite well.
Indeed I'm more curious how does D/I Ram work here, I've tested to run some code in IRAM which works, but in runtime I don't really want to spit the data and executable to different memory blocks, which will break the linker result. But running it from D/I I will eventually get this InstrFetchProhibited error which is quite annoying.

free data afterward is not a problem, we don't really need that afterward though.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Any examples on working with memory executables?

Postby jcsbanks » Fri Jul 12, 2019 8:45 pm

I was worried that after you realloc using data that free(data) is then a double free, or if the new pointer is to the same address you have also just freed the buffer you have just realloc. The second will not happen here because the malloc is a different type of memory.

One of us is mistaken I think, could be me but would like to know.
Last edited by jcsbanks on Fri Jul 12, 2019 8:54 pm, edited 1 time in total.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Any examples on working with memory executables?

Postby jcsbanks » Fri Jul 12, 2019 8:47 pm

My only use of this was for standalone routines that needed no linking. That kept it very simple and fast. The elf loader looks really good though for more complex needs don't you think?

TimLee
Posts: 8
Joined: Tue May 29, 2018 7:21 pm

Re: Any examples on working with memory executables?

Postby TimLee » Fri Jul 12, 2019 9:29 pm

The biggest problem of elf loader is its license I think lol :) Also it is too big haha

I'm working on a MicroPython native module loader, so I cannot exactly do the same what it does because mpy format is somewhat limited, I do only have a few place to use, but fortunately seems like it is quite enough for current task.

The realloc and free part in the above code is quite weirdly still not working, and I did tried to comment out the free part, looks like it is not the culprit here. So I end up working on a similar way to handle the text/literal part by allocating different memory parts now, quite similar to what elf-loader doing, but without a ELF header.

Still being headache on what's going on here with with D/IRAM setting. Looks like if I malloc a part of memory in D/IRAM,it just won't load the code somehow, but IRAM is okay though.

jcsbanks
Posts: 305
Joined: Tue Mar 28, 2017 8:03 pm

Re: Any examples on working with memory executables?

Postby jcsbanks » Sat Jul 13, 2019 7:20 am

Yeah I could not get D/IRAM to work either, I tried, but ended up copying the buffer for D to I.

Could the elf loader author offer his work to you under a different license or are parts it uses also under GPL?

Who is online

Users browsing this forum: nathan_swidget and 152 guests