hw/core/loader.c | 9 --------- 1 file changed, 9 deletions(-)
From 84f25a8e4269f44255a8037837fdaa6e5404b76e Mon Sep 17 00:00:00 2001
From: Hua Yanghao <yanghao.hua@intel.com>
Date: Sun, 23 Jul 2017 21:48:21 +0200
Subject: [PATCH] hw/core/loader: do not check for regions overlap
There is a use case where regions are overlapped on purpose.
It should be up to the linker to check for regions overlap and qemu should
better not to do so.
For example:
SECTIONS
{
...... /* the normal text/data */
_on_chip_ram_load_start = .;
. = . + SIZEOF(.on_chip_ram_section);
_on_chip_ram_load_end = .;
.bss (NOLOAD) {
*(.bss*)
*(COM*)
}
...... /* other things */
}
with current hw/core/loader implementation, .bss section consumes no LMU address
space as .bss is not a loadable section, it is only useful for VMA at runtime.
Where the .on_chip_ram_section is told to be loaded (LMA) from the VMA of .bss
section. And qemu complains and exits. This patch fixes the issue and tested
running fine for the above scenario.
---
hw/core/loader.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index c17ace0a2e..9542cb3555 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -1099,26 +1099,17 @@ int rom_check_and_register_reset(void)
hwaddr addr = 0;
MemoryRegionSection section;
Rom *rom;
- AddressSpace *as = NULL;
QTAILQ_FOREACH(rom, &roms, next) {
if (rom->fw_file) {
continue;
}
- if ((addr > rom->addr) && (as == rom->as)) {
- fprintf(stderr, "rom: requested regions overlap "
- "(rom %s. free=0x" TARGET_FMT_plx
- ", addr=0x" TARGET_FMT_plx ")\n",
- rom->name, addr, rom->addr);
- return -1;
- }
addr = rom->addr;
addr += rom->romsize;
section = memory_region_find(rom->mr ? rom->mr : get_system_memory(),
rom->addr, 1);
rom->isrom = int128_nz(section.size) &&
memory_region_is_rom(section.mr);
memory_region_unref(section.mr);
- as = rom->as;
}
qemu_register_reset(rom_reset, NULL);
roms_loaded = 1;
--
2.11.0
On 23 July 2017 at 21:04, Hua Yanghao <huayanghao@gmail.com> wrote:
> From 84f25a8e4269f44255a8037837fdaa6e5404b76e Mon Sep 17 00:00:00 2001
> From: Hua Yanghao <yanghao.hua@intel.com>
> Date: Sun, 23 Jul 2017 21:48:21 +0200
> Subject: [PATCH] hw/core/loader: do not check for regions overlap
>
> There is a use case where regions are overlapped on purpose.
> It should be up to the linker to check for regions overlap and qemu should
> better not to do so.
>
> For example:
> SECTIONS
> {
> ...... /* the normal text/data */
> _on_chip_ram_load_start = .;
> . = . + SIZEOF(.on_chip_ram_section);
> _on_chip_ram_load_end = .;
>
> .bss (NOLOAD) {
> *(.bss*)
> *(COM*)
> }
> ...... /* other things */
> }
(I'm not sure why you end up with overlapping
program segments here since the bss segment ought
to be marked NOLOAD and ignored by QEMU. But I've
definitely seen overlapping segments myself where
the segments overlapping both are marked as LOAD.)
> with current hw/core/loader implementation, .bss section consumes no LMU address
> space as .bss is not a loadable section, it is only useful for VMA at runtime.
> Where the .on_chip_ram_section is told to be loaded (LMA) from the VMA of .bss
> section. And qemu complains and exits. This patch fixes the issue and tested
> running fine for the above scenario.
> ---
Oddly enough, I just ran into this scenario with an
ELF file myself the other day, and worked around it
with pretty much the same kind of local hack as this.
I agree that since this kind of ELF file with overlapping
segments seems to be quite common we should load it,
rather than complaining.
But...
(1) does this change give the right behaviour for
which of the two overlapping segment is honoured?
(I *think* the correct answer is that the second
segment in the program header table should be
loaded second, ie its definition of the memory
contents is used, not that of the first segment)
(2) should we allow the overlap only for ELF files but
retain the complain for overlapping ROMs of other types?
(eg by having the elf loader create "rom"s which
don't overlap by trimming the overlap itself)
Does anybody know (a) what the ELF spec mandates
for overlapping segments and (b) what the history
and rationale for QEMU's overlapping-roms check is?
thanks
-- PMM
> (I'm not sure why you end up with overlapping > program segments here since the bss segment ought > to be marked NOLOAD and ignored by QEMU. But I've > definitely seen overlapping segments myself where > the segments overlapping both are marked as LOAD.) Looks like qemu is not ignoring NOLOAD seciton check and used its VMA as if it is LMA ... If I remove the NOLOAD then .bss consumesthe LMA addresss and everything is working fine. > Oddly enough, I just ran into this scenario with an > ELF file myself the other day, and worked around it > with pretty much the same kind of local hack as this. > I agree that since this kind of ELF file with overlapping > segments seems to be quite common we should load it, > rather than complaining. Good to know I am not the only one who hit this issue ;-) > But... > > (1) does this change give the right behaviour for > which of the two overlapping segment is honoured? > (I *think* the correct answer is that the second > segment in the program header table should be > loaded second, ie its definition of the memory > contents is used, not that of the first segment) I am not sure if I understood this point. linker will check for section overlaps and if linker did not complain why should qemu complain. qemu should simply follow the LMA for each section and ignore NOLOAD section for me this is the sane behavior. > (2) should we allow the overlap only for ELF files but > retain the complain for overlapping ROMs of other types? > (eg by having the elf loader create "rom"s which > don't overlap by trimming the overlap itself) I think this should only apply for ELF files. (this is the only thing I care or understood so far, so not touching other types of input binaries ... however I am not sure if I am capable to provide a right patch to handle the ROM files properly, I only looked into qemu code starting today ...) > Does anybody know (a) what the ELF spec mandates > for overlapping segments and (b) what the history > and rationale for QEMU's overlapping-roms check is? > > thanks > -- PMM
On 23 July 2017 at 21:58, Hua Yanghao <huayanghao@gmail.com> wrote: >> (1) does this change give the right behaviour for >> which of the two overlapping segment is honoured? >> (I *think* the correct answer is that the second >> segment in the program header table should be >> loaded second, ie its definition of the memory >> contents is used, not that of the first segment) > I am not sure if I understood this point. linker will check for > section overlaps and if linker > did not complain why should qemu complain. qemu should simply follow > the LMA for each > section and ignore NOLOAD section for me this is the sane behavior. Suppose we have these two segments: SEGMENT 1: start 0x1000, end 0x2fff, data all 0xff SEGMENT 2: start 0x2000, end 0x3fff, data all 0x00 Clearly for the memory 0x1000..0x1fff we want the 0xff data, and for 0x3000..0x3fff we want 0x00. But for the memory 0x2000..0x2fff which is in both segment 1 and segment 2, should QEMU load 0xff or 0x00 bytes ? We shouldn't pick randomly or just do whatever our implementation "happens to do" -- we need to look at what the ELF spec says must happen and do that. >> (2) should we allow the overlap only for ELF files but >> retain the complain for overlapping ROMs of other types? >> (eg by having the elf loader create "rom"s which >> don't overlap by trimming the overlap itself) > I think this should only apply for ELF files. (this is the only thing > I care or understood so far, > so not touching other types of input binaries ... however I am not > sure if I am capable to provide > a right patch to handle the ROM files properly, I only looked into > qemu code starting today ...) The patch you have here will affect QEMU's handling of ROMs of all types, because the loader.c code handles all the registered ROM images, not just those that the ELF loader creates from ELF files. (PS: these questions are partly aimed at the other QEMU developers who I cc'd, not just you.) thanks -- PMM
> Suppose we have these two segments: > SEGMENT 1: start 0x1000, end 0x2fff, data all 0xff > SEGMENT 2: start 0x2000, end 0x3fff, data all 0x00 > > Clearly for the memory 0x1000..0x1fff we want the 0xff > data, and for 0x3000..0x3fff we want 0x00. > But for the memory 0x2000..0x2fff which is in > both segment 1 and segment 2, should QEMU load > 0xff or 0x00 bytes ? > > We shouldn't pick randomly or just do whatever our > implementation "happens to do" -- we need to look > at what the ELF spec says must happen and do that. I don't see how linker could allow that to happen. If two section overlaps one of them should be of NOLOAD type. Otherwise linker complains the overlapping of LMA. So for me just ignore NOLOAD section would do the trick. > The patch you have here will affect QEMU's handling > of ROMs of all types, because the loader.c code > handles all the registered ROM images, not just those > that the ELF loader creates from ELF files. > > (PS: these questions are partly aimed at the other > QEMU developers who I cc'd, not just you.) > Thanks PPM. This is really beyond my knowledge and hope someone could help making a clean patch! BR, Yanghao
On 23 July 2017 at 23:11, Hua Yanghao <huayanghao@gmail.com> wrote: >> Suppose we have these two segments: >> SEGMENT 1: start 0x1000, end 0x2fff, data all 0xff >> SEGMENT 2: start 0x2000, end 0x3fff, data all 0x00 >> >> Clearly for the memory 0x1000..0x1fff we want the 0xff >> data, and for 0x3000..0x3fff we want 0x00. >> But for the memory 0x2000..0x2fff which is in >> both segment 1 and segment 2, should QEMU load >> 0xff or 0x00 bytes ? >> >> We shouldn't pick randomly or just do whatever our >> implementation "happens to do" -- we need to look >> at what the ELF spec says must happen and do that. > I don't see how linker could allow that to happen. > If two section overlaps one of them should be of NOLOAD type. > Otherwise linker complains the overlapping of LMA. I have seen ELF files which have this overlap and where both segments are PT_LOAD. (I think in the cases I've seen the contents in both segments agree rather than being different data, but a loader is not going to be expected to do a comparison of the file data.) > So for me just ignore NOLOAD section would do the trick. We already ignore all the ELF segments which are not of type PT_LOAD: http://git.qemu.org/?p=qemu.git;a=blob;f=include/hw/elf_ops.h;h=a172a6068a48e233dd802043b3304a9e0a5d3be6;hb=HEAD#l353 If you're hitting this error case then I think the affected segments must both be of type PT_LOAD. (If you're not sure you can post here the output of running 'objdump -p' on the binary or otherwise show us the program header.) PS: you're consistently saying "section", but in the ELF format "section" and "segment" are two different things. QEMU doesn't actually look at the section table. In an ELF file, sections are used by the linker, but a program loader like QEMU (or the Linux kernel) looks only at the segment table in the program header. thanks -- PMM
> I have seen ELF files which have this overlap and
> where both segments are PT_LOAD. (I think in the cases
> I've seen the contents in both segments agree rather than
> being different data, but a loader is not going to be
> expected to do a comparison of the file data.)
Hmm ... OK. there are definitely things I haven't seen :-)
>> So for me just ignore NOLOAD section would do the trick.
>
> We already ignore all the ELF segments which are not
> of type PT_LOAD:
> http://git.qemu.org/?p=qemu.git;a=blob;f=include/hw/elf_ops.h;h=a172a6068a48e233dd802043b3304a9e0a5d3be6;hb=HEAD#l353
>
> If you're hitting this error case then I think the
> affected segments must both be of type PT_LOAD.
> (If you're not sure you can post here the output
> of running 'objdump -p' on the binary or otherwise
> show us the program header.)
Here is the objdump -p:
hua@grass:~/git/usw $ arm-none-eabi-objdump -p
output/qemu_arm_vexpress/qemu_arm
_vexpress.elf
output/qemu_arm_vexpress/qemu_arm_vexpress.elf: file format elf32-littlearm
Program Header:
0x70000001 off 0x00076e6c vaddr 0x60076d8c paddr 0x60076d8c align 2**2
filesz 0x00000008 memsz 0x00000008 flags r--
LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
filesz 0x0007773c memsz 0x00077c00 flags rwx
LOAD off 0x00077820 vaddr 0x70000000 paddr 0x60077740 align 2**3
filesz 0x00000038 memsz 0x00000038 flags r-x
LOAD off 0x00077858 vaddr 0x70080000 paddr 0x60077780 align 2**3
filesz 0x00000038 memsz 0x00000038 flags r-x
LOAD off 0x00077890 vaddr 0x70090000 paddr 0x600777c0 align 2**3
filesz 0x00000038 memsz 0x00000038 flags r-x
private flags = 5000200: [Version5 EABI] [soft-float ABI]
hua@grass:~/git/usw $ nm output/^C
hua@grass:~/git/usw $ arm-none-eabi-nm
output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep bss
60077738 B __bss_start
60077c00 B __bss_end
hua@grass:~/git/usw $ configs/qemu_arm_vexpress.py run
Note: you must have a locally modified qemu-system-arm to work with this build!
Please contact Hua Yanghao for more details!
echo "==> Ctrl-A X to exit"; export QEMU_AUDIO_DRV="none";
qemu-system-arm -M vexpress-a9 -m 512M -smp cpus=1 -nographic -kernel
output/qemu_arm_vexpress/qemu_arm_vexpress.elf
==> Ctrl-A X to exit
rom: requested regions overlap (rom phdr #2:
output/qemu_arm_vexpress/qemu_arm_vexpress.elf.
free=0x0000000060077c00, addr=0x0000000060077740)
qemu-system-arm: rom check and register reset failed
hua@grass:~/git/usw $ arm-none-eabi-nm
output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep 60077c00
60077c00 B __bss_end
60077c00 B _heap_low
hua@grass:~/git/usw $ arm-none-eabi-nm
output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep 60077740
60077740 T _lmu0_load_start
60077740 T _lmu_load_start
hua@grass:~/git/usw $ arm-none-eabi-nm
output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep lmu0
6006a458 t __lmu0_veneer
60077740 T _lmu0_load_start
60077778 T _lmu0_load_end
70000000 t lmu0
70000000 T _lmu0_start
70000038 T _lmu0_end
hua@grass:~/git/usw $
> PS: you're consistently saying "section", but in the
> ELF format "section" and "segment" are two different
> things. QEMU doesn't actually look at the section table.
> In an ELF file, sections are used by the linker, but a
> program loader like QEMU (or the Linux kernel)
> looks only at the segment table in the program header.
Yes I am looking from the "section" perspective.
As I intentionally want two sections to overlap (.bss and the lmu
section starting from LMA _lmu0_load_start).
I know loaders only care about segments. :-)
BR, Yanghao
On 24 July 2017 at 12:42, Hua Yanghao <huayanghao@gmail.com> wrote:
>> If you're hitting this error case then I think the
>> affected segments must both be of type PT_LOAD.
>> (If you're not sure you can post here the output
>> of running 'objdump -p' on the binary or otherwise
>> show us the program header.)
>
> Here is the objdump -p:
> hua@grass:~/git/usw $ arm-none-eabi-objdump -p
> output/qemu_arm_vexpress/qemu_arm
> _vexpress.elf
>
> output/qemu_arm_vexpress/qemu_arm_vexpress.elf: file format elf32-littlearm
>
> Program Header:
> 0x70000001 off 0x00076e6c vaddr 0x60076d8c paddr 0x60076d8c align 2**2
> filesz 0x00000008 memsz 0x00000008 flags r--
> LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
> filesz 0x0007773c memsz 0x00077c00 flags rwx
> LOAD off 0x00077820 vaddr 0x70000000 paddr 0x60077740 align 2**3
> filesz 0x00000038 memsz 0x00000038 flags r-x
> LOAD off 0x00077858 vaddr 0x70080000 paddr 0x60077780 align 2**3
> filesz 0x00000038 memsz 0x00000038 flags r-x
> LOAD off 0x00077890 vaddr 0x70090000 paddr 0x600777c0 align 2**3
> filesz 0x00000038 memsz 0x00000038 flags r-x
> private flags = 5000200: [Version5 EABI] [soft-float ABI]
> rom: requested regions overlap (rom phdr #2:
> output/qemu_arm_vexpress/qemu_arm_vexpress.elf.
> free=0x0000000060077c00, addr=0x0000000060077740)
Yep, this is complaining because you have two LOAD
segments which overlap:
LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
filesz 0x0007773c memsz 0x00077c00 flags rwx
which goes from 0x60000000 up to 0x600077bff, and
LOAD off 0x00077820 vaddr 0x70000000 paddr 0x60077740 align 2**3
filesz 0x00000038 memsz 0x00000038 flags r-x
which starts at 0x60077740, in the middle of the previous one.
So should the loader honour the first of these segment
definitions (which says "fill it with zeroes", because the
memsz is greater than the filesz), or the second (which says
"fill it with data from the file") ?
Also, it has different rwx flags -- so are you asking for the
memory to be rwx or r-x ? (This kind of inconsistency is why
overlapping segments are weird.)
>> PS: you're consistently saying "section", but in the
>> ELF format "section" and "segment" are two different
>> things. QEMU doesn't actually look at the section table.
>> In an ELF file, sections are used by the linker, but a
>> program loader like QEMU (or the Linux kernel)
>> looks only at the segment table in the program header.
> Yes I am looking from the "section" perspective.
> As I intentionally want two sections to overlap (.bss and the lmu
> section starting from LMA _lmu0_load_start).
> I know loaders only care about segments. :-)
Right, but QEMU only cares about segments and the check
you're trying to disable is a *segment* overlap check,
not a section overlap check. You can overlap sections
all you want as long as you don't end up with a final
ELF file with overlapping segments...
thanks
-- PMM
> Yep, this is complaining because you have two LOAD
> segments which overlap:
> LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
> filesz 0x0007773c memsz 0x00077c00 flags rwx
>
> which goes from 0x60000000 up to 0x600077bff, and
>
> LOAD off 0x00077820 vaddr 0x70000000 paddr 0x60077740 align 2**3
> filesz 0x00000038 memsz 0x00000038 flags r-x
>
> which starts at 0x60077740, in the middle of the previous one.
> So should the loader honour the first of these segment
> definitions (which says "fill it with zeroes", because the
> memsz is greater than the filesz), or the second (which says
> "fill it with data from the file") ?
> Also, it has different rwx flags -- so are you asking for the
> memory to be rwx or r-x ? (This kind of inconsistency is why
> overlapping segments are weird.)
I don't quite understand how those load segments are created.
Bear with me, from section point of view, 0x600077740 is both
the .bss (which is NOLOAD) and the .lmu0 section. Why this bss
section could end up in a loadable segments? I don't understand
how those rwx/r-x permission are created from my linker script all
memory regions share the same rwx attribute:
11 MEMORY
12 {
13 dram (rwx) : ORIGIN = CONFIG_DRAM_START, LENGTH = CONFIG_DRAM_SIZE
14 lmu0 (rwx) : ORIGIN = CONFIG_LMU0_START, LENGTH = CONFIG_LMU0_SIZE
15 lmu1 (rwx) : ORIGIN = CONFIG_LMU1_START, LENGTH = CONFIG_LMU1_SIZE
16 lmu2 (rwx) : ORIGIN = CONFIG_LMU2_START, LENGTH = CONFIG_LMU2_SIZE
17 }
output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep bss
60077738 B __bss_start
60077c00 B __bss_end
from this link: http://nairobi-embedded.org/040_elf_sec_seg_vma_mappings.html
It seems segments do consider NOLOAD .bss sections as part of loadable
data segments.
Does the loader needs to consider more things from the segments table
to distinguish that
the .bss section actually does not need to be touched?
BR, Yanghao
On Mon, Jul 24, 2017 at 2:09 PM, Hua Yanghao <huayanghao@gmail.com> wrote:
>> Yep, this is complaining because you have two LOAD
>> segments which overlap:
>> LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
>> filesz 0x0007773c memsz 0x00077c00 flags rwx
>>
>> which goes from 0x60000000 up to 0x600077bff, and
>>
>> LOAD off 0x00077820 vaddr 0x70000000 paddr 0x60077740 align 2**3
>> filesz 0x00000038 memsz 0x00000038 flags r-x
>>
>> which starts at 0x60077740, in the middle of the previous one.
>> So should the loader honour the first of these segment
>> definitions (which says "fill it with zeroes", because the
>> memsz is greater than the filesz), or the second (which says
>> "fill it with data from the file") ?
>> Also, it has different rwx flags -- so are you asking for the
>> memory to be rwx or r-x ? (This kind of inconsistency is why
>> overlapping segments are weird.)
>
> I don't quite understand how those load segments are created.
> Bear with me, from section point of view, 0x600077740 is both
> the .bss (which is NOLOAD) and the .lmu0 section. Why this bss
> section could end up in a loadable segments? I don't understand
> how those rwx/r-x permission are created from my linker script all
> memory regions share the same rwx attribute:
>
> 11 MEMORY
> 12 {
> 13 dram (rwx) : ORIGIN = CONFIG_DRAM_START, LENGTH = CONFIG_DRAM_SIZE
> 14 lmu0 (rwx) : ORIGIN = CONFIG_LMU0_START, LENGTH = CONFIG_LMU0_SIZE
> 15 lmu1 (rwx) : ORIGIN = CONFIG_LMU1_START, LENGTH = CONFIG_LMU1_SIZE
> 16 lmu2 (rwx) : ORIGIN = CONFIG_LMU2_START, LENGTH = CONFIG_LMU2_SIZE
> 17 }
>
> output/qemu_arm_vexpress/qemu_arm_vexpress.elf | sort | grep bss
> 60077738 B __bss_start
> 60077c00 B __bss_end
>
> from this link: http://nairobi-embedded.org/040_elf_sec_seg_vma_mappings.html
> It seems segments do consider NOLOAD .bss sections as part of loadable
> data segments.
> Does the loader needs to consider more things from the segments table
> to distinguish that
> the .bss section actually does not need to be touched?
>
> BR, Yanghao
I think I got where qemu went wrong, it should pick filesz instead of
memsz, right? ;-)
You see here the filesz does not actually include the bss section
where if you only check the memsz then it overlaps.
LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5
filesz 0x0007773c memsz 0x00077c00 flags rwx
-----
PT_LOAD
The array element specifies a loadable segment, described by p_filesz
and p_memsz. The bytes from the file are mapped to the beginning of
the memory segment. If the segment's memory size (p_memsz) is larger
than the file size (p_filesz), the "extra" bytes are defined to hold
the value 0 and to follow the segment's initialized area. The file
size may not be larger than the memory size. Loadable segment entries
in the program header table appear in ascending order,
sorted on the p_vaddr member.
-----
On 24 July 2017 at 13:21, Hua Yanghao <huayanghao@gmail.com> wrote: > I think I got where qemu went wrong, it should pick filesz instead of > memsz, right? ;-) > > You see here the filesz does not actually include the bss section > where if you only check the memsz then it overlaps. > > LOAD off 0x000000e0 vaddr 0x60000000 paddr 0x60000000 align 2**5 > filesz 0x0007773c memsz 0x00077c00 flags rwx > > ----- > PT_LOAD > > The array element specifies a loadable segment, described by p_filesz > and p_memsz. The bytes from the file are mapped to the beginning of > the memory segment. If the segment's memory size (p_memsz) is larger > than the file size (p_filesz), the "extra" bytes are defined to hold > the value 0 and to follow the segment's initialized area. The file > size may not be larger than the memory size. Loadable segment entries > in the program header table appear in ascending order, > > sorted on the p_vaddr member. > ----- In the bit of the spec you quote it says how p_memsz > p_filesz should be handled: "the 'extra' bytes are defined to hold the value 0". The segment itself is still p_memsz in size and the header defines that it has zeroes at the end of it. QEMU's loader needs to arrange that those zeroes are loaded. thanks -- PMM
> In the bit of the spec you quote it says how p_memsz > p_filesz > should be handled: "the 'extra' bytes are defined to hold the > value 0". The segment itself is still p_memsz in size and the > header defines that it has zeroes at the end of it. QEMU's loader > needs to arrange that those zeroes are loaded. > Do we have a way for qemu to take a "binary" instead of elf with the -kernel option? I can create a binary out of the elf that does not have any information about segments. I tried to feed -kernel with the objcopy-created binary but it does not work. :-(
On 23 July 2017 at 21:44, Peter Maydell <peter.maydell@linaro.org> wrote: > Does anybody know (a) what the ELF spec mandates > for overlapping segments and (b) what the history > and rationale for QEMU's overlapping-roms check is? Having asked around a bit, it appears that it's fairly common in the embedded world to treat the ELF "vaddr" as the "execution address" and the ELF "paddr" as "load address", with the size of the data to be loaded at the load address being specified by "filesz". The typical application is where an application is packed into ROM -- the ROM addresses are the paddr values, and something at runtime will unpack everything into the vaddr addresses where it eventually runs from (and handle the zero-initialization). The awkward part is that this is more pervasive convention rather than actually written down as a specification, and there's no way to tell whether a particular ELF file is using it or not. My current theory is that we can handle this with: * load the segment with the assumption that the memsz is the size to use (zero-filling), as we do now * _unless_ that would make it overlap with the following segment, in which case use the filesz That ought to make all the ELF files we currently load OK continue to load with the same semantics, and also permit loading of ELF files using the ARM embedded conventions. In some cases of ELF files using the embedded convention but not tightly packing their segments into ROM it will zero out some of the gaps between segments, but I think that should be harmless. thanks -- PMM
On Mon, Jul 24, 2017 at 6:46 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 23 July 2017 at 21:44, Peter Maydell <peter.maydell@linaro.org> wrote: >> Does anybody know (a) what the ELF spec mandates >> for overlapping segments and (b) what the history >> and rationale for QEMU's overlapping-roms check is? > > Having asked around a bit, it appears that it's fairly common > in the embedded world to treat the ELF "vaddr" as the "execution > address" and the ELF "paddr" as "load address", with the > size of the data to be loaded at the load address being > specified by "filesz". The typical application is where > an application is packed into ROM -- the ROM addresses are > the paddr values, and something at runtime will unpack > everything into the vaddr addresses where it eventually > runs from (and handle the zero-initialization). That's exactly what I am doing right now ;-) I have code at runtime not only initialize the bss, but also moving a few other sections around (e.g. from dram to onchip memory). And we even have use cases that the bss part should not be initialized at all! (on accurate simulation env where the .bss is preloaded with zeros, without overlapping sections of course) > The awkward part is that this is more pervasive convention > rather than actually written down as a specification, and > there's no way to tell whether a particular ELF file is > using it or not. Indeed, I thought this is the standard written somewhere :-) Maybe I am just in the embedded world for too long. > My current theory is that we can handle this with: > * load the segment with the assumption that the > memsz is the size to use (zero-filling), as > we do now > * _unless_ that would make it overlap with the following > segment, in which case use the filesz > > That ought to make all the ELF files we currently load > OK continue to load with the same semantics, and also > permit loading of ELF files using the ARM embedded > conventions. In some cases of ELF files using the > embedded convention but not tightly packing their > segments into ROM it will zero out some of the gaps > between segments, but I think that should be harmless. Sounds good PPM! currently I am working around this by objcopy a pure binary and it looks like qemu-system-arm is loading a binary at loader address + 0x10000. From man page it claims it also supports multiboot image which I thought I could remove this loader address + 0x10000 limiation however with no luck. but the binary works pretty fine though at the fixed address. not as convenient as elf image which I can run from any address. If this can be implemented in mainline I will be very happy but my knowledge with qemu is probably not enough to make a clean patch. Thanks a lot for the good discussion! BR, Yanghao
On 24 July 2017 at 21:03, Hua Yanghao <huayanghao@gmail.com> wrote: > Sounds good PPM! currently I am working around this by > objcopy a pure binary and it looks like qemu-system-arm is > loading a binary at loader address + 0x10000. From man page > it claims it also supports multiboot image which I thought I could > remove this loader address + 0x10000 limiation however with > no luck. but the binary works pretty fine though at the fixed address. > not as convenient as elf image which I can run from any address. If you give -kernel on ARM (non-M-profile) systems something that isn't an ELF file this means "I am a Linux kernel and want the calling convention documented for the kernel" (which includes that load address, among other things). If you're not a Linux kernel then don't do that. You probably want the "-device loader" documented in docs/generic-loader.txt, which is (as the name suggests) a generic way to load an arbitrary binary into memory, and lets you specify whatever load address you want. thanks -- PMM
On Mon, Jul 24, 2017 at 11:21 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 24 July 2017 at 21:03, Hua Yanghao <huayanghao@gmail.com> wrote: >> Sounds good PPM! currently I am working around this by >> objcopy a pure binary and it looks like qemu-system-arm is >> loading a binary at loader address + 0x10000. From man page >> it claims it also supports multiboot image which I thought I could >> remove this loader address + 0x10000 limiation however with >> no luck. but the binary works pretty fine though at the fixed address. >> not as convenient as elf image which I can run from any address. > > If you give -kernel on ARM (non-M-profile) systems something > that isn't an ELF file this means "I am a Linux kernel and > want the calling convention documented for the kernel" (which > includes that load address, among other things). If you're > not a Linux kernel then don't do that. > > You probably want the "-device loader" documented in > docs/generic-loader.txt, which is (as the name suggests) > a generic way to load an arbitrary binary into memory, > and lets you specify whatever load address you want. > It works like a charm, thanks PPM. I think this already solves my problem for using elf, now I just use objcopied binary. However if qemu could support elf type with overlapping segments that is even better. ;-)
© 2016 - 2025 Red Hat, Inc.