Linux list so functions

How to find function from lib .so files?

I can print list of exported function of one *.so file like

nm -C lib/libopencv_ml.so

and then find my function like

nm -C lib/libopencv_ml.so | grep myfunction

but when I want to find function from all .so files how to determine which .so contain my function?

This just print all entries of function but I need to know from which .so file it appear.

nm -C lib/*.so | grep cvSetZero

Seems -H option also not helped. -H, —with-filename print the file name for each match

nm -C lib/*.so | grep -Hn cvSetZero

Generate output like:

2 Answers 2

I found solution

nm -C -A lib/*.so | grep cvSetZero

It produce this kind of output:

You could append one last :
| c++filt

in order to demangle the symbols. Also as a generic note, gcc-nm should be used in a system compiled with LTO.

EDIT: Another way with nm is to use -D and —defined-only and after redirecting the possible errors to /dev/null , grep the exact symbol with ‘\bsymbol_name\b’ .

This way one can search the library that defines the symbol_name and not just uses it. -D allows to search only in dynamic libraries (.so).

But is seems the ultimate way to scan for library that defines(+) or not(-) a symbol is scanelf :

Run scanelf with -m option on / to search the whole system, without crossing mount points.

Источник

How do I list the symbols in a .so file

How do I list the symbols being exported from a .so file? If possible, I’d also like to know their source (e.g. if they are pulled in from a static library).

I’m using gcc 4.0.2, if that makes a difference.

11 Answers 11

The standard tool for listing symbols is nm , you can use it simply like this:

If you want to see symbols of a C++ library, add the «-C» option which demangle the symbols (it’s far more readable demangled).

If your .so file is in elf format, you have two options:

Either objdump ( -C is also useful for demangling C++):

If your .so file is in elf format, you can use readelf program to extract symbol information from the binary. This command will give you the symbol table:

You only should extract those that are defined in this .so file, not in the libraries referenced by it. Seventh column should contain a number in this case. You can extract it by using a simple regex:

or, as proposed by Caspin,:

For shared libraries libNAME.so the -D switch was necessary to see symbols in my Linux

and for static library as reported by others

I kept wondering why -fvisibility=hidden and #pragma GCC visibility did not seem to have any influence, as all the symbols were always visible with nm — until I found this post that pointed me to readelf and objdump, which made me realize that there seem to actually be two symbol tables:

  • The one you can list with nm
  • The one you can list with readelf and objdump

I think the former contains debugging symbols that can be stripped with strip or the -s switch that you can give to the linker or the install command. And even if nm does not list anything anymore, your exported symbols are still exported because they are in the ELF «dynamic symbol table», which is the latter.

Читайте также:  Checksum windows system files

Источник

Get names and addresses of exported functions in linux

I am able to get a list of exported function names and pointers from an executable in windows by using using the PIMAGE_DOS_HEADER API (example).

What is the equivalent API for Linux?

For context I am creating unit test executables and I am exporting functions starting with the name «test_» and I want the executable to just spin through and execute all of the test functions when run.

Example psuedo code:

EDIT:

I was able to find what I was after using the top answer from this question: List all the functions/symbols on the fly in C?

Additionally I had to use the gnu_hashtab_symbol_count function from Nominal Animal ‘s answer below to handle the DT_GNU_HASH instead of the DT_HASH .

My final test main function looks like this:

Which I then define tests in the assembly like:

Which produces output that looks like this:

2 Answers 2

I do get quite annoyed when I see questions asking how to do something in operating system X that you do in Y.

In most cases, it is not an useful approach, because each operating system (family) tends to have their own approach to issues, so trying to apply something that works in X in Y is like stuffing a cube into a round hole.

Please note: the text here is intended as harsh, not condesceding; my command of the English language is not as good as I’d like. Harshness combined with actual help and pointers to known working solutions seems to work best in overcoming nontechnical limitations, in my experience.

In Linux, a test environment should use something like

to list all the symbols in FILE . readelf is part of the binutils package, and is installed if you intend to build new binaries on the system. This leads to portable, robust code. Do not forget that Linux encompasses multiple hardware architectures that do have real differences.

To build binaries in Linux, you normally use some of the tools provided in binutils. If binutils provided a library, or there was an ELF library based on the code used in binutils, it would be much better to use that, rather than parse the output of the human utilities. However, there is no such library (the libbfd library binutils uses internally is not ELF-specific). The [URL=http://www.mr511.de/software/english.html]libelf[/URL] library is good, but it is completely separate work by chiefly a single author. Bugs in it have been reported to binutils, which is unproductive, as the two are not related. Simply put, there are no guarantees that it handles the ELF files on a given architecture the same way binutils does. Therefore, for robustness and reliability, you’ll definitely want to use binutils.

If you have a test application, it should use a script, say /usr/lib/yourapp/list-test-functions , to list the test-related functions:

This way, if there is an architecture that has quirks (in the binutils’ readelf output format in particular), you only need to modify the script. Modifying such a simple script is not difficult, and it is easy to verify the script works correctly — just compare the raw readelf output to the script output; anybody can do that.

A subroutine that constructs a pipe, fork() s a child process, executes the script in the child process, and uses e.g. getline() in the parent process to read the list of names, is quite simple and extremely robust. Since this is also the one fragile spot, we’ve made it very easy to fix any quirks or problems here by using that external script (that is customizable/extensible to cover those quirks, and easy to debug). Remember, if binutils itself has bugs (other than output formatting bugs), any binaries built will almost certainly exhibit those same bugs also.

Читайте также:  Настройка микрофона blue yeti windows 10

Being a Microsoft-oriented person, you probably will have trouble grasping the benefits of such a modular approach. (It is not specific to Microsoft, but specific to a single-vendor controlled ecosystem where the vendor-pushed approach is via overarching frameworks, and black boxes with clean but very limited interfaces. I think it as the framework limitation, or vendor-enforced walled garden, or prison garden. Looks good, but getting out is difficult. For description and history on the modular approach I’m trying to describe, see for example the Unix philosophy article at Wikipedia.)

The following shows that your approach is indeed possible in Linux, too — although clunky and fragile; this stuff is intended to be done using the standard tools instead. It’s just not the right approach in general.

The interface, symbols.h , is easiest to implement using a callback function that gets called for each symbol found:

The ELF symbol binding and type macros are word-size specific, so to avoid the hassle, I declared the enum types above. I omitted some uninteresting types ( STT_NOTYPE , STT_SECTION , STT_FILE ), however.

The implementation, symbols.c :

When compiling the above, remember to link against the dl library.

You may find the gnu_hashtab_symbol_count() function above interesting; the format of the table is not well documented anywhere that I can find. This is tested to work on both i386 and x86-64 architectures, but it should be vetted against the GNU sources before relying on it in production code. Again, the better option is to just use those tools directly via a helper script, as they will be installed on any development machine.

Technically, a DT_GNU_HASH table tells us the first dynamic symbol, and the highest index in any hash bucket tells us the last dynamic symbol, but since the entries in the DT_SYMTAB symbol table always begin at 0 (actually, the 0 entry is «none»), I only consider the upper limit.

To match library and function names, I recommend using strncmp() for a prefix match for libraries (match at the start of the library name, up to the first . ). Of course, you can use fnmatch() if you prefer glob patterns, or regcomp()+regexec() if you prefer regular expressions (they are built-in to the GNU C library, no external libraries are needed).

Here is an example program, example.c , that just prints out all the symbols:

To compile and run the above, use for example

To see the symbols in the program itself, use the -rdynamic flag at link time to add all symbols to the dynamic symbol table:

On my system, the latter prints out

I used . to mark where I removed lots of lines.

Источник

Unix / Linux — Shell Functions

In this chapter, we will discuss in detail about the shell functions. Functions enable you to break down the overall functionality of a script into smaller, logical subsections, which can then be called upon to perform their individual tasks when needed.

Using functions to perform repetitive tasks is an excellent way to create code reuse. This is an important part of modern object-oriented programming principles.

Shell functions are similar to subroutines, procedures, and functions in other programming languages.

Creating Functions

To declare a function, simply use the following syntax −

The name of your function is function_name, and that’s what you will use to call it from elsewhere in your scripts. The function name must be followed by parentheses, followed by a list of commands enclosed within braces.

Читайте также:  What is snmp trap in linux

Example

Following example shows the use of function −

Upon execution, you will receive the following output −

Pass Parameters to a Function

You can define a function that will accept parameters while calling the function. These parameters would be represented by $1, $2 and so on.

Following is an example where we pass two parameters Zara and Ali and then we capture and print these parameters in the function.

Upon execution, you will receive the following result −

Returning Values from Functions

If you execute an exit command from inside a function, its effect is not only to terminate execution of the function but also of the shell program that called the function.

If you instead want to just terminate execution of the function, then there is way to come out of a defined function.

Based on the situation you can return any value from your function using the return command whose syntax is as follows −

Here code can be anything you choose here, but obviously you should choose something that is meaningful or useful in the context of your script as a whole.

Example

Following function returns a value 10 −

Upon execution, you will receive the following result −

Nested Functions

One of the more interesting features of functions is that they can call themselves and also other functions. A function that calls itself is known as a recursive function.

Following example demonstrates nesting of two functions −

Upon execution, you will receive the following result −

Function Call from Prompt

You can put definitions for commonly used functions inside your .profile. These definitions will be available whenever you log in and you can use them at the command prompt.

Alternatively, you can group the definitions in a file, say test.sh, and then execute the file in the current shell by typing −

This has the effect of causing functions defined inside test.sh to be read and defined to the current shell as follows −

To remove the definition of a function from the shell, use the unset command with the .f option. This command is also used to remove the definition of a variable to the shell.

Источник

Thread: howto export functions in *.so libraries

Thread Tools
Display

howto export functions in *.so libraries

I am trying to convert one windows program to Linux.
The question is:
what is linux equivalent for

extern «C» int (__declspec(dllexport))someFunction(char* someparam)

Re: howto export functions in *.so libraries

In Linux (as usual) it’s easy and you have 3+ ways to do it.

    If you just declare them

Is just a mere macro to usually force the compiler to produce stdcall calling convention. In Linux AFAIK we only use cdecl ( http://en.wikipedia.org/wiki/X86_calling_conventions ).
Have fun!

Last edited by Emanuele_Z; January 16th, 2010 at 12:19 PM . Reason: add info

Re: howto export functions in *.so libraries

Re: howto export functions in *.so libraries

to be precise, the calling convention applies to i386 arch.
For x86-64 Windows and Linux follow 2 slightly different conventions: Linux follows AMD ABI calling convention, instead, as usual, M$ way is to slightly diverge from it from no apparent reason. sigh.
Anyway, given more registers in x86-64, a lot of variables are passed into them, instead of being put onto the stack then read (as happens with i386 convention). So even just for this reason (and believe me there are many more) x86-64 is faster than i386.

Источник

Оцените статью