Changeset View
Changeset View
Standalone View
Standalone View
libexec/rtld-elf/malloc.c
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | |||||
* The array of supported page sizes is provided by the user, i.e., the | * The array of supported page sizes is provided by the user, i.e., the | ||||
* program that calls this storage allocator. That program must initialize | * program that calls this storage allocator. That program must initialize | ||||
* the array before making its first call to allocate storage. The array | * the array before making its first call to allocate storage. The array | ||||
* must contain at least one page size. The page sizes must be stored in | * must contain at least one page size. The page sizes must be stored in | ||||
* increasing order. | * increasing order. | ||||
*/ | */ | ||||
void * | void * | ||||
malloc(size_t nbytes) | __crt_malloc(size_t nbytes) | ||||
{ | { | ||||
union overhead *op; | union overhead *op; | ||||
int bucket; | int bucket; | ||||
ssize_t n; | ssize_t n; | ||||
size_t amt; | size_t amt; | ||||
/* | /* | ||||
* First time malloc is called, setup page size and | * First time malloc is called, setup page size and | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | #ifdef RCHECK | ||||
op->ov_size = roundup2(nbytes, RSLOP); | op->ov_size = roundup2(nbytes, RSLOP); | ||||
op->ov_rmagic = RMAGIC; | op->ov_rmagic = RMAGIC; | ||||
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | ||||
#endif | #endif | ||||
return ((char *)(op + 1)); | return ((char *)(op + 1)); | ||||
} | } | ||||
void * | void * | ||||
calloc(size_t num, size_t size) | __crt_calloc(size_t num, size_t size) | ||||
{ | { | ||||
void *ret; | void *ret; | ||||
if (size != 0 && (num * size) / size != num) { | if (size != 0 && (num * size) / size != num) { | ||||
/* size_t overflow. */ | /* size_t overflow. */ | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if ((ret = malloc(num * size)) != NULL) | if ((ret = __crt_malloc(num * size)) != NULL) | ||||
memset(ret, 0, num * size); | memset(ret, 0, num * size); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
/* | /* | ||||
* Allocate more memory to the indicated bucket. | * Allocate more memory to the indicated bucket. | ||||
*/ | */ | ||||
Show All 36 Lines | */ | ||||
nextf[bucket] = op; | nextf[bucket] = op; | ||||
while (--nblks > 0) { | while (--nblks > 0) { | ||||
op->ov_next = (union overhead *)((caddr_t)op + sz); | op->ov_next = (union overhead *)((caddr_t)op + sz); | ||||
op = (union overhead *)((caddr_t)op + sz); | op = (union overhead *)((caddr_t)op + sz); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
free(void * cp) | __crt_free(void *cp) | ||||
{ | { | ||||
int size; | int size; | ||||
union overhead *op; | union overhead *op; | ||||
if (cp == NULL) | if (cp == NULL) | ||||
return; | return; | ||||
op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | ||||
#ifdef MALLOC_DEBUG | #ifdef MALLOC_DEBUG | ||||
Show All 24 Lines | |||||
* checking only the first block in each; if that fails we search | * checking only the first block in each; if that fails we search | ||||
* ``realloc_srchlen'' blocks in each list for a match (the variable | * ``realloc_srchlen'' blocks in each list for a match (the variable | ||||
* is extern so the caller can modify it). If that fails we just copy | * is extern so the caller can modify it). If that fails we just copy | ||||
* however many bytes was given to realloc() and hope it's not huge. | * however many bytes was given to realloc() and hope it's not huge. | ||||
*/ | */ | ||||
static int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ | static int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */ | ||||
void * | void * | ||||
realloc(void *cp, size_t nbytes) | __crt_realloc(void *cp, size_t nbytes) | ||||
{ | { | ||||
u_int onb; | u_int onb; | ||||
int i; | int i; | ||||
union overhead *op; | union overhead *op; | ||||
char *res; | char *res; | ||||
int was_alloced = 0; | int was_alloced = 0; | ||||
if (cp == NULL) | if (cp == NULL) | ||||
return (malloc(nbytes)); | return (__crt_malloc(nbytes)); | ||||
op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); | ||||
if (op->ov_magic == MAGIC) { | if (op->ov_magic == MAGIC) { | ||||
was_alloced++; | was_alloced++; | ||||
i = op->ov_index; | i = op->ov_index; | ||||
} else { | } else { | ||||
/* | /* | ||||
* Already free, doing "compaction". | * Already free, doing "compaction". | ||||
* | * | ||||
Show All 28 Lines | if (was_alloced) { | ||||
} | } | ||||
if (nbytes <= onb && nbytes > (size_t)i) { | if (nbytes <= onb && nbytes > (size_t)i) { | ||||
#ifdef RCHECK | #ifdef RCHECK | ||||
op->ov_size = roundup2(nbytes, RSLOP); | op->ov_size = roundup2(nbytes, RSLOP); | ||||
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | *(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC; | ||||
#endif | #endif | ||||
return(cp); | return(cp); | ||||
} else | } else | ||||
free(cp); | __crt_free(cp); | ||||
} | } | ||||
if ((res = malloc(nbytes)) == NULL) | if ((res = __crt_malloc(nbytes)) == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (cp != res) /* common optimization if "compacting" */ | if (cp != res) /* common optimization if "compacting" */ | ||||
bcopy(cp, res, (nbytes < onb) ? nbytes : onb); | bcopy(cp, res, (nbytes < onb) ? nbytes : onb); | ||||
return (res); | return (res); | ||||
} | } | ||||
/* | /* | ||||
* Search ``srchlen'' elements of each free list for a block whose | * Search ``srchlen'' elements of each free list for a block whose | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int fd = -1; | int fd = -1; | ||||
int offset; | int offset; | ||||
if (pagepool_end - pagepool_start > pagesz) { | if (pagepool_end - pagepool_start > pagesz) { | ||||
caddr_t addr = (caddr_t) | caddr_t addr = (caddr_t) | ||||
(((long)pagepool_start + pagesz - 1) & ~(pagesz - 1)); | (((long)pagepool_start + pagesz - 1) & ~(pagesz - 1)); | ||||
if (munmap(addr, pagepool_end - addr) != 0) { | if (munmap(addr, pagepool_end - addr) != 0) { | ||||
#ifdef IN_RTLD | |||||
rtld_fdprintf(STDERR_FILENO, _BASENAME_RTLD ": " | rtld_fdprintf(STDERR_FILENO, _BASENAME_RTLD ": " | ||||
"morepages: cannot munmap %p: %s\n", | "morepages: cannot munmap %p: %s\n", | ||||
addr, rtld_strerror(errno)); | addr, rtld_strerror(errno)); | ||||
#endif | |||||
} | } | ||||
} | } | ||||
offset = (long)pagepool_start - ((long)pagepool_start & ~(pagesz - 1)); | offset = (long)pagepool_start - ((long)pagepool_start & ~(pagesz - 1)); | ||||
if ((pagepool_start = mmap(0, n * pagesz, | if ((pagepool_start = mmap(0, n * pagesz, | ||||
PROT_READ|PROT_WRITE, | PROT_READ|PROT_WRITE, | ||||
MAP_ANON|MAP_PRIVATE, fd, 0)) == (caddr_t)-1) { | MAP_ANON|MAP_PRIVATE, fd, 0)) == (caddr_t)-1) { | ||||
#ifdef IN_RTLD | |||||
rtld_fdprintf(STDERR_FILENO, _BASENAME_RTLD ": morepages: " | rtld_fdprintf(STDERR_FILENO, _BASENAME_RTLD ": morepages: " | ||||
"cannot mmap anonymous memory: %s\n", | "cannot mmap anonymous memory: %s\n", | ||||
rtld_strerror(errno)); | rtld_strerror(errno)); | ||||
#endif | |||||
return 0; | return 0; | ||||
} | } | ||||
pagepool_end = pagepool_start + n * pagesz; | pagepool_end = pagepool_start + n * pagesz; | ||||
pagepool_start += offset; | pagepool_start += offset; | ||||
return n; | return n; | ||||
} | } |