Hi!
I am working on a project based on qemu-user. More exactly it is
qemu-ppc (version 0.13.0) with x86 host.
All the project and documentation about qemu will be open for everybody
as it is a project for my university that is a public one..
I have the need to relocate the target code in the memory space to some
other starting address.
So I went inside linux-user/elfload.c: load_elf_binary and there I found
many things that according to me are someway buggy or just "weak" ..
Of course I am only a student, and all of this was far beyond my
knowledge .. I am studying like a crazy for understanding all of this..
elf stuff, linking and loading .. and I may be just confused..
nevertheless I think it is worth of some attention by some of you gurus
outta there :)
First of all:
info->start_mmap = (abi_ulong)ELF_START_MMAP;
What is this? what is start_mmap supposed to point at at the end? Why
that static value is chosen at the beginning?
Then there is a block of code protected by the define:
#if defined(CONFIG_USE_GUEST_BASE)
this define appears to be enabled in my code though I do not use any
special parameter for qemu-ppc.. What is it supposed to do?
I mean I guess it wants to reserve a memory area for the target code,
starting at a user defined address (guest_base).. and all of that is
done in linux-user/main.c: main, through a proper command line
parameter, but then the guest_base address is not more used in the code
of qemu-user o.O
Inside the code, protected by that define in load_elf_binary, seems to
check if the system can reserve the requested area of program address
space, otherwise find a suitable address and set again guest_base to
that address.. but oddly that variable is never more taken in any
consideration then!!!
Going down the code I notice that for executable target binaries the
flag MAP_FIXED for mmap is set.. and in the requested starting address
the variable load_bias is always zero for executable files, so that the
starting address is simply the p_vaddr of the various program
segments..what does it mean? Simple! A target executable code is ALWAYS
loaded at the same address of the program address space it would be if
run on a target machine (not on the host machine through qemu)..far
enough? No for me!!
When executing in the original machine the binary was created for, its
OS creates an address space only for the target.. that means all the
address are free for it, and it can be loaded at any address chosen by
the link editor when creating the binary.. but here in qemu-user it
shares the address space with qemu-user code itself (and in my case with
all other I added to it!) so those addresses can be not free at all!!
Isn't that a big weakness??
I went a little forward, though with my poor skills.. I forced a bias,
created assembly PPC simple test binaries and had a look at what happens
when a shift of the start address is required (after fixing some
variables that did not consider fine such possibility):
The target global variables addresses are hard coded into the target
binary.. nothing in the process of elf loading or then in TCG do
anything for patching those addresses when there is a shift of the
starting code.. the result is simply got: segmentation fault when trying
to access those variables!
Moreover the way the various variables like start_code, start_data,
end_data, elf_brk were set was very odd to me:
It was like while cycling through all the program segments they could be
set for any new segment checked!
Now I must admit, through all my studying of ELF, I did not understand
yet (I'd appreciate very much if you can tell me it!!!) if it is
possible to have multiple code segments or multiple data segments in an
executable binary..
What I did was to check if the code had the PF_X flag or PF_W flag for
distinguishing whether it was a code segment or a data segment (hoping
there was only one of each), and set those variables accordingly..
This approach fails anyway when I use PIC code (I am trying to use PIC
code now as a solution for relocating code), it seems there are many
code segments and many writable segments, and I can't understand how to
set properly start_code, end_code.. etc there.
Another thing I had to edit while setting those variable was making them
consider as address not more p_vaddr, but the actual loading address
(error) ..
If any of you is interested in solving this problem I can provide all my
logs for various tests, source code for the test ppc binaries for
testing everything and of course my elfload.c
Thank you in advance for any support!
Best regards,
Stefano B.