Не получается проксировать glibc функцию в своей библиотеке

Мой код:

void * __wrap_mmap (void * addr, size_t length, int prot, int flags,
                   int fd, off_t offset)
{
/ * Some actions * /

     return __real_mmap (addr, length, prot, flags, fd, offset);
}

Я компилирую его с помощью флага компоновщика -Wl, -wrap = mmap и получаю символы в .so:

          U mmap@GLIBC_2.0
00001942 T __wrap_mmap

Что сделать, чтобы в результате я получил:

          U mmap@GLIBC_2.0
00001942 T mmap

где mmap - это функция __wrap_mmap. То есть сама моя функция mmap вызывает mmap@GLIBC_2.0, но имя имеет mmap.

Мне это нужно для подмены glibc функций используя LD_PRELOAD своей библиотеки. Но сложность заключается в том, что библиотека сама вызывает функции glibc после некоторых дополнительных действий. Спасибо.


Ответы (1 шт):

Автор решения: Fat-Zer

Если кратко, то -wrap используется для того чтобы обернуть функции вызываемые в текущем линкуемом бинарном файле. Для переопределения функций не входящих в него он ни как не применим.

Мне это нужно для подмены glibc функций используя LD_PRELOAD своей библиотеки. Но сложность заключается в том, что библиотека сама вызывает функции glibc после некоторых дополнительных действий.

Для этого нужно динамически загрузить символ с помощью dlsym():

#define _GNU_SOURCE   // для RTLD_NEXT

#include <stdio.h>
#include <dlfcn.h>
#include <sys/types.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
    static void *(*mmap_orig)(void *, size_t, int, int, int, off_t);

    if(!mmap_orig) {
        mmap_orig = dlsym(RTLD_NEXT, "mmap");
    }

    fprintf(stderr, "mmap %zd bytes\n", length);

    return mmap_orig(addr, length, prot, flags, fd, offset);
}

Сборка/проверка:

$ gcc -fPIC -c foo.c -o foo.o
$ gcc -shared foo.o -o libfoo.so
$ cat test.c
#include <sys/mman.h>

int main(void) {
    void *addr = mmap(0, 1024, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
    return 0;
}
$ gcc test.c
$ LD_PRELOAD="./libfoo.so" ./a.out
mmap 1024 bytes
→ Ссылка