choose exported symbols when linking an elf application and shared library - linker

when linking an elf application or share library, I want to choose which symbols to export. By default, when linking an application no function symbol is exported and when linking a shared library all function symbols are exported. Is there any way to control which symbols to export? When linking an application, I can use -rdynamic or -Wl,--export-dynamic to get all symbols, and I can use -Wl,--dynamic-list <symfile> to get only some symbols. However when linking a library, are those options ignored?

Found out after testing a little:
for ELF applications, you can use -rdynamic or -Wl,--export-dynamic to export all symbols, or you can use -Wl,--dynamic-list <sym-file> to export only some symbols when linking your application through gcc.
for ELF libraries, you can't use -rdynamic, -Wl,--export-dynamic or -Wl,--dynamic-list <symfile>, you must use -Wl,--version-script=<verfile> when linking your library through gcc.
The version-script and the sym-file are almost the same, except that for sym-file you do not code a version and a scope. Documentation: gnu ld

Is there any way to control which symbols to export?
The usual way to control symbol visibility in shared library is either
Use linker script, as described here, or
Use __attribute__((visibility("default"))) on symbols you explicitly want to export and build with -fvisibility=hidden (which will hide everything else).

Related

How to resolve weak symbol __gnu_Unwind_Find_exidx?

I am trying to build a c++ app on TizenRT platform. After linking, I find that the
_gnu_Unwind_Find_exidx symbol is coming as a weak symbol in the final binary. It seems that this symbol is used by unwind-arm.c. I could not find the implementation of this API in the arm gcc toolchain. I realised that we need to implement this API according to our platform and hence I implemented it in my C library.
However, even after linking the C++ app with the C library (Which has the new implementation of this API), the symbol still appears as a weak symbol in the final binary.
My link command is somewhat as follows:
arm-none-eabi-ld my-app.o --start-group libxxx.a libc.a libgcc.a --end-group
I have used libgcc.a at the end because I suppose that libc.a and other libraries might have a dependency on it. However, I have put all the libraries in the group. So, I was hoping that the linker would search all the libraries recursively to resolve all undefined symbols.
Does the linker treat weak symbols differently from undefined symbols?
How do I tell the linker to pick the implementation of the API in my C library?
Regards!

How to specify static linking for standard libraries in yocto-cmake?

I am new to cmake so, sorry if this question is very basic.
I want to build my project as statically linked with each standard library it uses.
Like, in gcc if we want to link the standard system libraries(libc, libgcc etc) as static, we specify '-static' option at the time of compilation.(Like gcc main.c -static -o main).
How we can achieve the same in cmake?
I have read multiple threads to define a how to define a library, how to build, link(as static & shared). But that is all for a custom library, I need information for standard system libraries.
[Edit]
In my project, I am using yocto at the top and the cmake is been used underneath it. running directly cmake works fine, as the generated executable has no dependencies on any shared library, all the used libraries are linked statically. But compiling from yocto causing the issue. the executable generated from the yocto build shows the dependencies on several standard shared libraries.
How we can specify static linking of standard libraries in yocto cmake?
Thanks in advance.

What is the difference between shared and dynamic libraries in C?

I don't understand the difference between the two types of libraries, and many websites say that they are the same thing, but at school we use two different commands to create them
dynamic library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -ldl
to execute:
$ ./main ./libsample.so
shared library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -L. -lsample
to execute:
$ LD_LIBRARY_PATH=. ./main
Can someone help me in understanding the difference between the two "codes"?
Dynamic Linked Library (.DLL) is the terminology used by Microsoft Windows. Shared Object (.so) is the terminology used by Unix and Linux.
Other than that, conceptually they're the same.
Regarding your snippets of commands, I guess the difference (and I'm only guessing here, because you didn't show us the relevant parts) is how the library is loaded. There is "link time loading" where the library is tied to the executable by the linker¹. And there is "runtime loading", where the program sort of "ingests" the dynamic/shared library.
runtime loading is done in Windows with the LoadLibrary (there's an …A and a …W variant) function, and on Unix/Linux with dlopen (which is made available by libdl which is linked to by that -ldl library link statement).
1: The linker is the program that creates the actually executable file from the intermediary objects created by the various compiler stages.
Dynamic and shared libraries are usually the same. But in your case, it looks as if you are doing something special.
In the shared library case, you specify the shared library at compile-time. When the app is started, the operating system will load the shared library before the application starts.
In the dynamic libary case, the library is not specified at compile-time, so it's not loaded by the operating system. Instead, your application will contain some code to load the library.
The first case is the normal case. The second case is a special use and it's mainly relevant if your application support extensions such a plug-ins. The dynamic loading is required because there can be many plug-ins and they are built after your application. So their names are not available at compile-time.

Make AIX load all shared symbols at run time?

I'm on AIX 5.3, working with C.
I have an application (foo) that links in a shared library (lib1.so) at run time, then dynamically loads another library (lib2.so) via dlopen(). lib2.so uses some functions in lib1.so that foo does not use. When I execute the application, I get an error similar to:
rtld: 0712-001 Symbol someLibFunc was referenced from module
/libdir/lib2.so(), but a runtime definition of the symbol was not found.
I don't believe that changing the dlopen() flags would have any effect, since my issue seems to have something to do with what symbols are imported when run-time linking occurs. Is there some type of ld option I can use when building foo to force it to import all shared library symbols? This same build works great in my Linux environment.
I found the culprit.
I ran 'dump -Tv' on lib1.so and found that the function I expected to be exported was not there (although it did show up in nm, oddly enough). The library was linked with -bexpall so all symbols should be there. I dug deeper into the ld man page and saw that expall did not export symbols prefixed with an underscore (_). The function I was trying to use began with an underscore. I found the 'expfull' ld option, which exports symbols prefixed with an underscore, rebuilt lib1.so with that option, and everything is good now.

Listing the dependencies of a shared library in Solaris

I am converting a set of static libraries to shared libraries and was able to create the shared libraries successfully. The problem is with the exe's because linking with static library can have unresolved symbols in the library but that is not the case with shared libraries. All the symbols in the shared library should get resolved.
Example:
PROG1 calls LIB1.a calls LIB2.a
Now the make file of PROG1 need not have LIB2.a as PROG1 calls to LIB1.a do not result in calling LIB2.a .So some LIB2.a symbols in LIB1.a can remain unresolved.
After conversion
Both LIB1.so and LIB2.so have to be included in the makefile of PROG1. Including LIB2.so resolves few linkage issues of LIB1.so but new issues appear due to inclusion of LIB2.so(as it may be depend on LIB3.so)
SO is there any way to find out the all the dependent libraries of a shared library?
I tried using ldd but it prints nothing.
Please let me know if my analysis is wrong.
This is a slightly personal opinion, but I think you should link your shared libraries so that you get an error for unresolved symbols (with -z defs). That means you sort out each library independently and don't get any nasty surprises at link time.
Of course, this only works if your libraries are clean and don't contain recursive dependencies (which are probably a bad thing anyway) and you aren't trying to do dynamic loading where you can load any of impl_1.so, impl_2.so or impl3_.so to provide code for a client client.so at runtime. But it works well if all you have are link time dependencies.
Indeed, if you don't do this, and are using ld rather than cc to do the linking,, you'll get pretty much what you're seeing - no dependencies, and errors at linktime

Resources