@@ -83,6 +83,9 @@ void *qemu_vmalloc(size_t size)
p = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (p == MAP_FAILED)
+ abort();
+
addr = (unsigned long)p;
if (addr == (target_ulong) addr) {
/* Allocated region overlaps guest address space.
@@ -98,6 +101,10 @@ void *qemu_vmalloc(size_t size)
void *qemu_malloc(size_t size)
{
char * p;
+
+ if (!size)
+ abort();
+
size += 16;
p = qemu_vmalloc(size);
*(size_t *)p = size;
@@ -122,19 +129,56 @@ void qemu_free(void *ptr)
void *qemu_realloc(void *ptr, size_t size)
{
- size_t old_size, copy;
- void *new_ptr;
+ void *new_ptr = NULL;
if (!ptr)
return qemu_malloc(size);
- old_size = *(size_t *)((char *)ptr - 16);
- copy = old_size < size ? old_size : size;
- new_ptr = qemu_malloc(size);
- memcpy(new_ptr, ptr, copy);
+
+ if (size) {
+ size_t old_size, copy;
+
+ old_size = *(size_t *)((char *)ptr - 16);
+ copy = old_size < size ? old_size : size;
+ new_ptr = qemu_malloc(size);
+ memcpy(new_ptr, ptr, copy);
+ }
+
qemu_free(ptr);
return new_ptr;
}
+char *qemu_strdup(const char *str)
+{
+ char *ptr;
+ size_t len = strlen(str);
+ ptr = qemu_malloc(len + 1);
+
+ if (ptr)
+ memcpy(ptr, str, len + 1);
+
+ return ptr;
+}
+
+char *qemu_strndup(const char *str, size_t size)
+{
+ const char *end = memchr(str, 0, size);
+ char *ptr;
+
+ if (end) {
+ size = end - str;
+ }
+
+ ptr = qemu_malloc(size + 1);
+
+ if (ptr) {
+ ptr[size] = 0;
+
+ memcpy(ptr, str, size);
+ }
+
+ return ptr;
+}
+
/* NOTE: all the constants are the HOST ones, but addresses are target. */
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
{
@@ -86,6 +86,9 @@ void *qemu_vmalloc(size_t size)
p = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED)
+ abort();
+
addr = (unsigned long)p;
if (addr == (target_ulong) addr) {
/* Allocated region overlaps guest address space.
@@ -101,6 +104,10 @@ void *qemu_vmalloc(size_t size)
void *qemu_malloc(size_t size)
{
char * p;
+
+ if (!size)
+ abort();
+
size += 16;
p = qemu_vmalloc(size);
*(size_t *)p = size;
@@ -125,19 +132,53 @@ void qemu_free(void *ptr)
void *qemu_realloc(void *ptr, size_t size)
{
- size_t old_size, copy;
- void *new_ptr;
+ void *new_ptr = NULL;
if (!ptr)
return qemu_malloc(size);
- old_size = *(size_t *)((char *)ptr - 16);
- copy = old_size < size ? old_size : size;
- new_ptr = qemu_malloc(size);
- memcpy(new_ptr, ptr, copy);
+
+ if (size) {
+ size_t old_size, copy;
+
+ old_size = *(size_t *)((char *)ptr - 16);
+ copy = old_size < size ? old_size : size;
+ new_ptr = qemu_malloc(size);
+ memcpy(new_ptr, ptr, copy);
+ }
+
qemu_free(ptr);
return new_ptr;
}
+char *qemu_strdup(const char *str)
+{
+ char *ptr;
+
+ size_t len = strlen(str);
+
+ ptr = qemu_malloc(len + 1);
+
+ memcpy(ptr, str, len + 1);
+
+ return ptr;
+}
+
+char *qemu_strndup(const char *str, size_t size)
+{
+ const char *end = memchr(str, 0, size);
+ char *ptr;
+
+ if (end)
+ size = end - str;
+
+ ptr = qemu_malloc(size + 1);
+
+ ptr[size] = 0;
+ memcpy(ptr, str, size);
+
+ return ptr;
+}
+
/* NOTE: all the constants are the HOST ones, but addresses are target. */
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
{
@@ -426,6 +467,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
if (!(flags & MAP_ANONYMOUS)) {
p = mmap(g2h(mmap_start), len, prot,
flags | MAP_FIXED, fd, host_offset);
+ if (p == MAP_FAILED)
+ goto fail;
host_start += offset - host_offset;
}
start = h2g(host_start);
the linux-user and bsd-user qemu_malloc behavior is not the same as the main qemu_malloc behavior This patch tries to make the xxx-user behavior on par with the main qemu_malloc behavior. In particular qemu_malloc and friends should abort if memory allocation fails. It also add the qemu_strdup and qemu_strndup function that were missing. Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net> --- bsd-user/mmap.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++----- linux-user/mmap.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 12 deletions(-)