* [Qemu-devel] ELF loader?
@ 2015-06-07 8:19 Liviu Ionescu
2015-06-07 10:46 ` Peter Maydell
0 siblings, 1 reply; 6+ messages in thread
From: Liviu Ionescu @ 2015-06-07 8:19 UTC (permalink / raw)
To: QEMU Developers
while debugging my Cortex-M code I added a trace in the ELF loader and I noticed an odd thing:
cortexm_mcu_image_load()
Load 10012 bytes at 0x08000000-0x0800271B.
Load 132 bytes at 0x0800271C-0x0800279F.
Load 704 bytes at 0x20000084-0x20000343. <---
Cortex-M3 core initialised.
the first two lines load some bytes in flash, the third one loads some bytes in ram. I checked the linker map and the ram range is actually the .bss section.
in other words, the .bss section is also "loaded". is this intentional, to automatically reserve memory for that area? (since it obviously has no content)
regards,
Liviu
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] ELF loader?
2015-06-07 8:19 [Qemu-devel] ELF loader? Liviu Ionescu
@ 2015-06-07 10:46 ` Peter Maydell
2015-06-07 16:03 ` Liviu Ionescu
0 siblings, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2015-06-07 10:46 UTC (permalink / raw)
To: Liviu Ionescu; +Cc: QEMU Developers
On 7 June 2015 at 09:19, Liviu Ionescu <ilg@livius.net> wrote:
> while debugging my Cortex-M code I added a trace in the ELF loader and I noticed an odd thing:
>
> cortexm_mcu_image_load()
> Load 10012 bytes at 0x08000000-0x0800271B.
> Load 132 bytes at 0x0800271C-0x0800279F.
> Load 704 bytes at 0x20000084-0x20000343. <---
> Cortex-M3 core initialised.
>
> the first two lines load some bytes in flash, the third one loads some bytes in ram. I checked the linker map and the ram range is actually the .bss section.
>
> in other words, the .bss section is also "loaded". is this intentional, to automatically reserve memory for that area? (since it obviously has no content)
ELF loaders don't look at the section table, they
look at the program headers, which describe the segments
in the program and typically look something like this:
Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x00000120 memsz 0x00000120 flags r-x
INTERP off 0x00000154 vaddr 0x08048154 paddr 0x08048154 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00004658 memsz 0x00004658 flags r-x
LOAD off 0x00004ef0 vaddr 0x0804def0 paddr 0x0804def0 align 2**12
filesz 0x000001cc memsz 0x00000350 flags rw-
DYNAMIC off 0x00004efc vaddr 0x0804defc paddr 0x0804defc align 2**2
filesz 0x000000f0 memsz 0x000000f0 flags rw-
NOTE off 0x00000168 vaddr 0x08048168 paddr 0x08048168 align 2**2
filesz 0x00000044 memsz 0x00000044 flags r--
EH_FRAME off 0x00003d40 vaddr 0x0804bd40 paddr 0x0804bd40 align 2**2
filesz 0x000001c4 memsz 0x000001c4 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rw-
RELRO off 0x00004ef0 vaddr 0x0804def0 paddr 0x0804def0 align 2**0
filesz 0x00000110 memsz 0x00000110 flags r--
and we load everything marked LOAD. (This is /bin/true on my Linux
box, but the principle is the same for any ELF file.) This ELF file
has two LOAD segments. The first one is read-only and will have the
code in it; its filesz and memsz are the same, so the loader reads
all the content from the file. The second one is read-write, and its
filesz is smaller than the memsz (0x1cc vs 0x350). So the loader will
read some data from the file and set the rest to zeros. In this case
that's the .data section (and a lot of other stuff like GOT, PLT,
dynamic linker info, etc) followed by a .bss.
(Notice that the linker has put a number of different sections into
the same segment; the amount of info needed to load the file is
much simpler than the info needed by a linker, which is why ELF has
this dual segment/section view.)
This is all mandated by the ELF spec: you have to load the segments
the file requests where it asks for them to go, and you have to
zero-initialize any trailing parts. (This ensures the .bss really
is zero-initialized. Some ELF files intended for embedded use have
a little self-initializing bit on the front that manually clears
their own .bss section, but that's not part of the ELF spec, and
QEMU will handle the other kind too.)
-- PMM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] ELF loader?
2015-06-07 10:46 ` Peter Maydell
@ 2015-06-07 16:03 ` Liviu Ionescu
2015-06-08 7:50 ` Peter Maydell
0 siblings, 1 reply; 6+ messages in thread
From: Liviu Ionescu @ 2015-06-07 16:03 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
> On 07 Jun 2015, at 13:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On 7 June 2015 at 09:19, Liviu Ionescu <ilg@livius.net> wrote:
>> while debugging my Cortex-M code I added a trace in the ELF loader and I noticed an odd thing:
>>
>> cortexm_mcu_image_load()
>> Load 10012 bytes at 0x08000000-0x0800271B.
>> Load 132 bytes at 0x0800271C-0x0800279F.
>> Load 704 bytes at 0x20000084-0x20000343. <---
>> Cortex-M3 core initialised.
>>
>> the first two lines load some bytes in flash, the third one loads some bytes in ram. I checked the linker map and the ram range is actually the .bss section.
>>
>> in other words, the .bss section is also "loaded". is this intentional, to automatically reserve memory for that area? (since it obviously has no content)
>
> ELF loaders ... look ... at the program headers, ...
> load everything marked LOAD.
a similar objdump on my ELF shows:
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0800010d
Program Header:
LOAD off 0x00008000 vaddr 0x08000000 paddr 0x08000000 align 2**15
filesz 0x0000271c memsz 0x0000271c flags rwx
LOAD off 0x00010000 vaddr 0x20000000 paddr 0x0800271c align 2**15
filesz 0x00000084 memsz 0x00000084 flags rw-
LOAD off 0x00010084 vaddr 0x20000084 paddr 0x20000084 align 2**15
filesz 0x00000000 memsz 0x000002c0 flags rw-
private flags = 5000202: [Version5 EABI] [soft-float ABI] [has entry point]
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 00000354 08000000 08000000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .inits 00000028 08000354 08000354 00008354 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .data 00000084 20000000 0800271c 00010000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .data_CCMRAM 00000000 00000000 00000000 00010084 2**2
CONTENTS
4 .bss 000001c0 20000084 20000084 00010084 2**2
ALLOC
5 .text 000023a0 0800037c 0800037c 0000837c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .noinit 00000000 20000244 20000244 00010084 2**2
CONTENTS
7 ._check_stack 00000100 20000244 20000244 00010084 2**2
ALLOC
8 .comment 00000070 00000000 00000000 00010084 2**0
CONTENTS, READONLY
9 .ARM.attributes 00000031 00000000 00000000 000100f4 2**0
CONTENTS, READONLY
10 .debug_aranges 00000570 00000000 00000000 00010125 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_info 00006fc1 00000000 00000000 00010695 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_abbrev 00001cb6 00000000 00000000 00017656 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_line 00004c26 00000000 00000000 0001930c 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_frame 000015a8 00000000 00000000 0001df34 2**2
CONTENTS, READONLY, DEBUGGING
15 .debug_str 0005638f 00000000 00000000 0001f4dc 2**0
CONTENTS, READONLY, DEBUGGING
16 .debug_loc 00002dfd 00000000 00000000 0007586b 2**0
CONTENTS, READONLY, DEBUGGING
17 .debug_ranges 00000500 00000000 00000000 00078668 2**0
CONTENTS, READONLY, DEBUGGING
18 .debug_macro 00004519 00000000 00000000 00078b68 2**0
CONTENTS, READONLY, DEBUGGING
so, the reason for loading the .bss section is just the presence of the LOAD flag for the first header.
> ... the loader will
> read some data from the file and set the rest to zeros.
> ... mandated by the ELF spec: you have to load the segments
> the file requests where it asks for them to go, and you have to
> zero-initialize any trailing parts.
:-)
this applies to large operating system loader, in the embedded world things are a bit different.
> ... Some ELF files intended for embedded use have
> a little self-initializing bit on the front that manually clears
> their own .bss section, but that's not part of the ELF spec, and
> QEMU will handle the other kind too.
as I said, in the embedded world things are a bit different, there is no ELF loader, or you can consider the debugger as an ELF loader since it is reading the ELF file and programming the flash.
but during this step it makes no sense to write/clear the RAM, since what you call 'a little self-initializing bit' is actually a quite complex startup code, which must handle a table of RAM regions to be zeroed, plus that it must copy the content of the .data section from flash to RAM (the second header in my file, to be copied from 0x0800271c to 0x20000000).
so, in this case, as for most MCUs, loading the third RAM area is completely useless, the embedded code *always* handle these details.
---
what is even more curious is that the third header is marked as load, although the linker script is configured to remove the LOAD attribute from the header:
/* The primary uninitialised data section. */
.bss (NOLOAD) : ALIGN(4)
{
__bss_start__ = .; /* standard newlib definition */
_sbss = .; /* STM specific definition */
*(.bss_begin .bss_begin.*)
*(.bss .bss.*)
*(COMMON)
*(.bss_end .bss_end.*)
. = ALIGN(4);
__bss_end__ = .; /* standard newlib definition */
_ebss = . ; /* STM specific definition */
} >RAM
I'm either missing something, or the linker did not honour the script (NOLOAD) property.
anyway, the problem is not harmful, it is more a curiosity for me, trying to understand what is the expected qemu behaviour.
regards,
Liviu
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] ELF loader?
2015-06-07 16:03 ` Liviu Ionescu
@ 2015-06-08 7:50 ` Peter Maydell
2015-06-08 8:27 ` Liviu Ionescu
0 siblings, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2015-06-08 7:50 UTC (permalink / raw)
To: Liviu Ionescu; +Cc: QEMU Developers
On 7 June 2015 at 17:03, Liviu Ionescu <ilg@livius.net> wrote:
>
>> On 07 Jun 2015, at 13:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>> ... Some ELF files intended for embedded use have
>> a little self-initializing bit on the front that manually clears
>> their own .bss section, but that's not part of the ELF spec, and
>> QEMU will handle the other kind too.
>
> as I said, in the embedded world things are a bit different, there
> is no ELF loader, or you can consider the debugger as an ELF loader
> since it is reading the ELF file and programming the flash.
>
> but during this step it makes no sense to write/clear the RAM
That depends on what the ELF file is. If I were writing a debugger's
ELF loader code I would make it clear the bss area, because a
debugger is supposed to handle any ELF file you throw at it,
and following the ELF spec is trivial.
-- PMM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] ELF loader?
2015-06-08 7:50 ` Peter Maydell
@ 2015-06-08 8:27 ` Liviu Ionescu
2015-06-08 9:03 ` Peter Maydell
0 siblings, 1 reply; 6+ messages in thread
From: Liviu Ionescu @ 2015-06-08 8:27 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
> On 08 Jun 2015, at 10:50, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On 7 June 2015 at 17:03, Liviu Ionescu <ilg@livius.net> wrote:
>>
>>> On 07 Jun 2015, at 13:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> ... Some ELF files intended for embedded use have
>>> a little self-initializing bit on the front that manually clears
>>> their own .bss section, but that's not part of the ELF spec, and
>>> QEMU will handle the other kind too.
>>
>> as I said, in the embedded world things are a bit different, there
>> is no ELF loader, or you can consider the debugger as an ELF loader
>> since it is reading the ELF file and programming the flash.
>>
>> but during this step it makes no sense to write/clear the RAM
>
> That depends on what the ELF file is.
yes and no.
in this peculiar case, the problem is the simplistic approach in the QEMU ELF loader, that uses only the header defs, ignoring the detailed definitions in the separate sections.
if you look carefully to the section in my file, you'll notice that the .bss section is **not** marked as LOAD (so the linker honoured the NOLOAD request), but the memory range in the header is marked as LOAD (I don't know the header structures, and the specs, but I would not exclude a linker bug).
> If I were writing a debugger's
> ELF loader code I would make it clear the bss area, because a
> debugger is supposed to handle any ELF file you throw at it,
> and following the ELF spec is trivial.
for a debugger ELF loader, clearing the bss area would simply hide possible problems in the embedded startup code.
for the startup code to clear the entire .bss area it requires correct linker scripts, which (unlike those used in the linux world, where you never deal with them), are part of each project and need to be manually maintained (a major problem for beginners), and it is usual to get linker scripts out of sync with the startup code requirement, and unstable embedded applications.
if the startup is buggy, and does not clear the .bss, or does not copy .data from flash, the program might not run properly when standalone if it assumes that all variables start as 0, although it runs fine when started by the debugger, since the debugger cleared those variables.
fortunately the ELF loader used in GDB does a good job in identifying the sections that need to be programmed (unlike the implementation used in QEMU).
regards,
Liviu
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] ELF loader?
2015-06-08 8:27 ` Liviu Ionescu
@ 2015-06-08 9:03 ` Peter Maydell
0 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2015-06-08 9:03 UTC (permalink / raw)
To: Liviu Ionescu; +Cc: QEMU Developers
On 8 June 2015 at 09:27, Liviu Ionescu <ilg@livius.net> wrote:
>
>> On 08 Jun 2015, at 10:50, Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On 7 June 2015 at 17:03, Liviu Ionescu <ilg@livius.net> wrote:
>>>
>>>> On 07 Jun 2015, at 13:46, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>> ... Some ELF files intended for embedded use have
>>>> a little self-initializing bit on the front that manually clears
>>>> their own .bss section, but that's not part of the ELF spec, and
>>>> QEMU will handle the other kind too.
>>>
>>> as I said, in the embedded world things are a bit different, there
>>> is no ELF loader, or you can consider the debugger as an ELF loader
>>> since it is reading the ELF file and programming the flash.
>>>
>>> but during this step it makes no sense to write/clear the RAM
>>
>> That depends on what the ELF file is.
>
> yes and no.
>
> in this peculiar case, the problem is the simplistic approach
> in the QEMU ELF loader, that uses only the header defs, ignoring
>the detailed definitions in the separate sections.
No. As I explained, this is correct. An ELF loader is *supposed*
to load based on the segment definitions. Sections are only
for linking. If you don't like the segment descriptions in your
ELF file you should probably change your linker script.
-- PMM
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-06-08 9:03 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-07 8:19 [Qemu-devel] ELF loader? Liviu Ionescu
2015-06-07 10:46 ` Peter Maydell
2015-06-07 16:03 ` Liviu Ionescu
2015-06-08 7:50 ` Peter Maydell
2015-06-08 8:27 ` Liviu Ionescu
2015-06-08 9:03 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).