aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Bucur <stefanb@zytor.com>2008-08-15 16:52:31 +0300
committerStefan Bucur <stefan@stefan-ubumac.(none)>2009-03-15 10:12:27 +0200
commitf046937fc4392e0f5b69be1312a597188c394fb6 (patch)
treec8df85b2c7ebf2639c8ea8cd1de8fdf5a62b726c
parentd7c4f9bc3852fa77c0dd9ea119f91993fa52663d (diff)
downloadsyslinux-elf-f046937fc4392e0f5b69be1312a597188c394fb6.tar.gz
syslinux-elf-f046937fc4392e0f5b69be1312a597188c394fb6.tar.xz
syslinux-elf-f046937fc4392e0f5b69be1312a597188c394fb6.zip
Implemented automatic memory cleanup for executable modules.
-rw-r--r--com32/elflink/exec.c11
-rw-r--r--com32/include/stdlib.h5
-rw-r--r--com32/lib/free.c15
3 files changed, 30 insertions, 1 deletions
diff --git a/com32/elflink/exec.c b/com32/elflink/exec.c
index 4f300c23..33d5ff7a 100644
--- a/com32/elflink/exec.c
+++ b/com32/elflink/exec.c
@@ -114,10 +114,21 @@ int spawnv(const char *name, const char **argv) {
if (*(module->main_func) != NULL) {
const char **last_arg = argv;
+ void *old_tag;
while (*last_arg != NULL)
last_arg++;
+ // Setup the memory allocation context
+ old_tag = __mem_get_tag_global();
+ __mem_set_tag_global(module);
+
+ // Execute the program
ret_val = (*(module->main_func))(last_arg - argv, argv);
+
+ // Clean up the allocation context
+ __free_tagged(module);
+ // Restore the allocation context
+ __mem_set_tag_global(old_tag);
} else {
// We can't execute without a main function
module_unload(module);
diff --git a/com32/include/stdlib.h b/com32/include/stdlib.h
index cd1d83c6..0b1e8f25 100644
--- a/com32/include/stdlib.h
+++ b/com32/include/stdlib.h
@@ -23,7 +23,7 @@ __extern long atol(const char *);
__extern long long atoll(const char *);
__extern __noreturn exit(int);
__extern __noreturn _Exit(int);
-__extern void free(void *);
+
static __inline__ long labs(long __n) {
return (__n < 0L) ? -__n : __n;
}
@@ -39,6 +39,7 @@ __extern __mallocfunc void *realloc(void *, size_t);
__extern int posix_memalign(void **memptr, size_t alignment,
size_t size);
+__extern void free(void *);
__extern void *__mem_get_tag_global();
@@ -47,6 +48,8 @@ __extern void __mem_set_tag_global(void *tag);
__extern void *__mem_get_tag(void *memptr);
__extern void __mem_set_tag(void *memptr, void *tag);
+__extern void __free_tagged(void *tag);
+
static __inline__ void *__malloc_tagged(size_t size, void *tag) {
void *result = malloc(size);
__mem_set_tag(result, tag);
diff --git a/com32/lib/free.c b/com32/lib/free.c
index 437a8fc0..5d0f3c51 100644
--- a/com32/lib/free.c
+++ b/com32/lib/free.c
@@ -79,3 +79,18 @@ void free(void *ptr)
/* Here we could insert code to return memory to the system. */
}
+
+void __free_tagged(void *tag) {
+ struct free_arena_header *fp, *nfp;
+
+ for (fp = __malloc_head.a.next, nfp = fp->a.next;
+ ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
+ fp = nfp, nfp = fp->a.next) {
+
+ if (ARENA_TYPE_GET(fp->a.attrs) == ARENA_TYPE_USED &&
+ fp->a.tag == tag) {
+ // Free this block
+ __free_block(fp);
+ }
+ }
+}