/*
 * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */

FILE_LICENCE(GPL2_OR_LATER);

#include <valgrind/memcheck.h>

/** @file
 *
 * iPXE user memory allocation API for linux
 *
 */

#include <assert.h>
#include <ipxe/umalloc.h>

#include <ipxe/linux_api.h>

/** Poison to make the metadata more unique */
#define POISON 0xa5a5a5a5
#define min(a,b) (((a)<(b))?(a):(b))

/** Metadata stored at the beginning of all allocations */
struct metadata
{
	unsigned poison;
	size_t size;
};

#define SIZE_MD (sizeof(struct metadata))

/**
 * Reallocate external memory
 *
 * @v old_ptr		Memory previously allocated by umalloc(), or NULL
 * @v new_size		Requested size
 * @ret new_ptr		Allocated memory, or NULL
 *
 * Calling realloc() with a new size of zero is a valid way to free a
 * memory block.
 */
static void * linux_realloc(void *ptr, size_t size)
{
	struct metadata md = {0, 0};
	struct metadata * mdptr = NULL;

	DBG2("linux_realloc(%p, %zd)\n", ptr, size);

	/* Check whether we have a valid pointer */
	if (ptr != NULL && ptr != NOWHERE) {
		mdptr = ptr - SIZE_MD;
		VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
		md = *mdptr;
		VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);

		/* Check for poison in the metadata */
		if (md.poison != POISON) {
			DBG("linux_realloc bad poison: 0x%x (expected 0x%x)\n", md.poison, POISON);
			return NULL;
		}
	} else {
		/* Handle NOWHERE as NULL */
		ptr = NULL;
	}

	/*
	 * At this point, ptr is either NULL or pointing to a region allocated by us.
	 * In the latter case mdptr is pointing to a valid metadata, otherwise it is NULL.
	 */

	/* Handle deallocation or allocation of size 0 */
	if (size == 0) {
		if (mdptr) {
			if (linux_munmap(mdptr, md.size))
				DBG("linux_realloc munmap failed: %s\n", linux_strerror(linux_errno));
			VALGRIND_FREELIKE_BLOCK(ptr, sizeof(*mdptr));
		}
		return NOWHERE;
	}

	if (ptr) {
		char *vbits = NULL;

		if (RUNNING_ON_VALGRIND > 0)
			vbits = linux_realloc(NULL, min(size, md.size));

/* prevent an unused variable warning when building w/o valgrind support */
#ifndef NVALGRIND
		VALGRIND_GET_VBITS(ptr, vbits, min(size, md.size));
#endif

		VALGRIND_FREELIKE_BLOCK(ptr, SIZE_MD);

		mdptr = linux_mremap(mdptr, md.size + SIZE_MD, size + SIZE_MD, MREMAP_MAYMOVE);
		if (mdptr == MAP_FAILED) {
			DBG("linux_realloc mremap failed: %s\n", linux_strerror(linux_errno));
			return NULL;
		}
		ptr = ((void *)mdptr) + SIZE_MD;

		VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
/* prevent an unused variable warning when building w/o valgrind support */
#ifndef NVALGRIND
		VALGRIND_SET_VBITS(ptr, vbits, min(size, md.size));
#endif

		if (RUNNING_ON_VALGRIND > 0)
			linux_realloc(vbits, 0);
	} else {
		mdptr = linux_mmap(NULL, size + SIZE_MD, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
		if (mdptr == MAP_FAILED) {
			DBG("linux_realloc mmap failed: %s\n", linux_strerror(linux_errno));
			return NULL;
		}
		ptr = ((void *)mdptr) + SIZE_MD;
		VALGRIND_MALLOCLIKE_BLOCK(ptr, size, SIZE_MD, 0);
	}

	/* Update the metadata */
	VALGRIND_MAKE_MEM_DEFINED(mdptr, SIZE_MD);
	mdptr->poison = POISON;
	mdptr->size = size;
	VALGRIND_MAKE_MEM_NOACCESS(mdptr, SIZE_MD);
	// VALGRIND_MALLOCLIKE_BLOCK ignores redzones currently, make our own
	VALGRIND_MAKE_MEM_NOACCESS(ptr + size, SIZE_MD);

	return ptr;
}

PROVIDE_UMALLOC(linux, urealloc, linux_realloc);
