Sorin Papuc
Sorin Papuc

Reputation: 101

How can my C code find the symbol corresponding to an address at run-time (in Linux)?

Given a function or variable run-time address, my code needs to find out the name and, if it's a variable, type information of the symbol. Or at least provide enough information for later, off-line extraction of the name (and type info).

It is Linux code and it is assumed debug information is available.

I tried to look into the ELF file format, binutils and all but the subject is huge, so I was hoping somebody can help me narrow the scope.

I can see the following types of solutions:

Thank you in advance.

Upvotes: 7

Views: 8023

Answers (3)

missimer
missimer

Reputation: 4079

What you want to look at is the Binary File Descriptor library specifically the symbol handling functions. libbfd provides a common set of functions for manipulating and reading various object formats. It does this by providing an abstract view of object files and then has specific back ends to handle the details of specific object types and architectures. ELF file formats are supported as is most likely the architecture you want to use.

I don't find libbfd difficult to use but I am always open to alternatives and libelf is another one. You will probably want to look at the gelf_getsym function specifically.

Upvotes: 2

o11c
o11c

Reputation: 16016

GNU libc provides a dladdr function for this exact purpose. However, it only works on functions, not variables.

   #define _GNU_SOURCE         /* See feature_test_macros(7) */
   #include <dlfcn.h>

   int dladdr(void *addr, Dl_info *info);

   The  function  dladdr()  takes  a function pointer and tries to resolve
   name and file where it  is  located.   Information  is  stored  in  the
   Dl_info structure:

       typedef struct {
           const char *dli_fname;  /* Pathname of shared object that
                                      contains address */
           void       *dli_fbase;  /* Address at which shared object
                                      is loaded */
           const char *dli_sname;  /* Name of symbol whose definition
                                      overlaps addr */
           void       *dli_saddr;  /* Exact address of symbol named
                                      in dli_sname */
       } Dl_info;

   If no symbol matching addr could be found, then dli_sname and dli_saddr
   are set to NULL.

   dladdr() returns 0 on error, and nonzero on success.

Of course, usually I do this sort of thing from gdb, not within the program itself.

Upvotes: 10

Lee Daniel Crocker
Lee Daniel Crocker

Reputation: 13171

C is a fully-compiled language. The names and types and other info about variables are generally discarded in the compilation process.

An exception is that most compilers will produce an executable with debugging information included, so that a live debugger has access to this information. This info is totally OS-specific, and even compiler-specific, and might even be in parts of memory not accessible to the program.

Upvotes: 0

Related Questions