I want to modify the glibc dynamic linker/loader so that before mapping a shared library into a process, the linker/loader checks whether the library has been loaded/in-use by any other process in the system or not. The linker/loader will perform a specific operation on the shared library code only if the library has not been used/loaded by any other process. I understand that currently the linker/loader only linearly maps the shared library and waits for demand paging to physically load the library.
I have tried to use the shell command lsof /path/library.so
from within the dynamic linker/loader code to accomplish that. To invoke lsof
command from within dynamic linker code, I have tried
system("lsof /path/library.so")
File* fp=popen("lsof /path/library.so", "r")
Building dynamic linker, however, gives me "multiple definitions of x symbols" error as I tried to include stdio.h (for popen()
) or stdlib.h (for system()
) header files. Can you please suggest how to resolve the glibc build error or any other better way to solve my original problem?
Addition 1: Thanks @EmployedRussian. I also explored the option that you mentioned.
One possible answer is: store them in a file or a database. If that is your answer, then the solution becomes obvious: check if the file or a database entry exists. If it does, you don't need to do the computation again.
The main problem for both lsof
or file/databased based solution is: when I add a new .c file and include <stdio.h>
in that file to do file operations (such as FILE* fp = fopen()
), the glibc build gives me errors like this for few functions:
'-Wl,-(' /path/glibc-2.30_build/elf/dl-allobjs.os /path/glibc-2.30_build/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/path/glibc-2.30_build/elf/librtld.mapT /usr/bin/ld: /path/glibc-2.30_build/libc_pic.a(dl-error.os): in function `__GI__dl_signal_exception': /path/glibc_2.30_shared_library/elf/dl-error-skeleton.c:91: multiple definition of `_dl_signal_exception'; /path/glibc-2.30_build/elf/dl-allobjs.os:/path/glibc_2.30_shared_library/elf/dl-error-skeleton.c:91: first defined here
Building dynamic linker, however, gives me "multiple definitions of x symbols" error
This is because the dynamic linker is very special, and you are very restricted in what you can do in the dynamic linker.
It is special because it must be a stand-alone program -- it can't use any other library (including libc.so.6
) -- it is responsible for loading all other libraries, so naturally it can't use anything that it has yet to load.
I just want to compute them once when the library is being physically loaded the first time.
This is still an XY Problem. What are you going to do with the result of this computation?
One possible answer is: store them in a file or a database.
If that is your answer, then the solution becomes obvious: check if the file or a database entry exists. If it does, you don't need to do the computation again.
Update:
The main problem for both lsof or file/databased based solution is: when I add a new .c file and include <stdio.h> in that file to do file operations (such as FILE* fp = fopen()), the glibc build gives me errors
This is the exact same problem: you are trying to use parts of libc.so
which can't be used in a dynamic linker.
If you want to store the result of your computation in a file, you need to use low-level parts which are usable. Use open()
and write()
instead of fopen()
and fprintf()
.
Alternatively, do it from within your library or program -- since you will no longer care about how many processes have loaded the library, there is no reason to try to perform this computation in the loader. (There might be a reason, but you are not explaining it; so we are back to XY problem.)