diff options
-rw-r--r-- | src/lib/libc/stdlib/malloc.3 | 4 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 83 |
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 | |||
79 | or larger, the memory returned will be page-aligned. | 79 | or larger, the memory returned will be page-aligned. |
80 | .Pp | 80 | .Pp |
81 | Allocation of a zero size object returns a pointer to a zero size object. | 81 | Allocation of a zero size object returns a pointer to a zero size object. |
82 | This zero size object is access protected, so any access to it will | ||
83 | generate an exception (SIGSEGV) | ||
82 | .Pp | 84 | .Pp |
83 | The | 85 | The |
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) |
11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.42 2001/05/11 15:30:14 art Exp $"; | 11 | static 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); |