qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH rc3 23/30] hw/core/loader: Let load_elf populate the processo


From: Aleksandar Markovic
Subject: Re: [PATCH rc3 23/30] hw/core/loader: Let load_elf populate the processor-specific flags
Date: Tue, 28 Jan 2020 20:25:50 +0100



On Tue, Jan 28, 2020 at 2:27 PM Aleksandar Markovic <address@hidden> wrote:


On Tuesday, January 28, 2020, BALATON Zoltan <address@hidden> wrote:
On Tue, 28 Jan 2020, Aleksandar Markovic wrote:
On Sunday, January 26, 2020, Aleksandar Markovic <
address@hidden> wrote:

From: Philippe Mathieu-Daudé <address@hidden>

Some platforms (like AVR) need to determine cpu type by reading
the ELF flags (field e_flags oin ELF header).

This patch enables discovery of the content of that flag while
using following functions:

  - load_elf()
  - load_elf_as()
  - load_elf_ram()
  - load_elf_ram_sym()

The added argument of these functions is of type uint32_t*. It is
allowed to pass NULL as that argument, and in such case no lookup
to the field e_flags will happen, and of course, no information
will be returned to the caller.


Applied to MIPS queue, with some commit message corrections and fixes.
 

We plan to use this new functionality for MIPS Malta board, for detection
of incompatible cpu/kernel combinations, and graceful exit (right now these
combinations result in hang or crash). I would say other boards could make
use of it too.

For that reason, if there is no objection, I plan to select this patch for
next MIPS queue.

No objection but kind of déjà vu:

https://lists.nongnu.org/archive/html/qemu-devel/2019-01/msg03427.html

I still think the interface of load_elf may need to be rethinked but I don't know a good way.


Perhaps having only two, "in" and "out", arguments that are pointers to structures?

Another thing that I noticed is "endian argument" that it seems everyone uses in a different way: 0, 1, true, false, bigendian, etc. Would c enumeration help? This looks to me like a time ticking bomb.

Just to add that some platforms like MIPS and SPARC must load elfs of more than one value of EM_MACHINE (in MIPS case, EM_MIPS and EM_NANOMIPS) and current load_elf() interface offers only clumsy solutions/workarounds in these cases.

Let's think about everything later on.


 This could be fixed in a later patch causing more code churn again though, so if there's a way to fix this it might be a good opportunity now. But I don't want to hold your patch series back so unless someone has a good idea to avoid this situation then we have to live with it.


Thank you. I will do some minor corrections for obvious unclarities and typos in the commit message while applying to my qieue.
 
Regards,
BALATON Zoltan


Regards,
Aleksandar




CC: Richard Henderson <address@hidden>
CC: Peter Maydell <address@hidden>
CC: Edgar E. Iglesias <address@hidden>
CC: Michael Walle <address@hidden>
CC: Thomas Huth <address@hidden>
CC: Laurent Vivier <address@hidden>
CC: Philippe Mathieu-Daudé <address@hidden>
CC: Aleksandar Rikalo <address@hidden>
CC: Aurelien Jarno <address@hidden>
CC: Jia Liu <address@hidden>
CC: David Gibson <address@hidden>
CC: Mark Cave-Ayland <address@hidden>
CC: BALATON Zoltan <address@hidden>
CC: Christian Borntraeger <address@hidden>
CC: Thomas Huth <address@hidden>
CC: Artyom Tarasenko <address@hidden>
CC: Fabien Chouteau <address@hidden>
CC: KONRAD Frederic <address@hidden>
CC: Max Filippov <address@hidden>

Signed-off-by: Michael Rolnik <address@hidden>
Reviewed-by: Aleksandar Markovic <address@hidden>
[PMD: Extracted from bigger patch,
      Replaced 'uint32_t *pe_flags' by 'int proc_flags']
[AM: Replaced 'int proc_flags' with 'uint32_t *pflags',
     replaced one instance of 'elf_sword' to 'elf_word',
     extended functionality to load_elf()]
Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
Signed-off-by: Aleksandar Markovic <address@hidden>
---
 hw/alpha/dp264.c               |  4 ++--
 hw/arm/armv7m.c                |  2 +-
 hw/arm/boot.c                  |  2 +-
 hw/core/generic-loader.c       |  2 +-
 hw/core/loader.c               | 37 +++++++++++++++++++------------------
 hw/cris/boot.c                 |  2 +-
 hw/hppa/machine.c              |  4 ++--
 hw/i386/multiboot.c            |  2 +-
 hw/i386/x86.c                  |  2 +-
 hw/lm32/lm32_boards.c          |  4 ++--
 hw/lm32/milkymist.c            |  2 +-
 hw/m68k/an5206.c               |  2 +-
 hw/m68k/mcf5208.c              |  2 +-
 hw/m68k/q800.c                 |  2 +-
 hw/microblaze/boot.c           |  4 ++--
 hw/mips/mips_fulong2e.c        |  2 +-
 hw/mips/mips_malta.c           |  3 ++-
 hw/mips/mips_mipssim.c         |  2 +-
 hw/mips/mips_r4k.c             |  2 +-
 hw/moxie/moxiesim.c            |  2 +-
 hw/nios2/boot.c                |  4 ++--
 hw/openrisc/openrisc_sim.c     |  2 +-
 hw/pci-host/prep.c             |  3 ++-
 hw/ppc/e500.c                  |  2 +-
 hw/ppc/mac_newworld.c          |  4 ++--
 hw/ppc/mac_oldworld.c          |  4 ++--
 hw/ppc/ppc440_bamboo.c         |  2 +-
 hw/ppc/sam460ex.c              |  3 ++-
 hw/ppc/spapr.c                 |  6 +++---
 hw/ppc/virtex_ml507.c          |  2 +-
 hw/riscv/boot.c                |  4 ++--
 hw/s390x/ipl.c                 |  7 ++++---
 hw/sparc/leon3.c               |  2 +-
 hw/sparc/sun4m.c               |  4 ++--
 hw/sparc64/sun4u.c             |  5 +++--
 hw/tricore/tricore_testboard.c |  2 +-
 hw/xtensa/sim.c                |  2 +-
 hw/xtensa/xtfpga.c             |  2 +-
 include/hw/elf_ops.h           |  6 +++++-
 include/hw/loader.h            | 21 ++++++++++++---------
 40 files changed, 92 insertions(+), 79 deletions(-)

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f2026fd..a8f9a89 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -115,7 +115,7 @@ static void clipper_init(MachineState *machine)
         exit(1);
     }
     size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys,
-                    NULL, &palcode_entry, &palcode_low, &palcode_high,
+                    NULL, &palcode_entry, &palcode_low, &palcode_high,
NULL,
                     0, EM_ALPHA, 0, 0);
     if (size < 0) {
         error_report("could not load palcode '%s'", palcode_filename);
@@ -134,7 +134,7 @@ static void clipper_init(MachineState *machine)
         uint64_t param_offset;

         size = load_elf(kernel_filename, NULL,
cpu_alpha_superpage_to_phys,
-                        NULL, &kernel_entry, &kernel_low, &kernel_high,
+                        NULL, &kernel_entry, &kernel_low, &kernel_high,
NULL,
                         0, EM_ALPHA, 0, 0);
         if (size < 0) {
             error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 7a3c48f..e4fc9a8 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -331,7 +331,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char
*kernel_filename, int mem_size)

     if (kernel_filename) {
         image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
-                                 &entry, &lowaddr,
+                                 &entry, &lowaddr, NULL,
                                  NULL, big_endian, EM_ARM, 1, 0, as);
         if (image_size < 0) {
             image_size = load_image_targphys_as(kernel_filename, 0,
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 8fb4a63..0c213ca 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -903,7 +903,7 @@ static int64_t arm_load_elf(struct arm_boot_info
*info, uint64_t *pentry,
     }

     ret = load_elf_as(info->kernel_filename, NULL, NULL, NULL,
-                      pentry, lowaddr, highaddr, big_endian, elf_machine,
+                      pentry, lowaddr, highaddr, NULL, big_endian,
elf_machine,
                       1, data_swab, as);
     if (ret <= 0) {
         /* The header loaded but the image didn't */
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
index 4b1fc86..1e5ccb7 100644
--- a/hw/core/generic-loader.c
+++ b/hw/core/generic-loader.c
@@ -140,7 +140,7 @@ static void generic_loader_realize(DeviceState *dev,
Error **errp)

         if (!s->force_raw) {
             size = load_elf_as(s->file, NULL, NULL, NULL, &entry, NULL,
NULL,
-                               big_endian, 0, 0, 0, as);
+                               NULL, big_endian, 0, 0, 0, as);

             if (size < 0) {
                 size = load_uimage_as(s->file, &entry, NULL, NULL, NULL,
NULL,
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 5099f27..d1b78f6 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -406,12 +406,12 @@ int load_elf(const char *filename,
              uint64_t (*elf_note_fn)(void *, void *, bool),
              uint64_t (*translate_fn)(void *, uint64_t),
              void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
-             uint64_t *highaddr, int big_endian, int elf_machine,
-             int clear_lsb, int data_swab)
+             uint64_t *highaddr, uint32_t *pflags, int big_endian,
+             int elf_machine, int clear_lsb, int data_swab)
 {
     return load_elf_as(filename, elf_note_fn, translate_fn,
translate_opaque,
-                       pentry, lowaddr, highaddr, big_endian, elf_machine,
-                       clear_lsb, data_swab, NULL);
+                       pentry, lowaddr, highaddr, pflags, big_endian,
+                       elf_machine, clear_lsb, data_swab, NULL);
 }

 /* return < 0 if error, otherwise the number of bytes loaded in memory */
@@ -419,12 +419,12 @@ int load_elf_as(const char *filename,
                 uint64_t (*elf_note_fn)(void *, void *, bool),
                 uint64_t (*translate_fn)(void *, uint64_t),
                 void *translate_opaque, uint64_t *pentry, uint64_t
*lowaddr,
-                uint64_t *highaddr, int big_endian, int elf_machine,
-                int clear_lsb, int data_swab, AddressSpace *as)
+                uint64_t *highaddr, uint32_t *pflags, int big_endian,
+                int elf_machine, int clear_lsb, int data_swab,
AddressSpace *as)
 {
     return load_elf_ram(filename, elf_note_fn, translate_fn,
translate_opaque,
-                        pentry, lowaddr, highaddr, big_endian,
elf_machine,
-                        clear_lsb, data_swab, as, true);
+                        pentry, lowaddr, highaddr, pflags, big_endian,
+                        elf_machine, clear_lsb, data_swab, as, true);
 }

 /* return < 0 if error, otherwise the number of bytes loaded in memory */
@@ -432,13 +432,13 @@ int load_elf_ram(const char *filename,
                  uint64_t (*elf_note_fn)(void *, void *, bool),
                  uint64_t (*translate_fn)(void *, uint64_t),
                  void *translate_opaque, uint64_t *pentry, uint64_t
*lowaddr,
-                 uint64_t *highaddr, int big_endian, int elf_machine,
-                 int clear_lsb, int data_swab, AddressSpace *as,
-                 bool load_rom)
+                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
+                 int elf_machine, int clear_lsb, int data_swab,
+                 AddressSpace *as, bool load_rom)
 {
     return load_elf_ram_sym(filename, elf_note_fn,
                             translate_fn, translate_opaque,
-                            pentry, lowaddr, highaddr, big_endian,
+                            pentry, lowaddr, highaddr, pflags, big_endian,
                             elf_machine, clear_lsb, data_swab, as,
                             load_rom, NULL);
 }
@@ -448,8 +448,9 @@ int load_elf_ram_sym(const char *filename,
                      uint64_t (*elf_note_fn)(void *, void *, bool),
                      uint64_t (*translate_fn)(void *, uint64_t),
                      void *translate_opaque, uint64_t *pentry,
-                     uint64_t *lowaddr, uint64_t *highaddr, int
big_endian,
-                     int elf_machine, int clear_lsb, int data_swab,
+                     uint64_t *lowaddr, uint64_t *highaddr, uint32_t
*pflags,
+                     int big_endian, int elf_machine,
+                     int clear_lsb, int data_swab,
                      AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
 {
     int fd, data_order, target_data_order, must_swab, ret =
ELF_LOAD_FAILED;
@@ -490,13 +491,13 @@ int load_elf_ram_sym(const char *filename,
     if (e_ident[EI_CLASS] == ELFCLASS64) {
         ret = load_elf64(filename, fd, elf_note_fn,
                          translate_fn, translate_opaque, must_swab,
-                         pentry, lowaddr, highaddr, elf_machine,
clear_lsb,
-                         data_swab, as, load_rom, sym_cb);
+                         pentry, lowaddr, highaddr, pflags, elf_machine,
+                         clear_lsb, data_swab, as, load_rom, sym_cb);
     } else {
         ret = load_elf32(filename, fd, elf_note_fn,
                          translate_fn, translate_opaque, must_swab,
-                         pentry, lowaddr, highaddr, elf_machine,
clear_lsb,
-                         data_swab, as, load_rom, sym_cb);
+                         pentry, lowaddr, highaddr, pflags, elf_machine,
+                         clear_lsb, data_swab, as, load_rom, sym_cb);
     }

  fail:
diff --git a/hw/cris/boot.c b/hw/cris/boot.c
index 2d2cc0c..b8947bc 100644
--- a/hw/cris/boot.c
+++ b/hw/cris/boot.c
@@ -76,7 +76,7 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info
*li)
        devboard SDK.  */
     image_size = load_elf(li->image_filename, NULL,
                           translate_kernel_address, NULL,
-                          &entry, NULL, &high, 0, EM_CRIS, 0, 0);
+                          &entry, NULL, &high, NULL, 0, EM_CRIS, 0, 0);
     li->entry = entry;
     if (image_size < 0) {
         /* Takes a kimage from the axis devboard SDK.  */
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 5d0de26..0ab36cf 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -140,7 +140,7 @@ static void machine_hppa_init(MachineState *machine)
     }

     size = load_elf(firmware_filename, NULL, NULL, NULL,
-                    &firmware_entry, &firmware_low, &firmware_high,
+                    &firmware_entry, &firmware_low, &firmware_high, NULL,
                     true, EM_PARISC, 0, 0);

     /* Unfortunately, load_elf sign-extends reading elf32.  */
@@ -169,7 +169,7 @@ static void machine_hppa_init(MachineState *machine)
     /* Load kernel */
     if (kernel_filename) {
         size = load_elf(kernel_filename, NULL, &cpu_hppa_to_phys,
-                        NULL, &kernel_entry, &kernel_low, &kernel_high,
+                        NULL, &kernel_entry, &kernel_low, &kernel_high,
NULL,
                         true, EM_PARISC, 0, 0);

         /* Unfortunately, load_elf sign-extends reading elf32.  */
diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 9a59f95..9e7d69d 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -199,7 +199,7 @@ int load_multiboot(FWCfgState *fw_cfg,
         }

         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
&elf_entry,
-                               &elf_low, &elf_high, 0, I386_ELF_MACHINE,
+                               &elf_low, &elf_high, NULL, 0,
I386_ELF_MACHINE,
                                0, 0);
         if (kernel_size < 0) {
             error_report("Error while loading elf kernel");
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 9b9a4d5..7f38e6b 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -413,7 +413,7 @@ static bool load_elfboot(const char *kernel_filename,
     uint64_t elf_note_type = XEN_ELFNOTE_PHYS32_ENTRY;
     kernel_size = load_elf(kernel_filename, read_pvh_start_addr,
                            NULL, &elf_note_type, &elf_entry,
-                           &elf_low, &elf_high, 0, I386_ELF_MACHINE,
+                           &elf_low, &elf_high, NULL, 0, I386_ELF_MACHINE,
                            0, 0);

     if (kernel_size < 0) {
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 5ae308b..d1894ad 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -138,7 +138,7 @@ static void lm32_evr_init(MachineState *machine)
         int kernel_size;

         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, NULL, NULL,
+                               &entry, NULL, NULL, NULL,
                                1, EM_LATTICEMICO32, 0, 0);
         reset_info->bootstrap_pc = entry;

@@ -232,7 +232,7 @@ static void lm32_uclinux_init(MachineState *machine)
         int kernel_size;

         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, NULL, NULL,
+                               &entry, NULL, NULL, NULL,
                                1, EM_LATTICEMICO32, 0, 0);
         reset_info->bootstrap_pc = entry;

diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 460d322..6d46134 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -177,7 +177,7 @@ milkymist_init(MachineState *machine)

         /* Boots a kernel elf binary.  */
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, NULL, NULL,
+                               &entry, NULL, NULL, NULL,
                                1, EM_LATTICEMICO32, 0, 0);
         reset_info->bootstrap_pc = entry;

diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 54ccbe1..bed43a9 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -65,7 +65,7 @@ static void an5206_init(MachineState *machine)
     }

     kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry,
-                           NULL, NULL, 1, EM_68K, 0, 0);
+                           NULL, NULL, NULL, 1, EM_68K, 0, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
         kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 158c5e4..a999c21 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -329,7 +329,7 @@ static void mcf5208evb_init(MachineState *machine)
     }

     kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry,
-                           NULL, NULL, 1, EM_68K, 0, 0);
+                           NULL, NULL, NULL, 1, EM_68K, 0, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
         kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 12491ec..1e32363 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -342,7 +342,7 @@ static void q800_init(MachineState *machine)
     if (linux_boot) {
         uint64_t high;
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &elf_entry, NULL, &high, 1,
+                               &elf_entry, NULL, &high, NULL, 1,
                                EM_68K, 0, 0);
         if (kernel_size < 0) {
             error_report("could not load kernel '%s'", kernel_filename);
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index d1d7dfb..925e3f7 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -145,13 +145,13 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu,
hwaddr ddr_base,

         /* Boots a kernel elf binary.  */
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, &low, &high,
+                               &entry, &low, &high, NULL,
                                big_endian, EM_MICROBLAZE, 0, 0);
         base32 = entry;
         if (base32 == 0xc0000000) {
             kernel_size = load_elf(kernel_filename, NULL,
                                    translate_kernel_address, NULL,
-                                   &entry, NULL, NULL,
+                                   &entry, NULL, NULL, NULL,
                                    big_endian, EM_MICROBLAZE, 0, 0);
         }
         /* Always boot into physical ram.  */
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 9eaa6e2..2e043cb 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -119,7 +119,7 @@ static int64_t load_kernel(CPUMIPSState *env)
                            cpu_mips_kseg0_to_phys, NULL,
                            (uint64_t *)&kernel_entry,
                            (uint64_t *)&kernel_low, (uint64_t
*)&kernel_high,
-                           0, EM_MIPS, 1, 0);
+                           NULL, 0, EM_MIPS, 1, 0);
     if (kernel_size < 0) {
         error_report("could not load kernel '%s': %s",
                      loaderparams.kernel_filename,
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 5aaeaa8..34b76bb 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1039,7 +1039,8 @@ static int64_t load_kernel(void)
     kernel_size = load_elf(loaderparams.kernel_filename, NULL,
                            cpu_mips_kseg0_to_phys, NULL,
                            (uint64_t *)&kernel_entry, NULL,
-                           (uint64_t *)&kernel_high, big_endian, EM_MIPS,
1, 0);
+                           (uint64_t *)&kernel_high, NULL, big_endian,
EM_MIPS,
+                           1, 0);
     if (kernel_size < 0) {
         error_report("could not load kernel '%s': %s",
                      loaderparams.kernel_filename,
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 84c03dd..b934ca9 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -74,7 +74,7 @@ static int64_t load_kernel(void)
     kernel_size = load_elf(loaderparams.kernel_filename, NULL,
                            cpu_mips_kseg0_to_phys, NULL,
                            (uint64_t *)&entry, NULL,
-                           (uint64_t *)&kernel_high, big_endian,
+                           (uint64_t *)&kernel_high, NULL, big_endian,
                            EM_MIPS, 1, 0);
     if (kernel_size >= 0) {
         if ((entry & ~0x7fffffffULL) == 0x80000000) {
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index fd926a3..b2aec43 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -98,7 +98,7 @@ static int64_t load_kernel(void)
     kernel_size = load_elf(loaderparams.kernel_filename, NULL,
                            cpu_mips_kseg0_to_phys, NULL,
                            (uint64_t *)&entry, NULL,
-                           (uint64_t *)&kernel_high, big_endian,
+                           (uint64_t *)&kernel_high, NULL, big_endian,
                            EM_MIPS, 1, 0);
     if (kernel_size >= 0) {
         if ((entry & ~0x7fffffffULL) == 0x80000000) {
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index 57af1b4..1d06e39 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -58,7 +58,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams
*loader_params)
     ram_addr_t initrd_offset;

     kernel_size = load_elf(loader_params->kernel_filename,  NULL, NULL,
NULL,
-                           &entry, &kernel_low, &kernel_high, 1, EM_MOXIE,
+                           &entry, &kernel_low, &kernel_high, NULL, 1,
EM_MOXIE,
                            0, 0);

     if (kernel_size <= 0) {
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index d78bc9e..46b8349 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -147,7 +147,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,

         /* Boots a kernel elf binary. */
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, &low, &high,
+                               &entry, &low, &high, NULL,
                                big_endian, EM_ALTERA_NIOS2, 0, 0);
         if ((uint32_t)entry == 0xc0000000) {
             /*
@@ -158,7 +158,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
              */
             kernel_size = load_elf(kernel_filename, NULL,
                                    translate_kernel_address, NULL,
-                                   &entry, NULL, NULL,
+                                   &entry, NULL, NULL, NULL,
                                    big_endian, EM_ALTERA_NIOS2, 0, 0);
             boot_info.bootstrap_pc = ddr_base + 0xc0000000 +
                 (entry & 0x07ffffff);
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 79e7049..ad53712 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -98,7 +98,7 @@ static void openrisc_load_kernel(ram_addr_t ram_size,

     if (kernel_filename && !qtest_enabled()) {
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &elf_entry, NULL, NULL, 1, EM_OPENRISC,
+                               &elf_entry, NULL, NULL, NULL, 1,
EM_OPENRISC,
                                1, 0);
         entry = elf_entry;
         if (kernel_size < 0) {
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index afa136d..fcf6235 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -335,7 +335,8 @@ static void raven_realize(PCIDevice *d, Error **errp)
         if (filename) {
             if (s->elf_machine != EM_NONE) {
                 bios_size = load_elf(filename, NULL, NULL, NULL, NULL,
-                                     NULL, NULL, 1, s->elf_machine, 0, 0);
+                                     NULL, NULL, NULL, 1, s->elf_machine,
+                                     0, 0);
             }
             if (bios_size < 0) {
                 bios_size = get_image_size(filename);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 12b6a5b..886442e 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1049,7 +1049,7 @@ void ppce500_init(MachineState *machine)
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name);

     payload_size = load_elf(filename, NULL, NULL, NULL,
-                            &bios_entry, &loadaddr, NULL,
+                            &bios_entry, &loadaddr, NULL, NULL,
                             1, PPC_ELF_MACHINE, 0, 0);
     if (payload_size < 0) {
         /*
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 3594517..464d012 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -168,7 +168,7 @@ static void ppc_core99_init(MachineState *machine)
     /* Load OpenBIOS (ELF) */
     if (filename) {
         bios_size = load_elf(filename, NULL, NULL, NULL, NULL,
-                             NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
+                             NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);

         g_free(filename);
     } else {
@@ -192,7 +192,7 @@ static void ppc_core99_init(MachineState *machine)

         kernel_size = load_elf(kernel_filename, NULL,
                                translate_kernel_address, NULL,
-                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE,
+                               NULL, &lowaddr, NULL, NULL, 1,
PPC_ELF_MACHINE,
                                0, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 0fa680b..7318d7e 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -143,7 +143,7 @@ static void ppc_heathrow_init(MachineState *machine)

     /* Load OpenBIOS (ELF) */
     if (filename) {
-        bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL,
+        bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL,
NULL,
                              1, PPC_ELF_MACHINE, 0, 0);
         g_free(filename);
     } else {
@@ -166,7 +166,7 @@ static void ppc_heathrow_init(MachineState *machine)
         kernel_base = KERNEL_LOAD_ADDR;
         kernel_size = load_elf(kernel_filename, NULL,
                                translate_kernel_address, NULL,
-                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE,
+                               NULL, &lowaddr, NULL, NULL, 1,
PPC_ELF_MACHINE,
                                0, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index b782641..da777ef 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -253,7 +253,7 @@ static void bamboo_init(MachineState *machine)
                               NULL, NULL);
         if (success < 0) {
             success = load_elf(kernel_filename, NULL, NULL, NULL,
&elf_entry,
-                               &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE,
+                               &elf_lowaddr, NULL, NULL, 1,
PPC_ELF_MACHINE,
                                0, 0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 437e214..89bc70e 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -439,7 +439,8 @@ static void sam460ex_init(MachineState *machine)

             success = load_elf(machine->kernel_filename, NULL,
                                NULL, NULL, &elf_entry,
-                               &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0,
0);
+                               &elf_lowaddr, NULL, NULL, 1,
PPC_ELF_MACHINE, 0,
+                               0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
         }
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 02cf53f..a0076e5 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2895,13 +2895,13 @@ static void spapr_machine_init(MachineState
*machine)

         spapr->kernel_size = load_elf(kernel_filename, NULL,
                                       translate_kernel_address, NULL,
-                                      NULL, &lowaddr, NULL, 1,
+                                      NULL, &lowaddr, NULL, NULL, 1,
                                       PPC_ELF_MACHINE, 0, 0);
         if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) {
             spapr->kernel_size = load_elf(kernel_filename, NULL,
                                           translate_kernel_address, NULL,
NULL,
-                                          &lowaddr, NULL, 0,
PPC_ELF_MACHINE,
-                                          0, 0);
+                                          &lowaddr, NULL, NULL, 0,
+                                          PPC_ELF_MACHINE, 0, 0);
             spapr->kernel_le = spapr->kernel_size > 0;
         }
         if (spapr->kernel_size < 0) {
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 6862552..7526947 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -259,7 +259,7 @@ static void virtex_init(MachineState *machine)

         /* Boots a kernel elf binary.  */
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, &low, &high, 1, PPC_ELF_MACHINE,
+                               &entry, &low, &high, NULL, 1,
PPC_ELF_MACHINE,
                                0, 0);
         boot_info.bootstrap_pc = entry & 0x00ffffff;

diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 027303d..b8e7652 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -101,7 +101,7 @@ target_ulong riscv_load_firmware(const char
*firmware_filename,
     uint64_t firmware_entry, firmware_start, firmware_end;

     if (load_elf(firmware_filename, NULL, NULL, NULL, &firmware_entry,
-                 &firmware_start, &firmware_end, 0, EM_RISCV, 1, 0) > 0) {
+                 &firmware_start, &firmware_end, NULL, 0, EM_RISCV, 1, 0)
0) {
         return firmware_entry;
     }

@@ -119,7 +119,7 @@ target_ulong riscv_load_kernel(const char
*kernel_filename, symbol_fn_t sym_cb)
     uint64_t kernel_entry, kernel_high;

     if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
-                         &kernel_entry, NULL, &kernel_high, 0,
+                         &kernel_entry, NULL, &kernel_high, NULL, 0,
                          EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
         return kernel_entry;
     }
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index ca544d6..49506e4 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -139,7 +139,7 @@ static void s390_ipl_realize(DeviceState *dev, Error
**errp)

         bios_size = load_elf(bios_filename, NULL,
                              bios_translate_addr, &fwbase,
-                             &ipl->bios_start_addr, NULL, NULL, 1,
+                             &ipl->bios_start_addr, NULL, NULL, NULL, 1,
                              EM_S390, 0, 0);
         if (bios_size > 0) {
             /* Adjust ELF start address to final location */
@@ -164,7 +164,7 @@ static void s390_ipl_realize(DeviceState *dev, Error
**errp)
     if (ipl->kernel) {
         kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL,
                                &pentry, NULL,
-                               NULL, 1, EM_S390, 0, 0);
+                               NULL, NULL, 1, EM_S390, 0, 0);
         if (kernel_size < 0) {
             kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
             if (kernel_size < 0) {
@@ -473,7 +473,8 @@ static int load_netboot_image(Error **errp)

     img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL,
                             &ipl->start_addr,
-                            NULL, NULL, 1, EM_S390, 0, 0, NULL, false);
+                            NULL, NULL, NULL, 1, EM_S390, 0, 0, NULL,
+                            false);

     if (img_size < 0) {
         img_size = load_image_size(netboot_filename, ram_ptr, ram_size);
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 8038887..f5a087d 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -297,7 +297,7 @@ static void leon3_generic_hw_init(MachineState
*machine)
         uint64_t entry;

         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               &entry, NULL, NULL,
+                               &entry, NULL, NULL, NULL,
                                1 /* big endian */, EM_SPARC, 0, 0);
         if (kernel_size < 0) {
             kernel_size = load_uimage(kernel_filename, NULL, &entry,
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 2aaa5bf..d404353 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -270,7 +270,7 @@ static unsigned long sun4m_load_kernel(const char
*kernel_filename,
 #endif
         kernel_size = load_elf(kernel_filename, NULL,
                                translate_kernel_address, NULL,
-                               NULL, NULL, NULL, 1, EM_SPARC, 0, 0);
+                               NULL, NULL, NULL, NULL, 1, EM_SPARC, 0, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                     RAM_size - KERNEL_LOAD_ADDR,
bswap_needed,
@@ -721,7 +721,7 @@ static void prom_init(hwaddr addr, const char
*bios_name)
     if (filename) {
         ret = load_elf(filename, NULL,
                        translate_prom_address, &addr, NULL,
-                       NULL, NULL, 1, EM_SPARC, 0, 0);
+                       NULL, NULL, NULL, 1, EM_SPARC, 0, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 9550827..c746040 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -175,7 +175,8 @@ static uint64_t sun4u_load_kernel(const char
*kernel_filename,
         bswap_needed = 0;
 #endif
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
kernel_entry,
-                               kernel_addr, &kernel_top, 1, EM_SPARCV9,
0, 0);
+                               kernel_addr, &kernel_top, NULL, 1,
EM_SPARCV9, 0,
+                               0);
         if (kernel_size < 0) {
             *kernel_addr = KERNEL_LOAD_ADDR;
             *kernel_entry = KERNEL_LOAD_ADDR;
@@ -439,7 +440,7 @@ static void prom_init(hwaddr addr, const char
*bios_name)
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
         ret = load_elf(filename, NULL, translate_prom_address, &addr,
-                       NULL, NULL, NULL, 1, EM_SPARCV9, 0, 0);
+                       NULL, NULL, NULL, NULL, 1, EM_SPARCV9, 0, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_
testboard.c
index aef3289..20c9ccb 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -42,7 +42,7 @@ static void tricore_load_kernel(CPUTriCoreState *env)

     kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL,
                            NULL, NULL, &entry, NULL,
-                           NULL, 0,
+                           NULL, NULL, 0,
                            EM_TRICORE, 1, 0);
     if (kernel_size <= 0) {
         error_report("no kernel file '%s'",
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index a22743a..aeb46d8 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -108,7 +108,7 @@ void xtensa_sim_load_kernel(XtensaCPU *cpu,
MachineState *machine)
         uint64_t elf_entry;
         uint64_t elf_lowaddr;
         int success = load_elf(kernel_filename, NULL,
translate_phys_addr, cpu,
-                               &elf_entry, &elf_lowaddr, NULL, big_endian,
+                               &elf_entry, &elf_lowaddr, NULL, NULL,
big_endian,
                                EM_XTENSA, 0, 0);

         if (success > 0) {
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 8220c7a..8e2dd13 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -415,7 +415,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board,
MachineState *machine)
         uint64_t elf_entry;
         uint64_t elf_lowaddr;
         int success = load_elf(kernel_filename, NULL,
translate_phys_addr, cpu,
-                &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0, 0);
+                &elf_entry, &elf_lowaddr, NULL, NULL, be, EM_XTENSA, 0,
0);
         if (success > 0) {
             entry_point = elf_entry;
         } else {
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index e07d276..a1411bf 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -316,7 +316,8 @@ static int glue(load_elf, SZ)(const char *name, int fd,
                               void *translate_opaque,
                               int must_swab, uint64_t *pentry,
                               uint64_t *lowaddr, uint64_t *highaddr,
-                              int elf_machine, int clear_lsb, int
data_swab,
+                              uint32_t *pflags, int elf_machine,
+                              int clear_lsb, int data_swab,
                               AddressSpace *as, bool load_rom,
                               symbol_fn_t sym_cb)
 {
@@ -389,6 +390,9 @@ static int glue(load_elf, SZ)(const char *name, int fd,
             }
     }

+    if (pflags) {
+        *pflags = (elf_word)ehdr.e_flags;
+    }
     if (pentry)
         *pentry = (uint64_t)(elf_sword)ehdr.e_entry;

diff --git a/include/hw/loader.h b/include/hw/loader.h
index 48a96cd..a9eeea3 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -101,6 +101,7 @@ const char *load_elf_strerror(int error);
  * @pentry: Populated with program entry point. Ignored if NULL.
  * @lowaddr: Populated with lowest loaded address. Ignored if NULL.
  * @highaddr: Populated with highest loaded address. Ignored if NULL.
+ * @pflags: Populated with ELF processor-specific flags. Ignore if NULL.
  * @bigendian: Expected ELF endianness. 0 for LE otherwise BE
  * @elf_machine: Expected ELF machine type
  * @clear_lsb: Set to mask off LSB of addresses (Some architectures use
@@ -131,8 +132,9 @@ int load_elf_ram_sym(const char *filename,
                      uint64_t (*elf_note_fn)(void *, void *, bool),
                      uint64_t (*translate_fn)(void *, uint64_t),
                      void *translate_opaque, uint64_t *pentry,
-                     uint64_t *lowaddr, uint64_t *highaddr, int
big_endian,
-                     int elf_machine, int clear_lsb, int data_swab,
+                     uint64_t *lowaddr, uint64_t *highaddr, uint32_t
*pflags,
+                     int big_endian, int elf_machine,
+                     int clear_lsb, int data_swab,
                      AddressSpace *as, bool load_rom, symbol_fn_t sym_cb);

 /** load_elf_ram:
@@ -143,9 +145,9 @@ int load_elf_ram(const char *filename,
                  uint64_t (*elf_note_fn)(void *, void *, bool),
                  uint64_t (*translate_fn)(void *, uint64_t),
                  void *translate_opaque, uint64_t *pentry, uint64_t
*lowaddr,
-                 uint64_t *highaddr, int big_endian, int elf_machine,
-                 int clear_lsb, int data_swab, AddressSpace *as,
-                 bool load_rom);
+                 uint64_t *highaddr, uint32_t *pflags, int big_endian,
+                 int elf_machine, int clear_lsb, int data_swab,
+                 AddressSpace *as, bool load_rom);

 /** load_elf_as:
  * Same as load_elf_ram(), but always loads the elf as ROM
@@ -154,8 +156,9 @@ int load_elf_as(const char *filename,
                 uint64_t (*elf_note_fn)(void *, void *, bool),
                 uint64_t (*translate_fn)(void *, uint64_t),
                 void *translate_opaque, uint64_t *pentry, uint64_t
*lowaddr,
-                uint64_t *highaddr, int big_endian, int elf_machine,
-                int clear_lsb, int data_swab, AddressSpace *as);
+                uint64_t *highaddr, uint32_t *pflags, int big_endian,
+                int elf_machine, int clear_lsb, int data_swab,
+                AddressSpace *as);

 /** load_elf:
  * Same as load_elf_as(), but doesn't allow the caller to specify an
@@ -165,8 +168,8 @@ int load_elf(const char *filename,
              uint64_t (*elf_note_fn)(void *, void *, bool),
              uint64_t (*translate_fn)(void *, uint64_t),
              void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
-             uint64_t *highaddr, int big_endian, int elf_machine,
-             int clear_lsb, int data_swab);
+             uint64_t *highaddr, uint32_t *pflags, int big_endian,
+             int elf_machine, int clear_lsb, int data_swab);

 /** load_elf_hdr:
  * @filename: Path of ELF file
--
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]