Hi,
We've got an unusual elf binary and we seem to be running into a bug in
the elf loader. I'm not an elf expert, so my apologies if I get the
terminology wrong.
The elf spec says that PT_LOAD segments must be ordered by vaddr. We
want to have a segment at a relatively low fixed vaddr. The exact
address is not important, except that it's lower than the standard elf
headers and so it must be the first segment in the elf file.
However, this segment also has no size in the file...it's basically all
statically allocated at runtime.
In the kernel elf loader, the p_vaddr and p_offset of the first segment
are used to determine the load_addr for use with the rest of the
segments. In the case of this elf file, the first segment does not
actually have a valid p_offset.
Anyone have any suggestions on how to deal with this? One crude hack we
considered was to simply not set the load_addr if the first segment
doesn't have a valid p_offset, but that doesn't solve the general case.
Thanks,
Chris
No responses in a couple days so I'm resending. I've CC'd a few people
who've touched binfmt_elf.c recently.
We've got an unusual elf binary and we seem to be running into a bug in
the elf loader. I'm not an elf expert, so my apologies if I get the
terminology wrong.
The elf spec says that PT_LOAD segments must be ordered by vaddr. We
want to have a segment at a relatively low fixed vaddr. The exact
address is not important, except that it's lower than the standard elf
headers and so it must be the first segment in the elf file.
However, this segment also has no size in the file...it's basically all
statically allocated at runtime.
In the kernel elf loader, the p_vaddr and p_offset of the first segment
are used to determine the load_addr for use with the rest of the
segments. In the case of this elf file, the first segment does not
actually have a valid p_offset.
Anyone have any suggestions on how to deal with this? One crude hack we
considered was to simply not set the load_addr if the first segment
doesn't have a valid p_offset, but that doesn't solve the general case.
Thanks,
Chris
Chris Friesen wrote:
> The elf spec says that PT_LOAD segments must be ordered by vaddr. We
> want to have a segment at a relatively low fixed vaddr. The exact
> address is not important, except that it's lower than the standard elf
> headers and so it must be the first segment in the elf file.
So you want a zero mapping at a particular address? So the vaddr and
the memsz are set, but offset and filesz are zero?
> In the kernel elf loader, the p_vaddr and p_offset of the first
> segment are used to determine the load_addr for use with the rest of
> the segments. In the case of this elf file, the first segment does
> not actually have a valid p_offset.
Well, you could make the p_offset the same as the first segment with a
non-zero filesz. That should satisfy the elf loader, though it might
still confuse things.
Why can't you create this mapping at runtime?
J
Jeremy Fitzhardinge wrote:
> Chris Friesen wrote:
>
>>The elf spec says that PT_LOAD segments must be ordered by vaddr. We
>>want to have a segment at a relatively low fixed vaddr. The exact
>>address is not important, except that it's lower than the standard elf
>>headers and so it must be the first segment in the elf file.
>
>
> So you want a zero mapping at a particular address? So the vaddr and
> the memsz are set, but offset and filesz are zero?
I believe that's correct. It's basically the equivalent of BSS, but
used for an emulated OS (the app in question is an emulator).
> Well, you could make the p_offset the same as the first segment with a
> non-zero filesz. That should satisfy the elf loader, though it might
> still confuse things.
Interesting idea. Worth a try.
However, this doesn't address the kernel side of things. Am I correct
in thinking that the kernel is making an invalid assumption that it can
find the load_addr based on the first segment?
> Why can't you create this mapping at runtime?
Our emulated OS wants to put stuff at fixed addresses in this range, so
we're trying to keep the loader from allocating stuff there before our
program gets a chance to start up.
Chris
Chris Friesen wrote:
> I believe that's correct. It's basically the equivalent of BSS, but
> used for an emulated OS (the app in question is an emulator).
Right.
>> Well, you could make the p_offset the same as the first segment with a
>> non-zero filesz. That should satisfy the elf loader, though it might
>> still confuse things.
>
> Interesting idea. Worth a try.
>
> However, this doesn't address the kernel side of things. Am I correct
> in thinking that the kernel is making an invalid assumption that it
> can find the load_addr based on the first segment?
God, that code is such a tangle. I'm not sure why it particularly cares
about the offset, though perhaps its making sure that (offset %
pagesize) == (vaddr % pagesize), which only matters for filesz>0.
It's not too surprising it falls over with more unconventional ELF files.
>> Why can't you create this mapping at runtime?
>
> Our emulated OS wants to put stuff at fixed addresses in this range,
> so we're trying to keep the loader from allocating stuff there before
> our program gets a chance to start up.
Hm, you might want to have a look at how valgrind gets itself started.
J