2011-11-30 32 views
7

Quiero crear una biblioteca compartida que se puede cargar de dos maneras diferentes en objetivos:Carga dinámica de bibliotecas compartidas de Linux?

  1. LD_PRELOAD
  2. carga dinámica mediante dlsym

Mi biblioteca compartida se ve así:

#include "stdio.h" 

void __attribute__ ((constructor)) my_load(void); 

void my_load(void) { 
    printf("asdf"); 
} 

void someFunc(void) { 
    printf("someFunc called"); 
} 

Lo estoy compilando como lo hago:

all: 
    gcc -fPIC -g -c -Wall MyLib.c 
    gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

No deseo a instalarlo con ldconfig, etc. El proceso de destino tiene el siguiente aspecto:

#include <stdio.h> 
#include <dlfcn.h> 

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

void func2() { 
    printf("%d\n", 2); 
} 

void func3() { 
    printf("%d\n", 3); 
} 

int main() { 
    void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1", 
         RTLD_NOW|RTLD_GLOBAL); 

    if(lib_handle == NULL) { 
    printf("Failed loading lib\n"); 
    } else { 
    printf("Loaded lib successfully\n"); 

    void (*some_func)() = dlsym(lib_handle, "someFunc"); 
    printf("%p\n", some_func); 

    dlclose(lib_handle); 
    } 

    func1(); 
    func2(); 
    func3(); 

    return 0; 
} 

El objetivo es compilado como así:

all: 
    gcc TestProg.c -ldl -o TestProg 

Mis preguntas son:

  1. Con la carga dinámica con dlopen como arriba, ¿por qué my_load parece que no se llama?
  2. Con el mismo método, ¿por qué dlsym siempre devuelve nil aunque dlopen devuelve no nulo? Del mismo modo, nm no enumera ni my_load ni someFunc como símbolos de .so.
  3. ¿Es posible utilizar LD_PRELOAD para cargar la biblioteca? Intenté copiar .so en el mismo directorio que el objetivo y luego invocar LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg, pero de nuevo my_load parece que no se está llamando.

Respuesta

6

Sus ficheros objeto no estaba vinculado a tu biblioteca:

gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

cambio para incluir el archivo objeto MyLib.o:

gcc MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

ACTUALIZACIÓN: simplemente tryed su comando localmente (sin cualquier MyLib.c o MyLib.o):

$ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok 
ok 
$ nm MyLib.so.1.0.1 
xxxxxxxx a _DYNAMIC 
xxxxxxxx a _GLOBAL_OFFSET_TABLE_ 
     w _Jv_RegisterClasses 
xxxxxxxx A __bss_start 
     w [email protected]@xxxxxxxxxxx 
xxxxxxxx d __dso_handle 
     w __gmon_start__ 
xxxxxxxx t __i686.get_pc_thunk.bx 
xxxxxxxx A _edata 
xxxxxxxx A _end 
xxxxxxxx T _fini 
xxxxxxxx T _init 

It es una biblioteca dinámica vacía.

+0

Funciona perfectamente. Se carga tanto como LR_PRELOAD como de forma dinámica. 'my_load' también se llama en ambos casos. ¡Gracias! –

+1

En realidad no está vacío, contiene algunas cosas libc. El enlace habría fallado si no hubiera especificado '-lc'. :) – ninjalj

Cuestiones relacionadas