/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/sysmacros.h>
#include "umem_base.h"
#include "misc.h"
/*
* malloc_data_t is an 8-byte structure which is located "before" the pointer
* returned from {m,c,re}alloc and memalign. The first four bytes give
* information about the buffer, and the second four bytes are a status byte.
*
* See umem_impl.h for the various magic numbers used, and the size
*
* The 'size' of the buffer includes the tags. That is, we encode the
* argument to umem_alloc(), not the argument to malloc().
*/
typedef struct malloc_data {
void *
{
#ifdef _LP64
#endif
#ifdef _LP64
if (size > UMEM_SECOND_ALIGN) {
size += sizeof (malloc_data_t);
}
#endif
return (NULL);
}
if (size <= UMEM_MAXBUF)
else
return (NULL);
#ifdef _LP64
} else if (high_size > 0) {
/*
* uses different magic numbers to make it harder to
* undetectably corrupt
*/
ret++;
low_size);
ret++;
} else if (size > UMEM_SECOND_ALIGN) {
ret++; /* leave the first 8 bytes alone */
low_size);
ret++;
#endif
} else {
ret++;
}
return ((void *)ret);
}
void *
{
void *retval;
return (NULL);
}
return (NULL);
return (retval);
}
/*
* memalign uses vmem_xalloc to do its work.
*
* in 64-bit, the memaligned buffer always has two tags. This simplifies the
* code.
*/
void *
{
void *buf;
return (NULL);
}
/*
* if malloc provides the required alignment, use it.
*/
if (align <= UMEM_ALIGN ||
#ifdef _LP64
#else
overhead = sizeof (malloc_data_t);
#endif
return (NULL);
}
return (NULL);
}
else
return (NULL);
}
{
#ifdef _LP64
ret++;
#endif
ret++;
}
return ((void *)ret);
}
void *
{
}
/*
* process_free:
*
* Pulls information out of a buffer pointer, and optionally free it.
* This is used by free() and realloc() to process buffers.
*
* On failure, calls umem_err_recoverable() with an appropriate message
* On success, returns the data size through *data_size_arg, if (!is_free).
*
* Preserves errno, since free()'s semantics require it.
*/
static int
int do_free, /* free the buffer, or just get its size? */
{
void *base;
const char *message;
buf--;
case MALLOC_MAGIC:
if (do_free)
goto process_malloc;
#ifdef _LP64
case MALLOC_SECOND_MAGIC:
if (do_free)
goto process_malloc;
case MALLOC_OVERSIZE_MAGIC: {
buf--;
MALLOC_MAGIC) {
message = "invalid or corrupted buffer";
break;
}
if (do_free) {
}
goto process_malloc;
}
#endif
case MEMALIGN_MAGIC: {
#ifdef _LP64
overhead += sizeof (malloc_data_t);
buf--;
message = "invalid or corrupted buffer";
break;
}
/*
* destroy the main tag's malloc_stat
*/
if (do_free)
#endif
if (do_free)
goto process_memalign;
}
default:
message = "double-free or invalid buffer";
else
message = "invalid or corrupted buffer";
break;
}
umem_err_recoverable("%s(%p): %s\n",
return (0);
if (do_free)
else
return (1);
if (do_free)
else
return (1);
}
void
{
if (buf <= (void *)0x00000001)
return;
/*
* Process buf, freeing it if it is not corrupt.
*/
}
void *
{
void *buf;
if (newsize == 0) {
return ((void *)0x00000001);
}
if (buf_arg <= (void *)0x00000001)
/*
* get the old data size without freeing the buffer
*/
return (NULL);
}
return (buf_arg);
return (NULL);
return (buf);
}