-1

许多操作系统允许存储映射文件,并懒惰地读取它们。如果操作系统可以做到这一点,那么它就有能力从 thunk 中创建常规指针。

是否有任何操作系统允许应用程序程序员从他自己的 thunk 中创建指针?

我知道操作系统在一定程度上已经支持此功能,因为可以创建一个管道,将其映射到内存中,并将一个进程连接到管道以完成我正在谈论的一些事情,所以这个功能似乎不太不可能或不合理。

这个特性的一个简单例子是一个指针,它计算它被取消引用的次数。以下程序将输出零,然后输出一。

static void setter(void* environment, void* input) {
 /* You can't set the counter */
}

static void getter(void* environment, void* output) {
  *((int*)output) = *((int*)environment)++;
}

int main(int argc, char** argv) {
 volatile int counter = 0;
 volatile int * const x = map_special_voodoo_magic(getter, setter, sizeof(*x),
                                                   &counter);

 printf("%i\n", *x);
 printf("%i\n", *x);

 unmap_special_voodoo_magic(x);
}

PS 需要一个 volatile 限定符,因为 x 指向的值会意外更改,对吧?同样,编译器没有理由认为取消引用 x 会改变计数器,所以那里也需要一个 volatile 对吗?

4

1 回答 1

1

以下代码没有错误检查,也不是完整的实现。但是,以下代码确实说明了如何将 thunk 转换为指针的基本思想。特别是,值 4 是按需计算的,而不是更早分配给内存的。

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>

void * value;

static void catch_function(int signal, siginfo_t* siginfo,
                 void* context) {
    if (value != siginfo->si_addr) {
        puts("ERROR: Wrong address!");
        exit(1);
    }

    mmap(value, sizeof(int), PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED
                        | MAP_ANON, -1, 0);

    *((int*)value) = 2 * 2;
}

int main(void) {
    struct sigaction new_action;

    value = mmap(NULL, sizeof(int), PROT_NONE, MAP_ANON | MAP_SHARED, -1,
                    0);

    sigemptyset(&new_action.sa_mask);

    new_action.sa_sigaction = catch_function;
    new_action.sa_flags = SA_SIGINFO;

    sigaction(SIGBUS, &new_action, NULL);

    printf("The square of 2 is: %i\n", *((int*)value));

    munmap(value, sizeof(int)); 

    return 0;
}
于 2012-08-25T23:19:10.500 回答