summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libc/stdlib/malloc.34
-rw-r--r--src/lib/libc/stdlib/malloc.c83
2 files changed, 50 insertions, 37 deletions
diff --git a/src/lib/libc/stdlib/malloc.3 b/src/lib/libc/stdlib/malloc.3
index e65668566e..2f7e0c61b5 100644
--- a/src/lib/libc/stdlib/malloc.3
+++ b/src/lib/libc/stdlib/malloc.3
@@ -34,7 +34,7 @@
34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35.\" SUCH DAMAGE. 35.\" SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: malloc.3,v 1.20 2000/10/25 15:23:15 aaron Exp $ 37.\" $OpenBSD: malloc.3,v 1.21 2001/10/30 17:01:07 tdeval Exp $
38.\" 38.\"
39.Dd August 27, 1996 39.Dd August 27, 1996
40.Dt MALLOC 3 40.Dt MALLOC 3
@@ -79,6 +79,8 @@ If the space is of
79or larger, the memory returned will be page-aligned. 79or larger, the memory returned will be page-aligned.
80.Pp 80.Pp
81Allocation of a zero size object returns a pointer to a zero size object. 81Allocation of a zero size object returns a pointer to a zero size object.
82This zero size object is access protected, so any access to it will
83generate an exception (SIGSEGV)
82.Pp 84.Pp
83The 85The
84.Fn calloc 86.Fn calloc
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index deef086428..3833bab5f9 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.42 2001/05/11 15:30:14 art Exp $"; 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.43 2001/10/30 17:01:07 tdeval Exp $";
12#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
13 13
14/* 14/*
@@ -63,28 +63,8 @@ static char rcsid[] = "$OpenBSD: malloc.c,v 1.42 2001/05/11 15:30:14 art Exp $";
63 * 63 *
64 */ 64 */
65 65
66#if defined(__i386__) && defined(__FreeBSD__) 66#if defined(__OpenBSD__) && defined(__sparc__)
67# define malloc_pageshift 12U 67# define malloc_pageshift 13U
68# define malloc_minsize 16U
69#endif /* __i386__ && __FreeBSD__ */
70
71#if defined(__sparc__) && !defined(__OpenBSD__)
72# define malloc_pageshift 12U
73# define malloc_minsize 16U
74# define MAP_ANON (0)
75# define USE_DEV_ZERO
76# define MADV_FREE MADV_DONTNEED
77#endif /* __sparc__ */
78
79/* Insert your combination here... */
80#if defined(__FOOCPU__) && defined(__BAROS__)
81# define malloc_pageshift 12U
82# define malloc_minsize 16U
83#endif /* __FOOCPU__ && __BAROS__ */
84
85#if defined(__OpenBSD__) && !defined(__sparc__)
86# define malloc_pageshift (PGSHIFT)
87# define malloc_minsize 16U
88#endif /* __OpenBSD__ */ 68#endif /* __OpenBSD__ */
89 69
90#ifdef _THREAD_SAFE 70#ifdef _THREAD_SAFE
@@ -164,7 +144,7 @@ struct pgfree {
164#define MALLOC_MAGIC ((struct pginfo*) 4) 144#define MALLOC_MAGIC ((struct pginfo*) 4)
165 145
166#ifndef malloc_pageshift 146#ifndef malloc_pageshift
167#define malloc_pageshift 12U 147#define malloc_pageshift (PGSHIFT)
168#endif 148#endif
169 149
170#ifndef malloc_minsize 150#ifndef malloc_minsize
@@ -730,7 +710,13 @@ malloc_make_chunks(bits)
730 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS); 710 (((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
731 711
732 /* Don't waste more than two chunks on this */ 712 /* Don't waste more than two chunks on this */
733 if ((1UL<<(bits)) <= l+l) { 713 /*
714 * If we are to allocate a memory protected page for the malloc(0)
715 * case (when bits=0), it must be from a different page than the
716 * pginfo page.
717 * --> Treat it like the big chunk alloc, get a second data page.
718 */
719 if (bits != 0 && (1UL<<(bits)) <= l+l) {
734 bp = (struct pginfo *)pp; 720 bp = (struct pginfo *)pp;
735 } else { 721 } else {
736 bp = (struct pginfo *)imalloc(l); 722 bp = (struct pginfo *)imalloc(l);
@@ -745,6 +731,16 @@ malloc_make_chunks(bits)
745 bp->total = bp->free = malloc_pagesize >> bits; 731 bp->total = bp->free = malloc_pagesize >> bits;
746 bp->page = pp; 732 bp->page = pp;
747 733
734 /* memory protect the page allocated in the malloc(0) case */
735 if (bits == 0) {
736 k = mprotect(pp, malloc_pagesize, PROT_NONE);
737 if (k < 0) {
738 ifree(pp);
739 ifree(bp);
740 return 0;
741 }
742 }
743
748 /* set all valid bits in the bitmap */ 744 /* set all valid bits in the bitmap */
749 k = bp->total; 745 k = bp->total;
750 i = 0; 746 i = 0;
@@ -792,14 +788,19 @@ malloc_bytes(size)
792 u_long *lp; 788 u_long *lp;
793 789
794 /* Don't bother with anything less than this */ 790 /* Don't bother with anything less than this */
795 if (size < malloc_minsize) 791 /* unless we have a malloc(0) requests */
792 if (size != 0 && size < malloc_minsize)
796 size = malloc_minsize; 793 size = malloc_minsize;
797 794
798 /* Find the right bucket */ 795 /* Find the right bucket */
799 j = 1; 796 if (size == 0)
800 i = size-1; 797 j=0;
801 while (i >>= 1) 798 else {
802 j++; 799 j = 1;
800 i = size-1;
801 while (i >>= 1)
802 j++;
803 }
803 804
804 /* If it's empty, make a page more of that size chunks */ 805 /* If it's empty, make a page more of that size chunks */
805 if (!page_dir[j] && !malloc_make_chunks(j)) 806 if (!page_dir[j] && !malloc_make_chunks(j))
@@ -830,7 +831,7 @@ malloc_bytes(size)
830 k += (lp-bp->bits)*MALLOC_BITS; 831 k += (lp-bp->bits)*MALLOC_BITS;
831 k <<= bp->shift; 832 k <<= bp->shift;
832 833
833 if (malloc_junk) 834 if (malloc_junk && bp->shift != 0)
834 memset((char *)bp->page + k, SOME_JUNK, bp->size); 835 memset((char *)bp->page + k, SOME_JUNK, bp->size);
835 836
836 return (u_char *)bp->page + k; 837 return (u_char *)bp->page + k;
@@ -955,10 +956,13 @@ irealloc(ptr, size)
955 956
956 if (p) { 957 if (p) {
957 /* copy the lesser of the two sizes, and free the old one */ 958 /* copy the lesser of the two sizes, and free the old one */
958 if (osize < size) 959 /* Don't move from/to 0 sized region !!! */
959 memcpy(p, ptr, osize); 960 if (osize != 1 && size != 0) {
960 else 961 if (osize < size)
961 memcpy(p, ptr, size); 962 memcpy(p, ptr, osize);
963 else
964 memcpy(p, ptr, size);
965 }
962 ifree(ptr); 966 ifree(ptr);
963 } 967 }
964 return p; 968 return p;
@@ -1127,7 +1131,7 @@ free_bytes(ptr, index, info)
1127 return; 1131 return;
1128 } 1132 }
1129 1133
1130 if (malloc_junk) 1134 if (malloc_junk && info->shift != 0)
1131 memset(ptr, SOME_JUNK, info->size); 1135 memset(ptr, SOME_JUNK, info->size);
1132 1136
1133 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS); 1137 info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
@@ -1163,6 +1167,13 @@ free_bytes(ptr, index, info)
1163 1167
1164 /* Free the page & the info structure if need be */ 1168 /* Free the page & the info structure if need be */
1165 page_dir[ptr2index(info->page)] = MALLOC_FIRST; 1169 page_dir[ptr2index(info->page)] = MALLOC_FIRST;
1170
1171 /* If the page was mprotected, unprotect it before releasing it */
1172 if (info->shift == 0) {
1173 mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
1174 /* Do we have to care if mprotect succeeds here ? */
1175 }
1176
1166 vp = info->page; /* Order is important ! */ 1177 vp = info->page; /* Order is important ! */
1167 if(vp != (void*)info) 1178 if(vp != (void*)info)
1168 ifree(info); 1179 ifree(info);