my_bin.c のような単純な C プログラムがあります。
#include <stdio.h>
int main()
{
printf("Success!\n");
return 0;
}
gcc でコンパイルし、実行可能ファイル my_bin を取得しました。
ここで、別の C プログラムを使用して main (またはこの my_bin を実行) を呼び出したいと考えています。次のようにmmapと関数ポインターを使用して行いました。
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
void (*fun)();
int fd;
int *map;
fd = open("./my_bin", O_RDONLY);
map = mmap(0, 8378, PROT_READ, MAP_SHARED, fd, 0);
fun = map;
fun();
return 0;
}
EDIT 1: PROT_EXEC を追加 応答からより明確にする ... 2 番目のプログラム内で外部バイナリ プログラムを呼び出したい。
メイン(他のプログラム)のアドレスで関数ポインタを初期化する方法がわかりません。何か案が?
編集2:
グーグルで調べた後、なぜセグフォルトが判明したのか、それは私のサイズとmmapのオフセット引数が原因です。ページサイズの倍数にする必要があります。【参考:C言語でmmapを使ってバイナリファイルを読み込んでいる時のセグメンテーション違反】
コードは次のようになります。
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
void (*fun)();
int fd;
int *map;
int offset = 8378;
int pageoffset = offset % getpagesize();
fd = open("./my_bin", O_RDONLY);
if(fd == -1) {
printf("Err opening file\n");
return -1;
}
map = mmap(0, 8378 + pageoffset, PROT_READ|PROT_EXEC,
MAP_SHARED, fd, offset - pageoffset);
perror("Err\n"); //This is printing err and Success!
//fun = map; // If I uncomment this and
//fun(); // this line then, still it
// print err and Success! from perror
// but later it says Illegal instruction.
return 0;
}
まだ fun() があるか、それがないと印刷されません... main() アドレスを指定する方法がわかりません。
編集2[解決済み]:
まず、定義を適切に読み取っていませんでした。バイナリ ファイルを読み取るアドレスを既に指定しています。2 番目: mmap: サイズとオフセットはページサイズの倍数である必要があります。