You can use handle = dlopen("library.so", RTLD_NOW | RTLD_GLOBAL); to load and bind all symbols in the named dynamic library. See man 3 dlopen for details.
Because memcpy() is a very common function, your replacement should probably be something like the following:
Code:
static volatile int active = 0;
void *memcpy(void *dest, const void *src, size_t n)
{
if (!active) {
unsigned char *d = (unsigned char *)dest;
const unsigned char *s = (const unsigned char *)src;
const unsigned char *const z = n + (const unsigned char *)src;
while (s < z)
*(d++) = *(s++);
return dest;
}
/*
* The body of your memcpy() function goes here
*/
}
with your init/constructor functions setting active nonzero only after it has prepared everything for your custom memcpy() to work correctly.
Originally Posted by
josymadamana
But dlsym is getting one symbol at a time and it is getting confused with my own implimentation of memcpy.
You can obtain the address of the next occurrence of the symbol in the library order, using the GNU extension RTLD_NEXT:
Code:
#define _GNU_SOURCE
#include <dlfcn.c>
static void *(true_memcpy)(void *, const void *, size_t) = NULL;
static void my_library_init(void) __attribute__((constructor));
static void my_library_init(void)
{
/* In C99, you cannot cast a void pointer to a function pointer,
* so you need to use the POSIX.1-2003 (Technical Corrigendum 1)
* workaround, also shown in the 'man 3 dlopen' Linux manpage.
*/
*(void **)(&true_memcpy) = dlsym(RTLD_NEXT, "memcpy");
/*
* Other initialization..
*/
/* Initialization complete. */
active = 1;
}
After the initialization, you can use true_memcpy(). Just remember that you still need that activation flag (you could set it after the assignment above, for example), because your function may be called before, and even during, your library initialization.