func: int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
  
  {
  
      unsigned int prot;
  
      PageDesc *p;
  
      target_ulong host_start, host_end, addr;
  
  
  
      /* Technically this isn't safe inside a signal handler.  However we
  
         know this only ever happens in a synchronous SEGV handler, so in
  
         practice it seems to be ok.  */
  
      mmap_lock();
  
  
  
      p = page_find(address >> TARGET_PAGE_BITS);
  
      if (!p) {
  
          mmap_unlock();
  
          return 0;
  
      }
  
  
  
      /* if the page was really writable, then we change its
  
         protection back to writable */
  
      if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) {
  
          host_start = address & qemu_host_page_mask;
  
          host_end = host_start + qemu_host_page_size;
  
  
  
          prot = 0;
  
          for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) {
  
              p = page_find(addr >> TARGET_PAGE_BITS);
  
              p->flags |= PAGE_WRITE;
  
              prot |= p->flags;
  
  
  
              /* and since the content will be modified, we must invalidate
  
                 the corresponding translated code. */
  
              tb_invalidate_phys_page(addr, pc, puc);
  
  #ifdef DEBUG_TB_CHECK
  
              tb_invalidate_check(addr);
  
  #endif
  
          }
  
          mprotect((void *)g2h(host_start), qemu_host_page_size,
  
                   prot & PAGE_BITS);
  
  
  
          mmap_unlock();
  
          return 1;
  
      }
  
      mmap_unlock();
  
      return 0;
  
  }
  