Revision 1565b7bc
b/exec.c | ||
---|---|---|
394 | 394 |
page. Return TRUE if the fault was succesfully handled. */ |
395 | 395 |
int page_unprotect(unsigned long address) |
396 | 396 |
{ |
397 |
unsigned int page_index, prot; |
|
398 |
PageDesc *p; |
|
397 |
unsigned int page_index, prot, pindex;
|
|
398 |
PageDesc *p, *p1;
|
|
399 | 399 |
unsigned long host_start, host_end, addr; |
400 | 400 |
|
401 |
page_index = address >> TARGET_PAGE_BITS; |
|
402 |
p = page_find(page_index); |
|
403 |
if (!p) |
|
401 |
host_start = address & host_page_mask; |
|
402 |
page_index = host_start >> TARGET_PAGE_BITS; |
|
403 |
p1 = page_find(page_index); |
|
404 |
if (!p1) |
|
404 | 405 |
return 0; |
405 |
if ((p->flags & (PAGE_WRITE_ORG | PAGE_WRITE)) == PAGE_WRITE_ORG) { |
|
406 |
/* if the page was really writable, then we change its |
|
407 |
protection back to writable */ |
|
408 |
host_start = address & host_page_mask; |
|
409 |
host_end = host_start + host_page_size; |
|
410 |
prot = 0; |
|
411 |
for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) |
|
412 |
prot |= page_get_flags(addr); |
|
406 |
host_end = host_start + host_page_size; |
|
407 |
p = p1; |
|
408 |
prot = 0; |
|
409 |
for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) { |
|
410 |
prot |= p->flags; |
|
411 |
p++; |
|
412 |
} |
|
413 |
/* if the page was really writable, then we change its |
|
414 |
protection back to writable */ |
|
415 |
if (prot & PAGE_WRITE_ORG) { |
|
413 | 416 |
mprotect((void *)host_start, host_page_size, |
414 | 417 |
(prot & PAGE_BITS) | PAGE_WRITE); |
415 |
p->flags |= PAGE_WRITE;
|
|
416 |
|
|
418 |
pindex = (address - host_start) >> TARGET_PAGE_BITS;
|
|
419 |
p1[pindex].flags |= PAGE_WRITE; |
|
417 | 420 |
/* and since the content will be modified, we must invalidate |
418 | 421 |
the corresponding translated code. */ |
419 | 422 |
tb_invalidate_page(address); |
Also available in: Unified diff