|
24 | 24 |
|
25 | 25 | //#define DEBUG_MMAP
|
26 | 26 |
|
| 27 | +/** macOS does not define this mask for the sharing type and options |
| 28 | + * this both matches the flag in linux, and works with macOS |
| 29 | + */ |
| 30 | +#define MAP_TYPE 0x000f |
| 31 | + |
27 | 32 | static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
|
28 | 33 | static __thread int mmap_lock_count;
|
29 | 34 |
|
@@ -671,79 +676,89 @@ int target_munmap(abi_ulong start, abi_ulong len)
|
671 | 676 | return ret;
|
672 | 677 | }
|
673 | 678 |
|
| 679 | +/** macOS/darwin does not have mremap. It is possible that (parts?) of |
| 680 | + * of this syscall could be emualted, but it is not necessary for Irix |
| 681 | + * https://ipads.se.sjtu.edu.cn:1312/opensource/powerlyra/commit/e226dc04639692b57fcaf666cf4006498c48f516 |
| 682 | + */ |
674 | 683 | abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
675 | 684 | abi_ulong new_size, unsigned long flags,
|
676 | 685 | abi_ulong new_addr)
|
677 | 686 | {
|
678 |
| - int prot; |
679 |
| - void *host_addr; |
680 |
| - |
681 |
| - mmap_lock(); |
682 |
| - |
683 |
| - if (flags & MREMAP_FIXED) { |
684 |
| - host_addr = mremap(g2h(old_addr), old_size, new_size, |
685 |
| - flags, g2h(new_addr)); |
686 |
| - |
687 |
| - if (reserved_va && host_addr != MAP_FAILED) { |
688 |
| - /* If new and old addresses overlap then the above mremap will |
689 |
| - already have failed with EINVAL. */ |
690 |
| - mmap_reserve(old_addr, old_size); |
691 |
| - } |
692 |
| - } else if (flags & MREMAP_MAYMOVE) { |
693 |
| - abi_ulong mmap_start; |
694 |
| - |
695 |
| - mmap_start = mmap_find_vma(0, new_size); |
696 |
| - |
697 |
| - if (mmap_start == -1) { |
698 |
| - errno = ENOMEM; |
699 |
| - host_addr = MAP_FAILED; |
700 |
| - } else { |
701 |
| - host_addr = mremap(g2h(old_addr), old_size, new_size, |
702 |
| - flags | MREMAP_FIXED, g2h(mmap_start)); |
703 |
| - if (reserved_va) { |
704 |
| - mmap_reserve(old_addr, old_size); |
705 |
| - } |
706 |
| - } |
707 |
| - } else { |
708 |
| - int prot = 0; |
709 |
| - if (reserved_va && old_size < new_size) { |
710 |
| - abi_ulong addr; |
711 |
| - for (addr = old_addr + old_size; |
712 |
| - addr < old_addr + new_size; |
713 |
| - addr++) { |
714 |
| - prot |= page_get_flags(addr); |
715 |
| - } |
716 |
| - } |
717 |
| - if (prot == 0) { |
718 |
| - host_addr = mremap(g2h(old_addr), old_size, new_size, flags); |
719 |
| - if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) { |
720 |
| - mmap_reserve(old_addr + old_size, new_size - old_size); |
721 |
| - } |
722 |
| - } else { |
723 |
| - errno = ENOMEM; |
724 |
| - host_addr = MAP_FAILED; |
725 |
| - } |
726 |
| - /* Check if address fits target address space */ |
727 |
| - if ((unsigned long)host_addr + new_size > (abi_ulong)-1) { |
728 |
| - /* Revert mremap() changes */ |
729 |
| - host_addr = mremap(g2h(old_addr), new_size, old_size, flags); |
730 |
| - errno = ENOMEM; |
731 |
| - host_addr = MAP_FAILED; |
732 |
| - } |
733 |
| - } |
734 |
| - |
735 |
| - if (host_addr == MAP_FAILED) { |
736 |
| - new_addr = -1; |
737 |
| - } else { |
738 |
| - new_addr = h2g(host_addr); |
739 |
| - prot = page_get_flags(old_addr); |
740 |
| - page_set_flags(old_addr, old_addr + old_size, 0); |
741 |
| - page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); |
742 |
| - } |
743 |
| - tb_invalidate_phys_range(new_addr, new_addr + new_size); |
744 |
| - mmap_unlock(); |
745 |
| - return new_addr; |
| 687 | + return -1; |
746 | 688 | }
|
| 689 | +// abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, |
| 690 | +// abi_ulong new_size, unsigned long flags, |
| 691 | +// abi_ulong new_addr) |
| 692 | +// { |
| 693 | +// int prot; |
| 694 | +// void *host_addr; |
| 695 | +// |
| 696 | +// mmap_lock(); |
| 697 | +// |
| 698 | +// if (flags & MREMAP_FIXED) { |
| 699 | +// host_addr = mremap(g2h(old_addr), old_size, new_size, |
| 700 | +// flags, g2h(new_addr)); |
| 701 | +// |
| 702 | +// if (reserved_va && host_addr != MAP_FAILED) { |
| 703 | +// /* If new and old addresses overlap then the above mremap will |
| 704 | +// already have failed with EINVAL. */ |
| 705 | +// mmap_reserve(old_addr, old_size); |
| 706 | +// } |
| 707 | +// } else if (flags & MREMAP_MAYMOVE) { |
| 708 | +// abi_ulong mmap_start; |
| 709 | +// |
| 710 | +// mmap_start = mmap_find_vma(0, new_size); |
| 711 | +// |
| 712 | +// if (mmap_start == -1) { |
| 713 | +// errno = ENOMEM; |
| 714 | +// host_addr = MAP_FAILED; |
| 715 | +// } else { |
| 716 | +// host_addr = mremap(g2h(old_addr), old_size, new_size, |
| 717 | +// flags | MREMAP_FIXED, g2h(mmap_start)); |
| 718 | +// if (reserved_va) { |
| 719 | +// mmap_reserve(old_addr, old_size); |
| 720 | +// } |
| 721 | +// } |
| 722 | +// } else { |
| 723 | +// int prot = 0; |
| 724 | +// if (reserved_va && old_size < new_size) { |
| 725 | +// abi_ulong addr; |
| 726 | +// for (addr = old_addr + old_size; |
| 727 | +// addr < old_addr + new_size; |
| 728 | +// addr++) { |
| 729 | +// prot |= page_get_flags(addr); |
| 730 | +// } |
| 731 | +// } |
| 732 | +// if (prot == 0) { |
| 733 | +// host_addr = mremap(g2h(old_addr), old_size, new_size, flags); |
| 734 | +// if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) { |
| 735 | +// mmap_reserve(old_addr + old_size, new_size - old_size); |
| 736 | +// } |
| 737 | +// } else { |
| 738 | +// errno = ENOMEM; |
| 739 | +// host_addr = MAP_FAILED; |
| 740 | +// } |
| 741 | +// /* Check if address fits target address space */ |
| 742 | +// if ((unsigned long)host_addr + new_size > (abi_ulong)-1) { |
| 743 | +// /* Revert mremap() changes */ |
| 744 | +// host_addr = mremap(g2h(old_addr), new_size, old_size, flags); |
| 745 | +// errno = ENOMEM; |
| 746 | +// host_addr = MAP_FAILED; |
| 747 | +// } |
| 748 | +// } |
| 749 | +// |
| 750 | +// if (host_addr == MAP_FAILED) { |
| 751 | +// new_addr = -1; |
| 752 | +// } else { |
| 753 | +// new_addr = h2g(host_addr); |
| 754 | +// prot = page_get_flags(old_addr); |
| 755 | +// page_set_flags(old_addr, old_addr + old_size, 0); |
| 756 | +// page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); |
| 757 | +// } |
| 758 | +// tb_invalidate_phys_range(new_addr, new_addr + new_size); |
| 759 | +// mmap_unlock(); |
| 760 | +// return new_addr; |
| 761 | +// } |
747 | 762 |
|
748 | 763 | int target_msync(abi_ulong start, abi_ulong len, int flags)
|
749 | 764 | {
|
|
0 commit comments