diff mbox

bring xxx-user qemu_malloc behavior up to speed with main qemu_malloc

Message ID 1252266691-32077-1-git-send-email-jcd@tribudubois.net
State Superseded
Headers show

Commit Message

Jean-Christophe Dubois Sept. 6, 2009, 7:51 p.m. UTC
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(-)

Comments

malc Sept. 6, 2009, 8:43 p.m. UTC | #1
On Sun, 6 Sep 2009, Jean-Christophe DUBOIS wrote:

> 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(-)
> 

[..snip..]

>  
> +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;
> +}

If qemu_malloc can not return NULL anymore then following is in order:

return memcpy(ptr, str, len + 1);

Likewise elsewhere.

[..snip..]
diff mbox

Patch

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index ff207cd..5a9a188 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -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)
 {
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 6ce4167..0e02a22 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -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);