Dlsym behavior for static linked libraries

I am trying to write some send function in C, which should get a string consisting of the name of the function, and then inside the send function in order to be able to call the function whose name is specified in the received argument. The thing is that I do not want to define a function in a dynamically loaded library. The flow should be something like this.

file1.c

void hello()
{
   fprintf(stderr,"Hello world\n");
}

void myfunc()
{
   mydispatch("hello");
}

file2.c

void mydispatch(const char *function)
{
...
}

I know this structure may be strange, but I was wondering if this could be done.

+3
source share
3 answers

You can use BFD to get runtime addresses from symbol names.

#include <stdio.h>
#include <stdlib.h>
#include <bfd.h>
#include <string.h>

void func1(int n)
{
    printf("%d\n", n);
}

void * addr_from_name(char * filename, char * symname)
{
    bfd *        ibfd;
    asymbol **   symtab;
    symbol_info  info;
    void *       symaddress = NULL;
    long         size;
    long         syms;
    unsigned int i;

    bfd_init();

    ibfd = bfd_openr(filename, NULL);
    bfd_check_format(ibfd, bfd_object);

    size   = bfd_get_symtab_upper_bound(ibfd);
    symtab = malloc(size);
    syms   = bfd_canonicalize_symtab(ibfd, symtab);

    for(i = 0; i < syms; i++) {
        if(strcmp(symtab[i]->name, symname) == 0) {
            bfd_symbol_info(symtab[i], &info);
            symaddress = (void *)info.value;
        }
    }

    bfd_close(ibfd);
    return symaddress;
}

int main(void)
{
    void (*func)(int) = addr_from_name("/homes/mk08/Desktop/lala", "func1");
    printf("%p\n", func);
    func(5);
    return EXIT_SUCCESS;
}

filename, . , / lala, :

gcc -Wall -std=gnu99 lala.c -o lala -lbfd && ./lala

:

0x400814
5

, . , . . .

+2

:

void mydispatch(const char *function)
{
    if (!strcmp(function, "hello")
        hello();
    else if (!strcmp(function, "goodbye")
        goodbye();
}

; .

: . , , - (, , ) - .

0

Perhaps you are using the following solution:

file1.c:

void myfunc()
{
   my_function_type fun = search_function( "operation1" );
   fun(); 
}

tools.h:

typedef void (*my_function_type)( void );
void register_function( my_function_type fp, const char* name );
my_function_type search_function( const char* name );

file2.c:

static void mydispatch( void )
{
...
}    

static void __attribute__ ((constructor)) register_functions()
{
     register_function( mydispatch, "operation1" );
}

In this solution, you do not need to compile old files again when you add functionality. Just compile the new file and link.

0
source

All Articles