最近阅读程序员自我修养这本书,遇到一个问题,百思不得其解
上代码,很简短:
PLT.c
#include <stdio.h>
int global_variable1 = 0;
void foo(){
global_variable1 = 1;
printf("global_variable:%d",global_variable1);
}
编译PIC共享文件 PLT.so:gcc -fPIC -shared -o PLT.so PLT.c
program.c
extern int global_variable1;
void main(){
global_variable1 = 1;
// foo();
// return 1;
}
编译 可执行文件 program: gcc -o program program.c ./PLT.so
program中global_variable1位于bss段,赋值为1执行movl $ox1 bss_address
倘若我使用 -fPIE参数:gcc -fPIE -o program program.c ./PLT.so
发现global_variable变量需要重定位,重定位地址位于GOT中。
那么问题来了:
1.首先,书上说通过readelf -d program |grep TEXTREL(代码重定位)判断文件是否是地址无关代码文件
我发现无论是否使用-fPIE参数,输出都是空,如此说明二者产生的program都是PIE?
2.PIE是代码部分地址无关的,可执行文件虚拟地址可以确定,linux下起始一般是80040000, gcc -o program program.c ./PLT.so该命令下,既然装载地址固定,那么代码中涉及到的数据地址,都位于bss或者data段,链接时已经确定了地址,
而代码如果涉及到函数调用,通过plt,也是地址无关的,那么是否可以说不通过-fPIE参数,而获得的program可执行文件也同样是PIE呢?如果是,那-fPIE的意义又在哪里呢?
3.什么条件使用和不使用-fPIE参数呢?
附图两张,其中提到可执行文件使用非PIC机制,且装载时代码并不重定位,那岂不是又矛盾了?
初涉及此方面问题,还请大神作答,十分感谢!