-1

I'm trying to understand Linux and *.so files. It's hard.
I try to figure out, how can I find which modules are available in a *.so file, e.g:

In my httpd configuration file I found the following line: LoadModule wsgi_module modules/mod_wsgi.so

I assume wsgi_module is a module "inside" of mod_wsgi.so.
Question: How can I list or find all modules of a *.so file?

N. J
  • 99

2 Answers2

1

In general, all .so files (whether they are libraries or modules) work by exporting named symbols – which typically represent functions or sometimes 'external' variables – that the program will import by name using the "dynamic linker". It's mostly the same for modules as it is for libraries.

In the case of Apache httpd modules, the "module name" wsgi_module is literally just the name of a symbol that the .so file exports (most likely pointing to a struct variable with pointers to all necessary functions for Apache to start using it as a module). The main program will load the .so using dlopen() and look up the specified symbol using dlsym().

(This may be different for other programs that use .so modules, as each program basically rolls its own; e.g. many programs expect all modules to provide a symbol with the same name every time.)

To see what names are being exported by a .so file, you can use nm from binutils:

$ nm -D -Ux /usr/lib/httpd/modules/mod_rewrite.so 
0000000000012020 D rewrite_module

Here -D makes nm show "dynamic" symbols, and the -U trims the list down only to the symbols that are "defined" (i.e. exported – the full list also contains symbols that are being imported from other libraries).

(According to everything it should be just -U, not -Ux, but apparently the nm/binutils version that I have mistakenly requires a parameter to be given to the short option so I have to use -Usomething. The long option --defined-only works as expected.)

You can compare this to a .so file that is just a regular C library, which works more or less the same way (the symbols are usually resolved at compile time when gcc hello.c -lcrypt is done, but can be loaded with dlsym as well):

$ nm -D -Ux /usr/lib/libcrypt.so
0000000000000000 A XCRYPT_2.0
0000000000000000 A XCRYPT_4.3
0000000000000000 A XCRYPT_4.4
0000000000010e30 T crypt@@XCRYPT_2.0
0000000000011090 T crypt_checksalt@@XCRYPT_4.3
000000000000f4d0 T crypt_gensalt@@XCRYPT_2.0
0000000000011000 T crypt_gensalt_ra@@XCRYPT_2.0
0000000000010e50 T crypt_gensalt_rn@@XCRYPT_2.0
0000000000011120 T crypt_preferred_method@@XCRYPT_4.4
0000000000010de0 T crypt_r@@XCRYPT_2.0
0000000000010d20 T crypt_ra@@XCRYPT_2.0
0000000000010c90 T crypt_rn@@XCRYPT_2.0

Alternatives to nm, from David's comment:

grawity
  • 501,077
0

Your assumptions are wrong : A .so file is just a shared library that was created by linking one or more object files.

Specifically, the LoadModule directive has the syntax of :

LoadModule module filename

The description of the directive says :

The LoadModule directive links in the object file or library filename and adds the module structure named module to the list of active modules. Module is the name of the external variable of type module in the file, and is listed as the Module Identifier in the module documentation.

This means that module is a specific name used in Apache. Not all .so libraries are Apache modules, and they are certainly not composed of Apache modules.

.so libraries are created by the linker from object files. Sometimes these files are also called "modules". Once having been linked, they cannot be unpacked again into their original object files, since this information is no longer available.

All that's left in the .so library are entry-points supplied by the original object files and the name of the object file they originally belonged to. However, you cannot guess, without disassembling the library, where the code from each object file starts or ends in it.

harrymc
  • 498,455