/* Corrigé de la partie 1 * * Ce programme fait une page-fault par page et les corrige toute indépendamment. */ #define _GNU_SOURCE /* a garder TOUT EN HAUT du fichier */ #include #include #include #include #include #include #define LEN (32*4096) void segv_handler(int sig, siginfo_t *info, void *_context) { ucontext_t *context = _context; int write = (context->uc_mcontext.gregs[REG_ERR] & 2); #ifdef __x86_64__ void *addr = (void *)(context->uc_mcontext.gregs[REG_CR2]); #elif __i386__ void *addr = (void *)(context->uc_mcontext.cr2); #else #error Architecture non support?e #endif void *page = (void *)(((unsigned long) addr) & ~4095); printf("oops %s at %p\n", write ? "write" : "read", addr); mprotect(page, 4096, PROT_READ|PROT_WRITE); } int main(int argc, char *argv[]) { char *buffer; struct sigaction act; int i; int ret; buffer = memalign(4096, LEN); if (!buffer) { printf("failed to malloc\n"); exit(-1); } printf("buffer = %p\n", buffer); ret = mprotect(buffer, LEN, PROT_NONE); if (ret < 0) { printf("failed to mprotect\n"); exit(-1); } act.sa_flags = SA_SIGINFO; act.sa_sigaction = segv_handler; sigaction(SIGSEGV, &act, NULL); if (argv[1]) { printf("Je ne vais faire aucune fault\n"); } else { printf("Je vais faire 32 faults (regarder dans /usr/bin/time)\n"); for(i=0; i<32; i++) buffer[i*4096+23] = 'a'; printf("Lancez moi avec un argument pour que comparer quand je ne fais pas de faults\n"); } return 0; } #if 0 /********************** * Attributs des pages */ enum status { INVALID, READONLY, READWRITE, }; struct pageattr { void * address; enum status status; int owner; } #endif