Page 1 of 1

Linked StaticLib Relocated OutOf Kernel Image To New Address

Posted: Mon Sep 28, 2009 1:17 pm
by NickJohnson
I have a small static ELF library with both code and data that I want to be able to relocate (entirely in userspace) to the address 0xFCFF0000 (which is usermode) at runtime, then jump to. It needs to be at this address - the reason why is irrelevant. However, I want it to be loaded around where the code and data of the rest of the executable is (~0x1000). The library only has to run it's main routines after being relocated, so I don't think I need position independent code.

There are two problems I've encountered:
1. It is hard to delimit the code/data I need to copy with symbols, so I can find it.
2. I can't figure out how to make the code run at one address but be loaded at another.

The first one is hard because I can't use a linker script (afaik) when creating a static library, and therefore can't insert symbols around the library's code/data segments. It also seems like it would be bad to have separate ELF sections for this library's code and data, because that would require modifying the system-wide linker script, and not many programs use this library (pretty much only the shell does).

The second one, regardless of its similarity to bootstrapping an ELF higher half kernel, is hard because the physical address field in the ELF program header is ignored for userspace loading, preventing the higher half kernel linker script trick. Is the only option here to use position independent code so that I don't have to care which address it is written to run at?

What is the best way to solve these problems?

Thanks,
Nick

Re: Relocating static library code/data at runtime

Posted: Mon Sep 28, 2009 1:29 pm
by Combuster
Well, a static library never gets loaded of its own so there is no problem here at all... #-o :wink:

I assume you want a shared library instead? have you considered emitting relocation information?

Re: Relocating static library code/data at runtime

Posted: Mon Sep 28, 2009 2:04 pm
by NickJohnson
No, I do mean static. The point is that the library is linked into the executable, but then during runtime (not loading), relocates itself to another address to do its job. I can't use a regular shared library because I have no filesystem at the point in the init system at which it must run, and the purpose of the library makes it important that I don't use the filesystem to load it. The function of this library requires that it be far from the rest of the code, and not be loaded into that position until just before it runs, so having a dynamic linker run and load it during execution would not work. It's essentially a shared library that has it's code and data in the executable statically.

Re: Relocating static library code/data at runtime

Posted: Thu Oct 01, 2009 12:28 am
by mybura
My solution, though not elegant (then again the problem is not elegant either) would be, given that it is a small library, to build stub calls to the actual library.

The stub calls would be using a table with function addresses to call the actual library. Once relocated, adjust the table's addresses by the delta between the original compiled/linked value and your code wouldn't know the difference.

As for tagging and moving the library code, if you have the source, try to embed a magic signature before and after the last part of the data and code segment. This shouldn't be difficult if you can intercept the assembler code that the compiler emits. Otherwise you will have to play around with the code generated by the compiler and it will probably break between compiler versions.

Re: Linked StaticLib Relocated OutOf Kernel Image To New Address

Posted: Thu Oct 01, 2009 4:33 pm
by gravaera
Have you thought of loading the library as a GRUB module? GRUB loads it somewhere, and passes you the physical address. All you need to do is link it to FCF-wherever-you-want, (VMA, of course) and you're home free.

You've made it clear that the physical address of the module doesn't really matter, and that it is static, and self contained, (i.e, I'm assuming no unresolved symbols, and it doesn't need to link to the kernel). So why not use the GRUB approach?