Linux 系统中,ELF动态链接文件被称为 动态共享对象(DSO,Dynamic Shared Object),简称共享对象 文件拓展名为".so" 动态链接下 一个程序可以被分成若干个文件:程序的主要部分 - 可执行文件 和 程序所依赖的共享对象(一个或多个.so文件),它们都可称作为程序的模块. 动态链接文件(共享对象)的装载地址为0x00000000:这并非工作时的实际地址,实际地址由装载器根据当前进程地址空间的空闲情况来动态分配一块足够大的虚拟地址空间给共享对象. 装载时重定…
参考文献: <ELF V1.2> <程序员的自我修养---链接.装载与库>第6章 可执行文件的装载与进程 第7章 动态链接 <Linux GOT与PLT> 开发平台: [root@tanghuimin dynamic_link]# uname -a Linux tanghuimin -.el6.x86_64 # SMP Fri Feb :: UTC x86_64 x86_64 x86_64 GNU/Linux 实例讲解之前先来一段理论铺垫,文字很繁琐但很必要事先了解.…
这篇文章是自己疑惑究竟地址无关性是如何实现,然后查看汇编和CPU指令手册,最后分析解除自己疑惑的,高手不要鄙视,哈哈. 编译C代码时候需要制定--acps/ropi选项,如下例子: void SystemInit(void) { } void fun_for_sub(void) { int j; ;j >=; j--) ; } int main(void) { fun_for_sub(); ); } C-example 编译: armcc -c --cpu Cortex-M3 -O0 --apc…
参考文献: <ELF V1.2> <程序员的自我修养---链接.装载与库>第4章 静态链接 开发平台: [thm@tanghuimin static_link]$ uname -a Linux tanghuimin -.el6.x86_64 # SMP Fri Feb :: UTC x86_64 x86_64 x86_64 GNU/Linux 1.ELF文件格式概貌…
前言: 我们都知道我们所写的程序是被编译为一条条的CPU指令去执行的,但是在linux系统下能够运行的程序在windows环境下却运行不起来,但是我们使用的CPU明明是一样的,这又是为什么呢? 一.程序的执行:编译.链接和装载 程序示例1: // add_lib.c int add(int a, int b) { return a+b; } // link_example.c #include <stdio.h> int main() { int a = 10; int b = 5; int…
PLT 全称:Procedure Linkage Table ,直译:过程连接表 由于在动态连接中,程序的模块之间包含了大量的函数引用,所以在程序开始执行前,动态链接会耗费较多的时间用于模块之间函数引用的符号查找以及重定位工作. 但是在程序实际运行时很多函数其实时没有调用到的,这里就时一个优化的点,于是就引入了延迟绑定技术(PLT). 基本思想: 但函数第一次被用到时才由动态连接器进行绑定(符号查找,重定位等),暂没用到就先不绑定.这样几句大大加快了程序的启动速度. PLT将GOT(Global…
一 什么是MAP文件 什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号.源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方.任何时候使用,不需要有额外的程序进行支持.而且,这是唯一能找出程序崩溃的地方的救星. 如果要查找代码行号,需要使用下面的公式做一些十六进制的减法运算: 崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000 为什么要这样做呢?我们得到的崩溃地址都是由 偏移地址+ 基地址得来的,所以在计…
 一 什么是MAP文件       什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号.源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方.任何时候使用,不需要有额外的程序进行支持.而且,这是唯一能找出程序崩溃的地方的救星.       如果要查找代码行号,需要使用下面的公式做一些十六进制的减法运算:       崩溃行偏移 = 崩溃地址(Crash Address) - 基地址(ImageBase Address) - 0x1000       为什么要这样做呢?我们得到的…
加载和动态链接 从编译/链接和运行的角度看,应用程序和库程序的连接有两种方式. 一种是固定的.静态的连接,就是把需要用到的库函数的目标代码(二进制)代码从程序库中抽取出来,链接进应用软件的目标映像中: 另一种是动态链接,是指库函数的代码并不进入应用软件的目标映像,应用软件在编译/链接阶段并不完成跟库函数的链接,而是把函数库的映像也交给用户,到启动应用软件目标映像运行时才把程序库的映像也装入用户空间(并加以定位),再完成应用软件与库函数的连接. 这样,就有了两种不同的ELF格式映像. 一种是静态链…
动态链接下,无论时可执行文件还是共享对象,一旦对其他共享对象有依赖,也就是所有导入的符号时,那么代码或数据中就会有对于导入符号的引用.而在编译时期这些导入符号的确切地址时未知的.只有在运行期才能确定真正确切的地址 静态编译下,这些未知的地址会被编译器一一修正. 对于动态链接来说,共享文件有两种编译方式(gcc -shared 和 gcc -fPIC -shared) 如果不使用PIC模式编译,那么装载时肯定是要重定位的,而且时每个进程都有一个副本(相对比较占用内存) 如果使用PIC模式编译,将会…