diff --git a/hw/an5206.c b/hw/an5206.c
index a4b83b0..4d4186c 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -68,7 +68,7 @@ static void an5206_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+    kernel_size = load_elf(kernel_filename, NULL, &elf_entry, NULL, NULL,
                            1, ELF_MACHINE, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 30a76a5..0e524dd 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -225,7 +225,7 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
 #endif
 
     /* Assume that raw images are linux kernels, and ELF images are not.  */
-    kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL,
+    kernel_size = load_elf(info->kernel_filename, NULL, &elf_entry, NULL, NULL,
                            big_endian, ELF_MACHINE, 1);
     entry = elf_entry;
     if (kernel_size < 0) {
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 034323d..be7930f 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -215,7 +215,7 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
     big_endian = 0;
 #endif
 
-    image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL,
+    image_size = load_elf(kernel_filename, NULL, &entry, &lowaddr, NULL,
                           big_endian, ELF_MACHINE, 1);
     if (image_size < 0) {
         image_size = load_image_targphys(kernel_filename, 0, flash_size);
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 1a66649..176146f 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -249,6 +249,11 @@ static void main_cpu_reset(void *opaque)
     env->pc = bootstrap_pc;
 }
 
+static uint64_t convert_address(uint64_t addr)
+{
+    return addr - 0x80000000LL;
+}
+
 static
 void axisdev88_init (ram_addr_t ram_size,
                      const char *boot_device,
@@ -345,7 +350,7 @@ void axisdev88_init (ram_addr_t ram_size,
 
         /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis 
            devboard SDK.  */
-        kernel_size = load_elf(kernel_filename, -0x80000000LL,
+        kernel_size = load_elf(kernel_filename, convert_address,
                                &entry, NULL, &high, 0, ELF_MACHINE, 0);
         bootstrap_pc = entry;
         if (kernel_size < 0) {
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index ce45a59..68bb70d 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -43,7 +43,7 @@ static void dummy_m68k_init(ram_addr_t ram_size,
 
     /* Load kernel.  */
     if (kernel_filename) {
-        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+        kernel_size = load_elf(kernel_filename, NULL, &elf_entry, NULL, NULL,
                                1, ELF_MACHINE, 0);
         entry = elf_entry;
         if (kernel_size < 0) {
diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 14b9ec0..13b4223 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -184,7 +184,8 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
     return -1;
 }
 
-static int glue(load_elf, SZ)(const char *name, int fd, int64_t address_offset,
+static int glue(load_elf, SZ)(const char *name, int fd,
+                              uint64_t (*convert_address)(uint64_t),
                               int must_swab, uint64_t *pentry,
                               uint64_t *lowaddr, uint64_t *highaddr,
                               int elf_machine, int clear_lsb)
@@ -253,7 +254,11 @@ static int glue(load_elf, SZ)(const char *name, int fd, int64_t address_offset,
             }
             /* address_offset is hack for kernel images that are
                linked at the wrong physical address.  */
-            addr = ph->p_paddr + address_offset;
+            if (convert_address) {
+                addr = convert_address(ph->p_paddr);
+            } else {
+                addr = ph->p_paddr;
+            }
 
             snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
             rom_add_blob_fixed(label, data, mem_size, addr);
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 2f7f369..ad63155 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -44,6 +44,11 @@ static void main_cpu_reset(void *opaque)
     env->pc = bootstrap_pc;
 }
 
+static uint64_t convert_address(uint64_t addr)
+{
+    return addr - 0x80000000LL;
+}
+
 static
 void bareetraxfs_init (ram_addr_t ram_size,
                        const char *boot_device,
@@ -137,7 +142,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
 
         /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis 
            devboard SDK.  */
-        kernel_size = load_elf(kernel_filename, -0x80000000LL,
+        kernel_size = load_elf(kernel_filename, convert_address,
                                &entry, NULL, &high, 0, ELF_MACHINE, 0);
         bootstrap_pc = entry;
         if (kernel_size < 0) {
diff --git a/hw/loader.c b/hw/loader.c
index 1448887..adac249 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -276,7 +276,7 @@ static void *load_at(int fd, int offset, int size)
 #include "elf_ops.h"
 
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
-int load_elf(const char *filename, int64_t address_offset,
+int load_elf(const char *filename, uint64_t (*convert_address)(uint64_t),
              uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
              int big_endian, int elf_machine, int clear_lsb)
 {
@@ -312,10 +312,10 @@ int load_elf(const char *filename, int64_t address_offset,
 
     lseek(fd, 0, SEEK_SET);
     if (e_ident[EI_CLASS] == ELFCLASS64) {
-        ret = load_elf64(filename, fd, address_offset, must_swab, pentry,
+        ret = load_elf64(filename, fd, convert_address, must_swab, pentry,
                          lowaddr, highaddr, elf_machine, clear_lsb);
     } else {
-        ret = load_elf32(filename, fd, address_offset, must_swab, pentry,
+        ret = load_elf32(filename, fd, convert_address, must_swab, pentry,
                          lowaddr, highaddr, elf_machine, clear_lsb);
     }
 
diff --git a/hw/loader.h b/hw/loader.h
index 56676e1..17bdbe2 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -5,7 +5,7 @@
 int get_image_size(const char *filename);
 int load_image(const char *filename, uint8_t *addr); /* deprecated */
 int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
-int load_elf(const char *filename, int64_t address_offset,
+int load_elf(const char *filename, uint64_t (*convert_address)(uint64_t),
              uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
              int big_endian, int elf_machine, int clear_lsb);
 int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 5598611..be9faf0 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -270,7 +270,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+    kernel_size = load_elf(kernel_filename, NULL, &elf_entry, NULL, NULL,
                            1, ELF_MACHINE, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 2d02a10..801471b 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -46,15 +46,7 @@
 
 //#define DEBUG_BOARD_INIT
 
-#ifdef TARGET_MIPS64
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
-#else
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
-#endif
-
-#define ENVP_ADDR (int32_t)0x80002000
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
-
+#define ENVP_ADDR		0x80002000l
 #define ENVP_NB_ENTRIES	 	16
 #define ENVP_ENTRY_SIZE	 	256
 
@@ -679,6 +671,16 @@ static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
 }
 
 /* Kernel */
+static uint64_t kseg0_to_phys(uint64_t addr)
+{
+    return addr & 0x7fffffffll;
+}
+
+static uint64_t phys_to_kseg0(uint64_t addr)
+{
+    return addr | ~0x7fffffffll;
+}
+
 static int64_t load_kernel (void)
 {
     int64_t kernel_entry, kernel_low, kernel_high;
@@ -695,7 +697,7 @@ static int64_t load_kernel (void)
     big_endian = 0;
 #endif
 
-    if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
+    if (load_elf(loaderparams.kernel_filename, kseg0_to_phys,
                  (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
                  (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1) < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n",
@@ -733,8 +735,8 @@ static int64_t load_kernel (void)
 
     prom_set(prom_buf, prom_index++, loaderparams.kernel_filename);
     if (initrd_size > 0) {
-        prom_set(prom_buf, prom_index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
-                 PHYS_TO_VIRT(initrd_offset), initrd_size,
+        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
+		 phys_to_kseg0(initrd_offset), initrd_size,
                  loaderparams.kernel_cmdline);
     } else {
         prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline);
@@ -747,7 +749,7 @@ static int64_t load_kernel (void)
     prom_set(prom_buf, prom_index++, NULL);
 
     rom_add_blob_fixed("prom", prom_buf, prom_size,
-                       ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
+                       kseg0_to_phys(ENVP_ADDR));
 
     return kernel_entry;
 }
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index aa90116..e749ec0 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -35,14 +35,6 @@
 #include "loader.h"
 #include "elf.h"
 
-#ifdef TARGET_MIPS64
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
-#else
-#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
-#endif
-
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
-
 static struct _loaderparams {
     int ram_size;
     const char *kernel_filename;
@@ -55,6 +47,11 @@ typedef struct ResetData {
     uint64_t vector;
 } ResetData;
 
+static uint64_t kseg0_to_phys(uint64_t addr)
+{
+    return addr & 0x7fffffffll;
+}
+
 static int64_t load_kernel(void)
 {
     int64_t entry, kernel_low, kernel_high;
@@ -69,7 +66,7 @@ static int64_t load_kernel(void)
     big_endian = 0;
 #endif
 
-    kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
+    kernel_size = load_elf(loaderparams.kernel_filename, kseg0_to_phys,
                            (uint64_t *)&entry, (uint64_t *)&kernel_low,
                            (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
     if (kernel_size >= 0) {
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index b69d7c3..b290014 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -21,10 +21,6 @@
 #include "loader.h"
 #include "elf.h"
 
-#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
-
-#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
-
 #define MAX_IDE_BUS 2
 
 static const int ide_iobase[2] = { 0x1f0, 0x170 };
@@ -75,6 +71,16 @@ typedef struct ResetData {
     uint64_t vector;
 } ResetData;
 
+static uint64_t kseg0_to_phys(uint64_t addr)
+{
+    return addr & 0x7fffffffll;
+}
+
+static uint64_t phys_to_kseg0(uint64_t addr)
+{
+    return addr | ~0x7fffffffll;
+}
+
 static int64_t load_kernel(void)
 {
     int64_t entry, kernel_low, kernel_high;
@@ -88,7 +94,7 @@ static int64_t load_kernel(void)
 #else
     big_endian = 0;
 #endif
-    kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
+    kernel_size = load_elf(loaderparams.kernel_filename, kseg0_to_phys,
                            (uint64_t *)&entry, (uint64_t *)&kernel_low,
                            (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
     if (kernel_size >= 0) {
@@ -132,8 +138,8 @@ static int64_t load_kernel(void)
     params_buf[1] = tswap32(0x12345678);
 
     if (initrd_size > 0) {
-        snprintf((char *)params_buf + 8, 256, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
-                 PHYS_TO_VIRT((uint32_t)initrd_offset),
+        snprintf((char *)params_buf + 8, 256, "rd_start=0x%" PRIx64 " rd_size=%li %s",
+                 phys_to_kseg0(initrd_offset),
                  initrd_size, loaderparams.kernel_cmdline);
     } else {
         snprintf((char *)params_buf + 8, 256, "%s", loaderparams.kernel_cmdline);
diff --git a/hw/multiboot.c b/hw/multiboot.c
index a25fbf6..8ef533b 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -170,7 +170,7 @@ int load_multiboot(void *fw_cfg,
         uint64_t elf_low, elf_high;
         int kernel_size;
         fclose(f);
-        kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high,
+        kernel_size = load_elf(kernel_filename, NULL, &elf_entry, &elf_low, &elf_high,
                                0, ELF_MACHINE, 0);
         if (kernel_size < 0) {
             fprintf(stderr, "Error while loading elf kernel\n");
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 8743636..e7bec2f 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -104,6 +104,11 @@ static int petalogix_load_device_tree(target_phys_addr_t addr,
     return fdt_size;
 }
 
+static uint64_t convert_address(uint64_t addr)
+{
+    return addr - 0x30000000LL;
+}
+
 static void
 petalogix_s3adsp1800_init(ram_addr_t ram_size,
                           const char *boot_device,
@@ -163,12 +168,12 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
         uint32_t base32;
 
         /* Boots a kernel elf binary.  */
-        kernel_size = load_elf(kernel_filename, 0,
+        kernel_size = load_elf(kernel_filename, NULL,
                                &entry, &low, &high,
                                1, ELF_MACHINE, 0);
         base32 = entry;
         if (base32 == 0xc0000000) {
-            kernel_size = load_elf(kernel_filename, -0x30000000LL,
+            kernel_size = load_elf(kernel_filename, convert_address,
                                    &entry, NULL, NULL,
                                    1, ELF_MACHINE, 0);
         }
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index efe5a77..2a84435 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -120,7 +120,7 @@ static void bamboo_init(ram_addr_t ram_size,
     if (kernel_filename) {
         kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
         if (kernel_size < 0) {
-            kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
+            kernel_size = load_elf(kernel_filename, NULL, &elf_entry, &elf_lowaddr,
                                    NULL, 1, ELF_MACHINE, 0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index d4f9013..cceeab3 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -115,6 +115,11 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
     return 0;
 }
 
+static uint64_t convert_kernel_address(uint64_t addr)
+{
+    return KERNEL_LOAD_ADDR;
+}
+
 /* PowerPC Mac99 hardware initialisation */
 static void ppc_core99_init (ram_addr_t ram_size,
                              const char *boot_device,
@@ -180,7 +185,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
 
     /* Load OpenBIOS (ELF) */
     if (filename) {
-        bios_size = load_elf(filename, 0, NULL, NULL, NULL, 1, ELF_MACHINE, 0);
+        bios_size = load_elf(filename, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0);
 
         qemu_free(filename);
     } else {
@@ -232,15 +237,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
 #endif
         kernel_base = KERNEL_LOAD_ADDR;
 
-        /* Now we can load the kernel. The first step tries to load the kernel
-           supposing PhysAddr = 0x00000000. If that was wrong the kernel is
-           loaded again, the new PhysAddr being computed from lowaddr. */
-        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
-                               1, ELF_MACHINE, 0);
-        if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
-            kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
-                                   NULL, NULL, NULL, 1, ELF_MACHINE, 0);
-        }
+        kernel_size = load_elf(kernel_filename, convert_kernel_address, NULL,
+                               &lowaddr, NULL, 1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
                                     ram_size - kernel_base, bswap_needed,
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 93c95ba..a489e65 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -122,6 +122,12 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device)
     return 0;
 }
 
+
+static uint64_t convert_kernel_address(uint64_t addr)
+{
+    return KERNEL_LOAD_ADDR;
+}
+
 static void ppc_heathrow_init (ram_addr_t ram_size,
                                const char *boot_device,
                                const char *kernel_filename,
@@ -239,12 +245,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         /* Now we can load the kernel. The first step tries to load the kernel
            supposing PhysAddr = 0x00000000. If that was wrong the kernel is
            loaded again, the new PhysAddr being computed from lowaddr. */
-        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
-                               1, ELF_MACHINE, 0);
-        if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
-            kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
-                                   NULL, NULL, NULL, 1, ELF_MACHINE, 0);
-        }
+        kernel_size = load_elf(kernel_filename, convert_kernel_address, NULL,
+                               &lowaddr, NULL, 1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
                                     ram_size - kernel_base, bswap_needed,
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 90b4c56..425f68e 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -231,7 +231,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     if (kernel_filename) {
         kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
         if (kernel_size < 0) {
-            kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
+            kernel_size = load_elf(kernel_filename, NULL, &elf_entry, &elf_lowaddr,
                                    NULL, 1, ELF_MACHINE, 0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7e26282..61ee319 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -292,6 +292,11 @@ static void cpu_halt_signal(void *opaque, int irq, int level)
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
 }
 
+static uint64_t convert_kernel_address(uint64_t addr)
+{
+    return addr -0xf0000000ULL;
+}
+
 static unsigned long sun4m_load_kernel(const char *kernel_filename,
                                        const char *initrd_filename,
                                        ram_addr_t RAM_size)
@@ -312,8 +317,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
 #else
         bswap_needed = 0;
 #endif
-        kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
-                               NULL, 1, ELF_MACHINE, 0);
+        kernel_size = load_elf(kernel_filename, convert_kernel_address, NULL,
+                               NULL, NULL, 1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
@@ -636,6 +641,11 @@ static void afx_register_devices(void)
 device_init(afx_register_devices);
 
 /* Boot PROM (OpenBIOS) */
+static uint64_t convert_prom_address(uint64_t address)
+{
+    return address - PROM_VADDR;
+}
+
 static void prom_init(target_phys_addr_t addr, const char *bios_name)
 {
     DeviceState *dev;
@@ -655,7 +665,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
-        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
+        ret = load_elf(filename, convert_prom_address, NULL, NULL, NULL,
                        1, ELF_MACHINE, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index f339df3..f97b7ed 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -189,7 +189,7 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
 #else
         bswap_needed = 0;
 #endif
-        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL,
+        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
                                1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
@@ -583,6 +583,11 @@ device_init(pci_ebus_register);
 /* Boot PROM (OpenBIOS) */
 static void prom_init(target_phys_addr_t addr, const char *bios_name)
 {
+    uint64_t convert_prom_address(uint64_t addr)
+    {
+        return addr - PROM_VADDR;
+    }
+
     DeviceState *dev;
     SysBusDevice *s;
     char *filename;
@@ -600,7 +605,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
-        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
+        ret = load_elf(filename, convert_prom_address, NULL, NULL, NULL,
                        1, ELF_MACHINE, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);

