Set up go function pointer table
[akaros.git] / user / electric-fence / efence.c
1 /*
2  * Electric Fence - Red-Zone memory allocator.
3  * Bruce Perens, 1988, 1993
4  *
5  * For email below, drop spaces and <spam-buster> tag.
6  * MODIFIED:  March 20, 2014 (jric<spam-buster> @ <spam-buster> chegg DOT com)
7  *
8  * This is a special version of malloc() and company for debugging software
9  * that is suspected of overrunning or underrunning the boundaries of a
10  * malloc buffer, or touching free memory.
11  *
12  * It arranges for each malloc buffer to be followed (or preceded)
13  * in the address space by an inaccessable virtual memory page,
14  * and for free memory to be inaccessable. If software touches the
15  * inaccessable page, it will get an immediate segmentation
16  * fault. It is then trivial to uncover the offending code using a debugger.
17  *
18  * An advantage of this product over most malloc debuggers is that this one
19  * detects reading out of bounds as well as writing, and this one stops on
20  * the exact instruction that causes the error, rather than waiting until the
21  * next boundary check.
22  *
23  * There is one product that debugs malloc buffer overruns
24  * better than Electric Fence: "Purify" from Purify Systems, and that's only
25  * a small part of what Purify does. I'm not affiliated with Purify, I just
26  * respect a job well done.
27  *
28  * This version of malloc() should not be linked into production software,
29  * since it tremendously increases the time and memory overhead of malloc().
30  * Each malloc buffer will consume a minimum of two virtual memory pages,
31  * this is 16 kilobytes on many systems. On some systems it will be necessary
32  * to increase the amount of swap space in order to debug large programs that
33  * perform lots of allocation, because of the per-buffer overhead.
34  *
35  */
36 #include "efence.h"
37 #include <errno.h>
38 #include <memory.h>
39 #include <pthread.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include <parlib/spinlock.h>
45 #include <parlib/stdio.h>
46
47 /*
48  * MEMORY_CREATION_SIZE is the amount of memory to get from the operating
49  * system at one time. We'll break that memory down into smaller pieces for
50  * malloc buffers. One megabyte is probably a good value.
51  */
52 #define MEMORY_CREATION_SIZE 1024 * 1024
53
54 /*
55  * Enum Mode indicates the status of a malloc buffer.
56  */
57 enum _Mode {
58         NOT_IN_USE = 0, /* Available to represent a malloc buffer. */
59         FREE,           /* A free buffer. */
60         ALLOCATED,      /* A buffer that is in use. */
61         PROTECTED,      /* A freed buffer that can not be allocated again. */
62         INTERNAL_USE    /* A buffer used internally by malloc(). */
63 };
64 typedef enum _Mode Mode;
65
66 /*
67  * Struct Slot contains all of the information about a malloc buffer except
68  * for the contents of its memory.
69  */
70 struct _Slot {
71         void *userAddress;
72         void *internalAddress;
73         size_t userSize;
74         size_t internalSize;
75         Mode mode;
76 };
77 typedef struct _Slot Slot;
78
79 /*
80  * EF_ALIGNMENT is a global variable used to control the default alignment
81  * of buffers returned by malloc(), calloc(), and realloc(). It is all-caps
82  * so that its name matches the name of the environment variable that is used
83  * to set it. This gives the programmer one less name to remember.
84  * If the value is -1, it will be set from the environment or sizeof(int)
85  * at run time.
86  */
87 int EF_ALIGNMENT = -1;
88
89 /*
90  * EF_PROTECT_FREE is a global variable used to control the disposition of
91  * memory that is released using free(). It is all-caps so that its name
92  * matches the name of the environment variable that is used to set it.
93  * If its value is greater non-zero, memory released by free is made
94  * inaccessable and never allocated again. Any software that touches free
95  * memory will then get a segmentation fault. If its value is zero, freed
96  * memory will be available for reallocation, but will still be inaccessable
97  * until it is reallocated.
98  * If the value is -1, it will be set from the environment or to 0 at run-time.
99  */
100 int EF_PROTECT_FREE = -1;
101
102 /*
103  * EF_PROTECT_BELOW is used to modify the behavior of the allocator. When
104  * its value is non-zero, the allocator will place an inaccessable page
105  * immediately _before_ the malloc buffer in the address space, instead
106  * of _after_ it. Use this to detect malloc buffer under-runs, rather than
107  * over-runs. It won't detect both at the same time, so you should test your
108  * software twice, once with this value clear, and once with it set.
109  * If the value is -1, it will be set from the environment or to zero at
110  * run-time
111  */
112 int EF_PROTECT_BELOW = -1;
113
114 /*
115  * EF_ALLOW_MALLOC_0 is set if Electric Fence is to allow malloc(0). I
116  * trap malloc(0) by default because it is a common source of bugs.
117  */
118 int EF_ALLOW_MALLOC_0 = -1;
119
120 /*
121  * EF_FREE_WIPES is set if Electric Fence is to wipe the memory content
122  * of freed blocks.  This makes it easier to check if memory is freed or
123  * not
124  */
125 int EF_FREE_WIPES = -1;
126
127 /*
128  * allocationList points to the array of slot structures used to manage the
129  * malloc arena.
130  */
131 static Slot *allocationList = 0;
132
133 /*
134  * allocationListSize is the size of the allocation list. This will always
135  * be a multiple of the page size.
136  */
137 static size_t allocationListSize = 0;
138
139 /*
140  * slotCount is the number of Slot structures in allocationList.
141  */
142 static size_t slotCount = 0;
143
144 /*
145  * unUsedSlots is the number of Slot structures that are currently available
146  * to represent new malloc buffers. When this number gets too low, we will
147  * create new slots.
148  */
149 static size_t unUsedSlots = 0;
150
151 /*
152  * slotsPerPage is the number of slot structures that fit in a virtual
153  * memory page.
154  */
155 static size_t slotsPerPage = 0;
156
157 /*
158  * internalUse is set when allocating and freeing the allocatior-internal
159  * data structures.
160  */
161 static int internalUse = 0;
162
163 /*
164  * noAllocationListProtection is set to tell malloc() and free() not to
165  * manipulate the protection of the allocation list. This is only set in
166  * realloc(), which does it to save on slow system calls, and in
167  * allocateMoreSlots(), which does it because it changes the allocation list.
168  */
169 static int noAllocationListProtection = 0;
170
171 /*
172  * bytesPerPage is set at run-time to the number of bytes per virtual-memory
173  * page, as returned by Page_Size().
174  */
175 static size_t bytesPerPage = 0;
176
177 /*
178  * mutex to enable multithreaded operation
179  */
180 static struct spin_pdr_lock pdr_lock = SPINPDR_INITIALIZER;
181 #define RECURSE_UNLOCKED -1
182 static long lockholder = RECURSE_UNLOCKED;
183 static int lock_depth;
184
185 static long who_am_i(void)
186 {
187         if (in_vcore_context())
188                 return vcore_id();
189         else
190                 return (long)current_uthread;
191 }
192
193 static void lock(void)
194 {
195         long me = who_am_i();
196
197         if (!spin_pdr_trylock(&pdr_lock)) {
198                 if (lockholder == me) {
199                         lock_depth++;
200                         return;
201                 }
202                 spin_pdr_lock(&pdr_lock);
203         }
204         lockholder = me;
205         lock_depth = 1;
206 }
207
208 static void unlock(void)
209 {
210         lock_depth--;
211         if (!lock_depth) {
212                 lockholder = RECURSE_UNLOCKED;
213                 spin_pdr_unlock(&pdr_lock);
214         }
215 }
216
217 /*
218  * internalError is called for those "shouldn't happen" errors in the
219  * allocator.
220  */
221 static void internalError(void)
222 {
223         EF_Abort("Internal error in allocator.");
224 }
225
226 /*
227  * initialize sets up the memory allocation arena and the run-time
228  * configuration information.
229  */
230 static void initialize(void)
231 {
232         size_t size = MEMORY_CREATION_SIZE;
233         size_t slack;
234         char *string;
235         Slot *slot;
236
237         /*
238          * Import the user's environment specification of the default
239          * alignment for malloc(). We want that alignment to be under
240          * user control, since smaller alignment lets us catch more bugs,
241          * however some software will break if malloc() returns a buffer
242          * that is not word-aligned.
243          *
244          * I would like
245          * alignment to be zero so that we could catch all one-byte
246          * overruns, however if malloc() is asked to allocate an odd-size
247          * buffer and returns an address that is not word-aligned, or whose
248          * size is not a multiple of the word size, software breaks.
249          * This was the case with the Sun string-handling routines,
250          * which can do word fetches up to three bytes beyond the end of a
251          * string. I handle this problem in part by providing
252          * byte-reference-only versions of the string library functions, but
253          * there are other functions that break, too. Some in X Windows, one
254          * in Sam Leffler's TIFF library, and doubtless many others.
255          */
256         if (EF_ALIGNMENT == -1) {
257                 if ((string = getenv("EF_ALIGNMENT")) != 0)
258                         EF_ALIGNMENT = (size_t)atoi(string);
259                 else
260                         EF_ALIGNMENT = sizeof(int);
261         }
262
263         /*
264          * See if the user wants to protect the address space below a buffer,
265          * rather than that above a buffer.
266          */
267         if (EF_PROTECT_BELOW == -1) {
268                 if ((string = getenv("EF_PROTECT_BELOW")) != 0)
269                         EF_PROTECT_BELOW = (atoi(string) != 0);
270                 else
271                         EF_PROTECT_BELOW = 0;
272         }
273
274         /*
275          * See if the user wants to protect memory that has been freed until
276          * the program exits, rather than until it is re-allocated.
277          */
278         if (EF_PROTECT_FREE == -1) {
279                 if ((string = getenv("EF_PROTECT_FREE")) != 0)
280                         EF_PROTECT_FREE = (atoi(string) != 0);
281                 else
282                         EF_PROTECT_FREE = 0;
283         }
284
285         /*
286          * See if the user wants to allow malloc(0).
287          */
288         if (EF_ALLOW_MALLOC_0 == -1) {
289                 if ((string = getenv("EF_ALLOW_MALLOC_0")) != 0)
290                         EF_ALLOW_MALLOC_0 = (atoi(string) != 0);
291                 else
292                         EF_ALLOW_MALLOC_0 = 0;
293         }
294
295         /*
296          * See if the user wants us to wipe out freed memory.
297          */
298         if (EF_FREE_WIPES == -1) {
299                 if ((string = getenv("EF_FREE_WIPES")) != 0)
300                         EF_FREE_WIPES = (atoi(string) != 0);
301                 else
302                         EF_FREE_WIPES = 0;
303         }
304
305         /*
306          * Get the run-time configuration of the virtual memory page size.
307          */
308         bytesPerPage = Page_Size();
309
310         /*
311          * Figure out how many Slot structures to allocate at one time.
312          */
313         slotCount = slotsPerPage = bytesPerPage / sizeof(Slot);
314         allocationListSize = bytesPerPage;
315
316         if (allocationListSize > size)
317                 size = allocationListSize;
318
319         if ((slack = size % bytesPerPage) != 0)
320                 size += bytesPerPage - slack;
321
322         /*
323          * Allocate memory, and break it up into two malloc buffers. The
324          * first buffer will be used for Slot structures, the second will
325          * be marked free.
326          */
327         slot = allocationList = (Slot *)Page_Create(size);
328         memset((char *)allocationList, 0, allocationListSize);
329
330         slot[0].internalSize = slot[0].userSize = allocationListSize;
331         slot[0].internalAddress = slot[0].userAddress = allocationList;
332         slot[0].mode = INTERNAL_USE;
333         if (size > allocationListSize) {
334                 slot[1].internalAddress = slot[1].userAddress =
335                     ((char *)slot[0].internalAddress) + slot[0].internalSize;
336                 slot[1].internalSize = slot[1].userSize = size - slot[0].internalSize;
337                 slot[1].mode = FREE;
338         }
339
340         /*
341          * Deny access to the free page, so that we will detect any software
342          * that treads upon free memory.
343          */
344         Page_DenyAccess(slot[1].internalAddress, slot[1].internalSize);
345
346         /*
347          * Account for the two slot structures that we've used.
348          */
349         unUsedSlots = slotCount - 2;
350 }
351
352 /*
353  * allocateMoreSlots is called when there are only enough slot structures
354  * left to support the allocation of a single malloc buffer.
355  */
356 static void allocateMoreSlots(void)
357 {
358         size_t newSize = allocationListSize + bytesPerPage;
359         void *newAllocation;
360         void *oldAllocation = allocationList;
361
362         Page_AllowAccess(allocationList, allocationListSize);
363         noAllocationListProtection = 1;
364         internalUse = 1;
365
366         newAllocation = malloc(newSize);
367         memcpy(newAllocation, allocationList, allocationListSize);
368         memset(&(((char *)newAllocation)[allocationListSize]), 0, bytesPerPage);
369
370         allocationList = (Slot *)newAllocation;
371         allocationListSize = newSize;
372         slotCount += slotsPerPage;
373         unUsedSlots += slotsPerPage;
374
375         free(oldAllocation);
376
377         /*
378          * Keep access to the allocation list open at this point, because
379          * I am returning to memalign(), which needs that access.
380          */
381         noAllocationListProtection = 0;
382         internalUse = 0;
383 }
384
385 /*
386  * This is the memory allocator. When asked to allocate a buffer, allocate
387  * it in such a way that the end of the buffer is followed by an inaccessable
388  * memory page. If software overruns that buffer, it will touch the bad page
389  * and get an immediate segmentation fault. It's then easy to zero in on the
390  * offending code with a debugger.
391  *
392  * There are a few complications. If the user asks for an odd-sized buffer,
393  * we would have to have that buffer start on an odd address if the byte after
394  * the end of the buffer was to be on the inaccessable page. Unfortunately,
395  * there is lots of software that asks for odd-sized buffers and then
396  * requires that the returned address be word-aligned, or the size of the
397  * buffer be a multiple of the word size. An example are the string-processing
398  * functions on Sun systems, which do word references to the string memory
399  * and may refer to memory up to three bytes beyond the end of the string.
400  * For this reason, I take the alignment requests to memalign() and valloc()
401  * seriously, and
402  *
403  * Electric Fence wastes lots of memory. I do a best-fit allocator here
404  * so that it won't waste even more. It's slow, but thrashing because your
405  * working set is too big for a system's RAM is even slower.
406  */
407 extern C_LINKAGE void *memalign(size_t alignment, size_t userSize)
408 {
409         register Slot *slot;
410         register size_t count;
411         Slot *fullSlot = 0;
412         Slot *emptySlots[2];
413         size_t internalSize;
414         size_t slack;
415         char *address;
416
417         if (allocationList == 0)
418                 initialize();
419
420         lock();
421         if (userSize == 0 && !EF_ALLOW_MALLOC_0)
422                 EF_Abort("Allocating 0 bytes, probably a bug.");
423
424         /*
425          * If EF_PROTECT_BELOW is set, all addresses returned by malloc()
426          * and company will be page-aligned.
427          */
428         if (!EF_PROTECT_BELOW && alignment > 1) {
429                 if ((slack = userSize % alignment) != 0)
430                         userSize += alignment - slack;
431         }
432
433         /*
434          * The internal size of the buffer is rounded up to the next page-size
435          * boudary, and then we add another page's worth of memory for the
436          * dead page.
437          */
438         internalSize = userSize + bytesPerPage;
439         if ((slack = internalSize % bytesPerPage) != 0)
440                 internalSize += bytesPerPage - slack;
441
442         /*
443          * These will hold the addresses of two empty Slot structures, that
444          * can be used to hold information for any memory I create, and any
445          * memory that I mark free.
446          */
447         emptySlots[0] = 0;
448         emptySlots[1] = 0;
449
450         /*
451          * The internal memory used by the allocator is currently
452          * inaccessable, so that errant programs won't scrawl on the
453          * allocator's arena. I'll un-protect it here so that I can make
454          * a new allocation. I'll re-protect it before I return.
455          */
456         if (!noAllocationListProtection)
457                 Page_AllowAccess(allocationList, allocationListSize);
458
459         /*
460          * If I'm running out of empty slots, create some more before
461          * I don't have enough slots left to make an allocation.
462          */
463         if (!internalUse && unUsedSlots < 7) {
464                 allocateMoreSlots();
465         }
466
467         /*
468          * Iterate through all of the slot structures. Attempt to find a slot
469          * containing free memory of the exact right size. Accept a slot with
470          * more memory than we want, if the exact right size is not available.
471          * Find two slot structures that are not in use. We will need one if
472          * we split a buffer into free and allocated parts, and the second if
473          * we have to create new memory and mark it as free.
474          *
475          */
476
477         for (slot = allocationList, count = slotCount; count > 0; count--) {
478                 if (slot->mode == FREE && slot->internalSize >= internalSize) {
479                         if (!fullSlot || slot->internalSize < fullSlot->internalSize) {
480                                 fullSlot = slot;
481                                 if (slot->internalSize == internalSize && emptySlots[0])
482                                         break; /* All done, */
483                         }
484                 } else if (slot->mode == NOT_IN_USE) {
485                         if (!emptySlots[0])
486                                 emptySlots[0] = slot;
487                         else if (!emptySlots[1])
488                                 emptySlots[1] = slot;
489                         else if (fullSlot && fullSlot->internalSize == internalSize)
490                                 break; /* All done. */
491                 }
492                 slot++;
493         }
494         if (!emptySlots[0])
495                 internalError();
496
497         if (!fullSlot) {
498                 /*
499                  * I get here if I haven't been able to find a free buffer
500                  * with all of the memory I need. I'll have to create more
501                  * memory. I'll mark it all as free, and then split it into
502                  * free and allocated portions later.
503                  */
504                 size_t chunkSize = MEMORY_CREATION_SIZE;
505
506                 if (!emptySlots[1])
507                         internalError();
508
509                 if (chunkSize < internalSize)
510                         chunkSize = internalSize;
511
512                 if ((slack = chunkSize % bytesPerPage) != 0)
513                         chunkSize += bytesPerPage - slack;
514
515                 /* Use up one of the empty slots to make the full slot. */
516                 fullSlot = emptySlots[0];
517                 emptySlots[0] = emptySlots[1];
518                 fullSlot->internalAddress = Page_Create(chunkSize);
519                 fullSlot->internalSize = chunkSize;
520                 fullSlot->mode = FREE;
521                 unUsedSlots--;
522         }
523
524         /*
525          * If I'm allocating memory for the allocator's own data structures,
526          * mark it INTERNAL_USE so that no errant software will be able to
527          * free it.
528          */
529         if (internalUse)
530                 fullSlot->mode = INTERNAL_USE;
531         else
532                 fullSlot->mode = ALLOCATED;
533
534         /*
535          * If the buffer I've found is larger than I need, split it into
536          * an allocated buffer with the exact amount of memory I need, and
537          * a free buffer containing the surplus memory.
538          */
539         if (fullSlot->internalSize > internalSize) {
540                 emptySlots[0]->internalSize = fullSlot->internalSize - internalSize;
541                 emptySlots[0]->internalAddress =
542                     ((char *)fullSlot->internalAddress) + internalSize;
543                 emptySlots[0]->mode = FREE;
544                 fullSlot->internalSize = internalSize;
545                 unUsedSlots--;
546         }
547
548         if (!EF_PROTECT_BELOW) {
549                 /*
550                  * Arrange the buffer so that it is followed by an inaccessable
551                  * memory page. A buffer overrun that touches that page will
552                  * cause a segmentation fault.
553                  */
554                 address = (char *)fullSlot->internalAddress;
555
556                 /* Set up the "live" page. */
557                 if (internalSize - bytesPerPage > 0)
558                         Page_AllowAccess(fullSlot->internalAddress,
559                                          internalSize - bytesPerPage);
560
561                 address += internalSize - bytesPerPage;
562
563                 /* Set up the "dead" page. */
564                 Page_DenyAccess(address, bytesPerPage);
565
566                 /* Figure out what address to give the user. */
567                 address -= userSize;
568         } else { /* EF_PROTECT_BELOW != 0 */
569                 /*
570                  * Arrange the buffer so that it is preceded by an inaccessable
571                  * memory page. A buffer underrun that touches that page will
572                  * cause a segmentation fault.
573                  */
574                 address = (char *)fullSlot->internalAddress;
575
576                 /* Set up the "dead" page. */
577                 Page_DenyAccess(address, bytesPerPage);
578
579                 address += bytesPerPage;
580
581                 /* Set up the "live" page. */
582                 if (internalSize - bytesPerPage > 0)
583                         Page_AllowAccess(address, internalSize - bytesPerPage);
584         }
585
586         fullSlot->userAddress = address;
587         fullSlot->userSize = userSize;
588
589         /*
590          * Make the pool's internal memory inaccessable, so that the program
591          * being debugged can't stomp on it.
592          */
593         if (!internalUse)
594                 Page_DenyAccess(allocationList, allocationListSize);
595
596         unlock();
597         return address;
598 }
599
600 /*
601  * Find the slot structure for a user address.
602  */
603 static Slot *slotForUserAddress(void *address)
604 {
605         register Slot *slot = allocationList;
606         register size_t count = slotCount;
607
608         for (; count > 0; count--) {
609                 if (slot->userAddress == address)
610                         return slot;
611                 slot++;
612         }
613
614         return 0;
615 }
616
617 /*
618  * Find the slot structure for an internal address.
619  */
620 static Slot *slotForInternalAddress(void *address)
621 {
622         register Slot *slot = allocationList;
623         register size_t count = slotCount;
624
625         for (; count > 0; count--) {
626                 if (slot->internalAddress == address)
627                         return slot;
628                 slot++;
629         }
630         return 0;
631 }
632
633 /*
634  * Given the internal address of a buffer, find the buffer immediately
635  * before that buffer in the address space. This is used by free() to
636  * coalesce two free buffers into one.
637  */
638 static Slot *slotForInternalAddressPreviousTo(void *address)
639 {
640         register Slot *slot = allocationList;
641         register size_t count = slotCount;
642
643         for (; count > 0; count--) {
644                 if (((char *)slot->internalAddress) + slot->internalSize == address)
645                         return slot;
646                 slot++;
647         }
648         return 0;
649 }
650
651 extern C_LINKAGE void free(void *address)
652 {
653         Slot *slot;
654         Slot *previousSlot = 0;
655         Slot *nextSlot = 0;
656
657         lock();
658
659         if (address == 0) {
660                 unlock();
661                 return;
662         }
663
664         if (allocationList == 0)
665                 EF_Abort("free() called before first malloc().");
666
667         if (!noAllocationListProtection)
668                 Page_AllowAccess(allocationList, allocationListSize);
669
670         slot = slotForUserAddress(address);
671
672         if (!slot)
673                 EF_Abort("free(%a): address not from malloc().", address);
674
675         if (slot->mode != ALLOCATED) {
676                 if (internalUse && slot->mode == INTERNAL_USE)
677                         /* Do nothing. */;
678                 else {
679                         EF_Abort("free(%a): freeing free memory.", address);
680                 }
681         }
682
683         if (EF_PROTECT_FREE)
684                 slot->mode = PROTECTED;
685         else
686                 slot->mode = FREE;
687
688         if (EF_FREE_WIPES)
689                 memset(slot->userAddress, 0xbd, slot->userSize);
690
691         previousSlot = slotForInternalAddressPreviousTo(slot->internalAddress);
692         nextSlot = slotForInternalAddress(((char *)slot->internalAddress) +
693                                           slot->internalSize);
694
695         if (previousSlot &&
696             (previousSlot->mode == FREE || previousSlot->mode == PROTECTED)) {
697                 /* Coalesce previous slot with this one. */
698                 previousSlot->internalSize += slot->internalSize;
699                 if (EF_PROTECT_FREE)
700                         previousSlot->mode = PROTECTED;
701
702                 slot->internalAddress = slot->userAddress = 0;
703                 slot->internalSize = slot->userSize = 0;
704                 slot->mode = NOT_IN_USE;
705                 slot = previousSlot;
706                 unUsedSlots++;
707         }
708         if (nextSlot && (nextSlot->mode == FREE || nextSlot->mode == PROTECTED)) {
709                 /* Coalesce next slot with this one. */
710                 slot->internalSize += nextSlot->internalSize;
711                 nextSlot->internalAddress = nextSlot->userAddress = 0;
712                 nextSlot->internalSize = nextSlot->userSize = 0;
713                 nextSlot->mode = NOT_IN_USE;
714                 unUsedSlots++;
715         }
716
717         slot->userAddress = slot->internalAddress;
718         slot->userSize = slot->internalSize;
719
720         /*
721          * Free memory is _always_ set to deny access. When EF_PROTECT_FREE
722          * is true, free memory is never reallocated, so it remains access
723          * denied for the life of the process. When EF_PROTECT_FREE is false,
724          * the memory may be re-allocated, at which time access to it will be
725          * allowed again.
726          */
727         Page_DenyAccess(slot->internalAddress, slot->internalSize);
728
729         if (!noAllocationListProtection)
730                 Page_DenyAccess(allocationList, allocationListSize);
731
732         unlock();
733 }
734
735 extern C_LINKAGE void *realloc(void *oldBuffer, size_t newSize)
736 {
737         void *newBuffer = malloc(newSize);
738
739         lock();
740
741         if (oldBuffer) {
742                 size_t size;
743                 Slot *slot;
744
745                 Page_AllowAccess(allocationList, allocationListSize);
746                 noAllocationListProtection = 1;
747
748                 slot = slotForUserAddress(oldBuffer);
749
750                 if (slot == 0)
751                         EF_Abort("realloc(%a, %d): address not from malloc().", oldBuffer,
752                                  newSize);
753
754                 if (newSize < (size = slot->userSize))
755                         size = newSize;
756
757                 if (size > 0)
758                         memcpy(newBuffer, oldBuffer, size);
759
760                 free(oldBuffer);
761                 noAllocationListProtection = 0;
762                 Page_DenyAccess(allocationList, allocationListSize);
763
764                 if (size < newSize)
765                         memset(&(((char *)newBuffer)[size]), 0, newSize - size);
766
767                 /* Internal memory was re-protected in free() */
768         }
769         unlock();
770
771         return newBuffer;
772 }
773
774 extern C_LINKAGE void *malloc(size_t size)
775 {
776         if (!allocationList)
777                 initialize(); /* This sets EF_ALIGNMENT */
778         return memalign(EF_ALIGNMENT, size);
779 }
780
781 extern C_LINKAGE char *strdup(const char *s1)
782 {
783         if (!s1)
784                 return 0;
785         char *s2 = malloc(strlen(s1) + 1);
786
787         if (!s2) {
788                 errno = ENOMEM;
789                 return 0;
790         }
791
792         return strcpy(s2, s1);
793 }
794
795 extern C_LINKAGE char *strndup(const char *s1, size_t n)
796 {
797         if (!s1)
798                 return 0;
799         int complete_size = n; /* includes terminating null */
800         for (int i = 0; i < n - 1; i++) {
801                 if (!s1[i]) {
802                         complete_size = i + 2;
803                         break;
804                 }
805         }
806         char *s2 = malloc(complete_size);
807
808         if (!s2) {
809                 errno = ENOMEM;
810                 return 0;
811         }
812
813         strncpy(s2, s1, complete_size - 1);
814         s2[complete_size - 1] = '\0';
815
816         return s2;
817 }
818
819 extern C_LINKAGE void *calloc(size_t nelem, size_t elsize)
820 {
821         size_t size = nelem * elsize;
822         void *allocation;
823
824         allocation = malloc(size);
825         memset(allocation, 0, size);
826
827         return allocation;
828 }
829
830 /*
831  * This will catch more bugs if you remove the page alignment, but it
832  * will break some software.
833  */
834 extern C_LINKAGE void *valloc(size_t size)
835 {
836         return memalign(bytesPerPage, size);
837 }
838
839 extern C_LINKAGE int posix_memalign(void **memptr, size_t alignment,
840                                     size_t size)
841 {
842         *memptr = memalign(alignment, size);
843         if (!*memptr) {
844                 errno = ENOMEM;
845                 return -1;
846         }
847         return 0;
848 }
849
850 extern C_LINKAGE void *aligned_alloc(size_t alignment, size_t size)
851 {
852         return memalign(alignment, size);
853 }