home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / NHEAPCHK.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-07  |  12.0 KB  |  413 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      NHEAPCHK.ASM                                                 |
  3. ;|                                                                   |
  4. ;|      Turbo-C Run Time Library        Version 3.0                  |
  5. ;|                                                                   |
  6. ;|      Copyright (c) 1987,1988,1990 by Borland International Inc.   |
  7. ;|      All Rights Reserved.                                         |
  8. ;[]-----------------------------------------------------------------[]
  9.  
  10.     INCLUDE    RULES.ASI
  11.  
  12.     LOCALS
  13.     INCLUDE    _HEAP.INC
  14.  
  15. IF LPROG
  16.   EXTRADISP    equ    2         ; Allow for FAR returns when getting parms
  17.   DIST        equ    FAR
  18. ELSE
  19.   EXTRADISP     equ    0
  20.   DIST        equ    NEAR
  21. ENDIF
  22.  
  23. IF LDATA EQ false
  24.  
  25. ;-----------------------------------------------------------------------
  26. ; Memory Block Header (near heap)
  27. ;-----------------------------------------------------------------------
  28. ; Each block in the heap, whether allocated or free, has a header.
  29. ; For an allocated block, only the first two fields of the header are
  30. ; used. For a free block all eight bytes are used, thus the smallest 
  31. ; possible block is the size of a free header.
  32. ;
  33. ; Field       Description
  34. ; ---------   ----------------------------------------------------------
  35. ; size        total size, in bytes, of this block (+1 if the block is in use)
  36. ; prev_real   pointer to the physically previous block in the heap
  37. ; prev_free   pointer to the logically previous free block
  38. ; next_free   pointer to the logically next free block
  39. ;
  40. ; Note that the size field is also used to indicate whether the block
  41. ; is allocated or free.  A doubly-linked queue is maintained of the
  42. ; free blocks and it is important to know that ordering of the blocks
  43. ; in this queue is logical rather than physical.  If there is only one
  44. ; free block on the heap prev_free and next_free point to itself.
  45. ;-----------------------------------------------------------------------
  46. Header        STRUC
  47. bsize        dw    ?  
  48. prev_real    dw    ?
  49. prev_free    dw    ?
  50. next_free    dw    ?
  51.         ENDS
  52.  
  53. ;-----------------------------------------------------------------------
  54. ; heapinfo structure (near heap)
  55. ;-----------------------------------------------------------------------
  56. ; Used by the heapwalk function.
  57. ; heapwalk accepts a pointer to a struct of this type.
  58. ; On entry, the pointer field contains the address of the previous
  59. ; memory block in the heap (NULL for the first call).  The next block
  60. ; in the heap is then found and its address is stored in the structure 
  61. ; along with its size, in bytes, and a 'used' flag.
  62. ;-----------------------------------------------------------------------
  63. HeapInfo    STRUC
  64. hi_ptr        dw    ?
  65. hi_size        dw    ?
  66. hi_inuse    dw    ?
  67.         ENDS
  68.  
  69. UsedHeaderSize    EQU    4
  70. FreeHeaderSize    EQU    8
  71.  
  72. ;-----------------------------------------------------------------------
  73. ; Only three variables are needed to efficiently manage the heap.
  74. ;-----------------------------------------------------------------------
  75.                 EXTRN __first:word        ;pointer to the first block
  76.                 EXTRN __last:word         ;pointer to the last block
  77.                 EXTRN __rover:word        ;pointer to an arbitrary free block
  78.  
  79.  
  80. _TEXT           SEGMENT PUBLIC 'CODE'
  81.         ASSUME CS:_TEXT        
  82.  
  83. ;-----------------------------------------------------------------------------
  84. ; C callable function which checks and verifies the heap.
  85. ; Walk through the physical heap and free block queue checking for
  86. ; bad links, adjacent free blocks, and sum the free block sizes both
  87. ; ways.  If the physical free block sum does not equal the free-block
  88. ; queue sum, there is an error.
  89. ;
  90. ; Args:                 void
  91. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  92. ;-----------------------------------------------------------------------------
  93.         PUBLIC    _heapcheck
  94. _heapcheck    PROC DIST
  95.         push    si
  96.         push    di
  97.         push    bx
  98.         push    cx
  99.         push    dx
  100.  
  101.                 mov     bx,__first              ;bx = first block in heap
  102.         or    bx,bx            ;is it NULL?
  103.         jz    @@EmptyHeap
  104.         mov    si,[bx.bsize]        ;si = next block after bx
  105.         and    si,0fffeh
  106.         add    si,bx
  107.  
  108.         xor    cx,cx            ;cx = size sum of physical free blocks
  109.                 mov     dx,cx                   ;dx = size sum of free block queue
  110. @@SearchPhysicalLinks:
  111.         test    BYTE PTR [bx.bsize],01h    ;is this block used?
  112.         jnz    @@CheckPhysicalLinks
  113.         add    cx,[bx.bsize]        ;cx += size of this free block
  114.                 cmp     bx,[__last]             ;at the end of the heap?
  115.         je    @@QueueCheck
  116.         test    BYTE PTR [si.bsize],01h    ;this block should be used
  117.         jz    @@HeapCorrupt        ;Oh nooooo, Mr. Bill!
  118. @@CheckPhysicalLinks:
  119.                 cmp     bx,[__last]             ;at the end of the heap?
  120.         je    @@QueueCheck
  121.         cmp    si,bx                  ;check those links!
  122.         jbe    @@HeapCorrupt
  123.         cmp    [bx.bsize],FreeHeaderSize
  124.         jb    @@HeapCorrupt
  125.                 cmp     si,[__first]
  126.         jbe    @@HeapCorrupt
  127.                 cmp     si,[__last]
  128.         ja    @@HeapCorrupt
  129.         cmp    [si.prev_real],bx
  130.         jne    @@HeapCorrupt
  131.         mov    bx,si            ;bx = next block in heap
  132.         mov    si,[bx.bsize]        ;si = next block after bx
  133.         and    si,0fffeh
  134.         add    si,bx
  135.         jmp    SHORT @@SearchPhysicalLinks
  136. @@QueueCheck:
  137.                 mov     bx,[__rover]
  138.         or    bx,bx
  139.         jz    @@EvaluateResults
  140. @@QueueLoop:
  141.         mov    ax,[bx.bsize]        ;this block should be free
  142.         test    al,01h            ;well, is it?
  143.         jnz    @@HeapCorrupt        ;Oh nooooo, Mr. Bill!
  144.         add    dx,ax            ;dx += size of this block
  145.                 cmp     bx,[__first]
  146.         jb    @@HeapCorrupt
  147.                 cmp     bx,[__last]
  148.         jae    @@HeapCorrupt
  149.         mov    si,[bx.next_free]    ;si = the next free block
  150.                 cmp     si,[__rover]            ;done?
  151.         je    @@EvaluateResults
  152.         cmp    si,bx              ;check those links!
  153.         je    @@HeapCorrupt
  154.         mov    bx,si
  155.         jmp    SHORT @@QueueLoop
  156. @@EmptyHeap:    
  157.         mov    ax,_HEAPEMPTY
  158.         jmp    SHORT @@AllDone
  159.  
  160. @@EvaluateResults:
  161.         cmp    dx,cx
  162.         jne    @@HeapCorrupt
  163. @@HeapOK:
  164.         mov    ax,_HEAPOK
  165.         jmp    SHORT @@AllDone
  166. @@HeapCorrupt:
  167.         mov    ax,_HEAPCORRUPT
  168. @@AllDone:
  169.         pop    dx
  170.         pop    cx
  171.         pop    bx
  172.         pop    di
  173.         pop    si
  174.         ret
  175.         ENDP
  176.  
  177. ;-----------------------------------------------------------------------------
  178. ; C callable function which checks and verifies a node on the heap.
  179. ;-----------------------------------------------------------------------------
  180. ; Args:                 node to check (stack)
  181. ; Returns:              _HEAPCORRUPT, _BADNODE, _FREEENTRY, or _USEDENTRY in ax
  182. ;-----------------------------------------------------------------------------
  183.         PUBLIC    _heapchecknode
  184. _heapchecknode    PROC DIST
  185.         push    si
  186.         push    di
  187.         push    bp
  188.  
  189.         mov    bp,sp
  190.  
  191.         mov    ax,[bp+8+EXTRADISP]    ;ax = node to find
  192.         sub    ax,UsedHeaderSize
  193.  
  194.                 mov     bx,[__first]            ;bx = first block in heap
  195.         or    bx,bx            ;is it NULL?
  196.         jz    @@NotFound
  197.         mov    si,[bx.bsize]        ;si = next block after bx
  198.         and    si,0fffeh
  199.         add    si,bx
  200.  
  201. @@SearchPhysicalLinks:
  202.         cmp    bx,ax
  203.         je    @@Found
  204.         test    BYTE PTR [bx.bsize],01h    ;is this block used?
  205.         jnz    @@CheckPhysicalLinks
  206.                 cmp     bx,[__last]             ;at the end of the heap?
  207.         je    @@NotFound
  208.         test    BYTE PTR [si.bsize],01h    ;this block should be used
  209.         jz    @@HeapCorrupt        ;Oh nooooo, Mr. Bill!
  210. @@CheckPhysicalLinks:
  211.                 cmp     bx,[__last]             ;at the end of the heap?
  212.         je    @@NotFound
  213.         cmp    si,bx                  ;check those links!
  214.         jbe    @@HeapCorrupt
  215.         cmp    [bx.bsize],FreeHeaderSize
  216.         jb    @@HeapCorrupt
  217.                 cmp     si,[__first]
  218.         jbe    @@HeapCorrupt
  219.                 cmp     si,[__last]
  220.         ja    @@HeapCorrupt
  221.         cmp    si,bx
  222.         jbe    @@HeapCorrupt
  223.         cmp    [si.prev_real],bx
  224.         jne    @@HeapCorrupt
  225.         mov    bx,si            ;bx = next block in heap
  226.         mov    si,[bx.bsize]        ;si = next block after bx
  227.         and    si,0fffeh
  228.         add    si,bx
  229.         jmp    SHORT @@SearchPhysicalLinks
  230. @@HeapCorrupt:
  231.         mov    ax,_HEAPCORRUPT
  232.         jmp    SHORT @@AllDone
  233. @@NotFound:    
  234.         mov    ax,_BADNODE
  235.         jmp    SHORT @@AllDone
  236. @@Found:    
  237.         test    BYTE PTR [bx.bsize],01
  238.         jnz    @@UsedEntry
  239. @@FreeEntry:
  240.         mov    ax,_FREEENTRY
  241.         jmp    SHORT @@AllDone
  242. @@UsedEntry:
  243.         mov    ax,_USEDENTRY
  244. @@AllDone:
  245.         pop    bp
  246.         pop    di
  247.         pop    si
  248.         ret
  249.         ENDP
  250.  
  251. ;-----------------------------------------------------------------------------
  252. ; C callable function which fills the free areas with a given value
  253. ;-----------------------------------------------------------------------------
  254. ; Args:                 unsigned int, fill value (stack)
  255. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  256. ;-----------------------------------------------------------------------------
  257.         PUBLIC    _heapfillfree
  258. _heapfillfree    PROC DIST
  259.         push    bp
  260.         mov    bp,sp
  261.         mov    ax,[bp+4+EXTRADISP]
  262.  
  263.         push    si
  264.         push    di
  265.  
  266.                 cmp     __first,0
  267.                 je      @@EmptyHeap
  268.  
  269.                 mov     bx,__rover
  270.         or    bx,bx
  271.                 jz      @@HeapOK
  272.         cld
  273. @@QueueLoop:
  274.         mov    cx,[bx.bsize]
  275.         sub    cx,FreeHeaderSize
  276.         shr    cx,1
  277.         lea    di,[bx+8]
  278.         rep
  279.         stosw
  280.         mov    cx,[bx.next_free]    ;cx = next free block
  281.                 cmp     cx,[__rover]            ;done?
  282.         je    @@HeapOK
  283.         cmp    bx,cx            ;check links
  284.         je    @@HeapCorrupt
  285.         or    cx,cx
  286.         jz    @@HeapCorrupt
  287.         mov    bx,cx            ;get the next free block
  288.         jmp    SHORT @@QueueLoop
  289. @@HeapOK:
  290.         mov    ax,_HEAPOK
  291.         jmp    SHORT @@AllDone
  292. @@EmptyHeap:    
  293.         mov    ax,_HEAPEMPTY
  294.         jmp    SHORT @@AllDone
  295. @@HeapCorrupt:
  296.         mov    ax,_HEAPCORRUPT
  297. @@AllDone:
  298.         pop    di
  299.         pop    si
  300.         pop    bp
  301.         ret
  302.         ENDP
  303.  
  304. ;-----------------------------------------------------------------------------
  305. ; C callable function which checks the free areas of the heap for a given value
  306. ;-----------------------------------------------------------------------------
  307. ; Args:                 unsigned int, fill value (stack)
  308. ; Returns:              _HEAPOK, _HEAPEMPTY, _BADVALUE, or _HEAPCORRUPT in ax
  309. ;-----------------------------------------------------------------------------
  310.         PUBLIC    _heapcheckfree
  311. _heapcheckfree    PROC DIST
  312.         push    bp
  313.         mov    bp,sp
  314.         mov    ax,[bp+4+EXTRADISP]
  315.  
  316.         push    si
  317.         push    di
  318.  
  319.                 cmp     __first,0
  320.                 je      @@EmptyHeap
  321.  
  322.                 mov     bx,__rover
  323.         or    bx,bx
  324.                 jz      @@HeapOK
  325.         cld
  326. @@QueueLoop:
  327.         mov    cx,[bx.bsize]
  328.         sub    cx,FreeHeaderSize
  329.         shr    cx,1
  330.         lea    di,[bx+8]
  331.         repe
  332.         scasw
  333.         jnz    @@BadValue
  334.         mov    cx,[bx.next_free]    ;cx = next free block
  335.                 cmp     cx,[__rover]            ;done?
  336.         je    @@HeapOK
  337.         cmp    bx,cx            ;check links
  338.         je    @@HeapCorrupt
  339.         or    cx,cx
  340.         jz    @@HeapCorrupt
  341.         mov    bx,cx            ;get the next free block
  342.         jmp    SHORT @@QueueLoop
  343. @@HeapOK:
  344.         mov    ax,_HEAPOK
  345.         jmp    SHORT @@AllDone
  346. @@EmptyHeap:    
  347.         mov    ax,_HEAPEMPTY
  348.         jmp    SHORT @@AllDone
  349. @@BadValue:
  350.         mov    ax,_BADVALUE
  351. @@HeapCorrupt:
  352.         mov    ax,_HEAPCORRUPT
  353. @@AllDone:
  354.         pop    di
  355.         pop    si
  356.         pop    bp
  357.         ret
  358.         ENDP
  359.  
  360. ;-----------------------------------------------------------------------------
  361. ; C callable function to walk through the heap node by node
  362. ;-----------------------------------------------------------------------------
  363. ; Args:                 pointer to a heapinfo structure (stack)
  364. ; Returns:              _HEAPOK, _HEAPEMPTY, _HEAPEND in ax
  365. ;-----------------------------------------------------------------------------
  366.         PUBLIC    _heapwalk
  367. _heapwalk    PROC DIST
  368.         push    bp
  369.         push    si
  370.  
  371.         mov    bp,sp
  372.         mov    bx,[bp+6+EXTRADISP]        ;bx = address of heapinfo struct
  373.         mov    si,[bx.hi_ptr]        ;si = previous block
  374.         or    si,si            ;si == NULL?
  375.         je    @@FirstBlock
  376.         sub    si,UsedHeaderSize
  377.                 cmp     si,[__last]             ;last block?
  378.         je    @@HeapEnd
  379. @@InnerBlock:
  380.         add    si,[si.bsize]        ;si = next block
  381.         and    si,0fffeh        ;strip 'used' bit
  382.         jmp    SHORT @@SaveInfo
  383. @@FirstBlock:
  384.                 mov     si,[__first]
  385.         or    si,si
  386.         jz    @@HeapEmpty
  387. @@SaveInfo:
  388.         mov    [bx.hi_ptr],si
  389.         add    [bx.hi_ptr],UsedHeaderSize
  390.         mov    ax,[si.bsize]
  391.         and    ax,0fffeh        ;strip 'used' bit
  392.         mov    [bx.hi_size],ax
  393.         mov    ax,[si.bsize]
  394.         and    ax,0001h        ;retrieve 'used' bit
  395.         mov    [bx.hi_inuse],ax
  396. @@HeapOK:
  397.         mov    ax,_HEAPOK
  398.         jmp    SHORT @@AllDone
  399. @@HeapEmpty:
  400.         mov    ax,_HEAPEMPTY
  401.         jmp    SHORT @@AllDone
  402. @@HeapEnd:
  403.         mov    ax,_HEAPEND
  404. @@AllDone:
  405.         pop    si
  406.         pop    bp
  407.         ret
  408.         ENDP
  409.         ENDS
  410. ENDIF
  411.         END
  412.  
  413.