diff options
Diffstat (limited to 'lib/util')
| -rw-r--r-- | lib/util/Makemodule.am | 1 | ||||
| -rw-r--r-- | lib/util/is_memory_zero.c | 54 | 
2 files changed, 55 insertions, 0 deletions
| diff --git a/lib/util/Makemodule.am b/lib/util/Makemodule.am index 113855c..c66c786 100644 --- a/lib/util/Makemodule.am +++ b/lib/util/Makemodule.am @@ -7,6 +7,7 @@ libutil_a_SOURCES += lib/util/fast_urem_by_const.h  libutil_a_SOURCES += include/threadpool.h  libutil_a_SOURCES += include/w32threadwrap.h  libutil_a_SOURCES += lib/util/threadpool_serial.c +libutil_a_SOURCES += lib/util/is_memory_zero.c  libutil_a_CFLAGS = $(AM_CFLAGS)  libutil_a_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/lib/util/is_memory_zero.c b/lib/util/is_memory_zero.c new file mode 100644 index 0000000..3974ee2 --- /dev/null +++ b/lib/util/is_memory_zero.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * is_memory_zero.c + * + * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "util.h" + +#include <stdint.h> + +#define U64THRESHOLD (128) + +static bool test_u8(const unsigned char *blob, size_t size) +{ +	while (size--) { +		if (*(blob++) != 0) +			return false; +	} + +	return true; +} + +bool is_memory_zero(const void *blob, size_t size) +{ +	const sqfs_u64 *u64ptr; +	size_t diff; + +	if (size < U64THRESHOLD) +		return test_u8(blob, size); + +	diff = (uintptr_t)blob % sizeof(sqfs_u64); + +	if (diff != 0) { +		diff = sizeof(sqfs_u64) - diff; + +		if (!test_u8(blob, diff)) +			return false; + +		blob = (const char *)blob + diff; +		size -= diff; +	} + +	u64ptr = blob; + +	while (size >= sizeof(sqfs_u64)) { +		if (*(u64ptr++) != 0) +			return false; + +		size -= sizeof(sqfs_u64); +	} + +	return test_u8((const unsigned char *)u64ptr, size); +} | 
