Make AIX load all shared symbols at run time? - c

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.

Related

Link error using old libraries

I am trying to use third-party libraries (.a) , for which I dont have the source code, that worked in an older app. I imported the older app into Xcode 7 and built and ran it successfully. The libraries were dependent on system libraries which had extension .dylib The program still worked.
I then tried to build a new app using the same libraries. However, I had to replace the system libraries with their .tbd equivalents. When I issued the build command, I got link errors such as shown below where the library name is libavutil.a
ld: library not found for -lavutil
clang: error: linker command failed with exit code 1 (use -v to see invocation
I read in stack overflow posts about the need to add to the 'other linker flags' in the build settings.
My questions are:
Do I need to add flags (to Debug and Release) such as lavutil for libavutil.a or flags for the system libraries -lc++ for libc++?
Am I on the right track? Or is there some other solution to the
linker errors.
Reading through some SO posts on similar linker errors encountered by others, it was suggested that instead of adding a -lavutil like statement to the other linker flags, I could drag and drop the libraries into the window that opens up for multiple values. This worked well. Drag and drop maintains the right relative directory structure and removes the ambiguity that the linker may encounter to find the libraries. The linker errors were eliminated and I could execute the program.
In summary, I switched to Xcode 7, changed target to 9.2, dragged my third-party libraries, and built and ran.

choose exported symbols when linking an elf application and shared library

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).

What does this linking error mean?

When I was compiling a new software, I encountered a bunch of errors emitted by ld.
/usr/lib/libstreamanalyzer.so.0: undefined reference to `xmlSAXUserParseMemory#LIBXML2_2.4.30'
/usr/lib/libstreamanalyzer.so.0: undefined reference to `xmlCtxtResetPush#LIBXML2_2.6.1'
/usr/lib/libstreamanalyzer.so.0: undefined reference to `xmlCreatePushParserCtxt#LIBXML2_2.4.30'
This seems to be confusing. Linker is supposed to be looking for symbols in objects, not library names, but it seems in this case those before the # is the function name/symbol, and LIBXML2_2.6.1 is a library name. And for dynamic library, the soname x.y.z version should only matter in dynamic linking stage, that is when the executable actually runs.
So what does this error really means, and what part of the above assumptions are wrong?
Edit:
The problem appears after installing libxml2 2.7.8. It is gone after libxml2 is upgraded to 2.9.1.
When I was compiling a new software, I encountered a bunch of errors
No, you didn't. You encountered errors when linking, which is different from compiling.
Linker is supposed to be looking for symbols in objects
UNIX linkers also look for symbols in libraries (both archive and shared).
LIBXML2_2.6.1 is a library name
No, it's not. It's a symbol version, which happens to reflect the library in which that symbol was defined.
So what does this error really means
This error means: when libstreamanalyzer.so.0 was linked, it was linked against a library (most likely libxml2.so) that provided versioned symbols xmlSAXUserParseMemory#LIBXML2_2.4.30, etc.
You are now linking your binary against some other version of libxml2, one which does not provide these symbols, and your binary will not work.

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

link erlang nif on windows

I try to compile a erlang nif plugin on windows using the cygwin gcc.
It compiles fine but the linker issues some errors:
undefined reference to `_enif_get_int'
I'm currently linking against ei.lib and erl_interface.lib.
None of these contain the required symbols. Did I miss something?
It looks rather like you have a windows module (which expects symbols starting with underscore) linking against cygwin libraries (which typically don't export symbols with underscore).

Resources