共享对象本身显式调用内部函数

Shared object explicitly calling internal function in itself

我一直在重新编码我合并到我的共享对象库中的一些 libC 函数。其中一些函数在内部调用自己。

现在的问题是,当我从另一个程序使用 dlsym 时,dlsym 提供的函数(内部使用需要内部函数)将调用 libC 的函数,而不是我已经存在的函数在我的图书馆重新编码。

这是一个简单的例子:

lib.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *memset(void *s, int c, size_t n)
{
  printf("Calling LIB's Memset\n");
  for (size_t i = 0; i < n; ++i)
    ((char *) s)[i]  = c;
  return s;
}

void *calloc(size_t mnemb, size_t size)
{
  size_t sz = mnemb * size;
  void *addr = malloc(sz);

  printf("Calling LIB's Calloc\n");
  memset(addr, 0, sz);
  return addr;
}

gcc lib.c -fPIC -shared -o lib.so

main.c

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

int main(void)
{
  void *handler = dlopen("./lib.so", RTLD_NOW);
  void (*_calloc)(size_t, size_t);

  if (!handler)
  {
    printf("Could not open lib\n");
    return 1;
  }
  _calloc = dlsym(handler, "calloc");
  if (!_calloc)
  {
    printf("Could not extract symbol\n");
    return 1;
  }
  _calloc(10, 10);
  return 0;
}

gcc main.c -ldl

$ ./a.out 
Calling LIB's Calloc

如你所见,只调用了来自lib的calloc函数,没有调用内部的memset

如何在我的库中明确调用它自己的函数?

注意:我的函数必须以与 libC 相同的方式调用,因为它也必须与 LD_PRELOAD 一起工作。

How can I tell in my library to explicitly call its own functions ?

最好的方法可能是为您自己的函数指定不同的名称。例如,为它们的名称添加一致的前缀:my_strlenmy_printf 等。然后当库打算调用其中的其他函数时仅使用这些名称。愚蠢的例子:

size_t my_strlen(const char *s) {
    return *s ? (1 + my_strlen(s + 1)) : 0;
}

为了让外部调用者调用它们来代替它们的同名函数,请插入包装函数。例如:

size_t strlen(const char *s) {
    return my_strlen(s);
}

但是,同样,不要依赖库中的包装器。如果愿意,您甚至可以将包装器拆分到一个单独的库中。

这里的想法是尽量减少您接触链接器游戏和动态链接效果。当重点是替换您自己的标准库函数实现时,您不能完全避免这些,但通过这种方式,您可以减少它们给您带来麻烦的范围。