【问题标题】:Use dlsym on a static binary在静态二进制文件上使用 dlsym
【发布时间】:2013-01-12 02:12:31
【问题描述】:

有没有希望运行dlopen(NULL, ...) 并为静态编译的二进制文件获取符号?

例如,如果程序是动态编译的并且我使用-rdynamic,我可以使用以下代码获取符号。

$ gcc -o foo foo.c -ldl -rdynamic
$ ./foo bar
In bar!

但是对于-static,我收到一条神秘的错误消息:

$ gcc -static -o foo foo.c -ldl -rdynamic
/tmp/cc5LSrI5.o: In function `main':
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ./foo bar
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory

foo.c 的来源如下:

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

int foo() { printf("In foo!\n"); }
int bar() { printf("In bar!\n"); }

int main(int argc, char**argv)
{
  void *handle;
  handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
  if (handle == NULL) {
    fprintf(stderr, "%s\n", dlerror());
    return 1;
  }

  typedef void (*function)();
  function f = (function) dlsym(handle, argv[1]);
  if (f == NULL) {
    fprintf(stderr, "%s\n", dlerror());
    return 2;
  }
  f();

  return 0;
}

【问题讨论】:

    标签: static-linking dlopen dlsym


    【解决方案1】:

    有没有希望运行 dlopen(NULL, ...) 并为静态编译的二进制文件获取符号?

    没有。

    在大多数 UNIX 上,您甚至无法同时链接 -static-ldl。您可以使用 glibc,但这样做的实用性非常 有限。基本上,此功能仅用于支持 /etc/nsswitch.conf,仅此而已。

    进行动态查找也没有意义。

    如果您尝试允许根据命令行参数调用foobarbaz 之一,只需放入一个表格,例如

    struct { const char *fname, void (*fn)(void) } table[] =
      { {"foo", &foo}, {"bar", &bar}, ...};
    
    for (int i = 0; i < ...; ++i)
      if (strcmp(argv[1], table[i].fname) == 0)
        // found the entry, call it
        (*table[i].fn)();
    

    如果您尝试“可能”调用foo(如果它已链接),否则不执行任何操作,则使用弱引用:

    extern void foo(void) __attribute((weak));
    
    if (&foo != 0) {
      // foo was linked in, call it
      foo();
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-05
      • 2015-04-02
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 2017-11-05
      相关资源
      最近更新 更多