Revision 45d679d6 exec.c
b/exec.c | ||
---|---|---|
2498 | 2498 |
page. Return TRUE if the fault was successfully handled. */ |
2499 | 2499 |
int page_unprotect(target_ulong address, unsigned long pc, void *puc) |
2500 | 2500 |
{ |
2501 |
unsigned int page_index, prot, pindex;
|
|
2502 |
PageDesc *p, *p1;
|
|
2501 |
unsigned int prot;
|
|
2502 |
PageDesc *p; |
|
2503 | 2503 |
target_ulong host_start, host_end, addr; |
2504 | 2504 |
|
2505 | 2505 |
/* Technically this isn't safe inside a signal handler. However we |
... | ... | |
2507 | 2507 |
practice it seems to be ok. */ |
2508 | 2508 |
mmap_lock(); |
2509 | 2509 |
|
2510 |
host_start = address & qemu_host_page_mask; |
|
2511 |
page_index = host_start >> TARGET_PAGE_BITS; |
|
2512 |
p1 = page_find(page_index); |
|
2513 |
if (!p1) { |
|
2510 |
p = page_find(address >> TARGET_PAGE_BITS); |
|
2511 |
if (!p) { |
|
2514 | 2512 |
mmap_unlock(); |
2515 | 2513 |
return 0; |
2516 | 2514 |
} |
2517 |
host_end = host_start + qemu_host_page_size; |
|
2518 |
p = p1; |
|
2519 |
prot = 0; |
|
2520 |
for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) { |
|
2521 |
prot |= p->flags; |
|
2522 |
p++; |
|
2523 |
} |
|
2515 |
|
|
2524 | 2516 |
/* if the page was really writable, then we change its |
2525 | 2517 |
protection back to writable */ |
2526 |
if (prot & PAGE_WRITE_ORG) { |
|
2527 |
pindex = (address - host_start) >> TARGET_PAGE_BITS; |
|
2528 |
if (!(p1[pindex].flags & PAGE_WRITE)) { |
|
2529 |
mprotect((void *)g2h(host_start), qemu_host_page_size, |
|
2530 |
(prot & PAGE_BITS) | PAGE_WRITE); |
|
2531 |
p1[pindex].flags |= PAGE_WRITE; |
|
2518 |
if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) { |
|
2519 |
host_start = address & qemu_host_page_mask; |
|
2520 |
host_end = host_start + qemu_host_page_size; |
|
2521 |
|
|
2522 |
prot = 0; |
|
2523 |
for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) { |
|
2524 |
p = page_find(addr >> TARGET_PAGE_BITS); |
|
2525 |
p->flags |= PAGE_WRITE; |
|
2526 |
prot |= p->flags; |
|
2527 |
|
|
2532 | 2528 |
/* and since the content will be modified, we must invalidate |
2533 | 2529 |
the corresponding translated code. */ |
2534 |
tb_invalidate_phys_page(address, pc, puc);
|
|
2530 |
tb_invalidate_phys_page(addr, pc, puc); |
|
2535 | 2531 |
#ifdef DEBUG_TB_CHECK |
2536 |
tb_invalidate_check(address);
|
|
2532 |
tb_invalidate_check(addr); |
|
2537 | 2533 |
#endif |
2538 |
mmap_unlock(); |
|
2539 |
return 1; |
|
2540 | 2534 |
} |
2535 |
mprotect((void *)g2h(host_start), qemu_host_page_size, |
|
2536 |
prot & PAGE_BITS); |
|
2537 |
|
|
2538 |
mmap_unlock(); |
|
2539 |
return 1; |
|
2541 | 2540 |
} |
2542 | 2541 |
mmap_unlock(); |
2543 | 2542 |
return 0; |
Also available in: Unified diff