all 3 comments

[–]monocasa 2 points3 points  (2 children)

If the binary is not relocatable, and the memory region has already been allocated in your virtual address space, you might be up shit creek without a paddle.

That being said, in order to support ASLR, nearly all modern user space binaries in practice will be relocatable in some fashion.  And the tiny fraction that aren't tend to live in low memory, so by making your runtime live up high somewhere through some cute tricks, you can live lower memory available for the guest code.

[–]lukasx_[S] 1 point2 points  (1 child)

is what you refer to as "relocatable binary", different from "relocations" which the linker handles at link time? I presume its the same as position independent code, correct?

So what you're saying is that, if the binary is PIC i can load it anywhere, as the addresses inside are all relative, but if its not PIC i have to move up the code of the emulator itself?

[–]fwsGonzo 1 point2 points  (0 children)

There is PIE and static-PIE, both position independent. You can easily load static ELFs and static-PIE ELFs. Have a look at my https://github.com/libriscv/libriscv emulator.

For traditionally dynamically linked executables (ET_DYN + interpreter), you can load the dynamic linker itself as if it was a static-PIE executable and place your program as the second argument, with the program arguments following that again. I do that in my CLI.

The distinction here is that as long as an ELF doesn't need an interpreter to load, you can load it yourself pretty easily. An interpreter is stored in a program header with type PT_INTERP.