【软件开发底层知识修炼】十一 链接器-链接脚本

上一篇文章学习了链接器之-main函数不是第一个执行的函数:main函数不是第一个执行的函数

今天继续学习链接器,学习链接是如何动作的,从而引入链接脚本的概念。本文就学习链接脚本的概念。

1、链接脚本的作用

我们都知道可重定位文件经过链接器链接后最终形成可执行文件。这个链接的过程大概就是分为符号解析和重定位。

那么链接器到底是如何工作的呢?这取决于链接脚本。我们可以看下图:

在这里插入图片描述

几个可重定位文件与相应的库文件进行链接,链接器经过链接器的指导,最终形成可执行程序。

在学习链接链接脚本的大致格式之前,先练总结一下链接脚本的几个作用(实际上这些作用我们都知道,只不过今天才知道链接脚本的存在而已):

  • 链接脚本用于描述链接器处理目标文件(可重定位文件)与库文件的方式

    1. 合并各个目标文件中的段
    2. 重定位各个段的起始地址
    3. 重定位各个符号的最终地址(这个地址实际上是段内偏移地址)

2、链接脚本的格式

链接脚本也就是一个脚本文件,语法比较简单,下面我们直接看一个例子,来说明一个链接脚本大致有哪些内容:

在这里插入图片描述

上述的的描述还是很全面很仔细的。我们主要注意一下几点:

  • 各个段的链接地址必须符合具体平台的规则,比如在Intel处理器上与在Amd处理器上,或许各个段在整个地址空间的位置就会有一些差别
  • 链接脚本中能够直接定义标识符并制定存储地址
  • 链接脚本能够直接定义源代码(需要编译的.c .c++程序)中的标识符的地址
  • 我们主要学习Linux系统,在Linux中代码段(.text段的地址范围为[0x08048000,0x08049000])

我们现在可能还不理解上面的几条注意事项,但是经过下面的例子,就一定可以理解了:

我们写了如下的C程序与链接脚本:

8-1.c

#include <stdio.h>int s1;
extern int s2;int main()
{printf("&s1 = %p\n", &s1);printf("&s2 = %p\n", &s2);return 0;
}

8-1.lds

SECTIONS
{.text 0x08048400:{*(.text)}. = 0x01000000;s1 = .;. += 4;s2 = .;.data 0x0804a800:{*(.data)}.bss :{*(.bss)}
}

我们看上面的程序,在C程序中有一个extern int s2; 这个s2不是这个C文件的,是外部文件的,很明显,我们只有两个文件,另一个就是我们指定的链接脚本文件。

使用下述命令进行编译:

  • gcc 8-1.c 8-1.lds -o lyy

生成可执行程序lyy (注意如果编译的时候不加上我们自己定义的链接脚本,编译就会出错)

运行:

  • ./lyy

执行结果为:
在这里插入图片描述

很明显,s1的地址由于我们再链接脚本中指定了:

    . = 0x01000000;s1 = .;

所以s1的地址是:0x01000000;

而由于在链接脚本中有如下的两句话:

   . += 4;s2 = .;

所以s2的地址为:0x01000004;

如果我们不使用链接脚本指定这两个变量的地址,那么他们的地址就是随机的,这也符合我们平时的结果。

3、借助链接脚本修改程序的入口函数

不知道是否还记得在上一篇文章中:点击查看。我们学习了程序的执行流程,知道了main函数并不是真正的第一个开始执行的函数。而且我们有办法在编译程序的时候改变第一个执行的程序。那个时候使用的是在编译的时候指定入口函数的地址,就像下面这样:

  • gcc -e program -nostartfiles program.c -o program

今天我们来学习另一种方法,来修改程序的入口函数。

那就是在链接脚本中指定,大概格式如下:

在这里插入图片描述

下面给出一个例子,这个例子中没有main函数,我们自己指定一个函数,然后将它设为入口函数:

8-2.c

#include <stdio.h>
#include <stdlib.h>int program()
{printf("D.T.Software\n");exit(0);
}

8-2.lds

ENTRY(program)SECTIONS
{.text 0x08048400:{*(.text)}
}

使用下面命令进行编译(也可以先编译输出目标文件,然后进行链接,下面的命令直接一步完成而已):

  • gcc -nostartfiles 8-2.c 8-2.lds -o lyy2

没有报错,生成了可执行文件lyy2

运行程序结果为:

在这里插入图片描述

很明显,我们利用这个方法成功修改了这个C程序的入口函数。

为了更加深入,我们可以看看该可执行程序的符号信息:

使用以下命令查看可执行程序lyy2

  • nm lyy2

在这里插入图片描述

由于上面的8-2.lds链接脚本指定代码段其实地址为: 0x08048400,而我们的可执行程序的入口函数(program函数)的地址其实就是代码段(.text)地址,所以如上图,T代表代码段,地址为0x08048400。很完美的解释。

4 、 默认的链接脚本

上面我们学习了链接脚本的各种知识,但是我们平时并没有使用它或者看到它。但是这并不意味着学习它就没有用处。它对于我们理解整个系统原理有很大帮助。

可以使用下面的命令查看默认的链接脚本:

  • ld --verbose > defaults.lds

上述命令将默认的链接脚本输出到文件defaults.lds文件中,我们可以打开defaults.lds文件来查看默认链接脚本文件。

5、总结

记住,我们在学习的内容是可以让你走的更远,走的更高的铺垫。或许对你产生不了直接的影响,但是绝对会对你将来的学习之路产生深远的影响。不要一口吃一个胖子,慢慢来,从应用软件做起,深入学习底层原理!你的未来一定更加美好!!!

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

as3 physaxe 2d 物理引擎

http://drawlogic.com/2008/04/06/physaxe-2d-flash-physics-kit-for-haxe-and-list-of-flash-flex-actionscript-physics-engines-for-as3/转载于:https://www.cnblogs.com/vilyLei/archive/2010/11/30/1892298.html

前端学习(178):表格元素

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/ html4/strict.dtd"> <html><head><meta http-equiv"content-type" content"text/html; charsetutf-8"><title>表格</ti…

java后端分享整理

java规范总结1. Java 常见的代码规范1.1. Java 自带的工具方法1.1.1 比较两个对象是否相等1.1.2 apache commons工具类库1.1.2.1 字符串判空1.1.2.3 重复拼接字符串1.1.2.4 格式化日期1.1.2.4 包装临时对象 &#xff08;不是特别常用&#xff09;1.1.3 common-beanutils 操作对…

【OS学习笔记】十八 保护模式五:保户模式下如何进行内存保护 与 别名段的意义与作用 对应汇编代码

本片文章是上一篇文章&#xff1a;点击查看对应的汇编代码。可以学习上一篇文章后再来对照查看汇编代码。或者查阅书籍《X86汇编语言-从实模式到保护模式》点击下载第12章内容来学习。 ;代码清单12-1;文件名&#xff1a;c12_mbr.asm;文件说明&#xff1a;硬盘主引导扇区代码 ;设…

SharePoint要在master page中动态显示List数据的几种方式

我们都知道&#xff0c;在SharePoint中&#xff0c;Content page继承自Page layout&#xff0c;而Page layout又继承自Master page。Master page的作用大家都知道&#xff0c;它定义了站点的的整体外观和公共元素&#xff0c;因此有了很强的页面重用性和很好的页面编辑体验&…

前端学习(179):表单元素

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/ html4/strict.dtd"> <html><head><meta http-equiv"content-type" content"text/html; charsetutf-8"><title>表单</ti…

【软件开发底层知识修炼】十二 C/C++语言中内嵌汇编语言(asm)

上一篇文章学习了链接脚本的语法与相关概念&#xff1a;链接脚本的概念 在继续学习链接器的内容的同时&#xff0c;先学习一个新内容&#xff1a;内嵌汇编。 GCC编译器一般支持C/C内嵌汇编语言&#xff0c;这样可以实现语言本身无法实现的内容。我们本文主要介绍C语言中的内嵌…

并发编程总结

并发编程总结 1. ThreadLocal 每个线程复制一份2.volatile 解决内存可见性问题1. ThreadLocal 每个线程复制一份 package work.thread;/*** * @date 18/6/2019 11:59* @description:*/public class ThreadLocalDemo2 {// 每个线程的第几次操作private static ThreadLocal

【OS学习笔记】十九 保护模式六:保户模式下操作系统内核如何加载用户程序并运行

上一篇文章学习了保户模式下如何进行内存保护 与 别名段的意义与作用&#xff1a;点击链接查看上一篇文章&#xff1a;点击链接 本文接着学习&#xff0c;在保护模式下&#xff0c;内核是如何加载用户程序并运行的。其实这与在实模式下很像&#xff0c;只不过现在保护迷失多了…

数据思维整理

数据思维整理分享

常用的LaTeX公式用法

常用的LaTeX公式用法常用的latex公式用法常用的latex公式用法 加法 效果 减法 - 效果 − 乘法&#xff08;叉乘&#xff09; \times 例子: aba \times bab 效果 ab 乘法&#xff08;点乘&#xff09; \cdot 例子: a⋅ba \cdot ba⋅b 效果 a⋅b 除法 \div 例子&#xff1a;$ a…

linux平台下通过mcr方式从c++程序中调用matlab函数

小细节很多,所以容易出错. 平台:linux gcc matlab2010a 1 在matlab中写好函数例如branch,调用命令 mcc -W cpplib:libbranch -T link:lib branch.m -C 注意末尾的-C,很关键用于生成ctf文件,里面有执行需要的一些配置文件 2 将libbranch.so libbranch.ctf放在同一个目录中,写c程…

【OS学习笔记】二十 保护模式六:保户模式下操作系统内核如何加载用户程序并运行 对应的汇编代码之主引导扇区程序

本汇编代码对应保户模式下操作系统内核如何加载用户程序并运行 的实际主引导扇区代码&#xff1a; 对应的内核代码在&#xff1a;内核代码对应的用户程序代码在&#xff1a;用户程序代码 ;代码清单13-1;文件名&#xff1a;c13_mbr.asm;文件说明&#xff1a;硬盘主引导扇区代码…

java实现sql语句中 准确替换某个字符串

sql语句中准确 替换某个字符串 1.java 代码实现1.java 代码实现 public static void main(String[] args) {String sqls = "select pk_marbasclass from marbasclass where 11=11 and (enablestate = 2) and ((pk_org = 0001A210000000000EO5)) and code in(123) and…

geoserver native JAI error 问题解决方法

学习geotools&#xff0c;就会用到JAI. 最好不要把jar包放到jre环境下&#xff0c;而是在使用的时候&#xff0c;引入。因为在geoserver的web-lib目录下&#xff0c;存在JAI的jar.如果版本冲突&#xff0c;还会导致geoserver无法启动。版本正确也会报错&#xff1a;could not l…

【OS学习笔记】二十一 保护模式六:保户模式下操作系统内核如何加载用户程序并运行 对应的汇编代码之内核代码

本汇编代码对应文章保户模式下操作系统内核如何加载用户程序并运行 中的实际内核代码 对应的主引导扇区代码&#xff1a;主引导扇区代码对应的用户程序代码&#xff1a;用户程序代码 ;代码清单13-2;文件名&#xff1a;c13_core.asm;文件说明&#xff1a;保护模式微型核心程序 …

windows7下iis网站的.net框架版本设置

昨天下载了 VS2010 创建了一个默认的WebApplication&#xff0c;想看看在iis中运行的情况&#xff0c;虽说用了几个月的 win7 &#xff0c;但还从没有用过IIS。首先给人的感觉是IIS变化很大&#xff0c;多出了很多东西&#xff0c;让人感到很茫然。 先建个网站试试&#xff0c;…

【OS学习笔记】二十二 保护模式六:保户模式下操作系统内核如何加载用户程序并运行 对应的汇编代码之用户程序

本汇编代码对应文章&#xff1a;保户模式下操作系统内核如何加载用户程序并运行中的实际用户程序代码。 对应的主引导扇区代码&#xff1a;主引导扇区代码对应的内核代码&#xff1a;内核代码 ;代码清单13-3;文件名&#xff1a;c13.asm;文件说明&#xff1a;用户程序 ; SECTIO…

评教有感

上个星期学校组织了对教师的评比&#xff0c;用的是坤哥和六期师哥师姐做的评教系统。自己不但参与了评教的工作&#xff0c;还去五楼值班维持秩序。在值班的过程中碰到了米老师&#xff0c;再次认识到自己的不足。学习应该是无处不在的&#xff0c;就算是值班过程中也是可以学…

【OS学习笔记】二十三 保护模式七:保护模式下任务的隔离与任务的特权级概念

上一篇文章学习了保护模式下操作系统内核如何加载程序并运行&#xff1a;点击链接查看上一篇文章 本篇文章接着上一篇文章学习保护模式下任务的隔离。 包括以下学习内容&#xff1a; 任务的全局空间和局部空间任务的TSS任务的LDT任务的特权级概念等 1、回顾 在保护模式下&…