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

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      FEAPCHK.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. ;-----------------------------------------------------------------------
  24. ; Memory Block Header (far heap)
  25. ;-----------------------------------------------------------------------
  26. ; Each block in the heap, whether allocated or free, has a header.
  27. ; For an allocated block, only the first two fields of the header are
  28. ; used. For a free block all ten bytes are used.  Blocks are aligned on
  29. ; paragraph boundaries, thus the smallest possible block sixteen bytes.
  30. ;
  31. ; Field       Description
  32. ; ---------   ----------------------------------------------------------
  33. ; size        total size, in paragraphs, of this block
  34. ; prev_real   segment of the physically previous block in the heap
  35. ;          prev_real is 0 this block is free, get the prev_real from prev_real2
  36. ; prev_free   segment of the logically previous free block
  37. ; next_free   segment of the logically next free block
  38. ; prev_real2  segment of the physically previous block in the heap
  39. ; free_space  first byte of free space available
  40. ;
  41. ; A doubly-linked queue is maintained of the free blocks and it is important 
  42. ; to know that ordering of the blocks in this queue is logical rather than 
  43. ; physical.  If there is only one free block on the heap prev_free and 
  44. ; next_free point to itself.
  45. ;-----------------------------------------------------------------------
  46. bsize        EQU    0
  47. prev_real    EQU    2
  48. prev_free    EQU    4
  49. next_free    EQU    6
  50. prev_real2    EQU    8
  51. free_space    EQU    10
  52.  
  53. ;-----------------------------------------------------------------------
  54. ; heapinfo structure (far 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        dd    ?
  65. hi_size        dd    ?
  66. hi_inuse    dw    ?
  67.         ENDS
  68.  
  69. UsedHeaderSize    EQU    4
  70. FreeHeaderSize    EQU    10
  71.  
  72.         EXTRN    __brk:NEAR, __sbrk:NEAR
  73.  
  74. _TEXT           SEGMENT PUBLIC 'CODE'
  75.         ASSUME CS:_TEXT        
  76.  
  77. ;-----------------------------------------------------------------------
  78. ; Only three variables are needed to efficiently manage the heap.
  79. ; These reside in our own code segment for speed.
  80. ; We also set aside some scratch save areas.
  81. ;-----------------------------------------------------------------------
  82.                 EXTRN ___first:word        ;segment of the first block
  83.                 EXTRN ___last:word         ;segment of the last block
  84.                 EXTRN ___rover:word        ;segment of an arbitrary free block
  85.  
  86. ;-----------------------------------------------------------------------------
  87. ; C callable function which checks and verifies the heap.
  88. ; Walk through the physical heap and free block queue checking for
  89. ; bad links, adjacent free blocks, and sum the free block sizes both
  90. ; ways.  If the physical free block sum does not equal the free-block
  91. ; queue sum, there is an error.
  92. ;
  93. ; Args:                 void
  94. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  95. ;-----------------------------------------------------------------------------
  96. IF LDATA
  97.         PUBLIC    _heapcheck
  98. _heapcheck    LABEL    DIST
  99. ENDIF
  100.         PUBLIC    _farheapcheck 
  101. _farheapcheck   PROC    DIST
  102.                 push    si
  103.                 push    di
  104.                 push    bp
  105.                 push    ds
  106.  
  107.                 mov     ax,cs:[___first]
  108.         or    ax,ax
  109.         jnz    @@HeapNotEmpty
  110.         jmp    @@EmptyHeap
  111.  
  112. @@HeapNotEmpty:
  113.         xor    bx,bx
  114.         push    bx
  115.         push    bx
  116.         call    __sbrk             ;retrieve the break level
  117.         add    sp,4
  118.         or    ax,ax
  119.         jz    @@GoodOffset
  120.         jmp    @@HeapCorrupt
  121. @@GoodOffset:
  122.                 mov     bx,cs:[___last]
  123.         mov    ds,bx
  124.         add    bx,ds:[bsize]
  125.         cmp    bx,dx
  126.         je    @@CheckHeap
  127.         jmp    @@HeapCorrupt
  128. @@CheckHeap:
  129.                 mov     ax,cs:[___first]
  130.  
  131.         xor    cx,cx            ;cx = sum of physical free
  132.                 mov     dx,cx                   ;dx = sum of logical free
  133.  
  134.         mov    ds,ax            ;ds = first block in the heap
  135.         add    ax,WORD PTR ds:[bsize]
  136.         mov    es,ax            ;ax,es = next block in the heap
  137. @@SearchPhysicalLinks:
  138.         cmp    WORD PTR ds:[prev_real],0  ;is this block used?
  139.         jne    @@CheckPhysicalLinks       ;yep, skip this section
  140.         add    cx,ds:[bsize]
  141.         mov    si,ds            ;si = ds
  142.                 cmp     si,cs:[___last]         ;end-of-heap?
  143.         je    @@QueueCheck
  144.         cmp    WORD PTR es:[prev_real],0  ;is the next block free?
  145.         jnz    @@CheckPhysicalLinks
  146.         jmp    @@HeapCorrupt
  147. @@CheckPhysicalLinks:
  148.         mov    si,ds            ;si = ds
  149.         mov    di,es            ;di = es
  150.                 cmp     si,cs:[___last]         ;end-of-heap?
  151.         je    @@QueueCheck
  152.         cmp    si,di            ;check those links!
  153.         je    @@HeapCorrupt
  154.         cmp    WORD PTR ds:[bsize],0
  155.         je    @@HeapCorrupt
  156.                 cmp     di,cs:[___first]
  157.         jbe    @@HeapCorrupt
  158.                 cmp     di,cs:[___last]
  159.         ja    @@HeapCorrupt
  160.         cmp    WORD PTR es:[prev_real],0
  161.         je    @@NextBlockIsFree
  162. @@NextBlockIsUsed:
  163.         cmp    es:[prev_real],si
  164.         jmp    @@CheckPrevReal
  165. @@NextBlockIsFree:
  166.         cmp    es:[prev_real2],si
  167. @@CheckPrevReal:
  168.         jne    @@HeapCorrupt
  169.         mov    ds,di            ;ds = es
  170.         add    di,WORD PTR ds:[bsize]
  171.         mov    es,di            ;es = next block in the heap
  172.         jmp    SHORT @@SearchPhysicalLinks
  173.  
  174. @@QueueCheck:
  175.                 mov     ax,cs:[___rover]        ;ax = rover pointer
  176.         or    ax,ax
  177.         jz    @@EvaluateResults
  178.         mov    ds,ax            ;ds = free block
  179.         mov    si,ax            ;si = ds
  180. @@QueueLoop:
  181.         cmp    WORD PTR ds:[prev_real],0    ;this block should be free
  182.         jne    @@HeapCorrupt
  183.                 cmp     si,cs:[___first]
  184.         jb    @@HeapCorrupt
  185.                 cmp     si,cs:[___last]
  186.         jae    @@HeapCorrupt
  187.         add    dx,ds:[bsize]        ;dx += size of this block
  188.         mov    es,ds:[next_free]    ;es = next free block
  189.         mov    di,es            ;di = es
  190.         cmp    di,ax            ;done?
  191.         je    @@EvaluateResults
  192.         cmp    si,di            ;check those links?
  193.         je    @@HeapCorrupt
  194.         cmp    es:[prev_free],si
  195.         jne    @@HeapCorrupt
  196.         mov    si,es            ;ds = es
  197.         mov    ds,si
  198.         jmp    SHORT @@QueueLoop
  199.  
  200. @@HeapCorrupt:
  201.         mov    ax,_HEAPCORRUPT
  202.         jmp    SHORT @@AllDone
  203. @@EmptyHeap:
  204.         mov    ax,_HEAPEMPTY
  205.         jmp    SHORT @@AllDone
  206.         
  207. @@EvaluateResults:
  208.         cmp    cx,dx
  209.         jne    @@HeapCorrupt
  210. @@HeapOK:
  211.         mov    ax,_HEAPOK
  212. @@AllDone:
  213.                 pop     ds
  214.                 pop     bp
  215.                 pop     di
  216.                 pop     si
  217.         ret
  218.         ENDP
  219.  
  220. ;-----------------------------------------------------------------------------
  221. ; C callable function which checks and verifies a node on the heap.
  222. ;-----------------------------------------------------------------------------
  223. ; Args:                 node to check (stack)
  224. ; Returns:              _HEAPCORRUPT, _BADNODE, _FREEENTRY, or _USEDENTRY in ax
  225. ;-----------------------------------------------------------------------------
  226. IF LDATA
  227.         PUBLIC    _heapchecknode
  228. _heapchecknode    LABEL    DIST
  229. ENDIF
  230.         PUBLIC    _farheapchecknode
  231. _farheapchecknode    PROC DIST
  232.                 ARG     O:word, S:word
  233.  
  234.                 push    bp
  235.                 mov     bp,sp
  236.                 push    si
  237.                 push    di
  238.                 push    ds
  239.  
  240.         mov    ax,[S]          ;ax = segment to search for
  241.  
  242.                 mov     si,cs:[___first]        ;si = first block
  243.         or    si,si
  244.         jz    @@NotFound
  245.                 mov     di,cs:[___last]         ;di = last block
  246.         mov    bx,si            ;bx = first block
  247.  
  248. @@SearchPhysicalLinks:
  249.         mov    ds,bx
  250.         cmp    bx,ax            ;is this it?
  251.         je    @@Found
  252.         cmp    WORD PTR ds:[prev_real],0
  253.         je    @@BlockIsFree
  254. @@BlockIsUsed:
  255.         cmp    ds:[prev_real],si
  256.         jb    @@HeapCorrupt
  257.         jmp    SHORT @@Around
  258. @@BlockIsFree:
  259.         cmp    ds:[prev_real2],si
  260.         jb    @@HeapCorrupt
  261. @@Around:
  262.         mov    cx,bx
  263.         add    bx,ds:[bsize]
  264.         cmp    bx,cx
  265.         jne    @@SearchPhysicalLinks
  266. @@HeapCorrupt:
  267.         mov    ax,_HEAPCORRUPT
  268.         jmp    SHORT @@AllDone
  269. @@NotFound:
  270.         mov    ax,_BADNODE
  271.         jmp    SHORT @@AllDone
  272. @@Found:
  273.         cmp    WORD PTR ds:[prev_real],0
  274.         jnz    @@UsedEntry
  275. @@FreeEntry:
  276.         mov    ax,_FREEENTRY
  277.         jmp    SHORT @@AllDone
  278. @@UsedEntry:
  279.         mov    ax,_USEDENTRY
  280. @@AllDone:
  281.         pop    ds
  282.         pop    di
  283.         pop    si
  284.         pop    bp
  285.         ret
  286.         ENDP
  287.  
  288. ;-----------------------------------------------------------------------------
  289. ; C callable function which fills the free areas with a given value
  290. ;-----------------------------------------------------------------------------
  291. ; Args:                 unsigned int, fill value (stack)
  292. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  293. ;-----------------------------------------------------------------------------
  294. IF LDATA
  295.         PUBLIC    _heapfillfree
  296. _heapfillfree    LABEL    DIST
  297. ENDIF
  298.         PUBLIC    _farheapfillfree
  299. _farheapfillfree    PROC DIST
  300.                 ARG     fill:word
  301.  
  302.                 push    bp
  303.                 mov     bp,sp
  304.                 push    si
  305.                 push    di
  306.  
  307.                 cmp     cs:___first,0
  308.         jz    @@EmptyHeap
  309.  
  310.                 mov     bx,cs:___rover          ;bx = rover pointer
  311.         or    bx,bx
  312.                 jz      @@HeapOK
  313.  
  314.         cld
  315.         mov    ax,[fill]        ;ax = fill value
  316. @@QueueLoop:
  317.         mov    es,bx            ;es,bx = free block
  318.         mov    dx,es:[bsize]        ;dx = size of block (in para)
  319.         mov    si,es:[next_free]    ;si = next free block
  320.         mov    di,free_space
  321.         mov    cx,8 - (free_space/2)
  322. @@FillHerUp:
  323.         rep
  324.         stosw
  325.         xor    di,di
  326.         mov    cx,8
  327.         inc    bx
  328.         mov    es,bx
  329.         dec    dx
  330.         jnz    @@FillHerUp
  331. @@NextBlock:
  332.                 cmp     si,cs:[___rover]
  333.         je    @@HeapOK
  334.         or    si,si
  335.         jz    @@HeapCorrupt
  336.         mov    bx,si
  337.         jmp    SHORT @@QueueLoop
  338.  
  339. @@HeapCorrupt:
  340.         mov    ax,_HEAPCORRUPT
  341.         jmp    SHORT @@AllDone
  342. @@EmptyHeap:
  343.         mov    ax,_HEAPEMPTY
  344.         jmp    SHORT @@AllDone
  345. @@HeapOK:    
  346.         mov    ax,_HEAPOK
  347. @@AllDone:
  348.         pop    di
  349.         pop    si
  350.         pop    bp
  351.         ret
  352.         ENDP
  353.  
  354. ;-----------------------------------------------------------------------------
  355. ; C callable function which checks the free areas of the heap for a given value
  356. ;-----------------------------------------------------------------------------
  357. ; Args:                 unsigned int, fill value (stack)
  358. ; Returns:              _HEAPOK, _HEAPEMPTY, _BADVALUE, or _HEAPCORRUPT in ax
  359. ;-----------------------------------------------------------------------------
  360. IF LDATA
  361.         PUBLIC    _heapcheckfree
  362. _heapcheckfree    LABEL    DIST
  363. ENDIF
  364.         PUBLIC    _farheapcheckfree
  365. _farheapcheckfree    PROC DIST
  366.                 ARG     fill:word
  367.  
  368.                 push    bp
  369.                 mov     bp,sp
  370.                 push    si
  371.                 push    di
  372.  
  373.                 cmp     cs:___first,0
  374.         jz    @@EmptyHeap
  375.  
  376.                 mov     bx,cs:___rover          ;bx = rover pointer
  377.         or    bx,bx
  378.                 jz      @@HeapOK
  379.  
  380.         mov    ax,[fill]        ;ax = fill value
  381.         cld
  382. @@QueueLoop:
  383.         mov    es,bx            ;es,bx = free block
  384.         mov    dx,es:[bsize]        ;dx = size of block (in para)
  385.         mov    si,es:[next_free]    ;si = next free block
  386.         mov    di,free_space
  387.         mov    cx,8 - (free_space/2)
  388. @@CheckHerOut:
  389.         repe
  390.         scasw
  391.         jnz    @@BadValue
  392.         xor    di,di
  393.         mov    cx,8
  394.         inc    bx
  395.         mov    es,bx
  396.         dec    dx
  397.         jnz    @@CheckHerOut
  398. @@NextBlock:
  399.                 cmp     si,cs:[___rover]
  400.         je    @@HeapOK
  401.         or    si,si
  402.         jz    @@HeapCorrupt
  403.         mov    bx,si
  404.         jmp    SHORT @@QueueLoop
  405.  
  406. @@BadValue:
  407.         mov    ax,_BADVALUE
  408.         jmp    SHORT @@AllDone
  409. @@HeapCorrupt:
  410.         mov    ax,_HEAPCORRUPT
  411.         jmp    SHORT @@AllDone
  412. @@EmptyHeap:
  413.         mov    ax,_HEAPEMPTY
  414.         jmp    SHORT @@AllDone
  415. @@HeapOK:    
  416.         mov    ax,_HEAPOK
  417. @@AllDone:
  418.         pop    di
  419.         pop    si
  420.         pop    bp
  421.         ret
  422.         ENDP
  423.  
  424. ;-----------------------------------------------------------------------------
  425. ; C callable function to walk through the heap node by node
  426. ;-----------------------------------------------------------------------------
  427. ; Args:                 pointer to a heapinfo structure (stack)
  428. ; Returns:              _HEAPOK, _HEAPEMPTY, _HEAPEND in ax
  429. ;-----------------------------------------------------------------------------
  430. IF LDATA
  431.         PUBLIC    _heapwalk
  432. _heapwalk    LABEL    DIST
  433. ENDIF
  434.         PUBLIC    _farheapwalk
  435. _farheapwalk    PROC DIST
  436.                 ARG     O:word, S:word
  437.  
  438.                 push    bp
  439.                 mov     bp,sp
  440.                 push    si
  441.                 push    di
  442.  
  443.         mov    di,[O]          ;di = offset of struct
  444. IF LDATA
  445.                 push    ds
  446.                 mov     bx,[S]                  ;bx = segment of struct
  447.  
  448.         cmp    di,0FFF0h        ;psuedo-normalize it
  449.         jb    @@Normalized
  450.         inc    bx
  451.         sub    di,16d
  452. @@Normalized:
  453.         mov    ds,bx            ;ds:di = struct
  454. ENDIF
  455.         mov    bx,WORD PTR [di+hi_ptr+2]    ;bx = previous block
  456.         or    bx,bx
  457.         jz    @@FirstBlock
  458.                 cmp     bx,cs:[___last]         ;last block?
  459.         je    @@HeapEnd
  460.         or    bx,bx            ;first?
  461.         jne    @@InnerBlock
  462. @@FirstBlock:
  463.                 mov     bx,cs:[___first]
  464.         or    bx,bx
  465.         jz    @@HeapEmpty
  466.         mov    es,bx            ;es = first block
  467.         jmp    SHORT @@SaveInfo
  468. @@InnerBlock:
  469.         mov    es,bx            ;es = block
  470.         add    bx,es:[bsize]        ;bx = next block
  471.         mov    es,bx            ;es = next block
  472. @@SaveInfo:
  473.         mov    WORD PTR ds:[di+hi_ptr+2],es    ;save address
  474.         mov    WORD PTR ds:[di+hi_ptr],UsedHeaderSize
  475.         mov    ax,WORD PTR es:[bsize]        ;multiply size * 16
  476.         mov    bx,16d
  477.         mul    bx
  478.         mov    WORD PTR ds:[di+hi_size],ax    ;save it
  479.         mov    WORD PTR ds:[di+hi_size+2],dx
  480.         mov    WORD PTR ds:[di+hi_inuse],0    ;clear in-use flag
  481.         cmp    WORD PTR es:[prev_real], 0    ;is it free?
  482.         je    @@HeapOK
  483.                 inc     WORD PTR ds:[di+hi_inuse]      ;set in-use flag
  484. @@HeapOK:
  485.         mov    ax,_HEAPOK
  486.         jmp    SHORT @@AllDone
  487. @@HeapEmpty:
  488.         mov    ax,_HEAPEMPTY
  489.         jmp    SHORT @@AllDone
  490. @@HeapEnd:
  491.         mov    ax,_HEAPEND
  492. @@AllDone:
  493. IF LDATA
  494.         pop    ds
  495. ENDIF
  496.         pop    di
  497.         pop    si
  498.         pop    bp
  499.         ret
  500.         ENDP
  501.  
  502.                 ENDS
  503.         END
  504.