Re: Code loading and executing
Re: Code loading and executing
- Subject: Re: Code loading and executing
- From: Josh de Cesare <email@hidden>
- Date: Fri, 10 May 2002 11:22:20 -0700
Adrian,
You are almost certainly running into a problem with the
G3/G4's split L1 I and D caches. Basically what happens is that the
L1 I cache can contain stale bit after the D cache get loaded with
your code. After you copy the code into your mmap created buffer,
call msync on it with the MS_INVALIDATE option. This should cause
the kernel to flush the dcache for that region then invalidate the
icache for the region. After that, it should behave as expected.
Josh
At 8:43 PM +0300 5/10/02, Adrian MARINESCU wrote:
Hi there!
I'm not sure that this list is what I'm looking for, but maybe someone will
give me some help in this matter.
Right now I'm working for my diploma project - I'm doing a ELF loader for
various operating systems/processors. While I found this to be simple on
some processors/OSs, I have a rather strange problem on PowerPCs - I tried
Both MacOS and various Linux distributions running on PPC.
The problem is when I dynamically load code from a file I get random [at
least IMO] signals [Illegal Instruction, Segmentation Fault, Bus Error] when
executing the loaded code. I managed to write down a simple program that IMO
should work - when I try it on my G3 it randomly crashes:
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
typedef void (*FUNCTYPE)(void);
// this is the code I'm trying to run from a loaded block
void foo(void) {
int j = 0, i = 0;
// just do some code
i++;
i--;
for (i = 0; i < 100; i++) j += i;
}
// just to find out foo's code size
void foo2() {
}
void *codealloc(int size) {
void *m = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, -1, 0);
return m;
}
int main() {
int i, size = (int)(foo2-foo);
unsigned char *c = (unsigned char*)codealloc(4096);
FUNCTYPE fn;
if (c == MAP_FAILED) return 1;
if (c == 0) return 1;
memcpy(c, foo, size);
printf("copied %d bytes to %p\n", size, c);
fn = (FUNCTYPE)c;
// do some intensive calls
for (i = 0; i < 10000; i++) {
fn();
}
printf("done calling fn!\n");
return 0;
}
Take a look at the results:
[ibook:test] root# ./a.out
copied 120 bytes to 0x84000
Illegal instruction
[ibook:test] root# ./a.out
copied 120 bytes to 0x84000
Illegal instruction
[ibook:test] root# ./a.out
copied 120 bytes to 0x84000
done calling fn!
[ibook:test] root# ./a.out
copied 120 bytes to 0x84000
Illegal instruction
[ibook:test] root# ./a.out
copied 120 bytes to 0x84000
done calling fn!
I also tried this program on a PowerPC 701 and it works fine.
Strange enough, when I put a sleep(1) before calling the function the
stability of the program is increasing...but on heavy machine loads it also
crashes. Is there something I'm doing wrong? Are there more flags for mmap
needed?
I compiled this with both cc/gcc, with and without -fPIC/-fpic.
Any idea?
Best regards,
Adrian MARINESCU, RAV Development Team - http://www.rav.ro
PGP Key : http://homepages.gecad.ro/mady/mady.asc
Key ID : 1024/1F365951 Adrian MARINESCU <email@hidden>
Key fingerprint = 0397 839F F8A6 E720 A49E 7D07 469C BB5C
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.