Rev 9047 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9047 | Rev 9048 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 8876 $ |
8 | $Revision: 9048 $ |
9 | 9 | ||
Line 562... | Line 562... | ||
562 | mov ebp, esp |
562 | mov ebp, esp |
563 | mov ebx, cr2 |
563 | mov ebx, cr2 |
564 | push ebx ;that is locals: .err_addr = cr2 |
564 | push ebx ;that is locals: .err_addr = cr2 |
565 | inc [pg_data.pages_faults] |
565 | inc [pg_data.pages_faults] |
Line 566... | Line 566... | ||
566 | 566 | ||
Line 567... | Line 567... | ||
567 | mov eax, [pf_err_code] |
567 | mov esi, [pf_err_code] |
568 | 568 | ||
Line 569... | Line 569... | ||
569 | cmp ebx, OS_BASE ;ebx == .err_addr |
569 | cmp ebx, OS_BASE ;ebx == .err_addr |
570 | jb .user_space ;page in application memory |
570 | jb .user_space ;page in application memory |
Line -... | Line 571... | ||
- | 571 | ||
571 | 572 | cmp ebx, page_tabs |
|
572 | cmp ebx, page_tabs |
573 | jb .kernel_space ;page in kernel memory |
573 | jb .kernel_space ;page in kernel memory |
574 | |
574 | 575 | xor eax, eax |
|
575 | cmp ebx, kernel_tabs |
576 | cmp ebx, kernel_tabs |
576 | jb .alloc;.app_tabs ;page tables of application ; |
577 | jb .alloc;.app_tabs ;page tables of application ; |
577 | ;simply create one |
578 | ;simply create one |
578 | .core_tabs: |
579 | .core_tabs: |
- | 580 | .fail: ;simply return to caller |
|
- | 581 | mov esp, ebp |
|
- | 582 | pop ebx ;restore exception number (#PF) |
|
- | 583 | ret |
|
- | 584 | .fail_maybe_unlock: |
|
- | 585 | test esi, esi |
|
- | 586 | jz .fail |
|
- | 587 | .fail_unlock: |
|
Line 579... | Line 588... | ||
579 | .fail: ;simply return to caller |
588 | mov ecx, [current_process] |
- | 589 | add ecx, PROC.heap_lock |
|
- | 590 | call mutex_unlock |
|
- | 591 | jmp .fail |
|
- | 592 | ||
- | 593 | .user_space: |
|
- | 594 | ; PF entry in IDT is interrupt gate, so up to this moment |
|
- | 595 | ; atomicity was guaranteed by cleared IF. |
|
- | 596 | ; It is inpractical to guard all modifications in the page table by cli/sti, |
|
- | 597 | ; so enable interrupts and acquire the address space lock. |
|
- | 598 | ; Unfortunately, that enables the scenario when the fault of current thread |
|
- | 599 | ; is resolved by another thread when the current thread waits in mutex_lock, |
|
- | 600 | ; so watch out: in lock-protected section we can find out that |
|
580 | mov esp, ebp |
601 | ; there is no error already. |
581 | pop ebx ;restore exception number (#PF) |
602 | sti |
582 | ret |
603 | mov ecx, [current_process] |
Line 583... | Line 604... | ||
583 | 604 | add ecx, PROC.heap_lock |
|
584 | .user_space: |
605 | call mutex_lock |
585 | test eax, PG_READ |
606 | test esi, PG_READ |
586 | jnz .err_access ;Page presents |
607 | jnz .err_access ;Page is present |
587 | ;Access error ? |
- | |
588 | 608 | ;Access error ? |
|
589 | shr ebx, 12 |
609 | |
Line 590... | Line 610... | ||
590 | mov ecx, ebx |
610 | shr ebx, 12 |
591 | shr ecx, 10 |
611 | mov ecx, ebx |
- | 612 | shr ecx, 10 |
|
- | 613 | test dword [master_tab+ecx*4], PG_READ |
|
592 | mov edx, [master_tab+ecx*4] |
614 | jz .fail_unlock ;page table is not created |
593 | test edx, PG_READ |
- | |
- | 615 | ;incorrect address in program |
|
- | 616 | ||
594 | jz .fail ;page table is not created |
617 | mov eax, [page_tabs+ebx*4] |
- | 618 | test eax, PG_READ |
|
595 | ;incorrect address in program |
619 | jnz .exit_unlock ; already resolved by a parallel thread |
596 | 620 | test eax, LAZY_ALLOC_PAGE |
|
597 | mov eax, [page_tabs+ebx*4] |
621 | jz .fail_unlock ;address is not reserved for use, error |
Line 598... | Line 622... | ||
598 | test eax, 2 |
622 | test eax, LAZY_ALLOC_UNREADABLE |
- | 623 | jnz .fail_unlock |
|
- | 624 | .alloc: |
|
- | 625 | mov esi, eax |
|
599 | jz .fail ;address is not reserved for usage. Error |
626 | call alloc_zero_page |
600 | 627 | test eax, eax |
|
601 | .alloc: |
628 | jz .fail_maybe_unlock |
602 | call alloc_page |
629 | |
- | 630 | mov edx, PG_UWR |
|
603 | test eax, eax |
631 | test esi, LAZY_ALLOC_UNWRITABLE |
604 | jz .fail |
632 | jz @f |
605 | 633 | mov edx, PG_UR |
|
606 | stdcall map_page, [.err_addr], eax, PG_UWR |
634 | @@: |
607 | 635 | stdcall map_page, [.err_addr], eax, edx |
|
608 | mov edi, [.err_addr] |
636 | mov ecx, [current_process] |
609 | and edi, 0xFFFFF000 |
637 | add [ecx+PROC.mem_used], 0x1000 |
Line 610... | Line 638... | ||
610 | mov ecx, 1024 |
638 | .exit_unlock: |
611 | xor eax, eax |
639 | mov ecx, [current_process] |
- | 640 | add ecx, PROC.heap_lock |
|
- | 641 | call mutex_unlock |
|
- | 642 | .exit: ;iret with repeat fault instruction |
|
- | 643 | add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
|
- | 644 | restore_ring3_context |
|
- | 645 | iretd |
|
- | 646 | ||
- | 647 | .err_access: |
|
- | 648 | ; access denied? this may be a result of copy-on-write protection |
|
- | 649 | ; Check whether the problem has already been resolved |
|
- | 650 | ; while we were waiting in mutex_lock. |
|
- | 651 | mov eax, ebx |
|
- | 652 | shr eax, 12 |
|
612 | ;cld ;caller is duty for this |
653 | mov eax, [page_tabs+eax*4] |
613 | rep stosd |
654 | test eax, PG_READ |
614 | .exit: ;iret with repeat fault instruction |
655 | jz .fail_unlock ; someone has free'd the page |
615 | add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller |
656 | test eax, PG_USER |
616 | restore_ring3_context |
657 | jz .fail_unlock ; page is mprotect'ed without PROT_READ |
- | 658 | test eax, PG_WRITE |
|
- | 659 | jnz .exit_unlock ; someone has enabled write |
|
617 | iretd |
660 | test eax, PG_SHARED |
618 | 661 | jz .fail_unlock ; only shared pages can be copy-on-write |
|
619 | .err_access: |
662 | ; check list of mapped data |
- | 663 | and ebx, not 0xFFF |
|
- | 664 | call find_smap_by_address |
|
620 | ; access denied? this may be a result of copy-on-write protection for DLL |
665 | test esi, esi |
621 | ; check list of HDLLs |
666 | jz .fail_unlock |
622 | and ebx, not 0xFFF |
667 | ; ignore children of SMEM, only children of PEDESCR can have copy-on-write data |
- | 668 | cmp [esi+SMAP.type], SMAP_TYPE_PE |
|
- | 669 | jnz .fail_unlock |
|
623 | mov eax, [current_process] |
670 | shr edi, 12 |
624 | mov eax, [eax+PROC.dlls_list_ptr] |
671 | ; lock page array in PEDESCR |
625 | test eax, eax |
672 | mov esi, [esi+SMAP.parent] |
626 | jz .fail |
673 | lea ecx, [esi+PEDESCR.page_array_lock] |
627 | mov esi, [eax+HDLL.fd] |
674 | push eax |
628 | .scan_hdll: |
675 | call mutex_lock |
629 | cmp esi, eax |
676 | pop eax |
630 | jz .fail |
677 | ; check whether the page is shared |
631 | mov edx, ebx |
678 | ; PG_SHARED flag could be set by lock_and_map_page |
632 | sub edx, [esi+HDLL.base] |
679 | xor eax, [esi+sizeof.PEDESCR+edi*4] |
633 | cmp edx, [esi+HDLL.size] |
680 | test eax, not 0xFFF |
634 | jb .fault_in_hdll |
681 | jnz .fail_unlock2 |
635 | .scan_hdll.next: |
682 | ; check whether write is allowed by section attributes |
636 | mov esi, [esi+HDLL.fd] |
683 | mov eax, [esi+sizeof.PEDESCR+edi*4] |
637 | jmp .scan_hdll |
684 | test eax, IMAGE_SCN_MEM_WRITE shr 20 |
638 | .fault_in_hdll: |
685 | jz .fail_unlock2 |
639 | ; allocate new page, map it as rw and copy data |
686 | ; if we're faulting on the page which was originally shareable writable, |
- | 687 | ; it means that someone has disabled writing with mprotect; fail |
|
640 | call alloc_page |
688 | test eax, IMAGE_SCN_MEM_SHARED shr 20 |
641 | test eax, eax |
689 | jnz .fail_unlock2 |
642 | jz .fail |
690 | stdcall pe_copy_on_write, PG_UWR |
Line 643... | Line 691... | ||
643 | stdcall map_page, ebx, eax, PG_UWR |
691 | jc .fail_unlock2 |
644 | mov edi, ebx |
692 | .exit_unlock2: |
645 | mov ecx, 1024 |
693 | lea ecx, [esi+PEDESCR.page_array_lock] |
Line 646... | Line 694... | ||
646 | sub ebx, [esi+HDLL.base] |
694 | call mutex_unlock |
647 | mov esi, [esi+HDLL.parent] |
695 | jmp .exit_unlock |
Line 648... | Line 696... | ||
648 | mov esi, [esi+DLLDESCR.data] |
696 | .fail_unlock2: |
649 | add esi, ebx |
697 | lea ecx, [esi+PEDESCR.page_array_lock] |
650 | rep movsd |
- | |
- | 698 | call mutex_unlock |
|
Line 651... | Line 699... | ||
651 | jmp .exit |
699 | jmp .fail_unlock |
Line 652... | Line 700... | ||
652 | 700 | ||
653 | .kernel_space: |
701 | .kernel_space: |
Line 675... | Line 723... | ||
675 | call alloc_page |
723 | call alloc_page |
676 | test eax, eax |
724 | test eax, eax |
677 | jz .fail |
725 | jz .fail |
Line 678... | Line 726... | ||
678 | 726 | ||
679 | push eax |
727 | push eax |
680 | stdcall map_page, [.err_addr], eax, dword PG_SWR |
728 | stdcall map_page, [.err_addr], eax, PG_SWR |
681 | pop eax |
729 | pop eax |
682 | mov edi, [.err_addr] |
730 | mov edi, [.err_addr] |
683 | and edi, -4096 |
731 | and edi, -4096 |
Line 694... | Line 742... | ||
694 | ;cld ;caller is duty for this |
742 | ;cld ;caller is duty for this |
695 | rep movsd |
743 | rep movsd |
696 | jmp .exit |
744 | jmp .exit |
697 | endp |
745 | endp |
Line -... | Line 746... | ||
- | 746 | ||
- | 747 | ; Sometimes we can just allocate a page and let the caller fill it. |
|
- | 748 | ; Sometimes we need a zero-filled page, but we can zero it at the target. |
|
- | 749 | ; Sometimes we need a zero-filled page before mapping to the target. |
|
- | 750 | ; This function is for the last case. |
|
- | 751 | ; out: eax = physical page |
|
- | 752 | ; destroys: nothing |
|
- | 753 | proc alloc_zero_page |
|
- | 754 | call alloc_page |
|
- | 755 | test eax, eax |
|
- | 756 | jz .nothing |
|
- | 757 | spin_lock_irqsave zero_page_spinlock |
|
- | 758 | push ecx edx edi eax |
|
- | 759 | mov edi, [zero_page_tab] |
|
- | 760 | stdcall map_page, edi, [esp+4], PG_SWR |
|
- | 761 | pushd 0 [esp+4] edi ; for map_page |
|
- | 762 | mov ecx, 0x1000/4 |
|
- | 763 | xor eax, eax |
|
- | 764 | rep stosd |
|
- | 765 | call map_page |
|
- | 766 | pop eax edi edx ecx |
|
- | 767 | spin_unlock_irqrestore zero_page_spinlock |
|
- | 768 | .nothing: |
|
- | 769 | ret |
|
- | 770 | endp |
|
- | 771 | ||
- | 772 | ; in: ebx = address |
|
- | 773 | ; out if SMAP exists for this address: esi -> SMAP, edi = ebx - SMAP.base |
|
- | 774 | ; out if SMAP does not exist: esi = 0 |
|
- | 775 | proc find_smap_by_address |
|
- | 776 | mov edx, [current_process] |
|
- | 777 | add edx, PROC.smap_list |
|
- | 778 | mov esi, [edx+SMAP.fd] |
|
- | 779 | .scan: |
|
- | 780 | cmp esi, edx |
|
- | 781 | jz .fail |
|
- | 782 | mov edi, ebx |
|
- | 783 | sub edi, [esi+SMAP.base] |
|
- | 784 | cmp edi, [esi+SMAP.size] |
|
- | 785 | jb .exit |
|
- | 786 | mov esi, [esi+SMAP.fd] |
|
- | 787 | jmp .scan |
|
- | 788 | .fail: |
|
- | 789 | xor esi, esi |
|
- | 790 | .exit: |
|
- | 791 | ret |
|
- | 792 | endp |
|
- | 793 | ||
- | 794 | ; Someone is about to write to copy-on-write page inside mapped PE. |
|
- | 795 | ; Provide a page that can be written to. |
|
- | 796 | ; in: esi -> PEDESCR |
|
- | 797 | ; in: edi = page number inside PE |
|
- | 798 | ; in: eax = [esi+sizeof.PEDESCR+edi*4] |
|
- | 799 | ; in: ebx = address in process, must be page-aligned |
|
- | 800 | ; in: [esp+4] = access rights for the new page |
|
- | 801 | ; out: CF=0 - ok, CF=1 - error, no memory |
|
- | 802 | proc pe_copy_on_write |
|
- | 803 | ; 1. Decrement reference counter unless it is 0xFF. |
|
- | 804 | mov edx, eax |
|
- | 805 | and edx, 0xFF |
|
- | 806 | cmp edx, 0xFF |
|
- | 807 | jz @f |
|
- | 808 | dec eax |
|
- | 809 | @@: |
|
- | 810 | ; 2. If reference counter is zero now, transfer ownership from PEDESCR to the process. |
|
- | 811 | test eax, 0xFF |
|
- | 812 | jnz .alloc_copy |
|
- | 813 | mov dword [esi+sizeof.PEDESCR+edi*4], 0 |
|
- | 814 | and eax, not 0xFFF |
|
- | 815 | .remap: |
|
- | 816 | stdcall map_page, ebx, eax, [esp+4] |
|
- | 817 | clc |
|
- | 818 | ret 4 |
|
- | 819 | .alloc_copy: |
|
- | 820 | ; 3. Otherwise, store updated reference counter to PEDESCR, |
|
- | 821 | ; allocate new page, map it as rw and copy data. |
|
- | 822 | mov [esi+sizeof.PEDESCR+edi*4], eax |
|
- | 823 | stdcall kernel_alloc, 0x1000 |
|
- | 824 | test eax, eax |
|
- | 825 | jz .error |
|
- | 826 | push esi |
|
- | 827 | mov esi, ebx |
|
- | 828 | mov edi, eax |
|
- | 829 | mov ecx, 0x1000/4 |
|
- | 830 | rep movsd |
|
- | 831 | mov esi, eax |
|
- | 832 | call get_pg_addr |
|
- | 833 | push eax |
|
- | 834 | stdcall free_kernel_space, esi |
|
- | 835 | pop eax |
|
- | 836 | pop esi |
|
- | 837 | jmp .remap |
|
- | 838 | .error: |
|
- | 839 | stc |
|
- | 840 | ret 4 |
|
- | 841 | endp |
|
- | 842 | ||
- | 843 | PROT_READ = 1 |
|
- | 844 | PROT_WRITE = 2 |
|
- | 845 | PROT_EXEC = 4 |
|
- | 846 | proc mprotect stdcall uses ebx esi edi, address:dword, size:dword, access:dword |
|
- | 847 | locals |
|
- | 848 | retval dd -1 |
|
- | 849 | smap_ptr dd 0 |
|
- | 850 | endl |
|
- | 851 | mov ecx, [current_process] |
|
- | 852 | add ecx, PROC.heap_lock |
|
- | 853 | call mutex_lock |
|
- | 854 | test [access], not (PROT_READ+PROT_WRITE+PROT_EXEC) |
|
- | 855 | jnz .error |
|
- | 856 | cmp [size], 0 |
|
- | 857 | jz .error |
|
- | 858 | mov eax, [address] |
|
- | 859 | add [size], eax |
|
- | 860 | and eax, not 0xFFF |
|
- | 861 | .addrloop: |
|
- | 862 | mov [address], eax |
|
- | 863 | mov ecx, eax |
|
- | 864 | cmp eax, OS_BASE |
|
- | 865 | jae .error |
|
- | 866 | shr eax, 22 |
|
- | 867 | test byte [master_tab+eax*4], PG_READ |
|
- | 868 | jz .error |
|
- | 869 | shr ecx, 12 |
|
- | 870 | mov eax, [page_tabs+ecx*4] |
|
- | 871 | test al, PG_READ |
|
- | 872 | jnz .page_present |
|
- | 873 | test al, LAZY_ALLOC_PAGE |
|
- | 874 | jz .error |
|
- | 875 | cmp [retval], -1 |
|
- | 876 | jnz .skip_query |
|
- | 877 | inc [retval] |
|
- | 878 | test al, LAZY_ALLOC_UNREADABLE |
|
- | 879 | jnz @f |
|
- | 880 | or [retval], PROT_READ+PROT_EXEC |
|
- | 881 | @@: |
|
- | 882 | test al, LAZY_ALLOC_UNWRITABLE |
|
- | 883 | jnz @f |
|
- | 884 | or [retval], PROT_WRITE |
|
- | 885 | @@: |
|
- | 886 | .skip_query: |
|
- | 887 | and al, not (LAZY_ALLOC_UNREADABLE+LAZY_ALLOC_UNWRITABLE) |
|
- | 888 | test [access], PROT_READ |
|
- | 889 | jnz @f |
|
- | 890 | or al, LAZY_ALLOC_UNREADABLE |
|
- | 891 | @@: |
|
- | 892 | test [access], PROT_WRITE |
|
- | 893 | jnz @f |
|
- | 894 | or al, LAZY_ALLOC_UNWRITABLE |
|
- | 895 | @@: |
|
- | 896 | mov [page_tabs+ecx*4], eax |
|
- | 897 | jmp .nextpage |
|
- | 898 | .page_present: |
|
- | 899 | test eax, PG_SHARED |
|
- | 900 | jnz .page_shared |
|
- | 901 | .normal_page: |
|
- | 902 | cmp [retval], -1 |
|
- | 903 | jnz .skip_query2 |
|
- | 904 | inc [retval] |
|
- | 905 | test al, PG_USER |
|
- | 906 | jz @f |
|
- | 907 | or [retval], PROT_READ+PROT_EXEC |
|
- | 908 | @@: |
|
- | 909 | test al, PG_WRITE |
|
- | 910 | jz @f |
|
- | 911 | or [retval], PROT_WRITE |
|
- | 912 | @@: |
|
- | 913 | .skip_query2: |
|
- | 914 | and al, not (PG_USER+PG_WRITE) |
|
- | 915 | test [access], PROT_READ |
|
- | 916 | jz @f |
|
- | 917 | or al, PG_USER |
|
- | 918 | @@: |
|
- | 919 | test [access], PROT_WRITE |
|
- | 920 | jz @f |
|
- | 921 | or al, PG_WRITE |
|
- | 922 | @@: |
|
- | 923 | mov [page_tabs+ecx*4], eax |
|
- | 924 | mov eax, [address] |
|
- | 925 | invlpg [eax] |
|
- | 926 | jmp .nextpage |
|
- | 927 | .page_shared: |
|
- | 928 | mov esi, [smap_ptr] |
|
- | 929 | test esi, esi |
|
- | 930 | jz .find_smap |
|
- | 931 | mov edx, [address] |
|
- | 932 | sub edx, [esi+SMAP.base] |
|
- | 933 | cmp edx, [esi+SMAP.size] |
|
- | 934 | jb .found_smap |
|
- | 935 | .find_smap: |
|
- | 936 | mov ebx, [address] |
|
- | 937 | call find_smap_by_address |
|
- | 938 | mov [smap_ptr], esi |
|
- | 939 | test esi, esi |
|
- | 940 | jz .normal_page |
|
- | 941 | .found_smap: |
|
- | 942 | cmp [esi+SMAP.type], SMAP_TYPE_PE |
|
- | 943 | jnz .error |
|
- | 944 | shr edi, 12 |
|
- | 945 | mov esi, [esi+SMAP.parent] |
|
- | 946 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 947 | push eax |
|
- | 948 | call mutex_lock |
|
- | 949 | pop eax |
|
- | 950 | xor eax, [esi+sizeof.PEDESCR+edi*4] |
|
- | 951 | test eax, not 0xFFF |
|
- | 952 | jnz .normal_page_unlock |
|
- | 953 | mov eax, [esi+sizeof.PEDESCR+edi*4] |
|
- | 954 | test eax, IMAGE_SCN_MEM_SHARED shr 20 |
|
- | 955 | jnz .normal_page_unlock |
|
- | 956 | cmp [retval], -1 |
|
- | 957 | jnz .skip_query3 |
|
- | 958 | mov edx, [address] |
|
- | 959 | shr edx, 12 |
|
- | 960 | inc [retval] |
|
- | 961 | test byte [page_tabs+edx*4], PG_USER |
|
- | 962 | jz @f |
|
- | 963 | or [retval], PROT_READ+PROT_EXEC |
|
- | 964 | @@: |
|
- | 965 | test eax, IMAGE_SCN_MEM_WRITE shr 20 |
|
- | 966 | jz @f |
|
- | 967 | or [retval], PROT_WRITE |
|
- | 968 | @@: |
|
- | 969 | .skip_query3: |
|
- | 970 | test [access], PROT_WRITE |
|
- | 971 | jz .no_write |
|
- | 972 | push PG_SWR |
|
- | 973 | test [access], PROT_READ |
|
- | 974 | jz @f |
|
- | 975 | pop edx |
|
- | 976 | push PG_UWR |
|
- | 977 | @@: |
|
- | 978 | call pe_copy_on_write |
|
- | 979 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 980 | call mutex_unlock |
|
- | 981 | jmp .nextpage |
|
- | 982 | .normal_page_unlock: |
|
- | 983 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 984 | call mutex_unlock |
|
- | 985 | mov ecx, [address] |
|
- | 986 | shr ecx, 12 |
|
- | 987 | mov eax, [page_tabs+ecx*4] |
|
- | 988 | jmp .normal_page |
|
- | 989 | .no_write: |
|
- | 990 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 991 | call mutex_unlock |
|
- | 992 | mov ecx, [address] |
|
- | 993 | shr ecx, 12 |
|
- | 994 | mov eax, [page_tabs+ecx*4] |
|
- | 995 | jmp .skip_query2 |
|
- | 996 | .nextpage: |
|
- | 997 | mov eax, [address] |
|
- | 998 | add eax, 0x1000 |
|
- | 999 | cmp eax, [size] |
|
- | 1000 | jb .addrloop |
|
- | 1001 | .exit: |
|
- | 1002 | mov ecx, [current_process] |
|
- | 1003 | add ecx, PROC.heap_lock |
|
- | 1004 | call mutex_unlock |
|
- | 1005 | mov eax, [retval] |
|
- | 1006 | ret |
|
- | 1007 | .error: |
|
- | 1008 | or [retval], -1 |
|
- | 1009 | jmp .exit |
|
- | 1010 | endp |
|
698 | 1011 | ||
699 | ; returns number of mapped bytes |
1012 | ; returns number of mapped bytes |
700 | proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\ |
1013 | proc map_memEx stdcall uses ebx esi edi, lin_addr:dword,slot:dword,\ |
701 | ofs:dword,buf_size:dword,req_access:dword |
1014 | ofs:dword,buf_size:dword,req_access:dword,where:dword |
702 | locals |
1015 | locals |
703 | count dd ? |
1016 | count dd ? |
704 | process dd ? |
1017 | process dd ? |
Line 708... | Line 1021... | ||
708 | cmp [buf_size], 0 |
1021 | cmp [buf_size], 0 |
709 | jz .exit |
1022 | jz .exit |
Line 710... | Line 1023... | ||
710 | 1023 | ||
711 | mov eax, [slot] |
1024 | mov eax, [slot] |
712 | shl eax, 8 |
1025 | shl eax, 8 |
713 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
1026 | mov ecx, [SLOT_BASE+eax+APPDATA.process] |
714 | test eax, eax |
1027 | test ecx, ecx |
Line 715... | Line 1028... | ||
715 | jz .exit |
1028 | jz .exit |
- | 1029 | ||
- | 1030 | mov [process], ecx |
|
- | 1031 | add ecx, PROC.heap_lock |
|
716 | 1032 | call mutex_lock |
|
717 | mov [process], eax |
1033 | mov eax, [process] |
718 | mov ebx, [ofs] |
1034 | mov ebx, [ofs] |
719 | shr ebx, 22 |
1035 | shr ebx, 22 |
720 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
1036 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
721 | mov esi, [ipc_ptab] |
1037 | mov esi, [where] |
722 | and eax, 0xFFFFF000 |
1038 | and eax, 0xFFFFF000 |
723 | jz .exit |
1039 | jz .unlock_exit |
724 | stdcall map_page, esi, eax, PG_SWR |
1040 | stdcall map_page, esi, eax, PG_SWR |
725 | @@: |
1041 | @@: |
726 | mov edi, [lin_addr] |
1042 | mov edi, [lin_addr] |
727 | and edi, 0xFFFFF000 |
1043 | and edi, 0xFFFFF000 |
728 | mov ecx, [buf_size] |
1044 | mov ecx, [buf_size] |
729 | add ecx, 4095 |
- | |
Line 730... | Line 1045... | ||
730 | shr ecx, 12 |
1045 | add ecx, 4095 |
731 | inc ecx ; ??????????? |
1046 | shr ecx, 12 |
732 | 1047 | ||
733 | mov edx, [ofs] |
1048 | mov edx, [ofs] |
734 | shr edx, 12 |
1049 | shr edx, 12 |
735 | and edx, 0x3FF |
1050 | and edx, 0x3FF |
736 | .map: |
1051 | .map: |
737 | stdcall safe_map_page, [slot], [req_access], [ofs] |
1052 | stdcall lock_and_map_page, [slot], [req_access], [ofs] |
738 | jnc .exit |
1053 | jnc .unlock_exit |
739 | add [count], PAGE_SIZE |
1054 | add [count], PAGE_SIZE |
Line 740... | Line 1055... | ||
740 | add [ofs], PAGE_SIZE |
1055 | add [ofs], PAGE_SIZE |
741 | dec ecx |
1056 | dec ecx |
742 | jz .exit |
1057 | jz .unlock_exit |
743 | 1058 | ||
Line 744... | Line 1059... | ||
744 | add edi, PAGE_SIZE |
1059 | add edi, PAGE_SIZE |
745 | inc edx |
1060 | inc edx |
746 | cmp edx, 1024 |
1061 | cmp edx, 1024 |
747 | jnz .map |
1062 | jnz .map |
748 | 1063 | ||
Line 749... | Line 1064... | ||
749 | inc ebx |
1064 | inc ebx |
750 | mov eax, [process] |
1065 | mov eax, [process] |
751 | mov eax, [eax+PROC.pdt_0+ebx*4] |
1066 | mov eax, [eax+PROC.pdt_0+ebx*4] |
- | 1067 | and eax, 0xFFFFF000 |
|
- | 1068 | jz .unlock_exit |
|
- | 1069 | ||
- | 1070 | stdcall map_page, esi, eax, PG_SWR |
|
752 | and eax, 0xFFFFF000 |
1071 | xor edx, edx |
753 | jz .exit |
1072 | jmp .map |
754 | 1073 | .unlock_exit: |
|
755 | stdcall map_page, esi, eax, PG_SWR |
1074 | mov ecx, [process] |
Line 756... | Line 1075... | ||
756 | xor edx, edx |
1075 | add ecx, PROC.heap_lock |
757 | jmp .map |
1076 | call mutex_unlock |
758 | .exit: |
1077 | .exit: |
759 | mov eax, [count] |
- | |
760 | ret |
1078 | mov eax, [count] |
761 | endp |
1079 | ret |
Line 762... | Line -... | ||
762 | - | ||
763 | proc map_memEx stdcall, lin_addr:dword,slot:dword,\ |
1080 | endp |
764 | ofs:dword,buf_size:dword,req_access:dword |
1081 | |
Line 765... | Line 1082... | ||
765 | locals |
1082 | proc unmap_memEx stdcall uses ebx esi edi, lin_addr:dword,slot:dword,\ |
766 | count dd ? |
1083 | ofs:dword,mapped_size:dword,pagedir:dword |
767 | process dd ? |
1084 | locals |
- | 1085 | process dd ? |
|
- | 1086 | endl |
|
768 | endl |
1087 | |
769 | 1088 | cmp [mapped_size], 0 |
|
770 | mov [count], 0 |
- | |
- | 1089 | jz .exit |
|
771 | cmp [buf_size], 0 |
1090 | |
772 | jz .exit |
1091 | mov eax, [slot] |
773 | 1092 | shl eax, 8 |
|
- | 1093 | mov ecx, [SLOT_BASE+eax+APPDATA.process] |
|
774 | mov eax, [slot] |
1094 | mov [process], ecx |
- | 1095 | xor eax, eax |
|
775 | shl eax, 8 |
1096 | test ecx, ecx |
776 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
1097 | jz @f |
777 | test eax, eax |
1098 | add ecx, PROC.heap_lock |
- | 1099 | call mutex_lock |
|
778 | jz .exit |
1100 | mov ebx, [ofs] |
779 | 1101 | shr ebx, 22 |
|
- | 1102 | mov eax, [process] |
|
- | 1103 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
|
780 | mov [process], eax |
1104 | @@: |
781 | mov ebx, [ofs] |
1105 | xor esi, esi |
782 | shr ebx, 22 |
1106 | and eax, 0xFFFFF000 |
783 | mov eax, [eax+PROC.pdt_0+ebx*4] ;get page table |
1107 | jz @f |
784 | mov esi, [proc_mem_tab] |
1108 | mov esi, [pagedir] |
785 | and eax, 0xFFFFF000 |
1109 | stdcall map_page, esi, eax, PG_SWR |
Line 786... | Line 1110... | ||
786 | jz .exit |
1110 | @@: |
787 | stdcall map_page, esi, eax, PG_SWR |
1111 | mov ecx, shared_locked_mutex |
788 | @@: |
1112 | call mutex_lock |
- | 1113 | mov edi, [lin_addr] |
|
789 | mov edi, [lin_addr] |
1114 | shr edi, 12 |
790 | and edi, 0xFFFFF000 |
- | |
791 | mov ecx, [buf_size] |
- | |
792 | add ecx, 4095 |
1115 | mov ecx, [mapped_size] |
793 | shr ecx, 12 |
- | |
794 | inc ecx ; ??????????? |
1116 | add ecx, 4095 |
795 | 1117 | shr ecx, 12 |
|
Line 796... | Line 1118... | ||
796 | mov edx, [ofs] |
1118 | mov [mapped_size], ecx |
797 | shr edx, 12 |
1119 | |
798 | and edx, 0x3FF |
1120 | mov edx, [ofs] |
799 | .map: |
1121 | shr edx, 12 |
Line 800... | Line 1122... | ||
800 | stdcall safe_map_page, [slot], [req_access], [ofs] |
1122 | and edx, 0x3FF |
- | 1123 | lea esi, [esi+edx*4] |
|
- | 1124 | .map: |
|
- | 1125 | call unlock_and_unmap_page |
|
801 | jnc .exit |
1126 | dec [mapped_size] |
802 | add [count], PAGE_SIZE |
1127 | jz .done |
803 | add [ofs], PAGE_SIZE |
1128 | |
804 | dec ecx |
1129 | inc edi |
Line -... | Line 1130... | ||
- | 1130 | add esi, 4 |
|
805 | jz .exit |
1131 | test esi, 0xFFF |
806 | - | ||
807 | add edi, PAGE_SIZE |
1132 | jnz .map |
- | 1133 | ||
- | 1134 | inc ebx |
|
- | 1135 | xor esi, esi |
|
- | 1136 | cmp [process], 0 |
|
- | 1137 | jz .map |
|
- | 1138 | mov eax, [process] |
|
- | 1139 | mov eax, [eax+PROC.pdt_0+ebx*4] |
|
- | 1140 | and eax, 0xFFFFF000 |
|
808 | inc edx |
1141 | jz .map |
809 | cmp edx, 1024 |
1142 | |
- | 1143 | mov esi, [pagedir] |
|
- | 1144 | stdcall map_page, esi, eax, PG_SWR |
|
- | 1145 | jmp .map |
|
- | 1146 | .done: |
|
810 | jnz .map |
1147 | mov ecx, shared_locked_mutex |
811 | 1148 | call mutex_unlock |
|
Line 812... | Line 1149... | ||
812 | inc ebx |
1149 | cmp [process], 0 |
813 | mov eax, [process] |
1150 | jz .exit |
814 | mov eax, [eax+PROC.pdt_0+ebx*4] |
1151 | mov ecx, [process] |
- | 1152 | add ecx, PROC.heap_lock |
|
815 | and eax, 0xFFFFF000 |
1153 | call mutex_unlock |
816 | jz .exit |
1154 | .exit: |
817 | 1155 | mov eax, [pagedir] |
|
- | 1156 | mov ecx, eax |
|
- | 1157 | shr ecx, 12 |
|
- | 1158 | mov dword [page_tabs+ecx*4], 0 |
|
- | 1159 | invlpg [eax] |
|
818 | stdcall map_page, esi, eax, PG_SWR |
1160 | ret |
819 | xor edx, edx |
1161 | endp |
820 | jmp .map |
1162 | |
821 | .exit: |
1163 | ; in: esi+edx*4 = pointer to page table entry |
822 | mov eax, [count] |
1164 | ; in: [slot], [req_access], [ofs] on the stack |
823 | ret |
1165 | ; in: edi = linear address to map |
- | 1166 | ; in: address space lock must be held |
|
824 | endp |
1167 | ; out: CF cleared <=> failed |
- | 1168 | ; destroys: only eax |
|
825 | 1169 | proc lock_and_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
|
826 | ; in: esi+edx*4 = pointer to page table entry |
1170 | locals |
827 | ; in: [slot], [req_access], [ofs] on the stack |
1171 | locked_descr dd ? |
828 | ; in: edi = linear address to map |
1172 | endl |
829 | ; out: CF cleared <=> failed |
1173 | |
830 | ; destroys: only eax |
1174 | mov eax, [esi+edx*4] |
831 | proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword |
1175 | test eax, PG_READ |
832 | mov eax, [esi+edx*4] |
1176 | jz .not_present |
833 | test al, PG_READ |
1177 | test eax, PG_SHARED |
834 | jz .not_present |
1178 | jnz .resolve_shared |
835 | test al, PG_WRITE |
1179 | ; normal case: not shared allocated page, mark as shared and map with requested access |
836 | jz .resolve_readonly |
1180 | or dword [esi+edx*4], PG_SHARED |
837 | ; normal case: writable page, just map with requested access |
1181 | .map: |
838 | .map: |
1182 | and eax, not 0xFFF |
- | 1183 | stdcall map_page, edi, eax, [req_access] |
|
- | 1184 | stc |
|
- | 1185 | .fail: |
|
839 | stdcall map_page, edi, eax, [req_access] |
1186 | ret |
- | 1187 | .not_present: |
|
- | 1188 | ; check for alloc-on-demand page |
|
- | 1189 | test eax, LAZY_ALLOC_PAGE |
|
- | 1190 | jz .fail |
|
- | 1191 | ; allocate new page, save it to source page table |
|
840 | stc |
1192 | push ecx |
841 | .fail: |
1193 | call alloc_zero_page |
842 | ret |
1194 | pop ecx |
843 | .not_present: |
- | |
844 | ; check for alloc-on-demand page |
1195 | test eax, eax |
845 | test al, 2 |
1196 | jz .fail |
846 | jz .fail |
1197 | or eax, PG_READ+PG_SHARED |
847 | ; allocate new page, save it to source page table |
1198 | test dword [esi+edx*4], LAZY_ALLOC_UNREADABLE |
848 | push ecx |
1199 | jnz @f |
849 | call alloc_page |
1200 | or eax, PG_USER |
850 | pop ecx |
1201 | @@: |
851 | test eax, eax |
1202 | test dword [esi+edx*4], LAZY_ALLOC_UNWRITABLE |
- | 1203 | jnz @f |
|
852 | jz .fail |
1204 | or eax, PG_WRITE |
853 | or al, PG_UWR |
1205 | @@: |
854 | mov [esi+edx*4], eax |
1206 | mov [esi+edx*4], eax |
855 | jmp .map |
1207 | jmp .map |
856 | .resolve_readonly: |
- | |
857 | ; readonly page, probably copy-on-write |
- | |
858 | ; check: readonly request of readonly page is ok |
1208 | .resolve_shared: |
859 | test [req_access], PG_WRITE |
1209 | push ecx edx eax |
860 | jz .map |
1210 | mov eax, sizeof.SHARED_LOCKED_PAGE |
861 | ; find control structure for this page |
1211 | call malloc |
862 | pushf |
1212 | mov [locked_descr], eax |
863 | cli |
1213 | test eax, eax |
864 | cld |
1214 | jz .fail_pop |
- | 1215 | mov edx, [esp] |
|
865 | push ebx ecx |
1216 | and edx, not 0xFFF |
- | 1217 | mov [eax+SHARED_LOCKED_PAGE.address], edx |
|
- | 1218 | mov eax, [slot] |
|
- | 1219 | shl eax, 8 |
|
- | 1220 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
|
- | 1221 | mov ecx, [eax+PROC.smap_list] |
|
- | 1222 | add eax, PROC.smap_list |
|
- | 1223 | .find_shared_parent: |
|
- | 1224 | cmp ecx, eax |
|
866 | mov eax, [slot] |
1225 | jz .shared_orphan |
- | 1226 | mov edx, [ofs] |
|
- | 1227 | sub edx, [ecx+SMAP.base] |
|
- | 1228 | cmp edx, [ecx+SMAP.size] |
|
- | 1229 | jb .found_shared_parent |
|
867 | shl eax, 8 |
1230 | mov ecx, [ecx+SMAP.fd] |
868 | mov eax, [SLOT_BASE+eax+APPDATA.process] |
1231 | jmp .find_shared_parent |
- | 1232 | .shared_abandoned: |
|
- | 1233 | call mutex_unlock |
|
869 | mov eax, [eax+PROC.dlls_list_ptr] |
1234 | .shared_orphan: |
- | 1235 | ; no copy-on-write for orphans |
|
- | 1236 | test dword [esp], PG_WRITE |
|
- | 1237 | jnz @f |
|
- | 1238 | test [req_access], PG_WRITE |
|
- | 1239 | jnz .shared_forbidden |
|
- | 1240 | @@: |
|
870 | test eax, eax |
1241 | ; locking the same normal page for second time: |
- | 1242 | ; the first lock_and_map_page has set PG_SHARED, |
|
- | 1243 | ; now we must cooperate with that other thread. |
|
- | 1244 | mov ecx, shared_locked_mutex |
|
- | 1245 | call mutex_lock |
|
- | 1246 | mov eax, [locked_descr] |
|
871 | jz .no_hdll |
1247 | mov [eax+SHARED_LOCKED_PAGE.parent], 0 |
- | 1248 | .shared_common: |
|
- | 1249 | mov edx, [shared_locked_list+SHARED_LOCKED_PAGE.bk] |
|
872 | mov ecx, [eax+HDLL.fd] |
1250 | mov [eax+SHARED_LOCKED_PAGE.fd], shared_locked_list |
873 | .scan_hdll: |
1251 | mov [eax+SHARED_LOCKED_PAGE.bk], edx |
874 | cmp ecx, eax |
1252 | mov [edx+SHARED_LOCKED_PAGE.fd], eax |
- | 1253 | mov [shared_locked_list+SHARED_LOCKED_PAGE.bk], edx |
|
- | 1254 | call mutex_unlock |
|
875 | jz .no_hdll |
1255 | pop eax edx ecx |
- | 1256 | jmp .map |
|
- | 1257 | .shared_forbidden_unlock: |
|
- | 1258 | call mutex_unlock |
|
876 | mov ebx, [ofs] |
1259 | .shared_forbidden: |
877 | and ebx, not 0xFFF |
1260 | mov eax, [locked_descr] |
878 | sub ebx, [ecx+HDLL.base] |
1261 | call free |
- | 1262 | .fail_pop: |
|
- | 1263 | pop eax edx ecx |
|
- | 1264 | clc |
|
- | 1265 | ret |
|
- | 1266 | .found_shared_parent: |
|
- | 1267 | shr edx, 12 |
|
- | 1268 | mov eax, [locked_descr] |
|
- | 1269 | mov [eax+SHARED_LOCKED_PAGE.offs], edx |
|
- | 1270 | cmp [ecx+SMAP.type], SMAP_TYPE_PE |
|
- | 1271 | jnz .parent_smap |
|
- | 1272 | push edx |
|
- | 1273 | mov ecx, [ecx+SMAP.parent] |
|
879 | cmp ebx, [ecx+HDLL.size] |
1274 | add ecx, PEDESCR.page_array_lock |
880 | jb .hdll_found |
1275 | call mutex_lock |
- | 1276 | pop edx |
|
- | 1277 | mov eax, [esp] |
|
- | 1278 | xor eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4] |
|
- | 1279 | test eax, not 0xFFF |
|
- | 1280 | jnz .shared_abandoned |
|
- | 1281 | test dword [esp], PG_WRITE |
|
- | 1282 | jnz @f |
|
- | 1283 | test [req_access], PG_WRITE |
|
- | 1284 | jnz .pedescr_try_cow |
|
- | 1285 | @@: |
|
- | 1286 | mov eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4] |
|
- | 1287 | inc eax |
|
- | 1288 | test eax, 0xFF |
|
- | 1289 | jnz @f |
|
- | 1290 | dec eax |
|
- | 1291 | @@: |
|
- | 1292 | mov [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], eax |
|
- | 1293 | push ecx |
|
- | 1294 | mov ecx, pe_list_mutex |
|
- | 1295 | call mutex_lock |
|
- | 1296 | mov eax, [esp] |
|
- | 1297 | inc dword [eax+PEDESCR.refcount-PEDESCR.page_array_lock] |
|
- | 1298 | call mutex_unlock |
|
- | 1299 | pop ecx |
|
- | 1300 | call mutex_unlock |
|
- | 1301 | sub ecx, PEDESCR.page_array_lock |
|
- | 1302 | push ecx |
|
- | 1303 | .shared_common2: |
|
- | 1304 | mov ecx, shared_locked_mutex |
|
- | 1305 | call mutex_lock |
|
- | 1306 | mov eax, [locked_descr] |
|
- | 1307 | pop [eax+SHARED_LOCKED_PAGE.parent] |
|
- | 1308 | jmp .shared_common |
|
881 | mov ecx, [ecx+HDLL.fd] |
1309 | .pedescr_try_cow: |
882 | jmp .scan_hdll |
1310 | mov eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4] |
- | 1311 | test eax, IMAGE_SCN_MEM_WRITE shr 20 |
|
- | 1312 | jz @f |
|
- | 1313 | or dword [esp], PG_WRITE |
|
883 | .no_hdll: |
1314 | @@: |
- | 1315 | dec eax |
|
- | 1316 | test eax, 0xFF |
|
- | 1317 | jnz .pedescr_alloc_copy |
|
- | 1318 | mov dword [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], 0 |
|
884 | pop ecx ebx |
1319 | call mutex_unlock |
- | 1320 | mov eax, [locked_descr] |
|
885 | popf |
1321 | call free |
- | 1322 | pop eax edx ecx |
|
886 | clc |
1323 | or eax, PG_SHARED |
887 | ret |
1324 | mov [esi+edx*4], eax |
- | 1325 | jmp .map |
|
- | 1326 | .pedescr_alloc_copy: |
|
888 | .hdll_found: |
1327 | push ecx edx |
- | 1328 | stdcall kernel_alloc, 0x1000 |
|
- | 1329 | pop edx ecx |
|
- | 1330 | test eax, eax |
|
- | 1331 | jz .shared_forbidden_unlock |
|
- | 1332 | dec dword [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4] |
|
889 | ; allocate page, save it in page table, map it, copy contents from base |
1333 | push ecx esi edi |
- | 1334 | mov esi, edi |
|
- | 1335 | mov edi, eax |
|
890 | mov eax, [ecx+HDLL.parent] |
1336 | stdcall map_page, esi, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], PG_READ |
- | 1337 | mov ecx, 0x1000/4 |
|
- | 1338 | rep movsd |
|
- | 1339 | sub esi, 0x1000 |
|
891 | add ebx, [eax+DLLDESCR.data] |
1340 | sub edi, 0x1000 |
892 | call alloc_page |
1341 | mov eax, edi |
- | 1342 | call get_pg_addr |
|
- | 1343 | and dword [esp+12], 0xFFF |
|
- | 1344 | or dword [esp+12], eax |
|
- | 1345 | stdcall map_page, esi, eax, [req_access] |
|
- | 1346 | stdcall free_kernel_space, edi |
|
- | 1347 | pop edi esi ecx |
|
- | 1348 | call mutex_unlock |
|
- | 1349 | mov eax, [locked_descr] |
|
- | 1350 | call free |
|
- | 1351 | pop eax edx ecx |
|
- | 1352 | or eax, PG_SHARED |
|
- | 1353 | mov [esi+edx*4], eax |
|
- | 1354 | stc |
|
- | 1355 | ret |
|
- | 1356 | .parent_smap: |
|
- | 1357 | test dword [esp], PG_WRITE |
|
- | 1358 | jnz @f |
|
- | 1359 | test [req_access], PG_WRITE |
|
- | 1360 | jz .shared_forbidden |
|
- | 1361 | @@: |
|
- | 1362 | push [ecx+SMAP.parent] |
|
- | 1363 | mov ecx, shmem_list_mutex |
|
- | 1364 | call mutex_lock |
|
- | 1365 | mov eax, [esp] |
|
- | 1366 | inc dword [esp] |
|
- | 1367 | inc [eax+SMEM.refcount] |
|
- | 1368 | call mutex_unlock |
|
- | 1369 | jmp .shared_common2 |
|
- | 1370 | endp |
|
- | 1371 | ||
- | 1372 | ; in: esi -> process page table entry or esi < 0x1000 if no page table entry |
|
- | 1373 | ; in: edi = page number for mapped copy |
|
- | 1374 | ; in: shared_locked_mutex is held |
|
- | 1375 | ; destroys eax, ecx, edx |
|
- | 1376 | proc unlock_and_unmap_page |
|
- | 1377 | mov edx, [page_tabs+edi*4] |
|
- | 1378 | and edx, not 0xFFF |
|
- | 1379 | mov dword [page_tabs+edi*4], 0 |
|
- | 1380 | mov eax, edi |
|
- | 1381 | shl eax, 12 |
|
- | 1382 | invlpg [eax] |
|
- | 1383 | mov eax, [shared_locked_list+SHARED_LOCKED_PAGE.fd] |
|
- | 1384 | .check_list: |
|
- | 1385 | cmp eax, shared_locked_list |
|
- | 1386 | jz .not_in_list |
|
- | 1387 | cmp edx, [eax+SHARED_LOCKED_PAGE.address] |
|
- | 1388 | jz .found_in_list |
|
- | 1389 | mov eax, [eax+SHARED_LOCKED_PAGE.fd] |
|
- | 1390 | jmp .check_list |
|
- | 1391 | .found_in_list: |
|
- | 1392 | push esi |
|
- | 1393 | mov esi, [eax+SHARED_LOCKED_PAGE.parent] |
|
- | 1394 | mov edx, [eax+SHARED_LOCKED_PAGE.fd] |
|
- | 1395 | mov ecx, [eax+SHARED_LOCKED_PAGE.bk] |
|
- | 1396 | mov [edx+SHARED_LOCKED_PAGE.bk], ecx |
|
- | 1397 | mov [ecx+SHARED_LOCKED_PAGE.fd], edx |
|
- | 1398 | test esi, esi |
|
- | 1399 | jz .orphan |
|
- | 1400 | btr esi, 0 |
|
- | 1401 | jc .parent_smap |
|
- | 1402 | push eax |
|
- | 1403 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 1404 | call mutex_lock |
|
- | 1405 | mov edx, [esp] |
|
- | 1406 | mov edx, [edx+SHARED_LOCKED_PAGE.offs] |
|
- | 1407 | mov eax, [esi+sizeof.PEDESCR+edx*4] |
|
- | 1408 | and eax, 0xFF |
|
- | 1409 | cmp eax, 0xFF |
|
- | 1410 | jz .no_deref |
|
- | 1411 | mov eax, [esi+sizeof.PEDESCR+edx*4] |
|
- | 1412 | dec eax |
|
- | 1413 | test eax, 0xFF |
|
- | 1414 | jnz @f |
|
- | 1415 | call free_page |
|
- | 1416 | xor eax, eax |
|
- | 1417 | @@: |
|
- | 1418 | mov [esi+sizeof.PEDESCR+edx*4], eax |
|
- | 1419 | .no_deref: |
|
- | 1420 | lea ecx, [esi+PEDESCR.page_array_lock] |
|
- | 1421 | call mutex_unlock |
|
- | 1422 | call dereference_pe |
|
- | 1423 | pop eax |
|
- | 1424 | call free |
|
- | 1425 | pop esi |
|
- | 1426 | ret |
|
- | 1427 | .parent_smap: |
|
- | 1428 | call free |
|
- | 1429 | call dereference_smem |
|
- | 1430 | pop esi |
|
- | 1431 | ret |
|
- | 1432 | .orphan: |
|
- | 1433 | call free |
|
- | 1434 | pop esi |
|
893 | test eax, eax |
1435 | ret |
Line 894... | Line 1436... | ||
894 | jz .no_hdll |
1436 | .not_in_list: |
895 | or al, PG_UWR |
1437 | cmp esi, 0x1000 |
896 | mov [esi+edx*4], eax |
1438 | jb .just_free |
Line 955... | Line 1497... | ||
955 | 1497 | ||
956 | proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
1498 | proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
957 | locals |
1499 | locals |
958 | dst_slot dd ? |
1500 | dst_slot dd ? |
- | 1501 | dst_offset dd ? |
|
959 | dst_offset dd ? |
1502 | dst_ptr dd ? |
960 | buf_size dd ? |
1503 | buf_size dd ? |
- | 1504 | used_buf dd ? |
|
- | 1505 | mapped_size dd ? |
|
961 | used_buf dd ? |
1506 | result dd ? |
Line 962... | Line 1507... | ||
962 | endl |
1507 | endl |
963 | 1508 | ||
Line 964... | Line 1509... | ||
964 | pushf |
1509 | mov ecx, ipc_mutex |
965 | cli |
1510 | call mutex_lock |
966 | 1511 | ||
967 | mov eax, [PID] |
1512 | mov eax, [PID] |
Line 972... | Line 1517... | ||
972 | mov [dst_slot], eax |
1517 | mov [dst_slot], eax |
973 | shl eax, 8 |
1518 | shl eax, 8 |
974 | mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined? |
1519 | mov edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined? |
975 | test edi, edi |
1520 | test edi, edi |
976 | jz .no_ipc_area |
1521 | jz .no_ipc_area |
- | 1522 | mov [dst_ptr], edi |
|
Line 977... | Line 1523... | ||
977 | 1523 | ||
978 | mov ebx, edi |
1524 | mov ebx, edi |
979 | and ebx, 0xFFF |
1525 | and ebx, 0xFFF |
Line 990... | Line 1536... | ||
990 | stdcall alloc_kernel_space, esi |
1536 | stdcall alloc_kernel_space, esi |
991 | mov ecx, eax |
1537 | mov ecx, eax |
992 | pop edi esi |
1538 | pop edi esi |
993 | @@: |
1539 | @@: |
994 | mov [used_buf], ecx |
1540 | mov [used_buf], ecx |
995 | stdcall map_mem_ipc, ecx, [dst_slot], \ |
1541 | stdcall map_memEx, ecx, [dst_slot], \ |
996 | edi, esi, PG_SWR |
1542 | edi, esi, PG_SWR, [ipc_ptab] |
- | 1543 | mov [mapped_size], eax |
|
- | 1544 | mov [result], 3 ; buffer overflow |
|
- | 1545 | sub eax, [dst_offset] |
|
- | 1546 | jc .no_copy_data |
|
- | 1547 | cmp [buf_size], eax |
|
- | 1548 | jb @f |
|
- | 1549 | mov [buf_size], eax |
|
- | 1550 | @@: |
|
- | 1551 | cmp [buf_size], 8 |
|
- | 1552 | jb .no_copy_data |
|
Line -... | Line 1553... | ||
- | 1553 | ||
997 | 1554 | mov [result], 2 ; ipc blocked |
|
998 | mov edi, [dst_offset] |
1555 | mov edi, [dst_offset] |
999 | add edi, [used_buf] |
1556 | add edi, [used_buf] |
1000 | cmp dword [edi], 0 |
1557 | cmp dword [edi], 0 |
Line -... | Line 1558... | ||
- | 1558 | jnz .no_copy_data ;if dword [buffer]<>0 - ipc blocked now |
|
1001 | jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
1559 | |
1002 | 1560 | mov [result], 3 ; buffer overflow |
|
1003 | mov edx, dword [edi+4] |
1561 | mov edx, dword [edi+4] |
1004 | lea ebx, [edx+8] |
1562 | lea ebx, [edx+8] |
1005 | add ebx, [msg_size] |
1563 | add ebx, [msg_size] |
Line -... | Line 1564... | ||
- | 1564 | cmp ebx, [buf_size] |
|
1006 | cmp ebx, [buf_size] |
1565 | ja .no_copy_data ;esi<0 - not enough memory in buffer |
1007 | ja .buffer_overflow ;esi<0 - not enough memory in buffer |
1566 | |
1008 | 1567 | mov [result], 0 |
|
1009 | mov dword [edi+4], ebx |
1568 | mov dword [edi+4], ebx |
1010 | mov eax, [TASK_BASE] |
1569 | mov eax, [TASK_BASE] |
Line 1017... | Line 1576... | ||
1017 | add edi, 8 |
1576 | add edi, 8 |
1018 | mov esi, [msg_addr] |
1577 | mov esi, [msg_addr] |
1019 | ; add esi, new_app_base |
1578 | ; add esi, new_app_base |
1020 | cld |
1579 | cld |
1021 | rep movsb |
1580 | rep movsb |
- | 1581 | .no_copy_data: |
|
- | 1582 | stdcall unmap_memEx, [used_buf], [dst_slot], [dst_ptr], [mapped_size], [ipc_ptab] |
|
Line 1022... | Line -... | ||
1022 | - | ||
1023 | mov ebx, [ipc_tmp] |
- | |
1024 | mov edx, ebx |
1583 | |
1025 | shr ebx, 12 |
- | |
1026 | xor eax, eax |
- | |
1027 | mov [page_tabs+ebx*4], eax |
- | |
1028 | invlpg [edx] |
- | |
1029 | - | ||
1030 | mov ebx, [ipc_pdir] |
- | |
1031 | mov edx, ebx |
- | |
1032 | shr ebx, 12 |
- | |
1033 | xor eax, eax |
- | |
1034 | mov [page_tabs+ebx*4], eax |
- | |
1035 | invlpg [edx] |
- | |
1036 | - | ||
1037 | mov ebx, [ipc_ptab] |
- | |
1038 | mov edx, ebx |
1584 | cmp [result], 0 |
1039 | shr ebx, 12 |
- | |
1040 | xor eax, eax |
- | |
1041 | mov [page_tabs+ebx*4], eax |
- | |
1042 | invlpg [edx] |
- | |
1043 | 1585 | jnz @f |
|
1044 | mov eax, [dst_slot] |
1586 | mov eax, [dst_slot] |
1045 | shl eax, BSF sizeof.APPDATA |
1587 | shl eax, BSF sizeof.APPDATA |
- | 1588 | or [eax+SLOT_BASE+APPDATA.occurred_events], EVENT_IPC |
|
- | 1589 | @@: |
|
- | 1590 | mov eax, [used_buf] |
|
1046 | or [eax+SLOT_BASE+APPDATA.occurred_events], EVENT_IPC |
1591 | cmp eax, [ipc_tmp] |
- | 1592 | je @f |
|
- | 1593 | stdcall free_kernel_space, eax |
|
- | 1594 | @@: |
|
- | 1595 | mov ecx, ipc_mutex |
|
1047 | push 0 |
1596 | call mutex_unlock |
- | 1597 | mov eax, [result] |
|
1048 | jmp .ret |
1598 | ret |
- | 1599 | .no_pid: |
|
1049 | .no_pid: |
1600 | mov ecx, ipc_mutex |
1050 | popf |
1601 | call mutex_unlock |
1051 | mov eax, 4 |
1602 | mov eax, 4 |
1052 | ret |
1603 | ret |
- | 1604 | .no_ipc_area: |
|
1053 | .no_ipc_area: |
1605 | mov ecx, ipc_mutex |
1054 | popf |
1606 | call mutex_unlock |
1055 | xor eax, eax |
1607 | xor eax, eax |
1056 | inc eax |
1608 | inc eax |
1057 | ret |
- | |
1058 | .ipc_blocked: |
- | |
1059 | push 2 |
- | |
1060 | jmp .ret |
- | |
1061 | .buffer_overflow: |
- | |
1062 | push 3 |
- | |
1063 | .ret: |
- | |
1064 | mov eax, [used_buf] |
- | |
1065 | cmp eax, [ipc_tmp] |
- | |
1066 | je @f |
- | |
1067 | stdcall free_kernel_space, eax |
- | |
1068 | @@: |
- | |
1069 | pop eax |
- | |
1070 | popf |
- | |
1071 | ret |
1609 | ret |
Line 1072... | Line 1610... | ||
1072 | endp |
1610 | endp |
1073 | 1611 | ||
1074 | align 4 |
1612 | align 4 |
Line 1101... | Line 1639... | ||
1101 | f68: |
1639 | f68: |
1102 | cmp ebx, 4 |
1640 | cmp ebx, 4 |
1103 | jbe sys_sheduler |
1641 | jbe sys_sheduler |
1104 | cmp ebx, 11 |
1642 | cmp ebx, 11 |
1105 | jb undefined_syscall |
1643 | jb undefined_syscall |
1106 | cmp ebx, 29 |
1644 | cmp ebx, 32 |
1107 | ja undefined_syscall |
1645 | ja undefined_syscall |
1108 | xor eax, eax |
1646 | xor eax, eax |
1109 | jmp dword [f68call+ebx*4-11*4] |
1647 | jmp dword [f68call+ebx*4-11*4] |
1110 | .11: |
1648 | .11: |
1111 | call init_heap |
1649 | call init_heap |
Line 1222... | Line 1760... | ||
1222 | 1760 | ||
1223 | .29: |
1761 | .29: |
1224 | stdcall user_ring, ecx |
1762 | stdcall user_ring, ecx |
1225 | mov [esp+SYSCALL_STACK._eax], eax |
1763 | mov [esp+SYSCALL_STACK._eax], eax |
- | 1764 | ret |
|
- | 1765 | .30: |
|
- | 1766 | cmp ecx, OS_BASE |
|
- | 1767 | jae .fail |
|
- | 1768 | stdcall load_file_maybe_pe, ecx |
|
- | 1769 | test esi, esi |
|
- | 1770 | jz .30.not_pe |
|
- | 1771 | stdcall map_pe_usermode, esi, eax, ebx |
|
- | 1772 | mov [esp+32], eax |
|
- | 1773 | ret |
|
- | 1774 | .30.resolve_fail: |
|
- | 1775 | movi eax, -5 |
|
- | 1776 | jmp .30.error |
|
- | 1777 | .30.not_pe: |
|
- | 1778 | cmp eax, -0x1000 |
|
- | 1779 | ja .30.error |
|
- | 1780 | stdcall kernel_free, eax |
|
- | 1781 | movi eax, -31 |
|
- | 1782 | .30.error: |
|
- | 1783 | mov [esp+32], eax |
|
- | 1784 | ret |
|
- | 1785 | ||
- | 1786 | .31: |
|
- | 1787 | stdcall unmap_pe_usermode, ecx |
|
- | 1788 | mov [esp+32], eax |
|
- | 1789 | ret |
|
- | 1790 | ||
- | 1791 | .32: |
|
- | 1792 | stdcall mprotect, edx, esi, ecx |
|
- | 1793 | mov [esp+32], eax |
|
Line 1226... | Line 1794... | ||
1226 | ret |
1794 | ret |
1227 | 1795 | ||
1228 | .fail: |
1796 | .fail: |
Line 1249... | Line 1817... | ||
1249 | dd f68.25 ; unmask exception |
1817 | dd f68.25 ; unmask exception |
1250 | dd f68.26 ; user_unmap |
1818 | dd f68.26 ; user_unmap |
1251 | dd f68.27 ; load_file_umode |
1819 | dd f68.27 ; load_file_umode |
1252 | dd f68.28 ; loadFileUnicode |
1820 | dd f68.28 ; loadFileUnicode |
1253 | dd f68.29 ; user_ring |
1821 | dd f68.29 ; user_ring |
- | 1822 | dd f68.30 ; map_pe_usermode |
|
- | 1823 | dd f68.31 ; unmap_pe_usermode |
|
- | 1824 | dd f68.32 ; mprotect |
|
Line 1254... | Line 1825... | ||
1254 | 1825 | ||
1255 | align 4 |
1826 | align 4 |
1256 | proc load_pe_driver stdcall, file:dword, cmdline:dword |
1827 | proc load_pe_driver stdcall, file:dword, cmdline:dword |