linux调用共享库中的函数时通过plt表和got表实现位置无关代码,过程中涉及到lazy binding,即在第一调用外部函数时解析被调用的函数地址并将地址写入到got表,后续调用则不需要解析函数地址。这一部分和硬件架构有关,具体的是和cpu指令集相关,下面分析龙芯3a4000芯片这一块的代码,3a4000采用的是mips指令集。
1.c
void aaa();
int main(int argc, char **argv)
{int a = 0;aaa();a = 2;return 0;
}
#编译参数
gcc 1.c -L. -laaa -z lazy -g
2.c
void aaa()
{int a = 1;
}
#编译参数
gcc 2.c -fPIC -shared -o libaaa.so
使用gdb调试生成的可执行程序,打断点在mian函数的第一行。
反汇编查看main函数
可以看到sw zero,28(s8)对应int a = 0;这行代码,
ld v0, -32640(gp); 从相对于gp寄存器-32640的位置读取数据放到v0寄存器
move t9, v0; 将v0的值赋值给t9寄存器
jalr t9; 跳转
使用info registers命令查看寄存器值
x /1xg 读取0x120019010-32640位置内存
执行ni命令