Skip site navigation (1)Skip section navigation (2)
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>