home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) 1995-96 AROS - The Amiga Replacement OS
- $Id: purify.c,v 1.4 1997/01/28 13:41:55 digulla Exp $
- $Log: purify.c,v $
- Revision 1.4 1997/01/28 13:41:55 digulla
- Use string.h instead of memory.h
-
- Revision 1.3 1997/01/27 00:17:41 ldp
- Include proto instead of clib
-
- Revision 1.2 1996/12/10 13:59:45 aros
- Moved #include into first column to allow makedepend to see it.
-
- Revision 1.1 1996/08/23 17:26:45 digulla
- Files with functions for RT and Purify
-
-
- Desc:
- Lang:
- */
- /* Local prototypes */
- #define AROS_ALMOST_COMPATIBLE
- #include <exec/lists.h>
- #include <exec/execbase.h>
- #include <string.h>
- #include <stdlib.h>
- #include <proto/aros.h>
- #include <proto/exec.h>
- #include <aros/purify.h>
- #include <aros/rt.h>
-
- extern struct ExecBase * SysBase;
-
- struct PNode
- {
- struct Node Node;
- UBYTE * Memory;
- ULONG Size;
- UBYTE State[0];
- };
-
- static const char * pmsNames[] =
- {
- "free", "empty", "init.", "ro"
- };
-
- static struct List P_Memory;
- static int InitWasCalled;
-
- static struct PNode * FindNode (APTR memPtr);
- static int FindNextNodes (APTR memPtr, struct PNode **, struct PNode **);
-
- extern void RT_ShowRTStack (void);
-
- /*****************************************************************************
-
- NAME */
- #include <aros/purify.h>
-
- void Purify_Init (
-
- /* SYNOPSIS */
- void)
-
- /* FUNCTION
- Initialize purify.
-
- INPUTS
- none
-
- RESULT
- none
-
- NOTES
- This function is not part of any library and may thus be called at
- any time.
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- NEWLIST (&P_Memory);
- } /* Purify_Init */
-
-
- /*****************************************************************************
-
- NAME */
- #include <aros/purify.h>
-
- void Purify_AddMemory (
-
- /* SYNOPSIS */
- APTR memPtr,
- ULONG size)
-
- /* FUNCTION
- Add size bytes of memory at memPtr to watch. Any access to this
- memory will be checked after this call.
-
- INPUTS
- memPtr - Start of the memory block
- size - The size of the memory block
-
- RESULT
- none
-
- NOTES
- This function is not part of any library and may thus be called at
- any time.
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- struct PNode * node;
-
- if (!InitWasCalled)
- Purify_Init ();
-
- if (!(node = malloc (sizeof (struct PNode) + size)) )
- return;
-
- node->Memory = memPtr;
- node->Size = size;
- memset (node->State, PMS_FREE, size);
-
- AddHead (&P_Memory, (struct Node *)node);
- } /* Purify_AddMemory */
-
-
- /*****************************************************************************
-
- NAME */
- #include <aros/purify.h>
-
- void Purify_SetState (
-
- /* SYNOPSIS */
- APTR memPtr,
- ULONG size,
- ULONG state)
-
- /* FUNCTION
- Brings a block of memory into a certain state (eg. empty, initialized,
- read-only). memPtr and size must be within a block beforehand
- declared with Purify_AddMemory().
-
- INPUTS
- memPtr - Where to start
- size - How many bytes after memPtr
- state - The new state of the memory:
- PMS_EMPTY - The memory may be read from and written to,
- but any read before the first write will yield an
- error (read from uninitialized memory).
- PMS_INITIALIZED - The memory has been initialized and may
- be read and writen to.
- PMS_READONLY - The memory may be read but not written to.
- PMS_FREE - The memory may not be read from or written to.
-
- RESULT
- none
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- struct PNode * node, * nodeBefore, * nodeAfter;
- UBYTE * mem;
-
- if (!InitWasCalled)
- Purify_Init ();
-
- /* Look for a node which contains memPtr */
- node = FindNode (memPtr);
-
- mem = memPtr;
-
- /* Is there one ? */
- if (!node)
- {
- /* Look for the node we know about which comes least before and
- right next after memPtr. This will _not_ return any node
- which contains memPtr because there is none. If there are
- none or the area we look for is in none of them, print a
- message and exit. */
- if (!FindNextNodes (memPtr, &nodeBefore, &nodeAfter)
- || mem+size <= nodeAfter->Memory
- )
- {
- kprintf ("Purify: Tried to set state %s for unpurifed memory at %p:%ld\n"
- , pmsNames[state]
- , memPtr
- , size
- );
- return;
- }
-
- /* If we get here, we have found a node which comes after memPtr
- but memPtr is not inside the node */
- }
- else
- {
- if (mem+size <= node->Memory+node->Size)
- memset (&node->State[mem - node->Memory], state, size);
- else
- kprintf ("Purify: %p:%ld exceeds PNode %p:%ld\n"
- , mem
- , size
- , node->Memory
- , node->Size
- );
- }
- } /* Purify_SetState */
-
-
- /*****************************************************************************
-
- NAME */
- #include <aros/purify.h>
-
- void Purify_CheckAccess (
-
- /* SYNOPSIS */
- APTR memPtr,
- ULONG size,
- ULONG type)
-
- /* FUNCTION
- Checks a specific kind of access to memPtr[0...size-1].
-
- INPUTS
- memPtr - Where the access happens
- size - How many bytes are accessed
- type - Kind of access (PMA_READ, PMA_WRITE or PMA_MODIFY)
-
- RESULT
- none
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- struct PNode * node;
- UBYTE * mem;
-
- if (!InitWasCalled)
- Purify_Init ();
-
- /* Look for a node which contains memPtr */
- node = FindNode (memPtr);
-
- mem = memPtr;
-
- /* Is there one ? */
- if (!node)
- {
- kprintf ("Purify: Illegal access %p:%ld\n"
- , mem
- , size
- );
- RT_ShowRTStack ();
- }
- else
- {
- if (mem+size > node->Memory+node->Size)
- kprintf ("Purify: Access %p:%ld beyond bounds %p:%ld\n"
- , mem
- , size
- , node->Memory
- , node->Size
- );
- else
- {
- switch (type)
- {
- case PMA_READ:
- mem = &node->State[mem - node->Memory];
-
- for ( ; size; size --)
- {
- switch (*mem)
- {
- case PMS_EMPTY:
- kprintf ("Purify: Read of undefined memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
-
- case PMS_INITIALIZED:
- break;
-
- case PMS_READONLY:
- break;
-
- case PMS_FREE:
- kprintf ("Purify: Read of freed memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
- } /* switch */
- } /* for */
-
- break;
-
- case PMA_WRITE:
- mem = &node->State[mem - node->Memory];
-
- for ( ; size; size --)
- {
- switch (*mem)
- {
- case PMS_EMPTY:
- *mem = PMS_INITIALIZED;
- break;
-
- case PMS_INITIALIZED:
- break;
-
- case PMS_READONLY:
- kprintf ("Purify: Write to readonly memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
- break;
-
- case PMS_FREE:
- kprintf ("Purify: Write to freed memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
- } /* switch */
- }
-
- break;
-
- case PMA_MODIFY:
- mem = &node->State[mem - node->Memory];
-
- for ( ; size; size --)
- {
- switch (*mem)
- {
- case PMS_EMPTY:
- kprintf ("Purify: Modify of undefined memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
-
- case PMS_INITIALIZED:
- break;
-
- case PMS_READONLY:
- kprintf ("Purify: Modify of readonly memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
-
- case PMS_FREE:
- kprintf ("Purify: Modify of freed memory at %p (%ld bytes from the beginning of the block)\n"
- , node->Memory - node->State + mem
- , mem - node->State
- );
- RT_ShowRTStack ();
- size = 1;
- break;
- } /* switch */
- }
-
- break;
-
- } /* switch (access type) */
- } /* Complete within bounds ? */
- } /* Node with memPtr found ? */
- } /* Purify_CheckAccess */
-
-
- /*****************************************************************************
-
- NAME */
- static struct PNode * FindNode (
-
- /* SYNOPSIS */
- APTR memPtr)
-
- /* FUNCTION
- Searches for the PNode which contains memPtr.
-
- INPUTS
- memPtr - A pointer into a piece of memory previously made known
- with Purify_AddMemory.
-
- RESULT
- A pointer to a PNode which contains the memPtr or NULL if there
- is no such pointer. No error will be printed.
-
- NOTES
- Must not be called before Purify_Init().
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- struct PNode * node;
-
- for (node=GetHead(&P_Memory); node; node=GetSucc(node))
- {
- if (node->Memory <= (UBYTE *)memPtr
- || (UBYTE *)memPtr < node->Memory+node->Size
- )
- break;
- }
-
- return node;
- } /* FindNode */
-
-
- /*****************************************************************************
-
- NAME */
- static int FindNextNodes (
-
- /* SYNOPSIS */
- APTR memPtr,
- struct PNode ** before,
- struct PNode ** after)
-
- /* FUNCTION
- Returns the addresses of the PNodes right before and right right
- after memPtr.
-
- INPUTS
- memPtr - The address to look for
- before - Pointer to a pointer to PNode where the address of
- the node right before memPtr will be stored.
- after - Pointer to a pointer to PNode where the address of
- the node right after memPtr will be stored.
-
- RESULT
- The number of found PNodes. *before will contain a pointer to
- the PNode which is before memPtr or which contains memPtr or NULL
- if there is no node before PNode. *after will contain a pointer
- to the first PNode which comes right after memPtr or NULL if no
- PNode follows memPtr.
-
- NOTES
- Must not be called before Purify_Init().
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
- {
- int found = 0;
- struct PNode * node;
-
- *before = NULL;
- *after = NULL;
-
- for (node=GetHead(&P_Memory); node; node=GetSucc(node))
- {
- if (!*before)
- {
- if (node->Memory < (UBYTE *)memPtr)
- {
- found |= 1;
- *before = node;
- }
- }
- else
- {
- if (node->Memory < (UBYTE *)memPtr
- && (*before)->Memory < node->Memory
- )
- {
- found |= 1;
- *before = node;
- }
- }
-
- if (!*after)
- {
- if (node->Memory > (UBYTE *)memPtr)
- {
- found |= 2;
- *after = node;
- }
- }
- else
- {
- if (node->Memory > (UBYTE *)memPtr
- && (*after)->Memory > node->Memory
- )
- {
- found |= 2;
- *after = node;
- }
- }
- }
-
- if (found == 2)
- found = 1;
- else if (found == 3)
- found = 2;
-
- return found;
- } /* FindNextNodes */
-
-
- /*****************************************************************************
-
- NAME */
-
- /* SYNOPSIS */
-
- /* FUNCTION
-
- INPUTS
-
- RESULT
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
-
-
- /*****************************************************************************
-
- NAME */
-
- /* SYNOPSIS */
-
- /* FUNCTION
-
- INPUTS
-
- RESULT
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
-
-
- /*****************************************************************************
-
- NAME */
-
- /* SYNOPSIS */
-
- /* FUNCTION
-
- INPUTS
-
- RESULT
-
- NOTES
-
- EXAMPLE
-
- BUGS
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
-
- ******************************************************************************/
-
-
-