diff options
| author | Frank Gevaerts <frank@gevaerts.be> | 2010-09-26 12:05:42 +0000 |
|---|---|---|
| committer | Frank Gevaerts <frank@gevaerts.be> | 2010-09-26 12:05:42 +0000 |
| commit | 8ff4f1aec9f19613e4f67d2e22ae96bec7657292 (patch) | |
| tree | c9e2b19b56375fac35d996fb85d5e3a5802dfc45 /firmware/buffer.c | |
| parent | 927a7bdb4b91d3a63f014824711f796e5eb4c5ba (diff) | |
| download | rockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.zip rockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.tar.gz rockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.tar.bz2 rockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.tar.xz | |
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
Diffstat (limited to 'firmware/buffer.c')
| -rw-r--r-- | firmware/buffer.c | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/firmware/buffer.c b/firmware/buffer.c index 015fc04..a21a882 100644 --- a/firmware/buffer.c +++ b/firmware/buffer.c @@ -20,6 +20,8 @@ ****************************************************************************/ #include <stdio.h> #include "buffer.h" +#include "panic.h" +#include "logf.h" #if (CONFIG_PLATFORM & PLATFORM_HOSTED) unsigned char audiobuffer[(MEM*1024-256)*1024]; @@ -31,20 +33,94 @@ extern unsigned char audiobuffer[]; 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) { /* 32-bit aligned */ 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 *retval = audiobuf; - - audiobuf += size; +#ifdef BUFFER_ALLOC_DEBUG + struct buffer_start_marker *start; + struct buffer_end_marker *end; +#endif /* BUFFER_ALLOC_DEBUG */ + /* 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; } +#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 */ |