qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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).