Query regarding ELF loader arg style

Eric W. Biederman ebiederm at xmission.com
Thu Jan 16 18:27:13 EST 2014


Vivek Goyal <vgoyal at redhat.com> writes:

> On Tue, Jan 14, 2014 at 05:42:13PM -0800, Eric W. Biederman wrote:
>> Vivek Goyal <vgoyal at redhat.com> writes:
>> 
>> > Hi Eric,
>> >
>> > I am looking at kexec ELF loader code and wondering what are arg style
>> > options.
>> >
>> > #define ARG_STYLE_ELF   0
>> > #define ARG_STYLE_LINUX 1
>> > #define ARG_STYLE_NONE  2
>> >
>> >
>> > I have looked at them many a times but frankly never fully understood
>> > what do they represent and what's the intention behind them. Can you
>> > please elaborate a bit on this.
>> 
>> There is no standard of what kind of arguments a standalone ELF
>> executable will receive from a bootloader.
>> 
>> Which means that in practice to support different OS's you either need
>> to pass nothing or make something up.
>> 
>> ARG_STYLE_ELF is my own invention and a sad attempt at coming up with an
>> OS agnostic standard.
>> 
>> ARG_STYLE_LINUX is an ELF image receiving the same arguments as the
>> linux kernel.  It is a mess but it is reasonably well documented.
>
> Hi Eric,
>
>
> Even ARG_STYLE_LINUX seems to be making assumptions.
>
> For example, look at init_linux_parameters() in
> kexec-tools/kexec/arch/i386/x86-linux-setup.c.
>
> void init_linux_parameters(struct x86_linux_param_header *real_mode)
> {
>         /* Fill in the values that are usually provided by the kernel. */
>
>         /* Boot block magic */ 
>         memcpy(real_mode->header_magic, "HdrS", 4);
>         real_mode->protocol_version = 0x0206;
>         real_mode->initrd_addr_max = DEFAULT_INITRD_ADDR_MAX;
>         real_mode->cmdline_size = COMMAND_LINE_SIZE;
> }
>
> - We have no idea what's the max address we can load initrd at. So we make
>   assumptions.

Agreed that is a deficiency.  Today the maximum address is 4G and there
is a 4G pointer so assuming 4G seems safe.

> - We have no idea what's the maximum command line size kernel suppports. So
>   we make assumptions. The other side affect of this is that we can't do
>   error handling properly. I can't tell user back that you are passing
>   command line which is longer than what kernel can support.

Yes, that is unforutnate.

I expect the good solution is to have an ELF note for both of those
which will allows us to check these values in an architecture neutral
way.

But you are quite right that we haven't fixed that rough edge today :(

> - ELF does not tell anything whether it is self relocating or not. So we
>   are forced to load it at a address it has been compiled for (In case of
>   kdump). And that address is already occupied by current running kernel
>   so it does not work.

ELF does tell you if it is relocatable in the e_type field of the main
elf header.  In particular ET_DYN vs ET_EXEC.  ET_DYN can be loaded
anywhere, and ET_EXEC must be loaded at the specified address.  It would
not surprise me if the kernel build process is using ET_EXEC in error.

ET_DYN is also what is used for PIE executables and shared libraires.

The rule with ET_DYN without a dynamic linker is that a constant offset
must be added to the load address of all of the program segments but
otherwise nothing changes.  I thought I had support for that form in
kexec-tools.

Perhaps not.

> For the time being I have written a simple ELF loader along the lines of
> kexec-tools. It defaults to ARG_STYLE_LINUX and works only with kexec and
> not kexec on panic.

That sounds like a good start.

> I have also made purgatory a stand alone relocatable object and now
> purgatory is doing hash verification.

Cool.

> I am cleaning up the patches and will soon for another round of review
> pretty soon.

Sounds good.

Eric




More information about the kexec mailing list