Subversion Repositories Kolibri OS

Rev

Rev 5195 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. format PE console 4.0
  2. entry start
  3.  
  4. include 'win32a.inc'
  5. include '../../struct.inc'
  6. include '../../proc32.inc'
  7. include 'fpo.inc'
  8.  
  9. FS_ERRNO equ dword [errno]
  10. ENOMEM = 12
  11. include 'malloc.inc'
  12.  
  13. start:
  14.         cinvoke fopen, logfile_name, logfile_mode
  15.         mov     [logfile], eax
  16.         mov     edx, 1 ;shl 25
  17.         malloc_init
  18.         call    run_test
  19.         set_default_heap
  20.         stdcall destroy_mspace, ebp
  21.         cinvoke fclose, [logfile]
  22.         ret
  23.  
  24. FS_SYSCALL_PTR:
  25.         cmp     eax, 68
  26.         jnz     unknown_syscall
  27.         cmp     ebx, 12
  28.         jz      syscall_malloc
  29.         cmp     ebx, 13
  30.         jz      syscall_free
  31.         cmp     ebx, 20
  32.         jz      syscall_realloc
  33.         cmp     ebx, 26
  34.         jz      syscall_trim
  35.  
  36. unknown_syscall:
  37.         int3
  38.         jmp     $
  39.  
  40. syscall_malloc:
  41.         push    ecx edx
  42.         invoke  VirtualAlloc, 0, ecx, MEM_COMMIT, PAGE_READWRITE
  43.         pop     edx ecx
  44.         ret
  45. syscall_free:
  46.         push    ecx edx
  47.         invoke  VirtualFree, ecx, 0, MEM_RELEASE
  48.         test    eax, eax
  49.         jz      @f
  50.         pop     edx ecx
  51.         ret
  52. @@:
  53.         int3
  54.         jmp     $
  55. syscall_realloc:
  56.         push    esi edi
  57.         push    ecx edx
  58.         mov     esi, edx
  59.         call    syscall_malloc
  60.         mov     edi, eax
  61.         sub     esp, 1Ch
  62.         mov     edx, esp
  63.         invoke  VirtualQuery, esi, edx, 1Ch
  64.         mov     ecx, [esp+0Ch]
  65.         add     esp, 1Ch
  66.         cmp     ecx, [esp+4]
  67.         jb      @f
  68.         mov     ecx, [esp+4]
  69. @@:
  70.         shr     ecx, 2
  71.         push    esi edi
  72.         rep movsd
  73.         pop     edi ecx
  74.         call    syscall_free
  75.         mov     eax, edi
  76.         pop     edx ecx
  77.         pop     edi esi
  78.         ret
  79. syscall_trim:
  80.         push    eax ecx edi
  81.         lea     edi, [ecx+edx]
  82.         mov     ecx, esi
  83.         shr     ecx, 2
  84.         xor     eax, eax
  85.         rep stosd
  86.         pop     edi ecx eax
  87.         ret
  88.  
  89. macro next_random
  90. {
  91.         imul    edi, 1103515245
  92.         add     edi, 12345
  93. }
  94.  
  95. macro call_and_check_regs what
  96. {
  97.         push    ebx edi
  98.         what
  99.         cmp     edi, [esp]
  100.         jnz     edi_destroyed
  101.         cmp     ebx, [esp+4]
  102.         jnz     ebx_destroyed
  103.         add     esp, 8
  104. }
  105.  
  106. get_malloc_size:
  107.         and     eax, 1023
  108.         jnz     @f
  109.         next_random
  110.         mov     eax, edi
  111.         shr     eax, 16
  112.         shl     eax, 8
  113. @@:
  114.         ret
  115.  
  116. get_and_validate_memory:
  117.         xor     edx, edx
  118.         div     esi
  119.         mov     eax, [esp+edx*8+4]
  120.         mov     ecx, [esp+edx*8+8]
  121.         push    edi eax
  122.         mov     edi, eax
  123.         mov     al, [edi]
  124.         repz scasb
  125.         jnz     memory_destroyed
  126.         pop     ecx edi
  127.         ret
  128.  
  129. run_test:
  130. ; 65536 times run random operation.
  131. ; Randomly select malloc(random size from 1 to 1023 or from 256 to 16M),
  132. ; free(random of previously allocated areas),
  133. ; realloc(random of previously allocated areas, random size from 1 to 1023 or from 256 to 16M),
  134. ; realloc_in_place(<same as realloc>),
  135. ; memalign(random size from 1 to 1023 or from 256 to 16M, random power of 2 from 8 to 1024)
  136.         mov     edi, 0x12345678
  137.         xor     esi, esi        ; 0 areas allocated
  138.         mov     ebx, 65536
  139. .loop:
  140. ;       call    validate_release_chain
  141.         next_random
  142.         mov     eax, edi
  143.         shr     eax, 16
  144.         mov     ecx, eax
  145.         shr     eax, 3
  146.         and     ecx, 7
  147.         jz      .memalign
  148.         dec     ecx
  149.         jz      .realloc_in_place
  150.         dec     ecx
  151.         jz      .realloc
  152.         test    ebx, 64
  153.         jz      .prefer_free
  154. .prefer_malloc:
  155.         dec     ecx
  156.         jz      .free
  157.         jmp     .malloc
  158. .prefer_free:
  159.         dec     ecx
  160.         jnz     .free
  161. .malloc:
  162.         call    get_malloc_size
  163.         jz      .loop
  164.         push    eax
  165.         call_and_check_regs <stdcall malloc,eax>
  166.         pop     ecx
  167.         pushad
  168.         cinvoke fprintf, [logfile], malloc_str, ecx, eax
  169.         popad
  170.         test    eax, eax
  171.         jz      generic_malloc_failure
  172.         inc     esi
  173.         push    ecx eax
  174.         push    edi
  175.         mov     edi, eax
  176.         mov     eax, esi
  177.         rep stosb
  178.         pop     edi
  179.         jmp     .common
  180. .free:
  181.         test    esi, esi
  182.         jz      .loop
  183.         call    get_and_validate_memory
  184.         push    edx
  185.         pushad
  186.         cinvoke fprintf, [logfile], free_str, ecx
  187.         popad
  188.         call_and_check_regs <stdcall free,ecx>
  189. ;        call   validate_release_chain
  190.         pop     edx
  191.         dec     esi
  192.         pop     eax ecx
  193.         push    edi
  194.         lea     edi, [esp+4]
  195. @@:
  196.         dec     edx
  197.         js      @f
  198.         xchg    eax, [edi]
  199.         xchg    ecx, [edi+4]
  200.         add     edi, 8
  201.         jmp     @b
  202. @@:
  203.         pop     edi
  204.         jmp     .common
  205. .realloc:
  206.         test    esi, esi
  207.         jz      .loop
  208.         call    get_and_validate_memory
  209.         push    eax
  210.         next_random
  211.         mov     eax, edi
  212.         shr     eax, 16
  213.         call    get_malloc_size
  214.         jnz     @f
  215.         pop     eax
  216.         jmp     .loop
  217. @@:
  218.         push    eax edx
  219.         pushad
  220.         cinvoke fprintf, [logfile], realloc_str1, ecx, eax
  221.         popad
  222.         call_and_check_regs <stdcall realloc,ecx,eax>
  223.         pop     edx ecx
  224.         pushad
  225.         cinvoke fprintf, [logfile], realloc_str2, eax
  226.         popad
  227.         test    eax, eax
  228.         jz      generic_malloc_failure
  229.         push    ebx edi ecx
  230.         mov     ebx, [esp+edx*8+20]
  231.         mov     [esp+edx*8+16], eax
  232.         mov     [esp+edx*8+20], ecx
  233.         cmp     ebx, ecx
  234.         jae     @f
  235.         mov     ecx, ebx
  236. @@:
  237.         mov     edi, eax
  238.         mov     eax, [esp+12]
  239.         repz scasb
  240.         jnz     memory_destroyed
  241.         pop     ecx
  242.         sub     ecx, ebx
  243.         jbe     @f
  244.         rep stosb
  245. @@:
  246.         pop     edi ebx eax
  247.         jmp     .common
  248. .realloc_in_place:
  249.         test    esi, esi
  250.         jz      .loop
  251.         call    get_and_validate_memory
  252.         push    eax
  253.         next_random
  254.         mov     eax, edi
  255.         shr     eax, 16
  256.         call    get_malloc_size
  257.         jnz     @f
  258.         pop     eax
  259.         jmp     .loop
  260. @@:
  261.         push    eax edx
  262.         pushad
  263.         cinvoke fprintf, [logfile], realloc_in_place_str1, ecx, eax
  264.         popad
  265.         call_and_check_regs <stdcall realloc_in_place,ecx,eax>
  266.         pushad
  267.         cinvoke fprintf, [logfile], realloc_in_place_str2, eax
  268.         popad
  269.         pop     edx ecx
  270.         test    eax, eax
  271.         jnz     @f
  272.         pop     eax
  273.         jmp     .common
  274. @@:
  275.         cmp     [esp+edx*8+4], eax
  276.         jnz     generic_malloc_failure
  277.         push    ebx edi ecx
  278.         mov     ebx, [esp+edx*8+20]
  279.         mov     [esp+edx*8+20], ecx
  280.         cmp     ebx, ecx
  281.         jae     @f
  282.         mov     ecx, ebx
  283. @@:
  284.         mov     edi, eax
  285.         mov     eax, [esp+12]
  286.         repz scasb
  287.         jnz     memory_destroyed
  288.         pop     ecx
  289.         sub     ecx, ebx
  290.         jbe     @f
  291.         rep stosb
  292. @@:
  293.         pop     edi ebx eax
  294.         jmp     .common
  295. .memalign:
  296.         call    get_malloc_size
  297.         jz      .loop
  298.         next_random
  299.         mov     ecx, edi
  300.         shr     ecx, 29
  301.         mov     edx, 8
  302.         shl     edx, cl
  303.         push    eax edx
  304.         pushad
  305.         cinvoke fprintf, [logfile], memalign_str1, edx, eax
  306.         popad
  307.         call_and_check_regs <stdcall memalign, edx, eax>
  308.         pushad
  309.         cinvoke fprintf, [logfile], memalign_str2, eax
  310.         popad
  311.         dec     dword [esp]
  312.         test    eax, [esp]
  313.         jnz     memalign_invalid
  314.         add     esp, 4
  315.         pop     ecx
  316.         test    eax, eax
  317.         jz      generic_malloc_failure
  318.         inc     esi
  319.         push    ecx eax
  320.         push    edi
  321.         mov     edi, eax
  322.         mov     eax, esi
  323.         rep stosb
  324.         pop     edi
  325. .common:
  326.         cinvoke fflush, [logfile]
  327.         dec     ebx
  328.         jnz     .loop
  329. @@:
  330.         dec     esi
  331.         js      @f
  332.         pop     eax ecx
  333.         stdcall free, eax
  334.         jmp     @b
  335. @@:
  336.         ret
  337.  
  338. generic_malloc_failure:
  339.         mov     eax, 1
  340.         int3
  341.         jmp     $
  342.  
  343. memory_destroyed:
  344.         mov     eax, 2
  345.         int3
  346.         jmp     $
  347.  
  348. edi_destroyed:
  349.         mov     eax, 3
  350.         int3
  351.         jmp     $
  352.  
  353. ebx_destroyed:
  354.         mov     eax, 4
  355.         int3
  356.         jmp     $
  357.  
  358. memalign_invalid:
  359.         mov     eax, 5
  360.         int3
  361.         jmp     $
  362.  
  363. validate_release_chain:
  364.         push    ebx ebp
  365.         set_default_heap
  366.         lea     ecx, [ebp+malloc_state.release_list-tchunk_release_fd]
  367.         mov     eax, ecx
  368.         mov     edx, [ecx+tchunk_release_fd]
  369. @@:
  370.         cmp     [edx+tchunk_release_bk], eax
  371.         jnz     .fail
  372.         cmp     edx, ecx
  373.         jz      @f
  374.         mov     eax, edx
  375.         mov     edx, [edx+tchunk_release_fd]
  376.         jmp     @b
  377. @@:
  378.         lea     eax, [ebp-3]
  379.         add     eax, [ebp-4]
  380.         cmp     eax, [ebp+malloc_state.top]
  381.         jz      .ok
  382. .chunk_loop:
  383.         mov     ecx, [eax-4]
  384.         test    ecx, CINUSE_BIT
  385.         jnz     .next_chunk
  386.         cmp     ecx, 0x100
  387.         jb      .next_chunk
  388.         mov     edx, ecx
  389.         and     edx, not FLAG_BITS
  390.         lea     edx, [eax+edx]
  391.         cmp     [edx+tchunk_release_fd], edx
  392.         jnz     @f
  393.         cmp     [edx+tchunk_release_bk], edx
  394.         jnz     .fail
  395.         jmp     .next_chunk
  396. @@:
  397.         mov     ebx, [ebp+malloc_state.release_list]
  398. @@:
  399.         cmp     edx, ebx
  400.         jz      .next_chunk
  401.         mov     ebx, [ebx+tchunk_release_fd]
  402.         cmp     ebx, [ebp+malloc_state.release_list]
  403.         jnz     @b
  404.         jmp     .fail
  405. .next_chunk:
  406.         and     ecx, not FLAG_BITS
  407.         add     eax, ecx
  408.         cmp     eax, [ebp+malloc_state.top]
  409.         jb      .chunk_loop
  410.         ja      .fail
  411. .ok:
  412.         pop     ebp ebx
  413.         ret
  414. .fail:
  415.         int3
  416.         jmp     $
  417.  
  418. align 4
  419. data import
  420. library kernel32,'kernel32.dll',msvcrt,'msvcrt.dll'
  421. import kernel32,\
  422.         VirtualAlloc, 'VirtualAlloc', \
  423.         VirtualFree, 'VirtualFree', \
  424.         VirtualQuery, 'VirtualQuery'
  425. import msvcrt,\
  426.         fopen,'fopen',\
  427.         fclose,'fclose',\
  428.         fprintf,'fprintf',\
  429.         fflush,'fflush'
  430. end data
  431.  
  432. malloc_str      db      'malloc(0x%X) = 0x%X',10,0
  433. free_str        db      'free(0x%X)',10,0
  434. realloc_str1    db      'realloc(0x%X,0x%X)',0
  435. realloc_str2    db      ' = 0x%X',10,0
  436. realloc_in_place_str1   db      'realloc_in_place(0x%X,0x%X)',0
  437. realloc_in_place_str2   db      ' = 0x%X',10,0
  438. memalign_str1   db      'memalign(0x%X,0x%X)',0
  439. memalign_str2   db      ' = 0x%X',10,0
  440.  
  441. logfile_name    db      'test.log',0
  442. logfile_mode    db      'w',0
  443.  
  444. align 4
  445. logfile dd      ?
  446. errno   dd      ?
  447. default_heap    dd      ?
  448. process_data    rd      1024
  449.