深入理解计算机系统--链接


编译时打桩,编译命令

gcc -DCOMPILETIME -c my_malloc.c
gcc -I. -o main main.c my_malloc.o 

//my_malloc.h
#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)

void *mymalloc(size_t size);
void myfree(void *ptr);



//my_malloc.c
#ifdef COMPILETIME
#include <stdio.h>
#include <malloc.h>

void *mymalloc(size_t size) {
    void *ptr = malloc(size);
    printf("malloc(%d)=%p\n", (int)size, ptr);
    return ptr;
}

void myfree(void *ptr) {
    free(ptr);
    printf("free(%p)\n",ptr);
}

#endif



//main.c
#include <stdio.h>
#include <malloc.h>

int main() {
    int *p = malloc(sizeof(int));
    free(p);
    return 0;
}





链接时打桩,编译命令

gcc -DLINKTIME -c my_malloc.c 
gcc -c main.c
gcc -Wl,--wrap,malloc -Wl,--wrap,free -o main main.o my_malloc.o

//my_malloc.c
#ifdef LINKTIME
#include <stdio.h>

void *__real_malloc(size_t size);
void __real_free(void *ptr);

void *__wrap_malloc(size_t size) {
    void *ptr = __real_malloc(size);
    printf("malloc(%d) = %p\n", (int)size, ptr);
    return ptr;
}

void __wrap_free(void *ptr) {
    __real_free(ptr);
    printf("free(%p)\n", ptr);
}

#endif




//main.c
#include <stdio.h>
#include <malloc.h>

int main() {
    int *p = malloc(sizeof(int));
    free(p);
    return 0;
}

运行结果

malloc(4) = 0x746010
free(0x746010)





运行时库打桩机制

对 malloc,free函数的包装

#define _GUN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
//#define NULL 0;

void *malloc(size_t size) {
    void *(*malloc_func)(size_t size);
    char *error;
/*       
    void *handle = dlopen("/lib64/libc.so.6", RTLD_LAZY);
    if (!handle) {
        fprintf (stderr, "%s ", dlerror());
        exit(1);
    }
*/

    malloc_func = dlsym(RTLD_NEXT, "malloc");
    if((error=dlerror()) != NULL) {
        fputs(error,stderr);
        exit(1);
    }
    char *ptr = malloc_func(size);
    printf("malloc(%d) = %p\n", (int)size, ptr);
    return ptr;
}


void free(void *ptr) {

    void (*free_func) (void *) = NULL;
    char *error;
    if(!ptr) {
        return;
    }
    free_func = dlsym(RTLD_NEXT, "free");
    if((error=dlerror()) != NULL) {
        fputs(error,stderr);
        exit(1);
    }
    free_func(ptr);
    printf("free (%p)\n",ptr);

}

编译命令

gcc -D_GNU_SOURCE -DRUNTIME -shared -fPIC -o mymalloc.so mymalloc.c -ldl

执行

LD_PRELOAD="./mymalloc.so" uptime  

运行结果

malloc(37) = 0x2526040
。。。
free (0x2527020)
free (0x2526fe0)
malloc(12) = 0x2526fe0
malloc(12) = 0x2527020
free (0x25273e0)
free (0x2527110)
 23:44:38 up 349 days,  6:35,  5 users,  load average: 0.00, 0.01, 0.05




 

一些相关的命令

名称 含义
ar 创建静态库,插入删除列出和提取成员
ldd 列出一个可执行文件在运行时所需要的共享库
gcc 强大的编译工具
nm 列出一个目标文件的符号表中定义的符号
size 列出目标文件中section的名字和大小
objdump

所有二进制工具之母

能够显示一个目标文件中所有的信息

最大的作用是反汇编.text 片段中的二进制指令

readelf

显示一个目标文件的完整结构

包括ELF头中编码的所有信息,包含size和nm的功能

strace 跟踪调试工具
strip 删除多余的段

 

 

 

 

 

参考

关于Linux静态库和动态库的分析

程序的编译链接过程

程序运行流程——链接、装载及执行







 

一些相关的命令

名称 含义
ar 创建静态库,插入删除列出和提取成员
ldd 列出一个可执行文件在运行时所需要的共享库
gcc 强大的编译工具
nm 列出一个目标文件的符号表中定义的符号
size 列出目标文件中section的名字和大小
objdump

所有二进制工具之母

能够显示一个目标文件中所有的信息

最大的作用是反汇编.text 片段中的二进制指令

readelf

显示一个目标文件的完整结构

包括ELF头中编码的所有信息,包含size和nm的功能

strace 跟踪调试工具
strip 删除多余的段

 

 

 

 

 

参考

关于Linux静态库和动态库的分析

程序的编译链接过程

程序运行流程——链接、装载及执行

猜你喜欢

转载自blog.csdn.net/hixiaoxiaoniao/article/details/80920267
今日推荐