Hacker News new | past | comments | ask | show | jobs | submit login
Dynamic Linking (stephenmarz.com)
55 points by azhenley on July 1, 2020 | hide | past | favorite | 9 comments



Speaking of this. Do someone here knows any way to open a DSO in Linux not by passing the path, but by using a file descriptor or fd?

I know FreeBSD has such a call, but not Linux, and the only place i've found this was an implementation in Android, in its specialized linker that will manage to do this, but by meddling directly with the elf headers within the file.

Why i cant use the one who just uses the path? I want to load from memory (without resorting to create the file in temp fs), and for this i would use the memfd_create().

Anyway, i just want to know if there are any way to do this in Linux without having to "manually" do this by using libelf, DT_HASH, etc..

(Also in case i need to resort to elf, i bet i will be forced to do dependency resolution by hand, which will be pretty nasty just to be able to have this feature)


Either way you probably don't want memfd_create() unless you're writing the binary into memory yourself for some reason; you can just mmap arbitrary file descriptors.

I think you'd be able to do something like dlopen("/proc/self/fd/4") where 4 is your open file descriptor, but I'm not 100% on that.


Actually i have access to a mmap'ed file that happen to have the DSO payload among other things. In practice i dont need memfd_create(), as passing the payload with the right offset within the mmaped file would do the trick.. But given its a file with much more data then just the DSO, by using something like memfd_create() i could make it easy for the OS, passing just the content of the DSO file.

Note that in my use case i will/can pass the file descriptors to the child process, so that's why memfd_create suited me well. But if you happen to know how i can just use the mmaped file, as long as i can point the exact offset to be readed, it will be much better, because it will be basically a zero-copy implementation of it.

(If memfd_create() could be created by passing the memory address, without the need to use a write() in the created fd, it would also be much less expensive)

Thank you for your tip, that is a really nice trick!


> If memfd_create() could be created by passing the memory address, without the need to use a write() in the created fd

Thinking out loud, but vmsplice into a memfd (possibly through a pipe) might allow you to populate the memfd without any copy.


Yes, if i create a memfd, populate it with with a reference from vmsplice, that maps to a mmaped file memory chunk, open it with dlopen through procfs in the child process (that i've passed through pipe) will make it happen without any copy.

This is what i've been looking for, as the child process is sandboxed and it's good to have a option where there's no need to access the filesystem to work some things out.

This is pretty good, thank you. I've passed through vmsplice here and there.. but as i didn't need to use it, i've completely forgot about its existence. So thank you for this good reminder of a great syscall.


As a kid, I always thought this was all mysterious. Demystifying it is always fun.


More info, from the former glibc maintainer:

https://akkadia.org/drepper/dsohowto.pdf


Came to link this. It is _very_ good, in-depth coverage of all things shared libraries. I believe all this stuff still applies today as it applied those 10 or so years ago when this was written.


The first assembly listing is rather opaque.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: