dlsym() fails with an executable shared library

Mayank Kaushik mayank.utexas@gmail.com
Thu Dec 8 03:26:00 GMT 2011


Hi everyone,

I'm trying to build an executable shared library. I googled
extensively, and found two possible ways, but both have problems.

(1) The first was what's suggested by this very old thread:

http://gcc.gnu.org/ml/gcc-help/2003-07/msg00232.html

Library code: (The common caller code is at the end of the mail)

const char my_interp[] __attribute__((section(".interp"))) =
"/lib64/ld-linux-x86-64.so.2";

void my_func(int x)
{
    fprintf(stderr, "Inside %s: %d\n", __FUNCTION__, x);
}

void my_main(int argc, char **argv)
{
    int i;

    printf("argc: %d\n", argc);

    for (i = 0; i < argc; i++)
        printf(" %s", argv[i]);

    printf("\n");

    exit(0);
}

gcc -Wall -W -fPIC -shared -o library.so test.c -lc -Wl,-e,my_main

This almost works fully, but argc and argv[0] are inaccessible when
the shared library is run (the original poster also reported this, and
I saw the same), which is a deal-breaker.
$ ./library.so 1 2
argc: 0

(2) The second method is from these two sources:

http://marklodato.github.com/
http://sourceware.org/ml/binutils/2009-10/msg00088.html

Library code:

void my_func(int x)
{
    fprintf(stderr, "Inside %s: %d\n", __FUNCTION__, x);
}

int main(int argc, char **argv)
{
    int i;

    printf("argc: %d\n", argc);

    for (i = 0; i < argc; i++)
        printf(" %s", argv[i]);

    printf("\n");

    exit(0);
}

gcc -fPIC -fPIE -pie -o library.so test.c

This can read arguments fine, but dlsym() fails:

./library.so: undefined symbol: my_func

I'd appreciate help in getting this to work.

Thanks in advance,
Mayank

========================

Here's the caller code:

int main(void) {
    void *handle;
    void (*func)(int x);
    char *error;

    handle = dlopen("./library.so", RTLD_NOW);
    if (NULL == handle) {
        fprintf(stderr, "** could not dlopen\n");
        exit(1);
    }

    dlerror();

     *(void **) (&func) = dlsym(handle, "my_func");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(1);
    }

    func(1);

    return 0;
}



More information about the Gcc-help mailing list