gcc编译 替换库函数

替换同名函数

使用gcc选项no-builtin,默认不使用系统的优化函数,而使用自定义的函数。
case for study

1
2
3
4
5
6
7
8
9
// printf.c
#include <unistd.h>
#include <string.h>

int printf(const char* format, ...) {
write(STDOUT_FILENO, "my printf\n", 10);
write(STDOUT_FILENO, format, strlen(format));
return 0;
}

1
2
3
4
5
6
7
// main.c
#include <stdio.h>

int main() {
printf("hello\n");
return 0;
}
1
2
3
4
5
6
7
8
$ gcc -c printf.c 
$ gcc main.c printf.o -fno-builtin
$ ./a.out
my printf
hello
$ gcc main.c printf.o
$ ./a.out
hello

对于像signal这样的未给予优化的函数(毕竟仅仅是系统调用的包装),直接静态链接即可。

1
2
3
4
5
6
7
8
9
10
// signal.c
#include <stdio.h>
#include <signal.h> // 假设signal函数的定义调用了sigaction等函数

typedef void Sigfunc(int);

Sigfunc* signal(int signo, Sigfunc* func) {
printf("%d\n", signo);
return func;
}

1
2
3
4
5
6
7
// main.c
#include <signal.h>

int main() {
signal(SIGINT, SIG_DFL);
return 0;
}
1
2
3
4
$ gcc -c signal.c 
$ gcc main.c signal.o
$ ./a.out
2

替换不同名函数

__warp_前缀重写需要替换的库函数,__real_前缀调用原库函数,示例程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>

void *__wrap_malloc(size_t size)
{
void* result;
result = __real_malloc(size);
printf("malloc: allocate %d byte mem, start at %p\n", size, result);

return result;
}

int main()
{
int i,n;
char * buffer;
i = 20;
buffer = (char*)malloc(i+1);
if (buffer==NULL) exit(1);

for (n=0; n<i; n++)
buffer[n] = rand()%26+'a';
buffer[i]='\0';

printf("Random string: %s\n", buffer);
free(buffer);

return 0;
}

编译命令:

1
$ gcc test_malloc.c -Wl,--wrap=malloc -Wl,--warp=free

-Wl,--warp=malloc表示将程序中的malloc全部用__wrap_malloc替换。

reference
https://www.jianshu.com/p/eeba0e3dc900
https://hev.cc/2278.html