4e3b248f644d7c9cc6ba888b9dfe58d75273249c
[yaboot.git] / lib / malloc.c
1 /* Dumb memory allocation routines
2    
3    Copyright (C) 1997 Paul Mackerras
4                  1996 Maurizio Plaza
5                  1996 Jakub Jelinek
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "types.h"
22 #include "stddef.h"
23
24 /* Imported functions */
25 extern void prom_printf (char *fmt, ...);
26
27 static char *malloc_ptr = 0;
28 static char *malloc_top = 0;
29 static char *last_alloc = 0;
30
31 void malloc_init(void *bottom, unsigned long size)
32 {
33         malloc_ptr = bottom;
34         malloc_top = bottom + size;
35 }
36
37 void malloc_dispose(void)
38 {
39         malloc_ptr = 0;
40         last_alloc = 0;
41 }
42
43 void *malloc (unsigned int size)
44 {
45     char *caddr;
46
47     if (!malloc_ptr)
48         return NULL;
49     if ((malloc_ptr + size + sizeof(int)) > malloc_top) {
50         prom_printf("malloc failed\n");
51         return NULL;
52     }
53     *(int *)malloc_ptr = size;
54     caddr = malloc_ptr + sizeof(int);
55     malloc_ptr += size + sizeof(int);
56     last_alloc = caddr;
57     malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + 3) & (~3));
58     return caddr;
59 }
60
61 void *realloc(void *ptr, unsigned int size)
62 {
63     char *caddr, *oaddr = ptr;
64
65     if (!malloc_ptr)
66         return NULL;
67     if (oaddr == last_alloc) {
68         if (oaddr + size > malloc_top) {
69                 prom_printf("realloc failed\n");
70                 return NULL;
71         }
72         *(int *)(oaddr - sizeof(int)) = size;
73         malloc_ptr = oaddr + size;
74         return oaddr;
75     }
76     caddr = malloc(size);
77     if (caddr != 0 && oaddr != 0)
78         memcpy(caddr, oaddr, *(int *)(oaddr - sizeof(int)));
79     return caddr;
80 }
81
82 void free (void *m)
83 {
84     if (!malloc_ptr)
85         return;
86     if (m == last_alloc)
87         malloc_ptr = (char *) last_alloc - sizeof(int);
88 }
89
90 void mark (void **ptr)
91 {
92     if (!malloc_ptr)
93         return;
94     *ptr = (void *) malloc_ptr;
95 }
96
97 void release (void *ptr)
98 {
99     if (!malloc_ptr)
100         return;
101     malloc_ptr = (char *) ptr;
102 }
103
104 char *strdup(char const *str)
105 {
106     char *p = malloc(strlen(str) + 1);
107     if (p)
108          strcpy(p, str);
109     return p;
110 }