#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

// 这是 add 函数的机器码，假设它的二进制数据已经嵌入到这里
// 注意：这个数据需要根据具体架构和编译器生成的机器码来填充
unsigned char add_bin[] = {
    // 这里是针对 x86_64 架构的 add 函数的二进制机器码
    0x55,                   // push   %rbp
    0x48, 0x89, 0xe5,       // mov    %rsp,%rbp
    0x89, 0x7d, 0xfc,       // mov    %edi,-0x4(%rbp)
    0x89, 0x75, 0xf8,       // mov    %esi,-0x8(%rbp)
    0x8b, 0x55, 0xfc,       // mov    -0x4(%rbp),%edx
    0x8b, 0x45, 0xf8,       // mov    -0x8(%rbp),%eax
    0x01, 0xd0,             // add    %edx,%eax
    0x5d,                   // pop    %rbp
    0xc3                    // retq
};

void load_and_execute() {
    // 获取页面大小
    size_t pagesize = sysconf(_SC_PAGESIZE);

    // 分配可读、可写、可执行的内存页
    void *exec_mem = mmap(NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC,
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (exec_mem == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    // 将函数的机器码复制到可执行内存中
    memcpy(exec_mem, add_bin, sizeof(add_bin));

    // 定义一个函数指针并指向加载到内存中的代码段
    int (*add_func)(int, int) = (int (*)(int, int))exec_mem;

    // 调用加载的函数
    int result = add_func(2, 3);
    printf("Result of add(2, 3): %d\n", result);

    // 释放内存
    if (munmap(exec_mem, pagesize) == -1) {
        perror("munmap");
        exit(EXIT_FAILURE);
    }
}

int main() {
    load_and_execute();
    return 0;
}
