精华内容
下载资源
问答
  • 可重定位
    千次阅读
    2019-08-14 15:59:37

    可重定位代码 是什么意思呢?
    顾名思义,可重定位 就是 可以重新定位  的意思。
    我们都知道,在写代码时,代码里的各种跳转代码/指令,比如C语言里的goto,汇编里的jmp、jz等等,它们都是跳到某一地址,然后在该地址继续往下执行代码 的意思,我们写的代码时用的内存空间是逻辑空间,但是代码在实际运行时,用到的却是货真价实的物理地址空间。

    既然如此,那么在程序编译时,就需要有一个从  逻辑地址空间到   物理地址空间  的映射,如果这个映射做得不好,那么就会影响代码的正确执行。

    打个比方,下面有一段代码:
        AAAA;(假设这里是代码的起始地址0)


        ...        (中间经略过了187个地址)


        XXXX;(假设这一行的逻辑地址是188)
    circle:
       YYYY;(那么这一行就应该是189)
       ZZZZ;(190)
       MMM;(191)

    goto circle;(又跳到circle,也就是地址为189那里)


    因为操作系统给进程分配的内存的起始位置是无法确定的,换句话说,也就是程序 在运行时实际的物理起始位置是不确定,所以不能在编译时就把地址给写死,否则,如果实际运行时物理空间起始位置与编译时写死的起始地址  不一致的话,程序就会出问题。

    举个栗子,就拿上面的代码来讲,假设编译时,按照起始地址为0,给每一行代码都定死了地址(地址为右边括号里的数字),然而在实际运行这段程序时,系统可能给这个进程分配的 物理地址 起始地址为 2000,那么当代码执行到 goto circle;这一句时,本应该跳到的地址为2189,但是因为编译时已经把调转地址给写死了,实际却跳到地址189,至于这个189是哪一个进程的什么代码我们不知道,但可以肯定得是,这已经跳出了自己的物理空间,跳到别人的物理空间执行别人的代码去了,毫无疑问这样会出问题的。

    为了解决这个问题,科学家们就把心思放在编译这一步骤上。

    如果我们编译时,涉及  地址跳转,某个地址对应信息的读取、写入   等等之类与地址有关的操作,代码里所有地址都采用动态调整的方式,也就是可以根据操作系统实际给进程分配的  实际物理内存 的起始位置 ,而进行调整的话,那么代码就不会出错啦。

    同样拿上面的例子来说,假设运行该代码时,系统给这个进程分配的 物理地址 起始位置为 2000,而代码自动根据这个起始位置调整自己的地址,那么代码实际上是:
        AAAA;(假设这里是代码的起始地址2000)


        ...        (中间经略过了187个地址)


        XXXX;(假设这一行的逻辑地址是2188)
    circle:
       YYYY;(那么这一行就应该是2189)
       ZZZZ;(2190)
       MMM;(2191)

    goto circle;(又跳到circle,也就是2189那里)


    这样的话,代码的执行就不会出错啦。

    这种可以使地址平移的代码就叫做可重定位代码,它是在加载的时候,也就是系统给进程确定了物理地址时,才生成绝对地址的。

    重定位是由操作系统安排的。在装入程序前,系统会计算未使用的内存,然后将程序装入,并记下开始地址。在执行有相对地址的指令时,会将所有的地址加个刚才记下的开始地址,就叫重定位。它是实现多道程序在内存中同时运行的基础。

    实际上使得代码可重定位方式有两种,分别是动态重定位与静态重定位。
    1、静态重定位:即在程序装入内存的过程中完成,是指在程序开始运行前,程序中的各个地址有关的项均已完成重定位,地址变换通常是在装入时一次完成的,以后不再改变,故成为静态重定位。
    2、动态重定位:它不是在程序装入内存时完成的,而是CPU每次访问内存时 由动态地址变换机构(硬件)自动进行把相对地址转换为绝对地址。动态重定位需要软件和硬件相互配合完成。

    这里不讲述第2种,能理解第1种就可以啦。

    更多相关内容
  • 移动某些已分配区的内容,使所有进程的分区紧凑在一起,而把...采用紧凑技术的变分区法称为动态可重定位分区法。该论文为学校学期期末小论文,格式并非标准论文格式。部分资源来源于网络,若有侵权请联系作者删除!
  • 简单了解可重定位目标文件

    千次阅读 2019-10-01 23:04:42
    在介绍可重定位目标文件之前我们首先要了解一下什么是目标文件分哪几种。 1.可重定位目标文件 包含二进制代码和数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个执行目标文件。 2.执行目标...

    一.目标文件分类
    在介绍可重定位目标文件之前我们首先要了解一下什么是目标文件分哪几种。
    1.可重定位目标文件
    包含二进制代码和数据,其形式可以在编译时与其他可重定位目标文件合并起来,创建一个可执行目标文件。
    2.可执行目标文件
    包含二进制代码和数据,其形式可以被直接复制到内存并执行。
    3.共享目标文件
    一种特殊类型的可重定位目标文件,可以在加载或者运行时被动态的加载进内存并链接。
    二.如何生成可重定位目标文件
    使用gcc -c test.c
    test.c中的内容:

    #include <stdio.h>
    int main(){
    	printf("hello world");
    	return 0;
    }
    

    gcc命令:
    在这里插入图片描述
    这时文件夹中就会产生一个test.o文件如图:
    在这里插入图片描述
    这个文件就是可重定向的目标文件。
    三解读可重定向目标文件
    1.ELF头

    ELF头含义
    .test已编译程序的机器代码
    .rodata只读数据
    .data已初始化的全局变量和静态c变量
    .bss未初始化的全局和静态c变量
    .symtab一个符号表,它存放在程序中定义和引用的函数和全局变量信息
    .rel.text一个.text节中的位置的列表
    .rel.data被模块引用或定义的所有变量的重定位信息
    .debug一个调试符号表
    .line原始c源程序中的行号和.text节洪机器指令之间的映射
    .strtab一个字符串表

    2.使用readelf -S查看test.o(显示节区表内的所有信息,包括每个节的属性)
    在这里插入图片描述
    3.使用readelf -h查看test.o(显示在ELF文件头里包含的所有信息)
    在这里插入图片描述
    4.使用readelf -s查看test.o(显示符号表的信息,包含静态符号表(.symtab)和动态符号表(.dynsym))
    在这里插入图片描述

    展开全文
  • ELF可重定位目标文件南京大学计算机科学与技术系袁春风回顾:链接视图—可重定位目标文件被链接(合并)生成执行文件或共享目标文件静态链接库文件由若干个可重定位
  • 文章目录计算机原理系列之四 -------- 可重定位文件详解一、生成中间文件二、可重定位文件分析2.1 解析文件头,说明文件构成2.2 分析ELF文件各部分2.2.1 ELF header 上篇文章我们从整体上介绍了从C文件到执行文件...

    欢迎访问我的个人博客: luomuxiaoxiao.com



    上篇文章我们从整体上介绍了从C文件到可执行文件的编译过程,并逐个分析了单步编译时生成的中间文件的类型。为了搞清楚编译和链接过程中主要做了哪些工作, 我们应该首先明白编译前后,链接前后文件内容的改变。根据上篇文章内容, 编译前的文件格式是汇编文件,编译后的文件是可重定位文件。汇编文件就是简单的文本文件,而可重定位文件是一个ELF格式的二进制文件。因此,本章我们将从ELF文件格式入手分析 可重定位文件的结构。

    下面我们以C语言中经典的“hello, world”的产生的可重定位文件为例来说明。使用的环境如下:

    • ubuntu 64位操作系统
    • gcc作为编译工具(版本信息:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10))

    一、生成中间文件

    我们依然使用计算机原理系列之三 -------- 如何编译目标文件中的hello.c文件来研究,使用下列命令生成hello.o:

    gcc -E hello.c -o hello.i
    gcc -S hello.i -o hello.s
    gcc -c hello.s -o hello.o
    

    二、可重定位文件分析

    2.1 解析文件头,说明文件构成

    由于可重定位文件类型是ELF格式(关于ELF文件的知识,请阅读详解ELF文件),我们可以使用READELF命令查看其构成。

    $ readelf -h hello.o
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              REL (Relocatable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x0
      Start of program headers:          0 (bytes into file)
      Start of section headers:          672 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           0 (bytes)
      Number of program headers:         0
      Size of section headers:           64 (bytes)
      Number of section headers:         13
      Section header string table index: 10
    

    其中,我们关注以下字段:

    1. Type: REL (Relocatable file) : 可以看出.o文件的类型为可重定位文件
    2. Number of program headers: 0:可以看出可重定位文件program header table的长度为0。这是因为program header table保存的是segment信息,而segment是为了给加载器提供可执行程序在加载时所需的信息的,又因为可重定位文件本身并不能直接执行,因此在可重定位文件里不需要program header table
    3. Entry point address: 0x0: 同上,由于可重定位文件不能直接执行,因此其入口地址为0(默认值);
    4. *** of section headers:***:从ELF文件起始地址偏移672个字节处是section header table的起始地址,section header table中共有13项,每项的大小为64 byte
    5. Size of this header: 64: ELF文件头大小为64 byte

    2.2 分析ELF文件各部分

    可重定位文件属于二进制文件。在linux机器上,可以使用hexdump命令来查看二进制文件的内容。

    $ hexdump -C hello.o
    00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
    00000010  01 00 3e 00 01 00 00 00  00 00 00 00 00 00 00 00  |..>.............|
    00000020  00 00 00 00 00 00 00 00  a0 02 00 00 00 00 00 00  |................|
    00000030  00 00 00 00 40 00 00 00  00 00 40 00 0d 00 0a 00  |....@.....@.....|
    00000040  55 48 89 e5 bf 00 00 00  00 e8 00 00 00 00 b8 00  |UH..............|
    00000050  00 00 00 5d c3 68 65 6c  6c 6f 2c 20 77 6f 72 6c  |...].hello, worl|
    
    ... snip ...
    

    这实际上就是hello.o文件的实际内容。

    注:

    • 最前面一列是hexdump命令添加的,并非ELF文件的内容。它是一个十六进制的数字,表示字节序号。例如,00000040 55 48 89 e5 bf 00 00 00 00 e8 00 00 00 00 b8 00,其中00000400x40,十进制为64。表示hello.o文件的第64个字节是‘55’
    • 最后一部分由两个‘|’包含的数字和字符也是hexdump命令添加的,它将其左侧的十六进制数字转化成了对应的ASCII字符,所有的控制字符表示为‘.’,所有的可显示字符表示为对应的字符或图形。

    2.2.1 ELF header

    根据ELF文件的结构,ELF文件最开始的部分是ELF header,它是一个64字节大小的结构体,也就是对应了hello.o的前64个字符,即从0000000 - 00000040的部分。前十六个字节应该是对应其magic number的部分。我们注意到,从0000000 - 0000000F正好就是使用readelf读出来的magic的值。剩下的部分只要结合struct ElfN_Ehdr的成员信息和hexdump命令输出的内容即可一一验证。

    请点击此处继续阅读


    想第一时间查看我的文章吗?请关注我的微信公众号号,搜索“落木萧萧技术论坛”或登陆我的个人博客:www.luomuxiaoxiao.com,更多精彩文章等你。

    qrcode
    展开全文
  • LDE64(可重定位) 执照 LGPL v3 关于 该工具是用于Intel 64处理器的LDE(长度分解器引擎)。 它基于BeaEngine,能够解码32位和64位体系结构中的指令。 它是可重定位的引擎。 这是在上的原始LDE64的源代码。 它已...
  • 当进程在CPU上运行时,如指令中涉及逻辑地址时,操作系统自动根据页长得到页号和页内偏移,把页内偏移拷贝到物理地址寄存器,再根据页号,查页表,得到该页在内存中的块号,把块号左移页长的位数,写到物理地址...
  • 上几篇文章学习了Binutils辅助工具里面的几个实用的工具,那些工具对于以后的学习都是非常有...注意:本文讲解的并不是很详细,有些关键词例如符号、重定位、段等都没有具体说。这些比较原始的知识最好先去阅读相...

    上几篇文章学习了Binutils辅助工具里面的几个实用的工具,那些工具对于以后的学习都是非常有帮助的,尤其是C语、C++语言的学习以及调试是非常有帮助的。点击链接查看上一篇文章:点击查看

    本篇文章开始一个新的知识的学习,链接器的学习。学习完链接器的系列文章,我们将全面了解链接器的工作原理。

    注意:本文讲解的并不是很详细,有些关键词例如符号、重定位、段等都没有具体说。这些比较原始的知识最好先去阅读相关书籍,进行补充。本文只是通过实验来理解链接器的作用!!!

    1、可重定位文件与可执行文件

    我们都知道,源程序在经过gcc编译器编译后,实际上是经过四个步骤—预处理,编译,汇编,链接。最终得到一个可执行程序。这个可执行程序最终将会被操作系统的加载器加载带内存中去执行。

    在经过汇编之后,生成的文件是可重定位文件,然后可重定位文件经过链接器的链接,最终生成可执行文件。 今天我们就是来学习这个链接器的。

    那么可重定位文件是一个什么样的文件?为什么它不能执行?

    经过汇编后的文件是可重定位文件。它的文件格式与可执行文件很像(对于Linux,都是elf文件格式)。对于可重定位文件,它里面的代码与数据,都是各个文件独立的代码与数据,在一个工程中,会存在多个C文件,每个C文件都会被首先编译生成一个可重定位文件,然后经过链接器将这些可重定位文件进行链接,从而生成最终的可执行文件。

    对于可重定位文件:

    • 各个段没有具体的起始地址,只要段大小信息
    • 各个标识符没有实际地址,只有在段中的偏移地址(相对地址)
    • 段和标识符的实际地址都需要链接器具体制定,这也是链接器的主要作用

    对于可执行文件:

    • 各个段有自己的起始地址,这些地址就是将来要被加载到内存中的地址(虚拟内存),有了起始地址,才能说加载到内存,不然都不知道加载到哪里,何来的执行呢?这就是可执行文件与可重定位文件一个区别
    • 可执行文件中的各个符号,都有了正确的地址,以及符号被引用的地方也正确填上了符号的地址

    以上内容,说的很简单,如果不懂,参考《程序员的自我修养》与《深入理解计算机系统》第7章

    2、通过代码分析,具体了解链接器的作用

    链接器的作用简单的说就是:

    • 符号解析
    • 重定位

    下面我们以具体的程序例子来说明:

    test.c

    #include <stdio.h>
    
    int g_global = 0;
    int g_test = 1;
    
    extern int* g_pointer;
    extern void func();
    
    int main(int argc, char *argv[])
    {
        printf("&g_global = %p\n", &g_global);
        printf("&g_test = %p\n", &g_test);
        printf("&g_pointer = %p\n", &g_pointer);
        printf("g_pointer = %p\n", g_pointer);
        printf("&func = %p\n", &func);
        printf("&main = %p\n", &main);
        
        func();
    	
        return 0;
    }
    

    func.c

    #include <stdio.h>
    
    int* g_pointer;
    
    void func()
    {
        g_pointer = (int*)"D.T.Software";
    
        return;
    }
    

    对上述两个源程序进行编译生成两个可重定位文件:

    • gcc -c func.c -o func.o
    • gcc -c test.c -o test.o

    生成了可可重定位文件func.o与test.o

    1. 我们使用上几篇文章的学习的Binutils辅助工具来查看这两个可重定位文件的符号信息:
    • nm func.o
      在这里插入图片描述

    • nm test.o
      在这里插入图片描述

    可以看到,在test.o与func.o中,各个符号的地址都是0,而且有的符号还是未定义的。地址为0是因为,在没有链接之前,各个可重定位文件是独立的,他们无法加载到内存中去执行,各个符号还没有进行重定位。而又的符号未定义是因为该文件中引用了外部文件的代码或者数据。比如上述代码test.c程序中引用了func.c程序中的g_pointer变量与func()函数,那么在test.c程序中他们就是未定义的,需要将test.o与func.o链接,才能使整个程序是完整的。

    1. 还可以查看他们的段信息
    • objdump -h test.o
      在这里插入图片描述

    • objdump -h func.o
      在这里插入图片描述

    可以看到,各个段的地址都是0(VMA与LMA),所以这种可重定位文件是不可执行的,它连加载地址都没有怎么执行???

    最后我们将上述两个可重定位文件进行链接生成可执行文件,看看可执行文件里面是什么样子的?

    • gcc func.o test.o -o lyy

    生成了可执行文件lyy

    运行可执行文件:

    • ./lyy
      在这里插入图片描述
    1. 现在查看可执行文件lyy的符号信息
    • nm lyy
      在这里插入图片描述

    看到画红框的地方,是我们程序中有的,左边的地址都是各个符号的地址,此时不为0了,每个符号都有自己的加载地址。其他多余不认识的符号,我们再后面的文章会进行讲解。

    1. 查看可执行文件lyy的段信息,看看它与可重定位文件有什么区别
    • objdump -h lyy

    在这里插入图片描述

    以上图片显示的不全!

    可以看出,可执行文件的各个段,也都有了加载地址。那么他就可以加载到内存中进行执行了。

    上面我们没有分析符号的引用。由于分析符号的引用需要查看反汇编代码,这里反汇编代码太长了,就不贴了。直接说原理。

    实际上经过链接后,可执行文件中,对于符号的引用,已经可以将正确的符号地址填写到符号引用处(因为符号经过重定位已经有了运行时的地址,将这个地址填写到它被引用的地方即可)。当符号引用处是正确的符号地址,在运行时,引用才能够正确得到结果。

    3、链接器的意义

    从上面的实验,大致可以理解链接器的意义:

    链接器的主要作用是将各个可重定位目标模块之间的引用部分处理好,使得各个模块之间可以正确衔接。类似于下图:
    在这里插入图片描述

    链接器的工作内容:

    • 将目标文件(可重定位文件)与库文件整合成最终的可执行文件

      • 合并各个目标文件的段(.text .data .bss等)以及使得符号与付哈引用之间进行一个关联—符号解析
      • 确定各个段以及各个段中符号的最终地址—重定位

    4、总结

    上述内容,不够系统,也不够细致,只是从实验的角度来具体看可执行文件与可重定位文件,然后理解链接器到底做了什么。前提是你已经理解了一些基础的知识。如果不理解,还需要回头去看看编译链接过程中的基础知识。

    本文参考狄泰软件学院相关课程
    想学习的可以加狄泰软件学院群,
    群聊号码:199546072

    学习探讨加个人(可以免费帮忙下载CSDN资源):
    qq:1126137994
    微信:liu1126137994

    展开全文
  • ASIP处理器的可重定位编译器的设计.pdf
  • 编译原理之可重定位代码是什么意思?

    千次阅读 多人点赞 2018-01-01 11:45:57
    可重定位代码 是什么意思呢? 顾名思义,可重定位 就是 可以重新定位。 我们都知道,我们在写代码的时候,代码里的各种跳转代码/指令,比如C里的goto,汇编里的jmp、jz等等,它们都是跳转到某一地址,然后在该地址往...
  • 动态分区分配及可重定位分区分配

    千次阅读 2020-03-23 22:40:39
    动态分区分配及可重定位分区分配 分区大小不固定 分区分配的数据结构 二维表格(连续存储结构) 空闲分区表记录空闲分区的大小,位置和状态 已分配区表记录已占用分区的大小,位置和状态 双向循环链表(离散...
  • 基于可重定位分区分配算法的内存管理的设计实现分析.doc
  • 基于可重定位分区分配算法的内存管理的设计与实现.doc
  • 基于-可重定位分区分配算法的内存管理的设计分析实现.doc
  • 可重定位目标文件

    2018-02-06 00:38:19
    目标文件有三种形式: ...可重定位目标文件:包含二进制代码和数据,可以在编译时与其他可重定位目标文件合并起来,创建一个执行目标文件。 重定目标文件格式: 注意: bss段 在目标文件中不占实...
  • R3:优化可重定位代码以在网络嵌入式系统中进行有效的重新编程
  • 这一篇博客与前一篇博客内容连续,这一篇博客主要讨论可重定位分区分配与进程对换的相关知识,也是以理解概念为主要任务。多看几遍,就能搞懂。 动态重定位的引入 在连续分配方式中,必须把一个系统或用户程序...
  • ↵ 1.gcc组成 ...gcc hello.c -o hello 把hello.c编译成一个执行程序 如果gcc hello.c 不指定输出名,生成一个a.out文件。 可以通过./hello或者./a.out来运行程序 2.gcc编译步骤(包括预处理...
  • ELF可重定位目标文件的格式

    千次阅读 2018-07-08 19:23:28
    一个典型的ELF可重定位目标文件的格式如图1:图1 典型的ELF可重定位目标文件图2 执行文件的存储器映像ELF头以一个16字节的序列开始,描述了生成该文件的系统的字的大小和字节顺序。ELF头剩下的部分包含帮助连接器...
  • 连续分配方式 -- 可重定位分区分配

    万次阅读 2016-06-18 15:21:17
    ----- 可重定位分区分配 1、动态重定位的引入 在连续分配方式中,必须把一个系统或用户程序装入一连续的内存空间。如果在系统中只有若干个小的分区,即使 它们的容量总和大于要装入的程序,但由于这些分区不相邻接,...
  • 编译链接中的-可重定位目标文件

    千次阅读 2016-07-09 10:25:34
    可重定位目标文件理解: 资料一: 汇编器所产生的目标文件至少包括三个区,即文本区(text),数据区(data)和bss区。文本区一般包括程序的代码和常量,数据区通常存放全局变量等内容,bss区用于存放未初始化的变量或...
  • 重定位

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

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

    千次阅读 2017-08-30 17:40:51
    可重定位对象模块格式(OMF)是主要用于在Intel 80x86微处理器上运行的软件的目标文件格式。 它最初由Intel开发,名称为对象模块格式,也可能是DOS用户最了解的.OBJ文件。 它已经被工具界面标准委员会标准化了。 ...
  • 重定位寄存器

    2022-01-19 20:25:12
    来源《操作系统原理》
  • 重定位表修改办法.rar

    2021-06-09 16:34:42
    1.重定位表的修改方法,而不是修改入口点函数,根据相对地址偏移的方法。 2:重定位表的内容: 第[0001]项 数据项的数据为:[0006] 数据属性为:[3] RVA的地址为:[00001006] 重定位的数据:[68264000]; RVA里面的地址...
  • 重定位表1

    2022-08-03 20:20:52
    重定位项的高4位表示重定位的类型,如下图而低12位表示相对于 VirtualAddress 的偏移量,故需要重定位的地址的 RVA = VirtualAddre
  • 可重定位装入方式

    千次阅读 2011-08-22 16:58:43
    可重定位装入方式 程序装入内存时要把程序里表示地址的数据加上一个基值(程序装入地址),是多道系统的产物,单道程序直接装入内存0地址就好了 可重定位内存方式 分配内存时把内存中多个程序段紧凑在一起,避免...
  • 通过readelf工具解析ELF可重定位目标文件创建可重定位目标文件(main.o)ELF可重定位目标文件结构查看ELF头信息 创建可重定位目标文件(main.o) //main.c int sum(int *a,int n); int array[2]={1,2}; int ...
  • PE重定位练习

    2018-10-07 15:37:17
    该文件包含一个dll和PEview,和文章中的截图对应,方便大家更好的理解PE重定位原理

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 333,405
精华内容 133,362
关键字:

可重定位