共享对象本身显式调用内部函数
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_strlen
、my_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);
}
但是,同样,不要依赖库中的包装器。如果愿意,您甚至可以将包装器拆分到一个单独的库中。
这里的想法是尽量减少您接触链接器游戏和动态链接效果。当重点是替换您自己的标准库函数实现时,您不能完全避免这些,但通过这种方式,您可以减少它们给您带来麻烦的范围。
我一直在重新编码我合并到我的共享对象库中的一些 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_strlen
、my_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);
}
但是,同样,不要依赖库中的包装器。如果愿意,您甚至可以将包装器拆分到一个单独的库中。
这里的想法是尽量减少您接触链接器游戏和动态链接效果。当重点是替换您自己的标准库函数实现时,您不能完全避免这些,但通过这种方式,您可以减少它们给您带来麻烦的范围。