11

I want to create a shared library which can be loaded in two different ways into targets:

  1. LD_PRELOAD
  2. Dynamic loading via dlsym

My shared library looks like this:

#include "stdio.h"

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

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

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

I am compiling it like so:

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

I do not wish to install it with ldconfig, etc. The target process looks like this:

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

The target is compiled as so:

all:
    gcc TestProg.c -ldl -o TestProg

My questions are:

  1. With the dynamic loading with dlopen as above, why does my_load not appear to be called?
  2. With the same method, why does dlsym always return nil even though dlopen returns non-null? Similarly, nm doesn't list either my_load or someFunc as symbols of the .so.
  3. Is it possible to use LD_PRELOAD to load the library? I tried copying the .so into the same directory as the target then invoking LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg but again my_load seems not to be being called.
Mike Kwan
  • 24,123
  • 12
  • 63
  • 96

1 Answers1

7

Your object files was no linked into your library:

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

Change it to include your object file MyLib.o:

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

UPDATE: just tryed your command locally (without any MyLib.c or 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

It is an empty dynamic library.

osgx
  • 90,338
  • 53
  • 357
  • 513
  • Works perfectly. It is loaded as expected by both LR_PRELOAD as well as dynamically. `my_load` is also called in both cases. Thanks! – Mike Kwan Nov 30 '11 at 18:19
  • 1
    Actually it's not empty, it contains some libc stuff. The link would have failed if you hadn't specified `-lc`. :) – ninjalj Nov 30 '11 at 19:29