程式語言 - GNU - C/C++ - Memory Map(PROT_EXEC)



參考資訊:
https://github.com/pasce/daemon-skeleton-linux-c

main.c

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <SDL.h>

int cpu_42(int v)
{
    return 4 * v;
}

int cpu_speedx(int v)
{
    return 2 * v;
}

int main(int argc, char **argv)
{
    int n = 100;
    unsigned int s = 0;
    unsigned int t1 = 0;
    unsigned int t2 = 0;
    const int msize = 1024;

    void *icache = NULL;
    int (*code)(int) = NULL;

    int fd = open("/dev/mem", O_RDWR);
    printf("fd %d\n", fd);

    icache = mmap(NULL, msize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
    printf("icache %p\n", icache);

    code = icache;

    memcpy(icache, cpu_42, 64);
    s = code(n);
    printf("cpu_42 %d\n", s);

    memset(icache, 0, msize);
    memcpy(icache, cpu_speedx, 64);

    t1 = SDL_GetTicks();
    s = code(n);
    t2 = SDL_GetTicks();
    printf("cpu_speedx %d (%dms)\n", s, t2 - t1);

    munmap(icache, msize);
    close(fd);
    return 0;
}

執行

$ gcc main.c -o test -I/usr/include/SDL -lSDL
$ sudo ./test
    fd 3
    icache 0x7fbafdffd000
    cpu_42 400
    cpu_speedx 200 (0ms)