-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
glibc的构造函数和析构函数.md #19
Comments
普通函数放在.init是会破坏它们的结构的,因为函数的返回指令使得_init()函数会提前返回,必须使用汇编指令,不能让编译器产生ret指令 你好,关于这部分如何使用汇编将函数写入init节中有简单的demo吗,比如在init节中调用c语言的一个函数 |
可以在.init中添加一段调用指定C函数的汇编代码 示例代码如下
这里解释一下: |
非常感谢 |
ELF可执行程序默认入口是
_start
,定义在glibc/sysdeps/x86_64/start.S_start在执行main函数前后会执行一些初始化和结尾工作,可以使用
__attribute__((constructor))
和__attribute__((section(".init")))
让函数在main函数调用之前调用,使用__attribute__((destructor))
和__attribute__((section(".fini")))
让函数在main函数返回之后或调用exit()时调用接下来对具体实现过程进行分析
使用__attribute__((constructor)) 声明普通函数foo
测试代码
查看.text段汇编代码,可以看到foo函数存储在.text段
那么foo是怎么被调用的呢,使用gdb看下调用堆栈
可以看到foo最终被__libc_csu_init调用
__libc_csu_init在glibc/csu/elf-init.c,其中调用foo函数为以下几行代码
__init_array_end
和__init_array_start
符号是在链接控制脚本中定义的使用
$ ld -verbose
查看当前使用的链接控制脚本它们的值分别是.init_array的起始地址的结束地址
查看.init_array的16进制数据
可以看到
0x2007(小端)
即是函数foo的地址0x720
,即.init_array存放的就是构造函数的地址值接下来分析将函数放在.init段情况,使用
__attribute__((section(".init")))
声明普通函数bar,测试代码如下查看.init段内容,可以看到该函数存在于.init段
使用gdb查看调用堆栈
可以看出调用堆栈为
上面gdb在_init打断点再使用
s
命令继续执行是为了证明#1 0x00007fffffffcd58 in ?? ()
的??
是_init
_init函数定义在glibc/sysdeps/x86_64/crti.S
且从__libc_csu_init代码可以看出.init段中的函数是在__init_array_start函数指针调用之前调用的
值得注意的是,将bar函数指定存放在.init段执行会导致程序崩溃
《程序员的自我修养》第11.2.3节:
分析了__attribute__((constructor))和__attribute__((section(".init"))),其实__attribute__((destructor))和__attribute__((section(".fini")))的实现原理也类似,.fini对应.init, .fini_array对应.init_array,且这些函数都是通过__cxa_atexit函数进行注册,最终在程序调用exit()时被调用
在学习过程中还了解到.ctors和.dctors段,但是在实际编译过程却未见到这两个段,应该是跟gcc版本有关系,可参考以下链接
__do_global_ctors_aux not shown in objdump
Why does GCC put calls to constructors of global instances into different sections (depending on the target)?
Can't find .dtors and .ctors in binary
参考:
<程序员自我修养>
The text was updated successfully, but these errors were encountered: