Динамически загружаются общие библиотеки Linux? - PullRequest
8 голосов
/ 30 ноября 2011

Я хочу создать разделяемую библиотеку, которая может быть загружена в цели двумя различными способами:

  1. LD_PRELOAD
  2. Динамическая загрузка через dlsym

Моя общая библиотека выглядит так:

#include "stdio.h"

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

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

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

Я собираю это так:

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

Я не хочу устанавливать его с ldconfig и т. Д. Целевой процесс выглядит следующим образом:

#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;
}

Цель скомпилирована так:

all:
    gcc TestProg.c -ldl -o TestProg

Мои вопросы:

  1. При динамической загрузке с dlopen, как указано выше, почему my_load не вызывается?
  2. При использовании того же метода, почему dlsym всегда возвращает nil, хотя dlopen возвращает ненулевое значение? Точно так же nm не перечисляет ни my_load, ни someFunc как символы .so.
  3. Можно ли использовать LD_PRELOAD для загрузки библиотеки? Я попытался скопировать .so в ту же директорию, что и цель, затем вызвал LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg, но снова my_load, похоже, не вызывается.

1 Ответ

6 голосов
/ 30 ноября 2011

Ваши объектные файлы не были связаны с вашей библиотекой:

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

Измените его, чтобы включить ваш объектный файл MyLib.o:

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

ОБНОВЛЕНИЕ: просто опробовал вашу команду локально (без MyLib.c или 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 __cxa_finalize@@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

Это пустая динамическая библиотека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...