home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / compiler / aros / purify.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-28  |  11.8 KB  |  660 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: purify.c,v 1.4 1997/01/28 13:41:55 digulla Exp $
  4.     $Log: purify.c,v $
  5.     Revision 1.4  1997/01/28 13:41:55  digulla
  6.     Use string.h instead of memory.h
  7.  
  8.     Revision 1.3  1997/01/27 00:17:41  ldp
  9.     Include proto instead of clib
  10.  
  11.     Revision 1.2  1996/12/10 13:59:45  aros
  12.     Moved #include into first column to allow makedepend to see it.
  13.  
  14.     Revision 1.1  1996/08/23 17:26:45  digulla
  15.     Files with functions for RT and Purify
  16.  
  17.  
  18.     Desc:
  19.     Lang:
  20. */
  21. /* Local prototypes */
  22. #define AROS_ALMOST_COMPATIBLE
  23. #include <exec/lists.h>
  24. #include <exec/execbase.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <proto/aros.h>
  28. #include <proto/exec.h>
  29. #include <aros/purify.h>
  30. #include <aros/rt.h>
  31.  
  32. extern struct ExecBase * SysBase;
  33.  
  34. struct PNode
  35. {
  36.     struct Node Node;
  37.     UBYTE     * Memory;
  38.     ULONG    Size;
  39.     UBYTE    State[0];
  40. };
  41.  
  42. static const char * pmsNames[] =
  43. {
  44.     "free", "empty", "init.", "ro"
  45. };
  46.  
  47. static struct List P_Memory;
  48. static int InitWasCalled;
  49.  
  50. static struct PNode * FindNode (APTR memPtr);
  51. static int FindNextNodes (APTR memPtr, struct PNode **, struct PNode **);
  52.  
  53. extern void RT_ShowRTStack (void);
  54.  
  55. /*****************************************************************************
  56.  
  57.     NAME */
  58. #include <aros/purify.h>
  59.  
  60.     void Purify_Init (
  61.  
  62. /*  SYNOPSIS */
  63.     void)
  64.  
  65. /*  FUNCTION
  66.     Initialize purify.
  67.  
  68.     INPUTS
  69.     none
  70.  
  71.     RESULT
  72.     none
  73.  
  74.     NOTES
  75.     This function is not part of any library and may thus be called at
  76.     any time.
  77.  
  78.     EXAMPLE
  79.  
  80.     BUGS
  81.  
  82.     SEE ALSO
  83.  
  84.     INTERNALS
  85.  
  86.     HISTORY
  87.  
  88. ******************************************************************************/
  89. {
  90.     NEWLIST (&P_Memory);
  91. } /* Purify_Init */
  92.  
  93.  
  94. /*****************************************************************************
  95.  
  96.     NAME */
  97. #include <aros/purify.h>
  98.  
  99.     void Purify_AddMemory (
  100.  
  101. /*  SYNOPSIS */
  102.     APTR  memPtr,
  103.     ULONG size)
  104.  
  105. /*  FUNCTION
  106.     Add size bytes of memory at memPtr to watch. Any access to this
  107.     memory will be checked after this call.
  108.  
  109.     INPUTS
  110.     memPtr - Start of the memory block
  111.     size - The size of the memory block
  112.  
  113.     RESULT
  114.     none
  115.  
  116.     NOTES
  117.     This function is not part of any library and may thus be called at
  118.     any time.
  119.  
  120.     EXAMPLE
  121.  
  122.     BUGS
  123.  
  124.     SEE ALSO
  125.  
  126.     INTERNALS
  127.  
  128.     HISTORY
  129.  
  130. ******************************************************************************/
  131. {
  132.     struct PNode * node;
  133.  
  134.     if (!InitWasCalled)
  135.     Purify_Init ();
  136.  
  137.     if (!(node = malloc (sizeof (struct PNode) + size)) )
  138.     return;
  139.  
  140.     node->Memory = memPtr;
  141.     node->Size     = size;
  142.     memset (node->State, PMS_FREE, size);
  143.  
  144.     AddHead (&P_Memory, (struct Node *)node);
  145. } /* Purify_AddMemory */
  146.  
  147.  
  148. /*****************************************************************************
  149.  
  150.     NAME */
  151. #include <aros/purify.h>
  152.  
  153.     void Purify_SetState (
  154.  
  155. /*  SYNOPSIS */
  156.     APTR  memPtr,
  157.     ULONG size,
  158.     ULONG state)
  159.  
  160. /*  FUNCTION
  161.     Brings a block of memory into a certain state (eg. empty, initialized,
  162.     read-only). memPtr and size must be within a block beforehand
  163.     declared with Purify_AddMemory().
  164.  
  165.     INPUTS
  166.     memPtr - Where to start
  167.     size - How many bytes after memPtr
  168.     state - The new state of the memory:
  169.         PMS_EMPTY - The memory may be read from and written to,
  170.             but any read before the first write will yield an
  171.             error (read from uninitialized memory).
  172.         PMS_INITIALIZED - The memory has been initialized and may
  173.             be read and writen to.
  174.         PMS_READONLY - The memory may be read but not written to.
  175.         PMS_FREE - The memory may not be read from or written to.
  176.  
  177.     RESULT
  178.     none
  179.  
  180.     NOTES
  181.  
  182.     EXAMPLE
  183.  
  184.     BUGS
  185.  
  186.     SEE ALSO
  187.  
  188.     INTERNALS
  189.  
  190.     HISTORY
  191.  
  192. ******************************************************************************/
  193. {
  194.     struct PNode * node, * nodeBefore, * nodeAfter;
  195.     UBYTE * mem;
  196.  
  197.     if (!InitWasCalled)
  198.     Purify_Init ();
  199.  
  200.     /* Look for a node which contains memPtr */
  201.     node = FindNode (memPtr);
  202.  
  203.     mem = memPtr;
  204.  
  205.     /* Is there one ? */
  206.     if (!node)
  207.     {
  208.     /*  Look for the node we know about which comes least before and
  209.         right next after memPtr. This will _not_ return any node
  210.         which contains memPtr because there is none. If there are
  211.         none or the area we look for is in none of them, print a
  212.         message and exit. */
  213.     if (!FindNextNodes (memPtr, &nodeBefore, &nodeAfter)
  214.         || mem+size <= nodeAfter->Memory
  215.     )
  216.     {
  217.         kprintf ("Purify: Tried to set state %s for unpurifed memory at %p:%ld\n"
  218.         , pmsNames[state]
  219.         , memPtr
  220.         , size
  221.         );
  222.         return;
  223.     }
  224.  
  225.     /*  If we get here, we have found a node which comes after memPtr
  226.         but memPtr is not inside the node */
  227.     }
  228.     else
  229.     {
  230.     if (mem+size <= node->Memory+node->Size)
  231.         memset (&node->State[mem - node->Memory], state, size);
  232.     else
  233.         kprintf ("Purify: %p:%ld exceeds PNode %p:%ld\n"
  234.         , mem
  235.         , size
  236.         , node->Memory
  237.         , node->Size
  238.         );
  239.     }
  240. } /* Purify_SetState */
  241.  
  242.  
  243. /*****************************************************************************
  244.  
  245.     NAME */
  246. #include <aros/purify.h>
  247.  
  248.     void Purify_CheckAccess (
  249.  
  250. /*  SYNOPSIS */
  251.     APTR  memPtr,
  252.     ULONG size,
  253.     ULONG type)
  254.  
  255. /*  FUNCTION
  256.     Checks a specific kind of access to memPtr[0...size-1].
  257.  
  258.     INPUTS
  259.     memPtr - Where the access happens
  260.     size - How many bytes are accessed
  261.     type - Kind of access (PMA_READ, PMA_WRITE or PMA_MODIFY)
  262.  
  263.     RESULT
  264.     none
  265.  
  266.     NOTES
  267.  
  268.     EXAMPLE
  269.  
  270.     BUGS
  271.  
  272.     SEE ALSO
  273.  
  274.     INTERNALS
  275.  
  276.     HISTORY
  277.  
  278. ******************************************************************************/
  279. {
  280.     struct PNode * node;
  281.     UBYTE * mem;
  282.  
  283.     if (!InitWasCalled)
  284.     Purify_Init ();
  285.  
  286.     /* Look for a node which contains memPtr */
  287.     node = FindNode (memPtr);
  288.  
  289.     mem = memPtr;
  290.  
  291.     /* Is there one ? */
  292.     if (!node)
  293.     {
  294.     kprintf ("Purify: Illegal access %p:%ld\n"
  295.         , mem
  296.         , size
  297.     );
  298.     RT_ShowRTStack ();
  299.     }
  300.     else
  301.     {
  302.     if (mem+size > node->Memory+node->Size)
  303.         kprintf ("Purify: Access %p:%ld beyond bounds %p:%ld\n"
  304.         , mem
  305.         , size
  306.         , node->Memory
  307.         , node->Size
  308.         );
  309.     else
  310.     {
  311.         switch (type)
  312.         {
  313.         case PMA_READ:
  314.         mem = &node->State[mem - node->Memory];
  315.  
  316.         for ( ; size; size --)
  317.         {
  318.             switch (*mem)
  319.             {
  320.             case PMS_EMPTY:
  321.             kprintf ("Purify: Read of undefined memory at %p (%ld bytes from the beginning of the block)\n"
  322.                 , node->Memory - node->State + mem
  323.                 , mem - node->State
  324.             );
  325.             RT_ShowRTStack ();
  326.             size = 1;
  327.             break;
  328.  
  329.             case PMS_INITIALIZED:
  330.             break;
  331.  
  332.             case PMS_READONLY:
  333.             break;
  334.  
  335.             case PMS_FREE:
  336.             kprintf ("Purify: Read of freed memory at %p (%ld bytes from the beginning of the block)\n"
  337.                 , node->Memory - node->State + mem
  338.                 , mem - node->State
  339.             );
  340.             RT_ShowRTStack ();
  341.             size = 1;
  342.             break;
  343.             } /* switch */
  344.         } /* for */
  345.  
  346.         break;
  347.  
  348.         case PMA_WRITE:
  349.         mem = &node->State[mem - node->Memory];
  350.  
  351.         for ( ; size; size --)
  352.         {
  353.             switch (*mem)
  354.             {
  355.             case PMS_EMPTY:
  356.             *mem = PMS_INITIALIZED;
  357.             break;
  358.  
  359.             case PMS_INITIALIZED:
  360.             break;
  361.  
  362.             case PMS_READONLY:
  363.             kprintf ("Purify: Write to readonly memory at %p (%ld bytes from the beginning of the block)\n"
  364.                 , node->Memory - node->State + mem
  365.                 , mem - node->State
  366.             );
  367.             RT_ShowRTStack ();
  368.             size = 1;
  369.             break;
  370.             break;
  371.  
  372.             case PMS_FREE:
  373.             kprintf ("Purify: Write to freed memory at %p (%ld bytes from the beginning of the block)\n"
  374.                 , node->Memory - node->State + mem
  375.                 , mem - node->State
  376.             );
  377.             RT_ShowRTStack ();
  378.             size = 1;
  379.             break;
  380.             } /* switch */
  381.         }
  382.  
  383.         break;
  384.  
  385.         case PMA_MODIFY:
  386.         mem = &node->State[mem - node->Memory];
  387.  
  388.         for ( ; size; size --)
  389.         {
  390.             switch (*mem)
  391.             {
  392.             case PMS_EMPTY:
  393.             kprintf ("Purify: Modify of undefined memory at %p (%ld bytes from the beginning of the block)\n"
  394.                 , node->Memory - node->State + mem
  395.                 , mem - node->State
  396.             );
  397.             RT_ShowRTStack ();
  398.             size = 1;
  399.             break;
  400.  
  401.             case PMS_INITIALIZED:
  402.             break;
  403.  
  404.             case PMS_READONLY:
  405.             kprintf ("Purify: Modify of readonly memory at %p (%ld bytes from the beginning of the block)\n"
  406.                 , node->Memory - node->State + mem
  407.                 , mem - node->State
  408.             );
  409.             RT_ShowRTStack ();
  410.             size = 1;
  411.             break;
  412.  
  413.             case PMS_FREE:
  414.             kprintf ("Purify: Modify of freed memory at %p (%ld bytes from the beginning of the block)\n"
  415.                 , node->Memory - node->State + mem
  416.                 , mem - node->State
  417.             );
  418.             RT_ShowRTStack ();
  419.             size = 1;
  420.             break;
  421.             } /* switch */
  422.         }
  423.  
  424.         break;
  425.  
  426.         } /* switch (access type) */
  427.     } /* Complete within bounds ? */
  428.     } /* Node with memPtr found ? */
  429. } /* Purify_CheckAccess */
  430.  
  431.  
  432. /*****************************************************************************
  433.  
  434.     NAME */
  435.     static struct PNode * FindNode (
  436.  
  437. /*  SYNOPSIS */
  438.     APTR memPtr)
  439.  
  440. /*  FUNCTION
  441.     Searches for the PNode which contains memPtr.
  442.  
  443.     INPUTS
  444.     memPtr - A pointer into a piece of memory previously made known
  445.         with Purify_AddMemory.
  446.  
  447.     RESULT
  448.     A pointer to a PNode which contains the memPtr or NULL if there
  449.     is no such pointer. No error will be printed.
  450.  
  451.     NOTES
  452.     Must not be called before Purify_Init().
  453.  
  454.     EXAMPLE
  455.  
  456.     BUGS
  457.  
  458.     SEE ALSO
  459.  
  460.     INTERNALS
  461.  
  462.     HISTORY
  463.  
  464. ******************************************************************************/
  465. {
  466.     struct PNode * node;
  467.  
  468.     for (node=GetHead(&P_Memory); node; node=GetSucc(node))
  469.     {
  470.     if (node->Memory <= (UBYTE *)memPtr
  471.         || (UBYTE *)memPtr < node->Memory+node->Size
  472.     )
  473.         break;
  474.     }
  475.  
  476.     return node;
  477. } /* FindNode */
  478.  
  479.  
  480. /*****************************************************************************
  481.  
  482.     NAME */
  483.     static int FindNextNodes (
  484.  
  485. /*  SYNOPSIS */
  486.     APTR        memPtr,
  487.     struct PNode ** before,
  488.     struct PNode ** after)
  489.  
  490. /*  FUNCTION
  491.     Returns the addresses of the PNodes right before and right right
  492.     after memPtr.
  493.  
  494.     INPUTS
  495.     memPtr - The address to look for
  496.     before - Pointer to a pointer to PNode where the address of
  497.         the node right before memPtr will be stored.
  498.     after - Pointer to a pointer to PNode where the address of
  499.         the node right after memPtr will be stored.
  500.  
  501.     RESULT
  502.     The number of found PNodes. *before will contain a pointer to
  503.     the PNode which is before memPtr or which contains memPtr or NULL
  504.     if there is no node before PNode. *after will contain a pointer
  505.     to the first PNode which comes right after memPtr or NULL if no
  506.     PNode follows memPtr.
  507.  
  508.     NOTES
  509.     Must not be called before Purify_Init().
  510.  
  511.     EXAMPLE
  512.  
  513.     BUGS
  514.  
  515.     SEE ALSO
  516.  
  517.     INTERNALS
  518.  
  519.     HISTORY
  520.  
  521. ******************************************************************************/
  522. {
  523.     int found = 0;
  524.     struct PNode * node;
  525.  
  526.     *before = NULL;
  527.     *after  = NULL;
  528.  
  529.     for (node=GetHead(&P_Memory); node; node=GetSucc(node))
  530.     {
  531.     if (!*before)
  532.     {
  533.         if (node->Memory < (UBYTE *)memPtr)
  534.         {
  535.         found |= 1;
  536.         *before = node;
  537.         }
  538.     }
  539.     else
  540.     {
  541.         if (node->Memory < (UBYTE *)memPtr
  542.         && (*before)->Memory < node->Memory
  543.         )
  544.         {
  545.         found |= 1;
  546.         *before = node;
  547.         }
  548.     }
  549.  
  550.     if (!*after)
  551.     {
  552.         if (node->Memory > (UBYTE *)memPtr)
  553.         {
  554.         found |= 2;
  555.         *after = node;
  556.         }
  557.     }
  558.     else
  559.     {
  560.         if (node->Memory > (UBYTE *)memPtr
  561.         && (*after)->Memory > node->Memory
  562.         )
  563.         {
  564.         found |= 2;
  565.         *after = node;
  566.         }
  567.     }
  568.     }
  569.  
  570.     if (found == 2)
  571.     found = 1;
  572.     else if (found == 3)
  573.     found = 2;
  574.  
  575.     return found;
  576. } /* FindNextNodes */
  577.  
  578.  
  579. /*****************************************************************************
  580.  
  581.     NAME */
  582.  
  583. /*  SYNOPSIS */
  584.  
  585. /*  FUNCTION
  586.  
  587.     INPUTS
  588.  
  589.     RESULT
  590.  
  591.     NOTES
  592.  
  593.     EXAMPLE
  594.  
  595.     BUGS
  596.  
  597.     SEE ALSO
  598.  
  599.     INTERNALS
  600.  
  601.     HISTORY
  602.  
  603. ******************************************************************************/
  604.  
  605.  
  606. /*****************************************************************************
  607.  
  608.     NAME */
  609.  
  610. /*  SYNOPSIS */
  611.  
  612. /*  FUNCTION
  613.  
  614.     INPUTS
  615.  
  616.     RESULT
  617.  
  618.     NOTES
  619.  
  620.     EXAMPLE
  621.  
  622.     BUGS
  623.  
  624.     SEE ALSO
  625.  
  626.     INTERNALS
  627.  
  628.     HISTORY
  629.  
  630. ******************************************************************************/
  631.  
  632.  
  633. /*****************************************************************************
  634.  
  635.     NAME */
  636.  
  637. /*  SYNOPSIS */
  638.  
  639. /*  FUNCTION
  640.  
  641.     INPUTS
  642.  
  643.     RESULT
  644.  
  645.     NOTES
  646.  
  647.     EXAMPLE
  648.  
  649.     BUGS
  650.  
  651.     SEE ALSO
  652.  
  653.     INTERNALS
  654.  
  655.     HISTORY
  656.  
  657. ******************************************************************************/
  658.  
  659.  
  660.