Linux链接详解(1)中我们简单的分析了静态库的引用解析和重定位的内容, 下面我们结合实例来看一下静态链接重定位过程。

/*
* a.c
*/
int a = ;
void add(int c);
int main()
{
int c = ;
add(c);
return ; } /*
* b.c
*/
extern int a;
void add(int c)
{
a += c;
}

实例中使用了如上代码, 在a.c 中是我们的入口函数main 和定义的全局变量a,其中引用了函数add 它的定义在b.c中。在b.c中又引用了a.c中a的定义。我们先将其分别编译为目标文件反汇编可以看到如下:

 <main>:
: push %rbp
: e5 mov %rsp,%rbp
: ec sub $0x10,%rsp
: c7 fc 7b movl $0x7b,-0x4(%rbp)
f: 8b fc mov -0x4(%rbp),%eax
: c7 mov %eax,%edi
14: e8 00 00 00 00 callq 19 <main+0x19>
19: b8 00 00 00 00 mov $0x0,%eax
1e: c9 leaveq
1f: c3 retq Disassembly of section .data: <a>:
: e8 .byte 0xe8
: add (%rax),%eax # 以上是a.o 的反编译main 和data段的结果。
#
# 下面是b.c中add的反编译结果
<add>:
: push %rbp
: e5 mov %rsp,%rbp
: 7d fc mov %edi,-0x4(%rbp)
7: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # d <add+0xd>
d: 8b 45 fc mov -0x4(%rbp),%eax
: d0 add %edx,%eax
: mov %eax,0x0(%rip) # <add+0x18>
: 5d pop %rbp
: c3 retq

我们先分析一下函数的引用重定位: 首先这里可以看到a.c中add的引用,在模块a.o中 e8 00 00 00 00 callq 19 <main+0x19>   这条call指令就是调用add函数, call指令就是把下一条指令地址(CS:IP)压入栈,然后执行跳转指令,在解析引用之前是找不到add的定义入口处的 所以这里的偏移量是0. 这就是需要重定位信息的原因。a.o中add 重定位信息如下:

重定位节 '.rela.text' 位于偏移量 0x548 含有 1 个条目:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
  000a00000002 R_X86_64_PC32     0000000000000000 add - 4

这里的0x15就是代码段中需要重定位的位置   即 14: e8 00 00 00 00 callq 19 <main+0x19> 00 00 00 00 的首地址正是0x15.

我们再来看一下全局变量的引用:在模块b.o中 引用了a.o中的全局变量a, 我们可以看到b.o中add的反汇编程序 7: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # d <add+0xd> rip寄存器存放的是下一条指令的地址 这条指令的意思也就是说 取出rip+0x0地址的数据并将其放入edx寄存器,也就是找到全局变量a的值将它放到edx中。再看b.o的重定位信息

重定位节 '.rela.text' 位于偏移量 0x528 含有 2 个条目:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
  000900000002 R_X86_64_PC32     0000000000000000 a - 4

这里可以看到需要重定位的地方位于代码段的0x9 ,正是上面的偏移量的地址。

到此有了重定位信息再经过符号解析------由引用找到定义,各个段合并

最后我们看一下可执行文件a的反汇编程序:

00000000004004f0 <main>:
4004f0: push %rbp
4004f1: e5 mov %rsp,%rbp
4004f4: ec sub $0x10,%rsp
4004f8: c7 fc 7b movl $0x7b,-0x4(%rbp)
4004ff: 8b fc mov -0x4(%rbp),%eax
: c7 mov %eax,%edi
: e8 07 00 00 00 callq 400510 <add>   #400509 + 7  = 400510 跳转到此地址add执行
: b8 mov $0x0,%eax
40050e: c9 leaveq
40050f: c3 retq <add>:
: push %rbp
: e5 mov %rsp,%rbp
: 7d fc mov %edi,-0x4(%rbp)
: 8b 15 0f 0b 20 00 mov 0x200b0f(%rip),%edx # 60102c <a>   40051d + 0x200b0f = 60102c a变量的地址  取出放到edx寄存器中
40051d: 8b fc mov -0x4(%rbp),%eax
: d0 add %edx,%eax
: 0b mov %eax,0x200b04(%rip) # 60102c <a>
: 5d pop %rbp
: c3 retq
40052a: 0f 1f nopw 0x0(%rax,%rax,)

我们可以看到之前代码段中call 及mov后的偏移地址已经变为了实际可用的地址

Linux 链接详解----静态链接实例分析的更多相关文章

  1. linux内核剖析(六)Linux系统调用详解(实现机制分析)

    本文介绍了系统调用的一些实现细节.首先分析了系统调用的意义,它们与库函数和应用程序接口(API)有怎样的关系.然后,我们考察了Linux内核如何实现系统调用,以及执行系统调用的连锁反应:陷入内核,传递 ...

  2. Linux I/O 重定向详解及应用实例

    Linux I/O 重定向详解及应用实例 简解 > 输出 < 输入 >> 追加 & [> | < | >>]之前:输入输出; ls /dev & ...

  3. Linux命令详解之—pwd命令

    Linux的pwd命令也是一个非常常用的命令,本文为大家介绍下Linux中pwd命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux pwd命令用于显示工作目录. 执行pwd指 ...

  4. Linux权限详解 命令之 chmod:修改权限

    权限简介 Linux系统上对文件的权限有着严格的控制,用于如果相对某个文件执行某种操作,必须具有对应的权限方可执行成功. Linux下文件的权限类型一般包括读,写,执行.对应字母为 r.w.x. Li ...

  5. Linux 目录详解 树状目录结构图

    1.树状目录结构图 2./目录 目录 描述 / 第一层次结构的根.整个文件系统层次结构的根目录. /bin/ 需要在单用户模式可用的必要命令(可执行文件):面向所有用户,例如:cat.ls.cp,和/ ...

  6. Android应用AsyncTask处理机制详解及源码分析

    1 背景 Android异步处理机制一直都是Android的一个核心,也是应用工程师面试的一个知识点.前面我们分析了Handler异步机制原理(不了解的可以阅读我的<Android异步消息处理机 ...

  7. Java SPI机制实战详解及源码分析

    背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...

  8. [转帖]Linux文件系统详解

    Linux文件系统详解 https://www.cnblogs.com/alantu2018/p/8461749.html 贼复杂.. 从操作系统的角度详解Linux文件系统层次.文件系统分类.文件系 ...

  9. Linux 系统结构详解

    Linux 系统结构详解 Linux系统一般有4个主要部分: 内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统 ...

随机推荐

  1. Servlet 笔记-过滤器

    Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息. 可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet.Servlet 过滤 ...

  2. ASP动态网站建设之连接数据库相关操作

    连接数据库: string str = @"server=服务器名称;Integrated Security=SSPI;database=数据库名称;"; 注意封装公共类,将常用重 ...

  3. onclick事件触发 input type=“file” 上传文件

    添加按钮: <input type="button" name="button" value="浏览" onclick="j ...

  4. Android Studio常见问题解决

    1.Error:Execution failed for task ':XXXX:processDebugManifest'. > Manifest merger failed with mul ...

  5. 【机器学习实战】第 10 章 K-Means(K-均值)聚类算法

    第 10 章 K-Means(K-均值)聚类算法 K-Means 算法 聚类是一种无监督的学习, 它将相似的对象归到一个簇中, 将不相似对象归到不同簇中.相似这一概念取决于所选择的相似度计算方法.K- ...

  6. 读书笔记-你不知道的JS上-对象

    好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...

  7. Ubuntu下通过makefile生成静态库和动态库简单实例

    本文转自http://blog.csdn.net/fengbingchun/article/details/17994489 Ubuntu环境:14.04 首先创建一个test_makefile_gc ...

  8. linux-mv

    linux-mv 主要用于文件或者目录的移动或者改动, 命令参数 -i:ruguo目标文件或者目录存在,提示是否覆盖目标文件或目录 -f:无论目标文件是否存在,直接覆盖,不提示, 有好多参数,自己可以 ...

  9. WebSocket小插件

    一.WebSocket小介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...

  10. C#编写的艺术字类方法

    代码如下: using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing ...