On 4/26/23 12:36, Zhenlei Huang wrote:
Hi,

I'm recently working on https://reviews.freebsd.org/D39638 (sysctl(9): Enable 
vnet sysctl variables be loader tunable),
the changes to `sys/kern/link_elf_obj.c` are runtime tested, but not those to 
`sys/kern/link_elf.c` .

After some hacking I realized that `link_elf.c` is for EXEC (Executable file) 
or DYN (Shared object file), and `link_elf_obj.c` is
for REL (Relocatable file).

```
/* link_elf.c */
static int
link_elf_load_file(linker_class_t cls, const char* filename,
     linker_file_t* result)
{
...
        if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
                error = ENOSYS;
                goto out;
        }
...
}


/* link_elf_obj.c */
static int
link_elf_load_file(linker_class_t cls, const char *filename,
     linker_file_t *result)
{
...
        if (hdr->e_type != ET_REL) {
                error = ENOSYS;
                goto out;
        }
...
}
```

Run the following snip:
```
# find /boot/kernel -type f -name "*.ko" -exec readelf -h {} \; | grep Type
```
shows that all the kernel modules' types are `REL (Relocatable file)`.

I guess if some module such as if_bridge is linked to DYN type, then I can do 
runtime for the changes to `sys/kern/link_elf.c`.

I'm not familiar with elf and linkers, is that ( compile module and link it to 
DYN type ) possible ?


Hi,

I don't have an answer for you either, but I have seen in the past, loading kernel modules behaves a bit like libraries, in the following regard:

If two kernel modules define the same global symbol, then no warning is given and the first loaded symbol definition (I think) is used to resolve that symbol for all kernel modules, regardless of the prototype. Probably we should not allow this. That's why building LINT is a good thing, to avoid this issue.

Even if we don't have C++ support in the FreeBSD kernel, defining symbol names the way C++ does for C could be nice for the kernel too, also with regards to debugging systems.

Many times when I don't know what is going on, I do like this:

#include <sys/kdb.h>

....

if (not too fast or my sysctl debug) {
  printf("My tracer\n");
  kdb_backtrace();
}

Dtrace can also do this, but not during boot. Just track who is calling those functions, and you'll probably find the answer to your question!

--HPS


Best regards,
Zhenlei



Reply via email to