summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2010-09-26 12:05:42 +0000
committerFrank Gevaerts <frank@gevaerts.be>2010-09-26 12:05:42 +0000
commit8ff4f1aec9f19613e4f67d2e22ae96bec7657292 (patch)
treec9e2b19b56375fac35d996fb85d5e3a5802dfc45 /firmware
parent927a7bdb4b91d3a63f014824711f796e5eb4c5ba (diff)
downloadrockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.tar.gz
rockbox-8ff4f1aec9f19613e4f67d2e22ae96bec7657292.zip
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')
-rw-r--r--firmware/buffer.c82
-rw-r--r--firmware/export/buffer.h4
-rw-r--r--firmware/thread.c11
3 files changed, 94 insertions, 3 deletions
diff --git a/firmware/buffer.c b/firmware/buffer.c
index 015fc04b86..a21a882ff2 100644
--- a/firmware/buffer.c
+++ b/firmware/buffer.c
@@ -20,6 +20,8 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdio.h> 21#include <stdio.h>
22#include "buffer.h" 22#include "buffer.h"
23#include "panic.h"
24#include "logf.h"
23 25
24#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 26#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
25unsigned char audiobuffer[(MEM*1024-256)*1024]; 27unsigned char audiobuffer[(MEM*1024-256)*1024];
@@ -31,20 +33,94 @@ extern unsigned char audiobuffer[];
31 33
32unsigned char *audiobuf; 34unsigned char *audiobuf;
33 35
36#ifdef BUFFER_ALLOC_DEBUG
37static unsigned char *audiobuf_orig_start;
38
39struct buffer_start_marker
40{
41 unsigned int magic;
42 size_t buffer_size;
43};
44#define BUF_MAGIC 0xDEADD0D0
45
46struct buffer_end_marker
47{
48 unsigned int magic;
49 int last;
50};
51#endif /* BUFFER_ALLOC_DEBUG */
52
34void buffer_init(void) 53void buffer_init(void)
35{ 54{
36 /* 32-bit aligned */ 55 /* 32-bit aligned */
37 audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3); 56 audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3);
57#ifdef BUFFER_ALLOC_DEBUG
58 audiobuf_orig_start = audiobuf;
59#endif /* BUFFER_ALLOC_DEBUG */
38} 60}
39 61
40void *buffer_alloc(size_t size) 62void *buffer_alloc(size_t size)
41{ 63{
42 void *retval = audiobuf; 64 void *retval = audiobuf;
43 65#ifdef BUFFER_ALLOC_DEBUG
44 audiobuf += size; 66 struct buffer_start_marker *start;
67 struct buffer_end_marker *end;
68#endif /* BUFFER_ALLOC_DEBUG */
69
45 /* 32-bit aligned */ 70 /* 32-bit aligned */
46 audiobuf = (void *)(((unsigned long)audiobuf + 3) & ~3); 71 size = (size + 3) & ~3;
72
73#ifdef BUFFER_ALLOC_DEBUG
74 retval +=sizeof(struct buffer_start_marker);
75 end=(struct buffer_end_marker*)(audiobuf - sizeof(struct buffer_end_marker));
76 if(end->magic == BUF_MAGIC)
77 {
78 end->last=0;
79 }
80 start=(struct buffer_start_marker*)audiobuf;
81 start->magic = BUF_MAGIC;
82 start->buffer_size = size;
83 end=(struct buffer_end_marker*)(audiobuf+sizeof(struct buffer_start_marker)+size);
84 end->magic = BUF_MAGIC;
85 end->last = 1;
86
87 audiobuf = ((unsigned char *)end) + sizeof(struct buffer_end_marker);
88
89 logf("Alloc %x %d",(unsigned int)retval,size);
90#else /* !BUFFER_ALLOC_DEBUG */
91 audiobuf += size;
92#endif /* BUFFER_ALLOC_DEBUG */
93
94 if (audiobuf > audiobufend) {
95 panicf("OOM: %d bytes", (int) size);
96 }
47 97
48 return retval; 98 return retval;
49} 99}
50 100
101#ifdef BUFFER_ALLOC_DEBUG
102void buffer_alloc_check(char *name)
103{
104 unsigned char *buf_ptr = audiobuf_orig_start;
105 struct buffer_start_marker *start;
106 struct buffer_end_marker *end;
107
108
109 while(buf_ptr < audiobuf)
110 {
111 start=(struct buffer_start_marker*)buf_ptr;
112 if(start->magic != BUF_MAGIC)
113 {
114 panicf("%s corrupted buffer %x start", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
115 }
116 end=(struct buffer_end_marker*)(buf_ptr+sizeof(struct buffer_start_marker)+start->buffer_size);
117 if(end->magic != BUF_MAGIC)
118 {
119 panicf("%s corrupted %x end", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
120 }
121 if(end->last)
122 break;
123 buf_ptr=((unsigned char *)end)+sizeof(struct buffer_end_marker);
124 }
125}
126#endif /* BUFFER_ALLOC_DEBUG */
diff --git a/firmware/export/buffer.h b/firmware/export/buffer.h
index f0525edd68..18f53f0000 100644
--- a/firmware/export/buffer.h
+++ b/firmware/export/buffer.h
@@ -39,4 +39,8 @@ extern unsigned char *audiobuf;
39void buffer_init(void) INIT_ATTR; 39void buffer_init(void) INIT_ATTR;
40void *buffer_alloc(size_t size); 40void *buffer_alloc(size_t size);
41 41
42#ifdef BUFFER_ALLOC_DEBUG
43void buffer_alloc_check(char *name);
44#endif
45
42#endif 46#endif
diff --git a/firmware/thread.c b/firmware/thread.c
index b3d8ec3970..655af1a940 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -27,6 +27,7 @@
27#include "kernel.h" 27#include "kernel.h"
28#include "cpu.h" 28#include "cpu.h"
29#include "string.h" 29#include "string.h"
30#include "buffer.h"
30#ifdef RB_PROFILE 31#ifdef RB_PROFILE
31#include <profile.h> 32#include <profile.h>
32#endif 33#endif
@@ -1160,6 +1161,16 @@ void switch_thread(void)
1160 if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0) 1161 if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0)
1161 thread_stkov(thread); 1162 thread_stkov(thread);
1162 1163
1164#ifdef BUFFER_ALLOC_DEBUG
1165 /* Check if the current thread just did bad things with buffer_alloc()ed
1166 * memory */
1167 {
1168 static char name[32];
1169 thread_get_name(name, 32, thread);
1170 buffer_alloc_check(name);
1171 }
1172#endif
1173
1163#if NUM_CORES > 1 1174#if NUM_CORES > 1
1164 /* Run any blocking operations requested before switching/sleeping */ 1175 /* Run any blocking operations requested before switching/sleeping */
1165 run_blocking_ops(core, thread); 1176 run_blocking_ops(core, thread);