精华内容
下载资源
问答
  • 链接重定位
    2014-10-14 21:44:41

    链接重定位指静态链接时的重定位;

    装载重定位指dll或linux下的so文件要到装载到进程空间重定位

    更多相关内容
  • 静态链接——重定位

    2020-12-25 20:19:05
    静态链接——重定位静态链接符号解析重定位重定位类型重定位符号引用重定位PC相对引用重定位绝对引用 静态链接 想要理解静态链接这一过程,首先我们需要明白编译器驱动程序,它代表用户在需要时调用语言预处理器、...

    静态链接

    想要理解静态链接这一过程,首先我们需要明白编译器驱动程序,它代表用户在需要时调用语言预处理器编译器汇编器链接器
    示例程序:

    //main.c
    int sum(int *a, int n);
    int array[2] = {1, 2};
    int main(){
    	int val = sum(array, 2);
    	return val;
    }
    
    //sum.c
    int sum(int *a, int n){
    	int i, s = 0;
    	for(i=0; i<n; i++){
    		s += a[i];
    	}
    	return s;
    }
    

    当我们编辑完源代码需要运行时,大致过程如下图所示:
    编译器驱动程序大致过程
    其中,标红的地方就是这篇文章要讲述的过程。
    像Linux LD程序这样的静态链接器以一组可重定位目标文件和命令行参数作为输入,生成一个完全链接的、可以加载和运行的可执行目标文件作为输出。
    为了构造可执行文件,链接器必须完成两个主要任务:符号解析重定位

    符号解析

    目标文件中,会定义与引用符号。
    符号包括:函数、全局变量、静态变量(在C语言中任何以static属性声明的变量)
    注意:局部变量不属于符号。
    符号解析的目的是将每个符号引用正好和一个符号定义关联起来

    重定位

    编译器和汇编器生成从地址0开始的代码和数据节。
    链接器通过把每个符号定义与一个内存位置关联起来,从而重定位这些节。
    然后修改所有对这些符号的引用,使它们准确指向定义的内存位置。
    (简单来说,就是对符号定义进行重新定位,再修改符号引用指向的地址)
    链接器使用汇编器产生的重定位条目的详细指令,不加甄别地执行这样的重定位。

    重定位类型

    当汇编器遇到对最终位置未知的目标引用时,会生成一个重定位条目:其目的是告诉链接器在将目标文件合并成可执行文件时应该如何修改这个引用。

    ELF重定位条目的格式如下(offset、type、symbol、addend):

    typedef struct{
    	long offset; //需要被修改的引用的偏移量,也就是入口点偏移量
    	long type:32, //声明重定位的类型(相对地址引用or绝对地址引用)
    		 symbol:32; //标识被修改的符号,(例如sum函数,这里就是sum)
    	long addend; //有符号常数,有时候需要用该值做重定位偏移调整
    }Elf64_Rela;
    

    其中最基本的两种类型(type):

    R_X86_64_PC32: 重定位一个使用32位PC相对地址的引用。将指令中编码的32位值加上PC的当前运行值作为有效地址。(PC值通常是下一条指令在内存中的地址)
    R_X86_64_32: 重定位一个使用32位绝对地址的引用。CPU直接使用在指令中编码的32位值作为有效地址。

    重定位符号引用

    两种重定位算法如下:

    foreach section s {
    	foreach relocation entry r {
    		refptr = s + r.offset; //s是每个节,r是相关联重定位条目
    
    		//相对寻址
    		if (r.type == R_X86_64_PC32) {
    			refaddr = ADDR(s) + r.offset; 
    			//计算引用的运行时的地址。如果写题,题目会给出ADDR(s)
    			*refptr = (unsigned)(ADDR(r.symbol) + r.addend - refaddr); 
    			//refaddr = ADDR(s) + r.offset
    			//*refptr是指令中编码的32位值(重定位引用值)。
    			//后续还需读出PC值。
    			//有效地址为:下一条指令地址(PC值)+ *refptr
    		}
    
    		//绝对寻址
    		if (r.type == R_X86_64_32){
    			*refptr = (unsigned)(ADDR(r.symbol) + r.addend);
    			//*refptr是指令中编码的32位值(重定位引用值),即有效地址。
    		}
    	}
    }
    

    接下来我们用以下示例图(反汇编代码)来演示相对寻址与绝对寻址。
    已知:
    ADDR(s) = 0x4004d0;
    ADDR(sum) = 0x400e8;
    ADDR(array) = 0x601018;
    在这里插入图片描述
    这里main函数引用了两个全局符号:array和sum。从图中我们可以得知:
    array的type是R_X86_64_32(绝对寻址)
    sum的type是R_X86_64_PC32(相对寻址)
    在这里插入图片描述

    重定位PC相对引用

    第一步,我们需要列出上述示例中,sum的重定位条目:
    在这里插入图片描述
    从题目图中可以得知以下信息:
    在这里插入图片描述
    所以sum的重定位条目为:

    r.offset = 0xf
    r.symbol = sum
    r.type = R_X86_64_PC32
    r.addend = -0x4

    且题目已告知:

    ADDR(s) = 0x4004d0; ADDR(sum) = 0x400e8;

    第二步,根据公式可做如下计算:

    refaddr = ADDR(s) + r.offset
        = 0x4004d0 + 0xf
        = 0x4004df

    *refptr = (unsigned)(ADDR(r.symbol) + r.addend - refaddr)
        = 0x4004e8 + (-0x4) - 0x4004df
        = 0x5

    得到重定位引用值:0x5

    重定位绝对引用

    第一步,我们需要列出上述示例中,sum的重定位条目:
    在这里插入图片描述
    从题目图中可以得知以下信息:
    在这里插入图片描述
    所以array的重定位条目为:

    r.offset = 0xa
    r.symbol = array
    r.type = R_X86_64_32
    r.addend = 0

    且题目已告知:

    ADDR(array) = 0x601018;

    第二步,根据公式可做如下计算:

    *refptr = (unsigned)(ADDR(r.symbol) + r.addend)
        = 0x601018 + 0
        = 0x4601018

    得到重定位引用值:0x4601018(同时也是有效地址)

    展开全文
  • 链接器在连接过程中的工作就是把多个输入的目标文件加工合并成一个输出文件。有几种不同的方案: 按序叠加 按序叠加可以说是最简单的一个方案,就是将输入的目标文件按照次序叠加起来。 从图中可以看到,在有很...

    一、空间与地址分配

    链接器在连接过程中的工作就是把多个输入的目标文件加工合并成一个输出文件。有几种不同的方案:

    按序叠加
    按序叠加可以说是最简单的一个方案,就是将输入的目标文件按照次序叠加起来。

     从图中可以看到,在有很多输入文件的情况下,输出文件将有很多零散的段。因为每个段都要遵循空间对齐,所以这样会占用大量空间。比如,一个段长度只有1字节,但是按照空间对齐,其在内存也要占用4096个字节。

    相似段合并
    为了解决按需叠加所带来的问题,引入了相似段合并这个概念,就是把相同性质的段合并到一起。.bss段其实在目标文件和可执行文件中并不占用文件的空间(不占用磁盘空间),但是在装载时是要占用地址空间的。


    很多书中提到的“链接器为目标文件分配地址和空间”,这一句话其实是有两个含义的。对于.text和.data这样有实际数据的段,链接器在文件中和虚拟地址中都要分配空间。但是对于.bss这样的段,在文件中就不必分配空间,目的是节约磁盘空间。
    目前的链接器都不采用按序叠加的方法,而是采用相似段合并的方法。

    链接器采用的是相似段合并的方法,使用这种方法的链接器一般都采用两步链接的方法。
    第一步 空间与地址分配:链接器获取所有目标文件的段长度,将他们合并,计算出输出文件中各个段合并后的长度与位置,建立映射关系。
    第二步 符号解析与重定位:使用上一步所收集到的信息,读取输入文件中段的数据、重定位信息、进行符号解析和重定位、调解代码中的地址。
    链接器前后的程序所用的地址其实已经是程序应该在进程中使用的虚拟地址。Linux下一般从0x08048000开始分配。地址确定很简单,基址地址(0x08048000)+偏移地址(符号在进程中的地址)。

    二、符号

    链接的本质就是把多个不同的目标文件之间相互“粘”到一起,就像是拼图一样,把每一块“目标文件”拼接成一个完整的“程序”。
    在链接中,目标文件之间相互拼合实际上就是目标文件之间地址的引用,即对函数和变量的地址的引用。将函数和变量统称为符号,函数名或变量名就是符号名。

    符号的类型
    定义在本目标文件的全局符号:可被其他目标文件引用
    外部符号:在本目标文件中引用的全局符号
    段名:由编译器产生,值为该段的起始地址。
    局部符号:只在编译单元内部可见,其他目标文件不可见

    特殊符号
    在linux下使用ld作为链接器来链接可执行文件时,定义很多符号可以引用。这些符号称为特殊符号。以下是几个很具有代表性的特殊符号:

    __executable_strat:代码段的起始地址
    __etext或_etext或etext:代码段的结束地址
    _edata或edata:数据段的结束地址
    _end或end:程序的结束
    ELF符号表结构
    typedef struct
    {
        Elf32_Word st_name;
        Elf32_Addr st_value;
        Elf32_Word st_size;
        unsigned char st_info;
        unsigned char st_other;
        Elf32_Half st_shndx;
    }Elf32_Sym


    符号修饰与函数签名
    为了避免和库文件中的符号发生符号冲突,就出现了符号修饰机制。

    UNIX下的C语言规定,C语言中的符号经过编译后需要在在符号名前加上下划线“_“。

    int func()
        {
            ...
        }
    以上函数名被修饰成 “_func”。

    在C++中则增加了名称空间  namespace

    C++中的符号修饰
    因为C++支持重载的特征,所以函数符号修饰相对复杂,引入术语函数签名来表示C++中函数的符号修饰。函数签名包含了一个函数的信息,包括函数名、参数类型、所在类、以及名称空间。

    linux下函数签名的规则:所有符号都以_Z开头,在名称空间或类中后面紧跟N,再以E结尾。比如一个名称空间foo中的全局变量bar就会被修饰为_ZN3foo3barE。

    C++解决与C的兼容问题——extern
    C和C++中的符号修饰是不同的,所以就存在不兼容问题,为了解决这个兼容问题,C++中有个用来声明或定义一个C符号的extern “C” 关键字用法。以下是一个示例:

    extern “C”只能定义在全局范围,不能定义在函数内

    extern "C"
    {
        int func(int);
        int var;
    }
    同时C++编译器会在编译C++文件时默认定义一个宏**“__cplusplus”**,来使得能够兼容C语言的头文件,这也是能在C++中使用#include<stdio.h>的原因。

    强符号和弱符号
    在编程中会出现多个目标文件中含有相同名字全局符号的定义,这种情况就叫符号重复定义。为了解决这个问题,引入了强符号和弱符号规则。在C/C++语言中,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。以下是发生符号重复定义的处理规则:

    强符号与强符号之间:编译器报错
    强符号与弱符号之间:编译器选择强符号
    弱符号与弱符号之间:编译器选择其中占用空间最大的一个

    强引用和弱引用
    在编译器对引用的外部符号进行决议时,如果没有找到该符号定义,编译器就会报符号未定义错误的称之为强引用,如果没有找到该符号定义,编译器就默认其为0的称之为弱引用。

    库中定义的弱符号可以被用户定义的强符号所覆盖,使得用户可以让程序使用自定义版本的库函数。

    三、符号解析与重定位

    重定位

    #include "func.c"
    int main()
    {
        func();
    }

    在这段代码中的函数func()定义在其他文件中,所以编译器就暂时把地址0看做是“func()”的地址。等到链接器在完成地址和空间分配之后就可以确定所有符号的虚拟地址(包括func),那么链接器就可以根据重定位表对每个需要重定位的符号进行地址修正。

    符号解析

    链接是因为在目标文件中用到的符号被定义在其他目标文件。这也是编译过程中出现“undefined symbol”这类编译错误的原因。

    重定位的过程往往也伴随着符号的解析过程,每个重定位的入口都是对一个符号的引用,那么当链接器需要对某个符号的引用进行重定位时,它就要确定这个符号的目标地址,这时候链接器就会去查找由所输入目标文件的符号表组成的全局符号表,找到相应的符号进行重定位。

    展开全文
  • 4、代码重定位 4.1、重定位代码详解 1、代码启动过程简要分析 问题1:代码下载到哪里去? 数据手册上会有说明,位置不是我们想往哪里下载就往哪里下载的,下载错了启动的时候就找不到代码的位置在哪,一般是下载到...
  • 12. 重定位及动态链接

    千次阅读 2018-12-07 17:28:34
    12.1 符号的重定位 1. 重定位步骤 2. 重定位信息 3. 重定位操作举例 (1)源文件 (2)链接结果 (3)R_386_PC32的重定位 main.o重定位前 R_386_PC32的重定位方式 (4) R_386_32的重定位 重定位前 R_386_...

    12.1 符号的重定位

    1. 重定位步骤

    在这里插入图片描述

    2. 重定位信息

    在这里插入图片描述

    3. 重定位操作举例

    (1)源文件

    在这里插入图片描述

    (2)链接结果

    在这里插入图片描述

    (3)R_386_PC32的重定位

    main.o重定位前

    在这里插入图片描述
    在这里插入图片描述

    R_386_PC32的重定位方式

    在这里插入图片描述
    在这里插入图片描述

    (4) R_386_32的重定位

    重定位前

    在这里插入图片描述
    在这里插入图片描述

    R_386_32的重定位方式

    在这里插入图片描述

    swap.o重定位

    在这里插入图片描述
    在这里插入图片描述

    重定位后

    在这里插入图片描述

    12.2 可执行文件的加载

    1. 加载方法

    (1)通过调用execve系统调用函数来调用加载器
    (2)加载器(loader)根据可执行文件的程序(段)头表中的信息,将可执行文件的代码和数据从磁盘“拷 贝”到存储器中
    (3)加载后,将PC(EIP)设定指向 Entry point(即符号_start处),最终执行main函数,以启动程序执行
    在这里插入图片描述

    ELF头信息举例
    在这里插入图片描述

    2. 程序的加载和运行

    (1) UNIX/Linux系统中,可通过调用execve()函数来启动加载器。
    (2) execve()函数的功能是在当前进程上下文中加载并运行一个新程序。 execve()函数的用法如下:
         int execve(char *filename, char *argv[], *envp[]);
       ①filename:加载并运行的可执行文件名(如./hello)
       ②argv:可带参数列表
       ③envp:环境变量列表
     若错误(如找不到指定文件filename) ,则返回-1,并将控制权交给调用程序;
     若函数执行成功,则不返回 ,最终将控制权传递到可执行目标中的主函数main。
    (3) 主函数main()的原型形式如下:
         int main(int argc, char **argv, char **envp);
       或者: int main(int argc, char *argv[], char *envp[]);
    argc指定参数个数,参数列表中第一个总是命令名(可执行文件名)
     例如:命令行为“ld -o test main.o test.o” 时,argc=6

    3. 程序的加载和运行过程举例

    Step1: 在shell命令行提示符后输入命令:$./hello[enter]
    Step2: shell命令行解释器构造argv和envp
    在这里插入图片描述
    Step3: 调用fork()函数,创建一个子进程,与父进程shell完全相同( 只读/共享),包括只读代码段、可读写数据段、堆以及用户栈等。
    Step4: 调用execve()函数,在当前进程(新创建的子进程)的上下文中加载并运行hello程序。将hello中的.text节、.data节、.bss节等内容加载到当前进程的虚拟地址空间(仅修改当前进程上下文中关于存储映像的一些数据结构,不从磁盘拷贝代码、数据等内容)
    Step5:调用hello程序的main()函数,hello程序开始在一个进程的上下文中运行。int main(int argc, char *argv[], char *envp[]);

    12.3 共享库和动态链接

    1. 动态链接的共享库(Shared Libraries)

    静态库有一些缺点:
     – 库函数(如printf)被包含在每个运行进程的代码段中,对于并发运行上百个进程的系统,造成极大的主存资源浪费
     – 库函数(如printf)被合并在可执行目标中,磁盘上存放着数千个可执行文件,造成磁盘空间的极大浪费
     – 程序员需关注是否有函数库的新版本出现,并须定期下载、重新编译和链接,更新困难、使用不便
    解决方案: Shared Libraries (共享库)

    (1)共享库

    ① 是一个目标文件,包含有代码和数据
    ② 从程序中分离出来,磁盘和内存中都只有一个备份
    ③ 可以动态地在装入时运行时被加载并链接
    ④ Window称其为动态链接库(Dynamic Link Libraries,.dll文件)
    ⑤ Linux称其为动态共享对象(Dynamic Shared Objects,.so文件)

    (2)共享库的动态链接与优点

    动态链接可以按以下两种方式进行:
    ① 在第一次加载并运行时进行(load-time linking).
     – Linux通常由动态链接器(ld-linux.so)自动处理
     – 标准C库(libc.so) 通常按这种方式动态被链接
    ② 在已经开始运行后进行(run-time linking).
     – 在Linux中,通过调用dlopen()等接口来实现(用于分发软件包、构建高性能Web服务器等)

    共享库的优点:
    ① 在内存中只有一个备份,被所有进程共享,节省内存空间
    ② 一个共享库目标文件被所有程序共享链接,节省磁盘空间
    ③ 共享库升级时,被自动加载到内存和程序动态链接,使用方便
    ④ 共享库可分模块、独立、用不同编程语言进行开发,效率高
    ⑤ 第三方开发的共享库可作为程序插件,使程序功能易于扩展

    (3) 自定义一个动态共享库文件

    自定义库函数

    	//myproc1.c
    	#include <stdio.h>
    	void myfunc1() 
    	{  
    		printf("%s","This is myfunc1!\n"); 
    	} 
    	
    	//myproc2.c
    	#include <stdio.h>
    	void myfunc2() 
    	{  
    		printf("%s","This is myfunc2\n"); 
    	} 
    

    生成库文件

    $gcc -c myproc1.c myproc2.c  //预处理、编译、汇编
    $gcc -shared -fPIC -o mylib.so myproc1.o myproc2.o //生成位置无关的共享代码库文件mylib.so
    

    2. 动态链接

    (1)加载时的动态链接

    在这里插入图片描述
    在这里插入图片描述

    (2)运行时的动态链接

      可通过动态链接器接口提供的函数在运行时进行动态链接。类UNIX系统中的动 态链接器接口定义了相应的函数,如 dlopen, dlsym, dlerror, dlclose等, 其头文件为dlfcn.h。

    	#include <stdio.h> 
    	#include <dlfcn.h> 
    	int main() 
    	{ 
    		void *handle; 
    		void (*myfunc1)(); 
    		char *error; 
    		/* 动态装入包含函数myfunc1()的共享库文件*/ 
    		handle = dlopen("./mylib.so", RTLD_LAZY); 
    		if (!handle) { 
    			fprintf(stderr, "%s\n", dlerror()); 
    			exit(1);
    		} 
    		/* 获得一个指向函数myfunc1()的指针myfunc1*/ 
    		myfunc1 = dlsym(handle, "myfunc1"); 
    		if ((error = dlerror()) != NULL) { 
    			fprintf(stderr, "%s\n", error); 
    			exit(1);
    		} 
    		/* 现在可以像调用其他函数一样调用函数myfunc1() */ 
    		myfunc1(); 
    		/* 关闭(卸载)共享库文件*/ 
    		if (dlclose(handle)< 0) { 
    			fprintf(stderr, "%s\n", dlerror()); 
    			exit(1);
    		} 
    		return 0;
    	}
    

    3. 位置无关代码(PIC)

    动态链接用到一个重要概念:
     – 位置无关代码(Position-Independent Code,PIC )
     – GCC选项 -fPIC 指示生成PIC代码
    共享库代码是一种PIC
     – 共享库代码的位置可以是不确定
     – 即使共享库代码的长度发生变化,也不影响调用它的程序
    引入PIC的目的
     – 链接器无需修改代码即可将共享库加载到任意地址运行
    所有引用情况
    (1) 模块内的过程调用、跳转,采用PC相对偏移寻址
    (2) 模块内数据访问,如模块内的全局变量和静态变量
    (3) 模块外的过程调用、跳转
    (4) 模块外的数据访问,如外部变量的访问
    要实现动态链接, 必须生成PIC代码 ;
    要生成PIC代码,主要解决(3)(4)两个问题

    ① 模块内的过程调用、跳转

    在这里插入图片描述

    ② 模块内数据访问

    在这里插入图片描述

    ③ 模块外的数据访问

    在这里插入图片描述

    ④ 模块外的过程调用、跳转

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • plt和got引入延迟重定位机制之后,方案复杂度就更高了。为了让大家对延迟机制有深入的理解,将Linux方案写成C语言伪代码。
  • 重定位链接

    千次阅读 2016-07-10 11:32:44
    链接重定位是嵌入式C中很重要的部分,对于这一块掌握的越精细越好。 指令位置分类 指令分为两种: 位置无关编码(PIC):汇编源文件被编码成二进制可执行程序时编码方式与位置(内存地址)无关 位置相关编码:...
  • 链接二( 重定位)

    2020-05-16 11:47:45
    链接二( 重定位&&动态链接) 1.重定位过程 可重定位文件 = 用到.o文件的集合E+定义符号的集合D 将E中所有目标模块中相同的节合并: 对D中定义的符号重定位(确定新节中所有定义符号在虚拟地址空间中的...
  • 重定位

    千次阅读 2017-08-29 11:27:50
    扫描完成后的下一步就是链接过程的核心,重定位。由于重定位过程的两个步骤,判断程序地址计算最初的非空段,和解析外部符号的引用,是依次、共同处理的,所以我们讲重定位即同时涉及这两个过程。 链接器的第一次...
  • 符号引用重定位 重定位PC相对引用 简单讲解

    千次阅读 多人点赞 2020-06-10 16:28:59
    目录链接符号引用重定位简介例子重定位条目简介offsettypesymboladdend重定位PC相对引用重定位PC绝对引用 链接符号引用重定位 简介 我们知道一个.c文件可以被编译为.o文件,即目标文件,而假如一个.c中引用了别的.c...
  • 链接时的重定位与符号解析

    千次阅读 2019-04-29 19:32:39
    任何带有static属性声明的全局变量或者函数的模块都是私有的,即都是local属性的(local属性符号链接器看不到,链接器只关注global符号) (2)伪节 每个符号都被分配到目标文件的某个节。但是有三个特殊的伪节,...
  • 地址重定位

    2021-12-01 15:41:01
    可执行文件中代码以及数据的运行时内存地址是链接器指定的,确定程序运行时地址的过程就是重定位(Relocation)。 操作系统将逻辑地址转变为物理地址的过程,也就是对目标程序中的指令和数据进行修改的过程叫重定位。 ...
  • 地址重定位:静态重定位和动态重定位

    万次阅读 多人点赞 2019-04-24 09:06:18
    地址重定位就是操作系统将逻辑地址转变为物理地址的过程。。。也就是对目标程序中的指令和数据进行修改的过程 将逻辑地址空间重定位到物理地址空间的时机有三种: 1、程序编译连接时:符号绑定,各Obj模块的相对...
  • 重定位概念:程序在装入内存时将逻辑地址转换为物理地址。 重定位分类— 静态重定位:在程序装入内存时就将逻辑地址转换为物理地址 优势:操作简单,不需要额外的机构或操作。 劣势:程序一旦装入后地址就不可...
  • elf 可重定位文件的链接器和加载器。 为 ARM 架构用 C 语言开发。 这是我教员的“系统编程”课程的一个项目。 计算机工程与信息理论系。 塞尔维亚贝尔格莱德大学电气工程学院。 由 Marin Markić 开发。 没有...
  • 重定位引入和链接脚本 在了解重定位之前,必须先区分开链接地址和运行地址,位置有关代码和位置无关代码 =============================================== 链接地址和运行地址: 链接地址:指在链接时指定的地址...
  • 什么是重定位?为什么需要重定位

    万次阅读 多人点赞 2018-06-15 17:30:15
    1、链接地址和运行地址。①运行地址,顾名思义就是程序运行的时候的地址,也就是你用工具将代码下载到RAM的那个地址,也叫加载地址。②链接地址,由链接脚本指定的地址。为什么需要链接脚本指定地址呢?你想一下,在...
  • 用户程序要在系统中运行,必须要把它装入内存,然后再将其转变成一个可执行程序。 用户程序变为可执行程序... 链接:由链接程序将编译好的若干个目标模块以及它们所需要的若干个库函数链接在一起。形成转入模块 ...
  • 上几篇文章学习了Binutils辅助工具里面的几个实用的工具,那些工具对于以后的学习都是非常有...注意:本文讲解的并不是很详细,有些关键词例如符号、重定位、段等都没有具体说。这些比较原始的知识最好先去阅读相...
  • 因为发生太多重定位

    千次阅读 2021-01-15 03:57:39
    Safari浏览器下提示打不开该网页,因为发生了太多重定位,可能是因为正尝试查看的网站所致。当网站的重定位问题解决后,Safari可能会在此后打开此网站。如果重定位信息不再需要后已进行缓存,也可能会发生此问题。...
  • 链接器解析符号引用的方法是将每个引用与它输入的可重定位目标文件的符号表中的一个确定的符号定义关联起来,即使用的符号一定要找到相应的定义。可分为局部符号解析和全局符号解析。 局部符号解析:引用定义在相同...
  • 重定位表(Relocation Table)用于在程序加载到内存中时,进行内存地址的修正。一个简单程序test.exe需要三个动态链接库dll(a.dll,b.dll,c.dll),假设test.exe的ImageBase为400000H,而a.dll、b.dll、c.dll的...
  • 程序的链接与装入(动、静态重定位)  原由: 多道程序环境下,程序是并发执行的,所以要使程序运行,必须先为之创建进程,而创建进程的第一件事就是将程序和数据装入内存 目的: 用户程序到内存可执行...
  • 什么是重定位?为什么需要重定位?(嵌入式下)

    万次阅读 多人点赞 2017-11-11 20:22:30
    1、链接地址和运行地址。①运行地址,顾名思义就是程序运行的时候的地址,也就是你用工具将代码下载到RAM的那个地址,也叫加载地址。②链接地址,由链接脚本指定的地址。为什么需要链接脚本指定地址呢?你想一下,在...
  • ELF重定位

    千次阅读 2018-09-18 16:57:13
    ELF重定位 首先重定位就是将符号定义和符号引用进行连接的过程。可重定位文件需要包含...重定位实际上时一种给二进制文件打补丁的机制,如果使用了动态链接器,可以使用重定位在内存中打热补丁。用于创建可执行...
  • ARM之重定位链接脚本

    千次阅读 2018-05-14 16:52:42
    一、重定位 1、静态重定位:静态重定位是在程序执行之前进行重定位,它根据装配模块将要装入的内存起始 位置,直接修改装配模块的有关使用地址的指令。 2、动态重定位:动态重定位是指,不是在程序执行之前而是在...
  • 代码重定位解析

    千次阅读 2018-07-15 18:04:59
    (或者是重定位地址,或者链接地址) ( 2 )对于 bin 文件 首先将 elf 文件转换成 bin 文件 , 硬件机制的启动(没有加载器) , 如果 bin 文件所在位置不等于 runtime addr ,程序本身实现重定位 。 但是,我们...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 121,109
精华内容 48,443
关键字:

链接重定位