mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
Add improved memory checking to progs.
With pr_boundscheck >= 2, pointer access will be checked against allocated blocks (qfvalgrind?:). Currently extremely basic, but it seems to work.
This commit is contained in:
parent
56103f9a38
commit
49ad301d3d
3 changed files with 31 additions and 2 deletions
|
@ -103,7 +103,7 @@ void Z_Print (memzone_t *zone);
|
|||
void Z_CheckHeap (memzone_t *zone);
|
||||
void Z_SetError (memzone_t *zone, void (*err) (void *data, const char *msg),
|
||||
void *data);
|
||||
|
||||
void Z_CheckPointer (const memzone_t *zone, const void *ptr, int size);
|
||||
|
||||
void *Hunk_Alloc (int size); // returns 0 filled memory
|
||||
void *Hunk_AllocName (int size, const char *name);
|
||||
|
|
|
@ -261,6 +261,11 @@ PR_BoundsCheckSize (progs_t *pr, int addr, unsigned size)
|
|||
|| size > (unsigned) (pr->globals_size - addr))
|
||||
PR_RunError (pr, "invalid memory access: %d (0 to %d-%d)", addr,
|
||||
pr->globals_size, size);
|
||||
if (pr_boundscheck->int_val >= 2
|
||||
&& PR_GetPointer (pr, addr + size) > (pr_type_t *) pr->zone) {
|
||||
void *mem = (void *) PR_GetPointer (pr, addr);
|
||||
Z_CheckPointer (pr->zone, mem, size * sizeof (pr_type_t));
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
|
|
@ -363,7 +363,7 @@ Z_CheckHeap (memzone_t *zone)
|
|||
if ( (byte *)block + block->size != (byte *)block->next)
|
||||
Sys_Error ("Z_CheckHeap: block size does not touch the next "
|
||||
"block\n");
|
||||
if ( block->next->prev != block)
|
||||
if (block->next->prev != block)
|
||||
Sys_Error ("Z_CheckHeap: next block doesn't have proper back "
|
||||
"link\n");
|
||||
if (!block->tag && !block->next->tag)
|
||||
|
@ -378,6 +378,30 @@ Z_SetError (memzone_t *zone, void (*err) (void *, const char *), void *data)
|
|||
zone->data = data;
|
||||
}
|
||||
|
||||
void
|
||||
Z_CheckPointer (const memzone_t *zone, const void *ptr, int size)
|
||||
{
|
||||
const memblock_t *block;
|
||||
const char *block_mem;
|
||||
const char *check = (char *) ptr;
|
||||
|
||||
for (block = zone->blocklist.next ; ; block = block->next) {
|
||||
if (block->next == &zone->blocklist)
|
||||
break; // all blocks have been hit
|
||||
if (check < (const char *) block
|
||||
|| check >= (const char *) block + block->size)
|
||||
continue;
|
||||
// a block that overlaps with the memory region has been found
|
||||
if (!block->tag)
|
||||
zone->error (zone->data, "invalid access to unallocated memory");
|
||||
block_mem = (char *) &block[1];
|
||||
if (check < block_mem
|
||||
|| check + size > block_mem + block->size - sizeof (*block))
|
||||
zone->error (zone->data, "invalid access to allocated memory");
|
||||
return; // access ok
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in a new issue