Commit 6cdda0ff authored by Aleksandar Markovic's avatar Aleksandar Markovic
Browse files

hw/core/loader: Let load_elf() populate a field with CPU-specific flags



While loading the executable, some platforms (like AVR) need to
detect CPU type that executable is built for - and, with this patch,
this is enabled by reading the field 'e_flags' of the ELF header of
the executable in question. The change expands functionality of
the following functions:

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

The argument added to these functions is called 'pflags' and is of
type 'uint32_t*' (that matches 'pointer to 'elf_word'', 'elf_word'
being the type of the field 'e_flags', in both 32-bit and 64-bit
variants of ELF header). Callers are allowed to pass NULL as that
argument, and in such case no lookup to the field 'e_flags' will
happen, and no information will be returned, of course.

CC: Richard Henderson <rth@twiddle.net>
CC: Peter Maydell <peter.maydell@linaro.org>
CC: Edgar E. Iglesias <edgar.iglesias@gmail.com>
CC: Michael Walle <michael@walle.cc>
CC: Thomas Huth <huth@tuxfamily.org>
CC: Laurent Vivier <laurent@vivier.eu>
CC: Philippe Mathieu-Daudé <f4bug@amsat.org>
CC: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com>
CC: Aurelien Jarno <aurelien@aurel32.net>
CC: Jia Liu <proljc@gmail.com>
CC: David Gibson <david@gibson.dropbear.id.au>
CC: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: BALATON Zoltan <balaton@eik.bme.hu>
CC: Christian Borntraeger <borntraeger@de.ibm.com>
CC: Thomas Huth <thuth@redhat.com>
CC: Artyom Tarasenko <atar4qemu@gmail.com>
CC: Fabien Chouteau <chouteau@adacore.com>
CC: KONRAD Frederic <frederic.konrad@adacore.com>
CC: Max Filippov <jcmvbkbc@gmail.com>

Reviewed-by: default avatarAleksandar Rikalo <aleksandar.rikalo@rt-rk.com>
Signed-off-by: default avatarMichael Rolnik <mrolnik@gmail.com>
Signed-off-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: default avatarAleksandar Markovic <amarkovic@wavecomp.com>
Message-Id: <1580079311-20447-24-git-send-email-aleksandar.markovic@rt-rk.com>
parent 54fc33fd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -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,
+19 −18
Original line number Diff line number Diff line
@@ -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:
Loading