Date: Tue, 9 Apr 2024 12:15:23 +0100 From: Andrei Lascu <alas.20073@gmail.com> To: freebsd-questions@freebsd.org Subject: Questions about a symbol in `libc.so` Message-ID: <b84b34f8-0415-40b7-9177-32fa27f06890@gmail.com>
next in thread | raw e-mail | index | archive | help
Hello. Due to certain circumstances, I am currently working on a loader-like application for shared object files to be ran on a system running an OS derived from FreeBSD. I've got most of the stuff working to the level I need, but I've found something in `libc.so.7` that's got me stumped. The goal is to run a test file that, among others, calls `fdopen` from `libc.so`. Everything runs well, until line 124 in `findfp.c` is hit (as per the source for `libc.so` in FreeBSD 14 Stable), where `__sdidinit` is accessed. In my loader, there is no memory allocated for this variable, because there is no relocation entry for it. Here is where my confusion starts. Looking at the symbol table for `libc.so`, `__sdidinit` is a `LOCAL DEFAULT` [1] symbol. The only way I can think of to replicate that behaviour is to declare a variable static. However, the variable is declared as `int __sdidinit` in `findfp.c` (and also as `extern int __sdidinit` in `stdio/local.h`, which again, looks odd), which to me should mean it's a `GLOBAL` symbol (unless there is some weird linking stuff I didn't manage to hunt down during compilation). Furthermore, running the program through the system runtime loader (and also looking at the compiled assembly), accessing the variable seems to be done to what I 90% believe is a GOT lookup. However, with no relocation entry, I'm completely unsure how this is the case. My questions are as follows: 1) Is it possible to access a variable via a GOT lookup when a relocation entry does not exist? 2) Is there some explanation as to how this variable gets `LOCAL` binding? 3) Is perhaps the system loader doing some special thing because it considers `libc.so` especially, and it brings some relocation entries from somewhere else, or has some default ones? 4) A side question: while the symbol exists in `libc.so.7.full`, after doing a `make buildworld`, it seems to be stripped out of `libc.so.7` itself - I'm wondering if this is some optimization at work. Thanks in advance for your help, and apologies if this was the wrong mailing list to ask. Regards, Andrei. [1] I should mention I had a look at OpenBSD's `libc.so`, which was the other `libc.so` that I found with this symbol. In there, the main difference is that `__sdidinit` is `LOCAL HIDDEN`, which, if some similar mechanism might be employed in FreeBSD, might explain 2) and 4) above, but I'm still unsure where to look.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b84b34f8-0415-40b7-9177-32fa27f06890>