diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 6093dea..003d2ef 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -219,51 +219,53 @@ static int glue(load_elf, SZ)(const char *name, int fd, int64_t address_offset,
 
     glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
 
-    size = ehdr.e_phnum * sizeof(phdr[0]);
-    lseek(fd, ehdr.e_phoff, SEEK_SET);
-    phdr = qemu_mallocz(size);
-    if (!phdr)
-        goto fail;
-    if (read(fd, phdr, size) != size)
-        goto fail;
-    if (must_swab) {
-        for(i = 0; i < ehdr.e_phnum; i++) {
-            ph = &phdr[i];
-            glue(bswap_phdr, SZ)(ph);
-        }
-    }
-
-    total_size = 0;
-    for(i = 0; i < ehdr.e_phnum; i++) {
-        ph = &phdr[i];
-        if (ph->p_type == PT_LOAD) {
-            mem_size = ph->p_memsz;
-            /* XXX: avoid allocating */
-            data = qemu_mallocz(mem_size);
-            if (ph->p_filesz > 0) {
-                if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
-                    goto fail;
-                if (read(fd, data, ph->p_filesz) != ph->p_filesz)
-                    goto fail;
+    if (ehdr.e_phnum) {
+        size = ehdr.e_phnum * sizeof(phdr[0]);
+        lseek(fd, ehdr.e_phoff, SEEK_SET);
+        phdr = qemu_mallocz(size);
+        if (!phdr)
+            goto fail;
+        if (read(fd, phdr, size) != size)
+            goto fail;
+        if (must_swab) {
+            for(i = 0; i < ehdr.e_phnum; i++) {
+                ph = &phdr[i];
+                glue(bswap_phdr, SZ)(ph);
             }
-            /* address_offset is hack for kernel images that are
-               linked at the wrong physical address.  */
-            addr = ph->p_paddr + address_offset;
+        }
 
-            snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
-            rom_add_blob_fixed(label, data, mem_size, addr);
+        total_size = 0;
+        for(i = 0; i < ehdr.e_phnum; i++) {
+            ph = &phdr[i];
+            if (ph->p_type == PT_LOAD) {
+                mem_size = ph->p_memsz;
+                if (memsize) {
+                    data = qemu_mallocz(mem_size);
+                    if (ph->p_filesz > 0) {
+                        if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
+                            goto fail;
+                        if (read(fd, data, ph->p_filesz) != ph->p_filesz)
+                            goto fail;
+                    }
+                    /* address_offset is hack for kernel images that are
+                       linked at the wrong physical address.  */
+                    addr = ph->p_paddr + address_offset;
 
-            total_size += mem_size;
-            if (addr < low)
-                low = addr;
-            if ((addr + mem_size) > high)
-                high = addr + mem_size;
+                    snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
+                    rom_add_blob_fixed(label, data, mem_size, addr);
 
-            qemu_free(data);
-            data = NULL;
+                    total_size += mem_size;
+                    qemu_free(data);
+                    data = NULL;
+                }
+                if (addr < low)
+                    low = addr;
+                if ((addr + mem_size) > high)
+                    high = addr + mem_size;
+            }
         }
+        qemu_free(phdr);
     }
-    qemu_free(phdr);
     if (lowaddr)
         *lowaddr = (uint64_t)(elf_sword)low;
     if (highaddr)
