mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
Add optional (define BUFFER_ALLOC_DEBUG to enable it) code to check for code overflowing buffer_alloc()-allocated buffers.
Also add a panicf() if buffer_alloc() doesn't have enough space left to allocate a requested buffer git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28173 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
927a7bdb4b
commit
8ff4f1aec9
3 changed files with 94 additions and 3 deletions
|
@ -20,6 +20,8 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
#include "panic.h"
|
||||||
|
#include "logf.h"
|
||||||
|
|
||||||
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
||||||
unsigned char audiobuffer[(MEM*1024-256)*1024];
|
unsigned char audiobuffer[(MEM*1024-256)*1024];
|
||||||
|
@ -31,20 +33,94 @@ extern unsigned char audiobuffer[];
|
||||||
|
|
||||||
unsigned char *audiobuf;
|
unsigned char *audiobuf;
|
||||||
|
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
static unsigned char *audiobuf_orig_start;
|
||||||
|
|
||||||
|
struct buffer_start_marker
|
||||||
|
{
|
||||||
|
unsigned int magic;
|
||||||
|
size_t buffer_size;
|
||||||
|
};
|
||||||
|
#define BUF_MAGIC 0xDEADD0D0
|
||||||
|
|
||||||
|
struct buffer_end_marker
|
||||||
|
{
|
||||||
|
unsigned int magic;
|
||||||
|
int last;
|
||||||
|
};
|
||||||
|
#endif /* BUFFER_ALLOC_DEBUG */
|
||||||
|
|
||||||
void buffer_init(void)
|
void buffer_init(void)
|
||||||
{
|
{
|
||||||
/* 32-bit aligned */
|
/* 32-bit aligned */
|
||||||
audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3);
|
audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3);
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
audiobuf_orig_start = audiobuf;
|
||||||
|
#endif /* BUFFER_ALLOC_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *buffer_alloc(size_t size)
|
void *buffer_alloc(size_t size)
|
||||||
{
|
{
|
||||||
void *retval = audiobuf;
|
void *retval = audiobuf;
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
struct buffer_start_marker *start;
|
||||||
|
struct buffer_end_marker *end;
|
||||||
|
#endif /* BUFFER_ALLOC_DEBUG */
|
||||||
|
|
||||||
audiobuf += size;
|
|
||||||
/* 32-bit aligned */
|
/* 32-bit aligned */
|
||||||
audiobuf = (void *)(((unsigned long)audiobuf + 3) & ~3);
|
size = (size + 3) & ~3;
|
||||||
|
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
retval +=sizeof(struct buffer_start_marker);
|
||||||
|
end=(struct buffer_end_marker*)(audiobuf - sizeof(struct buffer_end_marker));
|
||||||
|
if(end->magic == BUF_MAGIC)
|
||||||
|
{
|
||||||
|
end->last=0;
|
||||||
|
}
|
||||||
|
start=(struct buffer_start_marker*)audiobuf;
|
||||||
|
start->magic = BUF_MAGIC;
|
||||||
|
start->buffer_size = size;
|
||||||
|
end=(struct buffer_end_marker*)(audiobuf+sizeof(struct buffer_start_marker)+size);
|
||||||
|
end->magic = BUF_MAGIC;
|
||||||
|
end->last = 1;
|
||||||
|
|
||||||
|
audiobuf = ((unsigned char *)end) + sizeof(struct buffer_end_marker);
|
||||||
|
|
||||||
|
logf("Alloc %x %d",(unsigned int)retval,size);
|
||||||
|
#else /* !BUFFER_ALLOC_DEBUG */
|
||||||
|
audiobuf += size;
|
||||||
|
#endif /* BUFFER_ALLOC_DEBUG */
|
||||||
|
|
||||||
|
if (audiobuf > audiobufend) {
|
||||||
|
panicf("OOM: %d bytes", (int) size);
|
||||||
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
void buffer_alloc_check(char *name)
|
||||||
|
{
|
||||||
|
unsigned char *buf_ptr = audiobuf_orig_start;
|
||||||
|
struct buffer_start_marker *start;
|
||||||
|
struct buffer_end_marker *end;
|
||||||
|
|
||||||
|
|
||||||
|
while(buf_ptr < audiobuf)
|
||||||
|
{
|
||||||
|
start=(struct buffer_start_marker*)buf_ptr;
|
||||||
|
if(start->magic != BUF_MAGIC)
|
||||||
|
{
|
||||||
|
panicf("%s corrupted buffer %x start", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
|
||||||
|
}
|
||||||
|
end=(struct buffer_end_marker*)(buf_ptr+sizeof(struct buffer_start_marker)+start->buffer_size);
|
||||||
|
if(end->magic != BUF_MAGIC)
|
||||||
|
{
|
||||||
|
panicf("%s corrupted %x end", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
|
||||||
|
}
|
||||||
|
if(end->last)
|
||||||
|
break;
|
||||||
|
buf_ptr=((unsigned char *)end)+sizeof(struct buffer_end_marker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* BUFFER_ALLOC_DEBUG */
|
||||||
|
|
|
@ -39,4 +39,8 @@ extern unsigned char *audiobuf;
|
||||||
void buffer_init(void) INIT_ATTR;
|
void buffer_init(void) INIT_ATTR;
|
||||||
void *buffer_alloc(size_t size);
|
void *buffer_alloc(size_t size);
|
||||||
|
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
void buffer_alloc_check(char *name);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "buffer.h"
|
||||||
#ifdef RB_PROFILE
|
#ifdef RB_PROFILE
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -1160,6 +1161,16 @@ void switch_thread(void)
|
||||||
if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0)
|
if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0)
|
||||||
thread_stkov(thread);
|
thread_stkov(thread);
|
||||||
|
|
||||||
|
#ifdef BUFFER_ALLOC_DEBUG
|
||||||
|
/* Check if the current thread just did bad things with buffer_alloc()ed
|
||||||
|
* memory */
|
||||||
|
{
|
||||||
|
static char name[32];
|
||||||
|
thread_get_name(name, 32, thread);
|
||||||
|
buffer_alloc_check(name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if NUM_CORES > 1
|
#if NUM_CORES > 1
|
||||||
/* Run any blocking operations requested before switching/sleeping */
|
/* Run any blocking operations requested before switching/sleeping */
|
||||||
run_blocking_ops(core, thread);
|
run_blocking_ops(core, thread);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue