pwn学习日记Day15 《程序员的自我修养》读书笔记
程序编译链接过程:
1.调用cc1程序,这个程序实际上就是GCC的C语言编译器,它将"hello.c"编译成一个临时的汇编文件"/tmp/ccUhtGSB.s"。
2.调用as程序,as程序是GNU的汇编器,它将"/tmp/ccUhtGSB.s"汇编成临时文件"/tmp/ccQZRPL5.o",这个"/tmp/ccQZRPL5.o"实际上就是前面的"hello.o"。
3.GCC调用collect2程序来完成最后的链接。
但是按照我们之前的理解,链接过程应该由id链接器来完成,collect2是什么程序?
collect2可以看作是链接器的一个包装,它会调用id链接器来完成对目标文件的链接,然后再对链接结果进行一些处理,主要是收集所有与程序初始化相关的信息并且构造初始化结构。
Q:为什么静态运行库里面一个目标文件只包含一个函数?比如libc.a里面的printf.o只有printf()函数、strlen.o只有strlen()函数,为什么要这样组织?
A:链接器在链接静态库的时候是以目标文件为单位的。比如我们引用了静态库中的printf()函数,那么链接器就会把库中包含printf()函数的哪个目标文件链接进来,如果很多函数都放在一个目标文件中,很可能很多没用的函数都被一起链接进了输出结果中。由于运行库有成百上千个函数,数量非常庞大,每个函数独立地放在一个目标文件中可以尽量减少空间的浪费,哪些没有被用到的目标文件(函数)就不要链接到最终的输出文件中。