这与我曾经做过的家庭作业非常相似.基本上我有一个“页面”列表和一个“框架”列表,以及相关信息.使用SIGSEGV我会捕获故障并根据需要更改内存保护位.我将包含您可能觉得有用的部分.
创建映射.最初它没有权限.
int w_create_mapping(size_t size,void **addr)
{
*addr = mmap(NULL,size * w_get_page_size(),PROT_NONE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0
);
if (*addr == MAP_Failed) {
perror("mmap");
return FALSE;
}
return TRUE;
}
安装信号处理程序
int w_set_exception_handler(w_exception_handler_t handler)
{
static struct sigaction sa;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask,SIGSEGV);
sa.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV,&sa,&prevIoUs_action) < 0)
return FALSE;
return TRUE;
}
异常处理程序
static void fault_handler(int signum,siginfo_t *info,void *context)
{
void *address; /* the address that faulted */
/* Memory location which caused fault */
address = info->si_addr;
if (FALSE == page_fault(address)) {
_exit(1);
}
}
增加保护
int w_protect_mapping(void *addr,size_t num_pages,w_prot_t protection)
{
int prot;
switch (protection) {
case PROTECTION_NONE:
prot = PROT_NONE;
break;
case PROTECTION_READ:
prot = PROT_READ;
break;
case PROTECTION_WRITE:
prot = PROT_READ | PROT_WRITE;
break;
}
if (mprotect(addr,num_pages * w_get_page_size(),prot) < 0)
return FALSE;
return TRUE;
}
由于团队可能会再次使用相同的作业,因此我无法公开全部使用.