All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
@ 2017-07-28 21:28 Anatol Pomozov
  2017-07-30 21:42 ` Eduardo Habkost
  2017-07-31  8:50 ` Peter Maydell
  0 siblings, 2 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-07-28 21:28 UTC (permalink / raw)
  To: qemu-devel, Paolo Bonzini, Richard Henderson, Eduardo Habkost

Hi

I am looking at x86 multiboot code and trying to add "ELF section
header" info feature. This will let target to learn more about booted
binary and its sections.

I have a draft here
https://github.com/anatol/qemu/commit/ad943a6eb78feee048b6bb2a1e5f49f5b686e24c

My understanding is that qemu multiboot loads only TEXT/BSS/DATA
sections. Other stuff like symbols sections and ELF headers are not
available for target.

So I need to perform 2 things:

 - Load ELF section headers into target's memory. I did by appending
additional space to mbs.mb_buf and copying header data. Is it the best
way to do?

 - Next I need to load other ELF sections such as symbols (e.g.
.shstrtab) that store section names. What is the best way to do in
multiboo.c code? Would it make sense to load all ELF sections?

Thanks in advance.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-28 21:28 [Qemu-devel] How to make ELF headers/symbol sections available for multiboot? Anatol Pomozov
@ 2017-07-30 21:42 ` Eduardo Habkost
  2017-07-31  6:25   ` Alexander Graf
                     ` (2 more replies)
  2017-07-31  8:50 ` Peter Maydell
  1 sibling, 3 replies; 17+ messages in thread
From: Eduardo Habkost @ 2017-07-30 21:42 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: qemu-devel, Paolo Bonzini, Richard Henderson, Alexander Graf, Kevin Wolf


CCing Alex, the original author of load_multiboot(), and Kevin,
who touched multiboot code recently.


On Fri, Jul 28, 2017 at 02:28:34PM -0700, Anatol Pomozov wrote:
> Hi
> 
> I am looking at x86 multiboot code and trying to add "ELF section
> header" info feature. This will let target to learn more about booted
> binary and its sections.

Are there existing OSes that use that information?


> 
> I have a draft here
> https://github.com/anatol/qemu/commit/ad943a6eb78feee048b6bb2a1e5f49f5b686e24c
> 
> My understanding is that qemu multiboot loads only TEXT/BSS/DATA
> sections. Other stuff like symbols sections and ELF headers are not
> available for target.
> 
> So I need to perform 2 things:
> 
>  - Load ELF section headers into target's memory. I did by appending
> additional space to mbs.mb_buf and copying header data. Is it the best
> way to do?
> 
>  - Next I need to load other ELF sections such as symbols (e.g.
> .shstrtab) that store section names. What is the best way to do in
> multiboo.c code? Would it make sense to load all ELF sections?
> 
> Thanks in advance.
> 

-- 
Eduardo

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-30 21:42 ` Eduardo Habkost
@ 2017-07-31  6:25   ` Alexander Graf
  2017-07-31 11:27   ` Kevin Wolf
  2017-07-31 17:21   ` Anatol Pomozov
  2 siblings, 0 replies; 17+ messages in thread
From: Alexander Graf @ 2017-07-31  6:25 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Anatol Pomozov, qemu-devel, Paolo Bonzini, Richard Henderson, Kevin Wolf

Hi Anatol,

> Am 30.07.2017 um 23:42 schrieb Eduardo Habkost <ehabkost@redhat.com>:
> 
> 
> CCing Alex, the original author of load_multiboot(), and Kevin,
> who touched multiboot code recently.
> 
> 
>> On Fri, Jul 28, 2017 at 02:28:34PM -0700, Anatol Pomozov wrote:
>> Hi
>> 
>> I am looking at x86 multiboot code and trying to add "ELF section
>> header" info feature. This will let target to

Do you have a pointer to what that feature does exactly?

>> learn more about booted
>> binary and its sections.
> 
> Are there existing OSes that use that information?
> 
> 
>> 
>> I have a draft here
>> https://github.com/anatol/qemu/commit/ad943a6eb78feee048b6bb2a1e5f49f5b686e24c
>> 
>> My understanding is that qemu multiboot loads only TEXT/BSS/DATA
>> sections. Other stuff like symbols sections and ELF headers are not
>> available for target.

Thes are not available inside the target, but they are available from the host (for example in -d in_asm).


Alex

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-28 21:28 [Qemu-devel] How to make ELF headers/symbol sections available for multiboot? Anatol Pomozov
  2017-07-30 21:42 ` Eduardo Habkost
@ 2017-07-31  8:50 ` Peter Maydell
  2017-07-31 13:04   ` Richard Henderson
  1 sibling, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2017-07-31  8:50 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: QEMU Developers, Paolo Bonzini, Richard Henderson, Eduardo Habkost

On 28 July 2017 at 22:28, Anatol Pomozov <anatol.pomozov@gmail.com> wrote:
> So I need to perform 2 things:
>
>  - Load ELF section headers into target's memory. I did by appending
> additional space to mbs.mb_buf and copying header data. Is it the best
> way to do?
>
>  - Next I need to load other ELF sections such as symbols (e.g.
> .shstrtab) that store section names. What is the best way to do in
> multiboo.c code? Would it make sense to load all ELF sections?

This seems a bit odd, because in general an ELF loader should
not care at all about sections and the section header. It
should only need to look at the program header, which defines
which segments to load. If the guest binary needs some things
to be loaded then I would expect that it is the job of the linker
that produces the guest binary to make sure those things are in
segments which are marked as LOAD.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-30 21:42 ` Eduardo Habkost
  2017-07-31  6:25   ` Alexander Graf
@ 2017-07-31 11:27   ` Kevin Wolf
  2017-07-31 17:21   ` Anatol Pomozov
  2 siblings, 0 replies; 17+ messages in thread
From: Kevin Wolf @ 2017-07-31 11:27 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Anatol Pomozov, qemu-devel, Paolo Bonzini, Richard Henderson,
	Alexander Graf

Am 30.07.2017 um 23:42 hat Eduardo Habkost geschrieben:
> CCing Alex, the original author of load_multiboot(), and Kevin,
> who touched multiboot code recently.

For some values of "recently". :-)

> On Fri, Jul 28, 2017 at 02:28:34PM -0700, Anatol Pomozov wrote:
> > Hi
> > 
> > I am looking at x86 multiboot code and trying to add "ELF section
> > header" info feature. This will let target to learn more about booted
> > binary and its sections.
> 
> Are there existing OSes that use that information?

You mean, like, relevant ones? I've used this feature before myself and
I think I've seen others use it for OSes that will never spread much
beyond their own computer, but from the more popular OSes that implement
Multiboot, it seems that at least NetBSD and the Hurd (or really GNU
Mach) are making some use of it.

> > I have a draft here
> > https://github.com/anatol/qemu/commit/ad943a6eb78feee048b6bb2a1e5f49f5b686e24c
> > 
> > My understanding is that qemu multiboot loads only TEXT/BSS/DATA
> > sections. Other stuff like symbols sections and ELF headers are not
> > available for target.
> > 
> > So I need to perform 2 things:
> > 
> >  - Load ELF section headers into target's memory. I did by appending
> > additional space to mbs.mb_buf and copying header data. Is it the best
> > way to do?

I think I would have done the same.

> >  - Next I need to load other ELF sections such as symbols (e.g.
> > .shstrtab) that store section names. What is the best way to do in
> > multiboo.c code? Would it make sense to load all ELF sections?

I think that the functions in include/hw/elf_ops.h (specifically
load_symbols32) might already do most of what you need. This file is
just a bit hard to navigate because the function names are composed by
preprocessor macros.

In the end it seems to fill a global variable struct syminfo *syminfos.
Maybe you can get the information you need from there, though it seems
to have been processed (keep only function symbols, sort the list). It
would be more correct to provide the original symbol table.

Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-31  8:50 ` Peter Maydell
@ 2017-07-31 13:04   ` Richard Henderson
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2017-07-31 13:04 UTC (permalink / raw)
  To: Peter Maydell, Anatol Pomozov
  Cc: Paolo Bonzini, QEMU Developers, Eduardo Habkost

On 07/31/2017 01:50 AM, Peter Maydell wrote:
> On 28 July 2017 at 22:28, Anatol Pomozov <anatol.pomozov@gmail.com> wrote:
>> So I need to perform 2 things:
>>
>>   - Load ELF section headers into target's memory. I did by appending
>> additional space to mbs.mb_buf and copying header data. Is it the best
>> way to do?
>>
>>   - Next I need to load other ELF sections such as symbols (e.g.
>> .shstrtab) that store section names. What is the best way to do in
>> multiboo.c code? Would it make sense to load all ELF sections?
> 
> This seems a bit odd, because in general an ELF loader should
> not care at all about sections and the section header. It
> should only need to look at the program header, which defines
> which segments to load. If the guest binary needs some things
> to be loaded then I would expect that it is the job of the linker
> that produces the guest binary to make sure those things are in
> segments which are marked as LOAD.

Agreed.  If you're touching ELF sections, then I think you're missing the point 
of the ELF program header entirely.  If you write your own linker script, you 
have complete control of the ELF PHDR, and can arrange for anything you like to 
be loaded.


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-30 21:42 ` Eduardo Habkost
  2017-07-31  6:25   ` Alexander Graf
  2017-07-31 11:27   ` Kevin Wolf
@ 2017-07-31 17:21   ` Anatol Pomozov
  2017-07-31 18:20     ` Richard Henderson
  2017-08-01 14:06     ` Kevin Wolf
  2 siblings, 2 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-07-31 17:21 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, Paolo Bonzini, Richard Henderson, Alexander Graf, Kevin Wolf

Hi

On Sun, Jul 30, 2017 at 2:42 PM, Eduardo Habkost <ehabkost@redhat.com> wrote:
>
> CCing Alex, the original author of load_multiboot(), and Kevin,
> who touched multiboot code recently.
>
>
> On Fri, Jul 28, 2017 at 02:28:34PM -0700, Anatol Pomozov wrote:
>> Hi
>>
>> I am looking at x86 multiboot code and trying to add "ELF section
>> header" info feature. This will let target to learn more about booted
>> binary and its sections.
>
> Are there existing OSes that use that information?

ELF sections info is needed for an OS to map address space properly.

I do not know much about production-grade OS but multiboot protocol is
quite popular among newly created and hobby OS. Multiboot provide some
useful information that need to be found somewhere else (e.g. by
requesting info from BIOS).

Here is an example of Phil's Rust OS that uses multiboot to read ELF
section information. https://os.phil-opp.com/allocating-frames/ They
use GRUB that loads all ELF sections into memory and provides ELF info
via multiboot structure.

It is interesting to see how LittleKernel tries to find the sections
information by using _start/_end markers in their linker script
https://github.com/littlekernel/lk/blob/master/arch/x86/64/kernel.ld
And while it works, in fact it just tries to recover ELF sections
information. And that is why I think it would be more useful if qemu
implemented ELF sections feature from Multiboot.

> Do you have a pointer to what that feature does exactly?

Quoting Multiboot specification
https://www.gnu.org/software/grub/manual/multiboot/multiboot.html

=======BEGIN=====

If bit 5 in the ‘flags’ word is set, then the following fields in the
Multiboot information structure starting at byte 28 are valid:

             +-------------------+
     28      | num               |
     32      | size              |
     36      | addr              |
     40      | shndx             |
             +-------------------+

These indicate where the section header table from an ELF kernel is,
the size of each entry, number of entries, and the string table used
as the index of names. They correspond to the ‘shdr_*’ entries
(‘shdr_num’, etc.) in the Executable and Linkable Format (elf)
specification in the program header. All sections are loaded, and the
physical address fields of the elf section header then refer to where
the sections are in memory (refer to the i386 elf documentation for
details as to how to read the section header(s)). Note that ‘shdr_num’
may be 0, indicating no symbols, even if bit 5 in the ‘flags’
=======END=======

Basically it makes some info from ELF header and section headers
available for target.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-31 17:21   ` Anatol Pomozov
@ 2017-07-31 18:20     ` Richard Henderson
  2017-08-02 22:00       ` Anatol Pomozov
  2017-08-01 14:06     ` Kevin Wolf
  1 sibling, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2017-07-31 18:20 UTC (permalink / raw)
  To: Anatol Pomozov, Eduardo Habkost
  Cc: qemu-devel, Paolo Bonzini, Alexander Graf, Kevin Wolf

On 07/31/2017 10:21 AM, Anatol Pomozov wrote:
> ELF sections info is needed for an OS to map address space properly.

No, ELF *program header* info is needed for an OS to map the address space
properly.  For example:

$ readelf -hl vmlinux-4.9.0-3-5kc-malta

Using a mips kernel binary I happend to have handy; it would be the same for
x86_64, prior to being bundled in the (imo superfluous bzImage) format.

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0xffffffff806ed590
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13351328 (bytes into file)
  Flags:                             0x80000001, noreorder, mips64r2
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         2
  Size of section headers:           64 (bytes)
  Number of section headers:         28
  Section header string table index: 27

The ELF file header, always at file offset 0.  The relevant info is the
encoding (64-bit little-endian), cpu (mips), and start of program headers.

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000001000 0xffffffff80100000 0xffffffff80100000
                 0x00000000009fefb4 0x0000000000a5a150  RWE    1000
  NOTE           0x00000000005fecb0 0xffffffff806fdcb0 0xffffffff806fdcb0
                 0x0000000000000024 0x0000000000000024  R      4

The ELF program header.  There is one segment to be loaded, at a given physical
address (which happens to match the virtual address, but that need not have
been so).

The segment consists of 0x9fefb4 bytes of data to be loaded from the file, and
occupies 0xa5a150 in memory.  The difference between the two sizes is "bss",
and should be zeroed.

A proper ELF loader will process *all* LOAD segments, however many are required
by the binary.  Though in practice there will probably only be 1 or 2.

Section to Segment mapping:
  Segment Sections...
  00     .text __ex_table __dbe_table .notes .rodata .pci_fixup __ksymtab
__ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data
.data..page_aligned .init.text .init.data .exit.text .data.reloc .sbss .bss
  01     __dbe_table .notes

This mapping is provided by readelf for convenience, not actually present in
the ELF file.  But it is handy when debugging a linker script.

> Quoting Multiboot specification
> https://www.gnu.org/software/grub/manual/multiboot/multiboot.html

I'm not sure why someone felt the need to re-invent the wheel, especially
considering its introduction section talks about trying to stop reinventing the
wheel...

But... whatever.  I'm not sure why this is relevant to $SUBJECT, since it does
not appear to have anything to do with ELF at all.


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-31 17:21   ` Anatol Pomozov
  2017-07-31 18:20     ` Richard Henderson
@ 2017-08-01 14:06     ` Kevin Wolf
  1 sibling, 0 replies; 17+ messages in thread
From: Kevin Wolf @ 2017-08-01 14:06 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: Eduardo Habkost, qemu-devel, Paolo Bonzini, Richard Henderson,
	Alexander Graf

Am 31.07.2017 um 19:21 hat Anatol Pomozov geschrieben:
> ELF sections info is needed for an OS to map address space properly.
> 
> I do not know much about production-grade OS but multiboot protocol is
> quite popular among newly created and hobby OS. Multiboot provide some
> useful information that need to be found somewhere else (e.g. by
> requesting info from BIOS).
> 
> Here is an example of Phil's Rust OS that uses multiboot to read ELF
> section information. https://os.phil-opp.com/allocating-frames/ They
> use GRUB that loads all ELF sections into memory and provides ELF info
> via multiboot structure.
> 
> It is interesting to see how LittleKernel tries to find the sections
> information by using _start/_end markers in their linker script
> https://github.com/littlekernel/lk/blob/master/arch/x86/64/kernel.ld
> And while it works, in fact it just tries to recover ELF sections
> information. And that is why I think it would be more useful if qemu
> implemented ELF sections feature from Multiboot.

Why would you calculate something at runtime by looping through the
section table when you could do this once and for all at link time?
This sounds completely inefficient and is probably a bad idea. What
littlekernel does is pretty much the standard way to do things.

This doesn't mean that the Multiboot feature is useless, but just that
the real use cases are different. Having symbol names in stack traces
is one of them.

And anyway, the feature is in the spec and QEMU implements this spec, so
I think we don't have to discuss whether having the feature would be
good. It just needs a clean implementation.

Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-07-31 18:20     ` Richard Henderson
@ 2017-08-02 22:00       ` Anatol Pomozov
  2017-08-02 22:45         ` Richard Henderson
  2017-08-03  8:39         ` Kevin Wolf
  0 siblings, 2 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-08-02 22:00 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Eduardo Habkost, qemu-devel, Paolo Bonzini, Alexander Graf, Kevin Wolf

Hello Richard

Thank you for this useful information. I still learning about ELF and
a lot of things are still unclear for me.

On Mon, Jul 31, 2017 at 11:20 AM, Richard Henderson <rth@twiddle.net> wrote:
> On 07/31/2017 10:21 AM, Anatol Pomozov wrote:
>> ELF sections info is needed for an OS to map address space properly.
>
> No, ELF *program header* info is needed for an OS to map the address space
> properly.  For example:
>
> $ readelf -hl vmlinux-4.9.0-3-5kc-malta

Thanks for this information about program headers. I reread elf_ops.h
and now I see that QEMU loads all PT_LOAD segments. I wonder why GRUB
bootloader loads also sections that are not in this segment (e.g. GRUB
loads content of .shstrtab into target's memory despite my elf does
not keep it in PT_LOAD segment).

What ELF specification says about it? Does it tell a loader to load
only PT_LOAD segments? In this case bootloaders should follow it as
well and current QEMU behavior is correct.

But multiboot expects section headers info and .shstrtab section to be
loaded to the target memory. I believe I need to modify my linker
script and add this information into the loadable segment.

Here is my current linker script:

======================
ENTRY(start)

SECTIONS {
    . = 1M;

    .text : {
        KEEP(*(.data.multiboot))
        *(.text .text*)
    }

    .rodata : {
        *(.rodata .rodata*)
    }

    .data : {
        *(.data .data.*)
    }

    .bss : {
        __bss_start = .;
        *(.bss .bss*)
        . = ALIGN(8);
        __bss_end = .;
    }
}
=======================

With my linker script only .text .rodata .data and .bss are included
into the loadable segment.


So my questions: how to tell the linker to include "section headers"
and ".shstrtab" section into loadable segment? Once it is done I can
try to modify QEMU to pass its addresses to the target.

>
> Using a mips kernel binary I happend to have handy; it would be the same for
> x86_64, prior to being bundled in the (imo superfluous bzImage) format.
>
> ELF Header:
>   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
>   Class:                             ELF64
>   Data:                              2's complement, little endian
>   Version:                           1 (current)
>   OS/ABI:                            UNIX - System V
>   ABI Version:                       0
>   Type:                              EXEC (Executable file)
>   Machine:                           MIPS R3000
>   Version:                           0x1
>   Entry point address:               0xffffffff806ed590
>   Start of program headers:          64 (bytes into file)
>   Start of section headers:          13351328 (bytes into file)
>   Flags:                             0x80000001, noreorder, mips64r2
>   Size of this header:               64 (bytes)
>   Size of program headers:           56 (bytes)
>   Number of program headers:         2
>   Size of section headers:           64 (bytes)
>   Number of section headers:         28
>   Section header string table index: 27
>
> The ELF file header, always at file offset 0.  The relevant info is the
> encoding (64-bit little-endian), cpu (mips), and start of program headers.
>
> Program Headers:
>   Type           Offset             VirtAddr           PhysAddr
>                  FileSiz            MemSiz              Flags  Align
>   LOAD           0x0000000000001000 0xffffffff80100000 0xffffffff80100000
>                  0x00000000009fefb4 0x0000000000a5a150  RWE    1000
>   NOTE           0x00000000005fecb0 0xffffffff806fdcb0 0xffffffff806fdcb0
>                  0x0000000000000024 0x0000000000000024  R      4
>
> The ELF program header.  There is one segment to be loaded, at a given physical
> address (which happens to match the virtual address, but that need not have
> been so).
>
> The segment consists of 0x9fefb4 bytes of data to be loaded from the file, and
> occupies 0xa5a150 in memory.  The difference between the two sizes is "bss",
> and should be zeroed.
>
> A proper ELF loader will process *all* LOAD segments, however many are required
> by the binary.  Though in practice there will probably only be 1 or 2.
>
> Section to Segment mapping:
>   Segment Sections...
>   00     .text __ex_table __dbe_table .notes .rodata .pci_fixup __ksymtab
> __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data
> .data..page_aligned .init.text .init.data .exit.text .data.reloc .sbss .bss
>   01     __dbe_table .notes
>
> This mapping is provided by readelf for convenience, not actually present in
> the ELF file.  But it is handy when debugging a linker script.
>
>> Quoting Multiboot specification
>> https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
>
> I'm not sure why someone felt the need to re-invent the wheel, especially
> considering its introduction section talks about trying to stop reinventing the
> wheel...
>
> But... whatever.  I'm not sure why this is relevant to $SUBJECT, since it does
> not appear to have anything to do with ELF at all.
>
>
> r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-02 22:00       ` Anatol Pomozov
@ 2017-08-02 22:45         ` Richard Henderson
  2017-08-03  8:39         ` Kevin Wolf
  1 sibling, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2017-08-02 22:45 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: Eduardo Habkost, qemu-devel, Paolo Bonzini, Alexander Graf, Kevin Wolf

On 08/02/2017 03:00 PM, Anatol Pomozov wrote:
> What ELF specification says about it? Does it tell a loader to load
> only PT_LOAD segments?

Yes.  In https://refspecs.linuxfoundation.org/ there is a link to "System V ABI
Edition 4.1", which AFAIK is the latest version of the ELF "gABI" spec.
Section 5 describes program loading.

> Here is my current linker script:
> 
> ======================
> ENTRY(start)
> 
> SECTIONS {
>     . = 1M;
> 
>     .text : {
>         KEEP(*(.data.multiboot))
>         *(.text .text*)
>     }
> 
>     .rodata : {
>         *(.rodata .rodata*)
>     }
> 
>     .data : {
>         *(.data .data.*)
>     }
> 
>     .bss : {
>         __bss_start = .;
>         *(.bss .bss*)
>         . = ALIGN(8);
>         __bss_end = .;
>     }
> }
> =======================

In the gnu ld manual, read about the PHDRS command, which describes all of the
ways you can manipulate the program header table.

Re-reading that now, I see FILEHDR and PHDR as keywords that can be used to
induce those portions of the file into the loadable segment, but I do not see
anything that could be used to load the section header.

You could force the symbol table and string table to be loaded, by referencing
their sections, but that won't affect the section header itself.


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-02 22:00       ` Anatol Pomozov
  2017-08-02 22:45         ` Richard Henderson
@ 2017-08-03  8:39         ` Kevin Wolf
  2017-08-04  4:53           ` Anatol Pomozov
  1 sibling, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2017-08-03  8:39 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Am 03.08.2017 um 00:00 hat Anatol Pomozov geschrieben:
> Hello Richard
> 
> Thank you for this useful information. I still learning about ELF and
> a lot of things are still unclear for me.
> 
> On Mon, Jul 31, 2017 at 11:20 AM, Richard Henderson <rth@twiddle.net> wrote:
> > On 07/31/2017 10:21 AM, Anatol Pomozov wrote:
> >> ELF sections info is needed for an OS to map address space properly.
> >
> > No, ELF *program header* info is needed for an OS to map the address space
> > properly.  For example:
> >
> > $ readelf -hl vmlinux-4.9.0-3-5kc-malta
> 
> Thanks for this information about program headers. I reread elf_ops.h
> and now I see that QEMU loads all PT_LOAD segments. I wonder why GRUB
> bootloader loads also sections that are not in this segment (e.g. GRUB
> loads content of .shstrtab into target's memory despite my elf does
> not keep it in PT_LOAD segment).

Remember that what we're talking about isn't primarily an ELF loader,
but a Multiboot loader. Multiboot can work without ELF (e.g. with flat
binaries) if bit 16 in the Multiboot header flags is set and the
additional header fields are correctly provided. However, if you are
loading an ELF binary, then Multiboot specifies that the bootloader
makes use of the ELF headers and you don't have to set bit 16 in the
header.

If ELF says that some things have to be loaded (and bit 16 is clear),
then the bootloader will load them. If Multiboot says that additional
things can or have to be loaded, it will load those, too. The section
headers are only one example of additional data that Multiboot provides.
It also loads additional modules, provides the e820 memory map, etc.,
none of which are described by ELF.

> What ELF specification says about it? Does it tell a loader to load
> only PT_LOAD segments? In this case bootloaders should follow it as
> well and current QEMU behavior is correct.

The current behaviour of QEMU is correct because it doesn't set bit 5 in
the flags field of the Multiboot info struct, i.e. it doesn't advertise
that the section headers are available, so it doesn't have to provide
it.

It is also not feature complete, because a full Multiboot implementation
would implement this and advertise bit 5. Adding the feature would be
useful because there are guest kernels that can make use of it.

> But multiboot expects section headers info and .shstrtab section to be
> loaded to the target memory. I believe I need to modify my linker
> script and add this information into the loadable segment.

No. First of all, you don't even need this information to find the start
and end of the kernel code. Second, if a Multiboot loader loads this, it
doesn't have to be in a loadable segment. This is more like debug
information, not like an inherent part of the program.

> Here is my current linker script:
> 
> ======================
> ENTRY(start)
> 
> SECTIONS {
>     . = 1M;
> 
>     .text : {
>         KEEP(*(.data.multiboot))
>         *(.text .text*)
>     }
> 
>     .rodata : {
>         *(.rodata .rodata*)
>     }
> 
>     .data : {
>         *(.data .data.*)
>     }
> 
>     .bss : {
>         __bss_start = .;
>         *(.bss .bss*)
>         . = ALIGN(8);
>         __bss_end = .;
>     }
> }
> =======================
> 
> With my linker script only .text .rodata .data and .bss are included
> into the loadable segment.
> 
> 
> So my questions: how to tell the linker to include "section headers"
> and ".shstrtab" section into loadable segment? Once it is done I can
> try to modify QEMU to pass its addresses to the target.

Requiring section headers to be contained in a loadable segment wouldn't
be a correct implementation of the Multiboot feature.

Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-03  8:39         ` Kevin Wolf
@ 2017-08-04  4:53           ` Anatol Pomozov
  2017-08-08 15:04             ` Kevin Wolf
  0 siblings, 1 reply; 17+ messages in thread
From: Anatol Pomozov @ 2017-08-04  4:53 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Hi Kevin

Thanks for the information.

So I sounds like we do want multiboot to load all sections regardless
of its segments info. To achieve it we need to read sections headers
and load all section that were not loaded yet.

I have a working implementation here
https://github.com/anatol/qemu/commit/26773cf4f1f30b2d0d3fd89cce024f8e9c5603c5
Tested it with my multiboot OS image. The target iterates over all
sections and prints their names/address. The output result is the same
for QEMU and for VmWare+GRUB.

Let me know if this idea looks good so I can send this patch to qemu maillist.


On Thu, Aug 3, 2017 at 1:39 AM, Kevin Wolf <kwolf@redhat.com> wrote:
> Am 03.08.2017 um 00:00 hat Anatol Pomozov geschrieben:
>> Hello Richard
>>
>> Thank you for this useful information. I still learning about ELF and
>> a lot of things are still unclear for me.
>>
>> On Mon, Jul 31, 2017 at 11:20 AM, Richard Henderson <rth@twiddle.net> wrote:
>> > On 07/31/2017 10:21 AM, Anatol Pomozov wrote:
>> >> ELF sections info is needed for an OS to map address space properly.
>> >
>> > No, ELF *program header* info is needed for an OS to map the address space
>> > properly.  For example:
>> >
>> > $ readelf -hl vmlinux-4.9.0-3-5kc-malta
>>
>> Thanks for this information about program headers. I reread elf_ops.h
>> and now I see that QEMU loads all PT_LOAD segments. I wonder why GRUB
>> bootloader loads also sections that are not in this segment (e.g. GRUB
>> loads content of .shstrtab into target's memory despite my elf does
>> not keep it in PT_LOAD segment).
>
> Remember that what we're talking about isn't primarily an ELF loader,
> but a Multiboot loader. Multiboot can work without ELF (e.g. with flat
> binaries) if bit 16 in the Multiboot header flags is set and the
> additional header fields are correctly provided. However, if you are
> loading an ELF binary, then Multiboot specifies that the bootloader
> makes use of the ELF headers and you don't have to set bit 16 in the
> header.
>
> If ELF says that some things have to be loaded (and bit 16 is clear),
> then the bootloader will load them. If Multiboot says that additional
> things can or have to be loaded, it will load those, too. The section
> headers are only one example of additional data that Multiboot provides.
> It also loads additional modules, provides the e820 memory map, etc.,
> none of which are described by ELF.
>
>> What ELF specification says about it? Does it tell a loader to load
>> only PT_LOAD segments? In this case bootloaders should follow it as
>> well and current QEMU behavior is correct.
>
> The current behaviour of QEMU is correct because it doesn't set bit 5 in
> the flags field of the Multiboot info struct, i.e. it doesn't advertise
> that the section headers are available, so it doesn't have to provide
> it.
>
> It is also not feature complete, because a full Multiboot implementation
> would implement this and advertise bit 5. Adding the feature would be
> useful because there are guest kernels that can make use of it.
>
>> But multiboot expects section headers info and .shstrtab section to be
>> loaded to the target memory. I believe I need to modify my linker
>> script and add this information into the loadable segment.
>
> No. First of all, you don't even need this information to find the start
> and end of the kernel code. Second, if a Multiboot loader loads this, it
> doesn't have to be in a loadable segment. This is more like debug
> information, not like an inherent part of the program.
>
>> Here is my current linker script:
>>
>> ======================
>> ENTRY(start)
>>
>> SECTIONS {
>>     . = 1M;
>>
>>     .text : {
>>         KEEP(*(.data.multiboot))
>>         *(.text .text*)
>>     }
>>
>>     .rodata : {
>>         *(.rodata .rodata*)
>>     }
>>
>>     .data : {
>>         *(.data .data.*)
>>     }
>>
>>     .bss : {
>>         __bss_start = .;
>>         *(.bss .bss*)
>>         . = ALIGN(8);
>>         __bss_end = .;
>>     }
>> }
>> =======================
>>
>> With my linker script only .text .rodata .data and .bss are included
>> into the loadable segment.
>>
>>
>> So my questions: how to tell the linker to include "section headers"
>> and ".shstrtab" section into loadable segment? Once it is done I can
>> try to modify QEMU to pass its addresses to the target.
>
> Requiring section headers to be contained in a loadable segment wouldn't
> be a correct implementation of the Multiboot feature.
>
> Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-04  4:53           ` Anatol Pomozov
@ 2017-08-08 15:04             ` Kevin Wolf
  2017-08-17 20:54               ` Anatol Pomozov
  0 siblings, 1 reply; 17+ messages in thread
From: Kevin Wolf @ 2017-08-08 15:04 UTC (permalink / raw)
  To: Anatol Pomozov
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Am 04.08.2017 um 06:53 hat Anatol Pomozov geschrieben:
> Hi Kevin
> 
> Thanks for the information.
> 
> So I sounds like we do want multiboot to load all sections regardless
> of its segments info. To achieve it we need to read sections headers
> and load all section that were not loaded yet.
> 
> I have a working implementation here
> https://github.com/anatol/qemu/commit/26773cf4f1f30b2d0d3fd89cce024f8e9c5603c5
> Tested it with my multiboot OS image. The target iterates over all
> sections and prints their names/address. The output result is the same
> for QEMU and for VmWare+GRUB.
> 
> Let me know if this idea looks good so I can send this patch to qemu maillist.

I'm not sure if I'll find the time to review this in detail, but I'll
just give it a quick look.

You seem to attempt to add support for 64 bit ELF binaries. The
Multiboot standard doesn't explicitly say that this is forbidden, but
everything in it expects 32 bit binaries and I don't think GRUB (as the
reference implementation for Multiboot) accepts 64 bit ELFs either. The
boot state is 32 bit protected mode in any case. So unless I'm mistaken
on GRUB's behaviour, I'd rather not support 64 bit ELFs.

You shouldn't look at ELF headers at all if MULTIBOOT_AOUT_KLUDGE is
given. In this case, the kernel image is to be treated as a flat binary
and section headers can't be expected. I think your code breaks non-ELF
kernels.

As for loading the section headers, duplicating ELF parser code may be
functionally correct, but probably not the best way to implement things.
As I wrote in an earlier email, load_elf() already parses all the
information that you need. You really just need to store it somewhere,
which would probably just mean adding a new parameter to load_elf() and
the parser could then store a copy of the data there if it's non-NULL.

If you have any other specific aspects that you want me to have a closer
look at, just let me know.

Kevin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-08 15:04             ` Kevin Wolf
@ 2017-08-17 20:54               ` Anatol Pomozov
  2017-09-11 18:48                 ` Anatol Pomozov
  2017-09-11 18:49                 ` Anatol Pomozov
  0 siblings, 2 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-08-17 20:54 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Hi

On Tue, Aug 8, 2017 at 8:04 AM, Kevin Wolf <kwolf@redhat.com> wrote:
> Am 04.08.2017 um 06:53 hat Anatol Pomozov geschrieben:
>> Hi Kevin
>>
>> Thanks for the information.
>>
>> So I sounds like we do want multiboot to load all sections regardless
>> of its segments info. To achieve it we need to read sections headers
>> and load all section that were not loaded yet.
>>
>> I have a working implementation here
>> https://github.com/anatol/qemu/commit/26773cf4f1f30b2d0d3fd89cce024f8e9c5603c5
>> Tested it with my multiboot OS image. The target iterates over all
>> sections and prints their names/address. The output result is the same
>> for QEMU and for VmWare+GRUB.
>>
>> Let me know if this idea looks good so I can send this patch to qemu maillist.
>
> I'm not sure if I'll find the time to review this in detail, but I'll
> just give it a quick look.
>
> You seem to attempt to add support for 64 bit ELF binaries. The
> Multiboot standard doesn't explicitly say that this is forbidden, but
> everything in it expects 32 bit binaries and I don't think GRUB (as the
> reference implementation for Multiboot) accepts 64 bit ELFs either. The
> boot state is 32 bit protected mode in any case. So unless I'm mistaken
> on GRUB's behaviour, I'd rather not support 64 bit ELFs.

Grub actually does support ELF64 loading with multiboot. Here is the
GRUB code that implements it
https://github.com/coreos/grub/blob/master/grub-core/loader/multiboot.c#L210

It would be great if QEMU behaved similar way.

Actually I've been using qemu with ELF64 multiboot for a while and it
works great.

>
> You shouldn't look at ELF headers at all if MULTIBOOT_AOUT_KLUDGE is
> given. In this case, the kernel image is to be treated as a flat binary
> and section headers can't be expected. I think your code breaks non-ELF
> kernels.

Ok, will revert this part back.

>
> As for loading the section headers, duplicating ELF parser code may be
> functionally correct, but probably not the best way to implement things.
> As I wrote in an earlier email, load_elf() already parses all the
> information that you need. You really just need to store it somewhere,
> which would probably just mean adding a new parameter to load_elf() and
> the parser could then store a copy of the data there if it's non-NULL.

Loading section headers is actually a small part of my change. It also:
  - calculates memory needed to load all sections into memory
  - allocates memory
  - loads sections

This "load all sections into memory" functionality is very multiboot
specific. But if you think if load_elf() is better place for it then I
can look at moving it to load_elf().

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-17 20:54               ` Anatol Pomozov
@ 2017-09-11 18:48                 ` Anatol Pomozov
  2017-09-11 18:49                 ` Anatol Pomozov
  1 sibling, 0 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-09-11 18:48 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Hello

I have these changes ready now
http://lists.nongnu.org/archive/html/qemu-devel/2017-08/msg03265.html
It added ELF parser functionality as discussed above. Are there any
open questions? What is the best way to proceed forward with these
patches?

I also have interest in adding Multiboot2 support to qemu. But before
going with it I would like to finish working on my current patchset.

On Thu, Aug 17, 2017 at 1:54 PM, Anatol Pomozov
<anatol.pomozov@gmail.com> wrote:
> Hi
>
> On Tue, Aug 8, 2017 at 8:04 AM, Kevin Wolf <kwolf@redhat.com> wrote:
>> Am 04.08.2017 um 06:53 hat Anatol Pomozov geschrieben:
>>> Hi Kevin
>>>
>>> Thanks for the information.
>>>
>>> So I sounds like we do want multiboot to load all sections regardless
>>> of its segments info. To achieve it we need to read sections headers
>>> and load all section that were not loaded yet.
>>>
>>> I have a working implementation here
>>> https://github.com/anatol/qemu/commit/26773cf4f1f30b2d0d3fd89cce024f8e9c5603c5
>>> Tested it with my multiboot OS image. The target iterates over all
>>> sections and prints their names/address. The output result is the same
>>> for QEMU and for VmWare+GRUB.
>>>
>>> Let me know if this idea looks good so I can send this patch to qemu maillist.
>>
>> I'm not sure if I'll find the time to review this in detail, but I'll
>> just give it a quick look.
>>
>> You seem to attempt to add support for 64 bit ELF binaries. The
>> Multiboot standard doesn't explicitly say that this is forbidden, but
>> everything in it expects 32 bit binaries and I don't think GRUB (as the
>> reference implementation for Multiboot) accepts 64 bit ELFs either. The
>> boot state is 32 bit protected mode in any case. So unless I'm mistaken
>> on GRUB's behaviour, I'd rather not support 64 bit ELFs.
>
> Grub actually does support ELF64 loading with multiboot. Here is the
> GRUB code that implements it
> https://github.com/coreos/grub/blob/master/grub-core/loader/multiboot.c#L210
>
> It would be great if QEMU behaved similar way.
>
> Actually I've been using qemu with ELF64 multiboot for a while and it
> works great.
>
>>
>> You shouldn't look at ELF headers at all if MULTIBOOT_AOUT_KLUDGE is
>> given. In this case, the kernel image is to be treated as a flat binary
>> and section headers can't be expected. I think your code breaks non-ELF
>> kernels.
>
> Ok, will revert this part back.
>
>>
>> As for loading the section headers, duplicating ELF parser code may be
>> functionally correct, but probably not the best way to implement things.
>> As I wrote in an earlier email, load_elf() already parses all the
>> information that you need. You really just need to store it somewhere,
>> which would probably just mean adding a new parameter to load_elf() and
>> the parser could then store a copy of the data there if it's non-NULL.
>
> Loading section headers is actually a small part of my change. It also:
>   - calculates memory needed to load all sections into memory
>   - allocates memory
>   - loads sections
>
> This "load all sections into memory" functionality is very multiboot
> specific. But if you think if load_elf() is better place for it then I
> can look at moving it to load_elf().

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] How to make ELF headers/symbol sections available for multiboot?
  2017-08-17 20:54               ` Anatol Pomozov
  2017-09-11 18:48                 ` Anatol Pomozov
@ 2017-09-11 18:49                 ` Anatol Pomozov
  1 sibling, 0 replies; 17+ messages in thread
From: Anatol Pomozov @ 2017-09-11 18:49 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Richard Henderson, Eduardo Habkost, qemu-devel, Paolo Bonzini,
	Alexander Graf

Hello

On Thu, Aug 17, 2017 at 1:54 PM, Anatol Pomozov
<anatol.pomozov@gmail.com> wrote:
> Hi
>
> On Tue, Aug 8, 2017 at 8:04 AM, Kevin Wolf <kwolf@redhat.com> wrote:
>> Am 04.08.2017 um 06:53 hat Anatol Pomozov geschrieben:
>>> Hi Kevin
>>>
>>> Thanks for the information.
>>>
>>> So I sounds like we do want multiboot to load all sections regardless
>>> of its segments info. To achieve it we need to read sections headers
>>> and load all section that were not loaded yet.
>>>
>>> I have a working implementation here
>>> https://github.com/anatol/qemu/commit/26773cf4f1f30b2d0d3fd89cce024f8e9c5603c5
>>> Tested it with my multiboot OS image. The target iterates over all
>>> sections and prints their names/address. The output result is the same
>>> for QEMU and for VmWare+GRUB.
>>>
>>> Let me know if this idea looks good so I can send this patch to qemu maillist.
>>
>> I'm not sure if I'll find the time to review this in detail, but I'll
>> just give it a quick look.
>>
>> You seem to attempt to add support for 64 bit ELF binaries. The
>> Multiboot standard doesn't explicitly say that this is forbidden, but
>> everything in it expects 32 bit binaries and I don't think GRUB (as the
>> reference implementation for Multiboot) accepts 64 bit ELFs either. The
>> boot state is 32 bit protected mode in any case. So unless I'm mistaken
>> on GRUB's behaviour, I'd rather not support 64 bit ELFs.
>
> Grub actually does support ELF64 loading with multiboot. Here is the
> GRUB code that implements it
> https://github.com/coreos/grub/blob/master/grub-core/loader/multiboot.c#L210
>
> It would be great if QEMU behaved similar way.
>
> Actually I've been using qemu with ELF64 multiboot for a while and it
> works great.
>
>>
>> You shouldn't look at ELF headers at all if MULTIBOOT_AOUT_KLUDGE is
>> given. In this case, the kernel image is to be treated as a flat binary
>> and section headers can't be expected. I think your code breaks non-ELF
>> kernels.


I have these changes ready now
http://lists.nongnu.org/archive/html/qemu-devel/2017-08/msg03265.html
It added ELF parser functionality as discussed above. Are there any
open questions? What is the best way to proceed forward with these
patches?

I also have interest in adding Multiboot2 support to qemu. But before
going with it I would like to finish working on my current patchset.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-09-11 18:49 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-28 21:28 [Qemu-devel] How to make ELF headers/symbol sections available for multiboot? Anatol Pomozov
2017-07-30 21:42 ` Eduardo Habkost
2017-07-31  6:25   ` Alexander Graf
2017-07-31 11:27   ` Kevin Wolf
2017-07-31 17:21   ` Anatol Pomozov
2017-07-31 18:20     ` Richard Henderson
2017-08-02 22:00       ` Anatol Pomozov
2017-08-02 22:45         ` Richard Henderson
2017-08-03  8:39         ` Kevin Wolf
2017-08-04  4:53           ` Anatol Pomozov
2017-08-08 15:04             ` Kevin Wolf
2017-08-17 20:54               ` Anatol Pomozov
2017-09-11 18:48                 ` Anatol Pomozov
2017-09-11 18:49                 ` Anatol Pomozov
2017-08-01 14:06     ` Kevin Wolf
2017-07-31  8:50 ` Peter Maydell
2017-07-31 13:04   ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.