home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / FHEAPCHK.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-10  |  19.0 KB  |  516 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      FEAPCHK.ASM                                                  |
  3. ;[]-----------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 5.0
  7. ;       Copyright (c) 1987, 1992 by Borland International
  8. ;       All Rights Reserved.
  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.                 call    _farheapcheck           ;make sure heap is OK first
  241.                 cmp     ax, _HEAPOK
  242.                 jne     @@AllDone
  243.  
  244.                 mov     ax,[S]                  ;ax = segment to search for
  245.  
  246.                 mov     si,cs:[___first]        ;si = first block
  247.                 mov     di,cs:[___last]         ;di = last block
  248.                 mov     bx,si                   ;bx = first block
  249.  
  250. @@SearchPhysicalLinks:
  251.                 mov     ds,bx
  252.                 cmp     bx,ax                   ;is this it?
  253.                 je      @@Found
  254.                 cmp     WORD PTR ds:[prev_real],0
  255.                 je      @@BlockIsFree
  256. @@BlockIsUsed:
  257.                 cmp     ds:[prev_real],si
  258.                 jb      @@HeapCorrupt
  259.                 jmp     SHORT @@Around
  260. @@BlockIsFree:
  261.                 cmp     ds:[prev_real2],si
  262.                 jb      @@HeapCorrupt
  263. @@Around:
  264.                 cmp     bx,di
  265.                 je      @@NotFound
  266.                 ja      @@HeapCorrupt
  267.                 mov     cx,bx
  268.                 add     bx,ds:[bsize]
  269.                 cmp     bx,cx
  270.                 jne     @@SearchPhysicalLinks
  271. @@HeapCorrupt:
  272.                 mov     ax,_HEAPCORRUPT
  273.                 jmp     SHORT @@AllDone
  274. @@EmptyHeap:
  275.                 mov     ax,_HEAPEMPTY
  276.                 jmp     SHORT @@AllDone
  277. @@NotFound:
  278.                 mov     ax,_BADNODE
  279.                 jmp     SHORT @@AllDone
  280. @@Found:
  281.                 cmp     WORD PTR ds:[prev_real],0
  282.                 jnz     @@UsedEntry
  283. @@FreeEntry:
  284.                 mov     ax,_FREEENTRY
  285.                 jmp     SHORT @@AllDone
  286. @@UsedEntry:
  287.                 mov     ax,_USEDENTRY
  288. @@AllDone:
  289.                 pop     ds
  290.                 pop     di
  291.                 pop     si
  292.                 pop     bp
  293.                 ret
  294.                 ENDP
  295.  
  296. ;-----------------------------------------------------------------------------
  297. ; C callable function which fills the free areas with a given value
  298. ;-----------------------------------------------------------------------------
  299. ; Args:                 unsigned int, fill value (stack)
  300. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  301. ;-----------------------------------------------------------------------------
  302. IF LDATA
  303.                 PUBLIC  _heapfillfree
  304. _heapfillfree   LABEL   DIST
  305. ENDIF
  306.                 PUBLIC  _farheapfillfree
  307. _farheapfillfree        PROC DIST
  308.                 ARG     fill:word
  309.  
  310.                 push    bp
  311.                 mov     bp,sp
  312.                 push    si
  313.                 push    di
  314.  
  315.                 call    _farheapcheck           ;make sure heap is OK first
  316.                 cmp     ax, _HEAPOK
  317.                 jne     @@AllDone
  318.  
  319.                 mov     bx,cs:___rover          ;bx = rover pointer
  320.                 or      bx,bx
  321.                 jz      @@HeapOK
  322.  
  323.                 cld
  324.                 mov     ax,[fill]               ;ax = fill value
  325. @@QueueLoop:
  326.                 mov     es,bx                   ;es,bx = free block
  327.                 mov     dx,es:[bsize]           ;dx = size of block (in para)
  328.                 mov     si,es:[next_free]       ;si = next free block
  329.                 mov     di,free_space
  330.                 mov     cx,8 - (free_space/2)
  331. @@FillHerUp:
  332.                 rep
  333.                 stosw
  334.                 xor     di,di
  335.                 mov     cx,8
  336.                 inc     bx
  337.                 mov     es,bx
  338.                 dec     dx
  339.                 jnz     @@FillHerUp
  340. @@NextBlock:
  341.                 cmp     si,cs:[___rover]
  342.                 je      @@HeapOK
  343.                 or      si,si
  344.                 jz      @@HeapCorrupt
  345.                 mov     bx,si
  346.                 jmp     SHORT @@QueueLoop
  347.  
  348. @@HeapCorrupt:
  349.                 mov     ax,_HEAPCORRUPT
  350.                 jmp     SHORT @@AllDone
  351. @@EmptyHeap:
  352.                 mov     ax,_HEAPEMPTY
  353.                 jmp     SHORT @@AllDone
  354. @@HeapOK:
  355.                 mov     ax,_HEAPOK
  356. @@AllDone:
  357.                 pop     di
  358.                 pop     si
  359.                 pop     bp
  360.                 ret
  361.                 ENDP
  362.  
  363. ;-----------------------------------------------------------------------------
  364. ; C callable function which checks the free areas of the heap for a given value
  365. ;-----------------------------------------------------------------------------
  366. ; Args:                 unsigned int, fill value (stack)
  367. ; Returns:              _HEAPOK, _HEAPEMPTY, _BADVALUE, or _HEAPCORRUPT in ax
  368. ;-----------------------------------------------------------------------------
  369. IF LDATA
  370.                 PUBLIC  _heapcheckfree
  371. _heapcheckfree  LABEL   DIST
  372. ENDIF
  373.                 PUBLIC  _farheapcheckfree
  374. _farheapcheckfree       PROC DIST
  375.                 ARG     fill:word
  376.  
  377.                 push    bp
  378.                 mov     bp,sp
  379.                 push    si
  380.                 push    di
  381.  
  382.                 call    _farheapcheck           ;make sure heap is OK first
  383.                 cmp     ax, _HEAPOK
  384.                 jne     @@AllDone
  385.  
  386.                 mov     bx,cs:___rover          ;bx = rover pointer
  387.                 or      bx,bx
  388.                 jz      @@HeapOK
  389.  
  390.                 mov     ax,[fill]               ;ax = fill value
  391.                 cld
  392. @@QueueLoop:
  393.                 mov     es,bx                   ;es,bx = free block
  394.                 mov     dx,es:[bsize]           ;dx = size of block (in para)
  395.                 mov     si,es:[next_free]       ;si = next free block
  396.                 mov     di,free_space
  397.                 mov     cx,8 - (free_space/2)
  398. @@CheckHerOut:
  399.                 repe
  400.                 scasw
  401.                 jnz     @@BadValue
  402.                 xor     di,di
  403.                 mov     cx,8
  404.                 inc     bx
  405.                 mov     es,bx
  406.                 dec     dx
  407.                 jnz     @@CheckHerOut
  408. @@NextBlock:
  409.                 cmp     si,cs:[___rover]
  410.                 je      @@HeapOK
  411.                 or      si,si
  412.                 jz      @@HeapCorrupt
  413.                 mov     bx,si
  414.                 jmp     SHORT @@QueueLoop
  415.  
  416. @@BadValue:
  417.                 mov     ax,_BADVALUE
  418.                 jmp     SHORT @@AllDone
  419. @@HeapCorrupt:
  420.                 mov     ax,_HEAPCORRUPT
  421.                 jmp     SHORT @@AllDone
  422. @@EmptyHeap:
  423.                 mov     ax,_HEAPEMPTY
  424.                 jmp     SHORT @@AllDone
  425. @@HeapOK:
  426.                 mov     ax,_HEAPOK
  427. @@AllDone:
  428.                 pop     di
  429.                 pop     si
  430.                 pop     bp
  431.                 ret
  432.                 ENDP
  433.  
  434. ;-----------------------------------------------------------------------------
  435. ; C callable function to walk through the heap node by node
  436. ;-----------------------------------------------------------------------------
  437. ; Args:                 pointer to a heapinfo structure (stack)
  438. ; Returns:              _HEAPOK, _HEAPEMPTY, _HEAPEND in ax
  439. ;-----------------------------------------------------------------------------
  440. IF LDATA
  441.                 PUBLIC  _heapwalk
  442. _heapwalk       LABEL   DIST
  443. ENDIF
  444.                 PUBLIC  _farheapwalk
  445. _farheapwalk    PROC DIST
  446.                 ARG     O:word, S:word
  447.  
  448.                 push    bp
  449.                 mov     bp,sp
  450.                 push    si
  451.                 push    di
  452.  
  453.                 mov     di,[O]                  ;di = offset of struct
  454. IF LDATA
  455.                 push    ds
  456.                 mov     bx,[S]                  ;bx = segment of struct
  457.  
  458.                 cmp     di,0FFF0h               ;psuedo-normalize it
  459.                 jb      @@Normalized
  460.                 inc     bx
  461.                 sub     di,16d
  462. @@Normalized:
  463.                 mov     ds,bx                   ;ds:di = struct
  464. ENDIF
  465.                 mov     bx,WORD PTR [di+hi_ptr+2]       ;bx = previous block
  466.                 or      bx,bx
  467.                 jz      @@FirstBlock
  468.                 cmp     bx,cs:[___last]         ;last block?
  469.                 je      @@HeapEnd
  470.                 or      bx,bx                   ;first?
  471.                 jne     @@InnerBlock
  472. @@FirstBlock:
  473.                 mov     bx,cs:[___first]
  474.                 or      bx,bx
  475.                 jz      @@HeapEmpty
  476.                 mov     es,bx                   ;es = first block
  477.                 jmp     SHORT @@SaveInfo
  478. @@InnerBlock:
  479.                 mov     es,bx                   ;es = block
  480.                 add     bx,es:[bsize]           ;bx = next block
  481.                 mov     es,bx                   ;es = next block
  482. @@SaveInfo:
  483.                 mov     WORD PTR ds:[di+hi_ptr+2],es    ;save address
  484.                 mov     WORD PTR ds:[di+hi_ptr],UsedHeaderSize
  485.                 mov     ax,WORD PTR es:[bsize]          ;multiply size * 16
  486.                 mov     bx,16d
  487.                 mul     bx
  488.                 mov     WORD PTR ds:[di+hi_size],ax     ;save it
  489.                 mov     WORD PTR ds:[di+hi_size+2],dx
  490.                 mov     WORD PTR ds:[di+hi_inuse],0     ;clear in-use flag
  491.                 cmp     WORD PTR es:[prev_real], 0      ;is it free?
  492.                 je      @@HeapOK
  493.                 inc     WORD PTR ds:[di+hi_inuse]      ;set in-use flag
  494. @@HeapOK:
  495.                 mov     ax,_HEAPOK
  496.                 jmp     SHORT @@AllDone
  497. @@HeapEmpty:
  498.                 mov     ax,_HEAPEMPTY
  499.                 jmp     SHORT @@AllDone
  500. @@HeapEnd:
  501.                 mov     ax,_HEAPEND
  502. @@AllDone:
  503. IF LDATA
  504.                 pop     ds
  505. ENDIF
  506.                 pop     di
  507.                 pop     si
  508.                 pop     bp
  509.                 ret
  510.                 ENDP
  511.  
  512.                 ENDS
  513.                 END
  514.