链接的目的链接过程

1.  链接的目的

    源代码经过编译后,生成了一系列的目标文件。每一个目标文件,具有自己的代码段、数据段、符号表、重定位表等信息(参考目标文件结构介绍)。

    在代码段中,编译生成的机器代码需要访问数据段的数据,或是代码段的函数。但在单个目标文件中,只有局部的数据和代码信息。如下例:

    文件a.c:

    unsigned long a = 10;

     

    void main()

    {

        print_a();

    }

 

    文件b.c:

    #include <stdio.h>

    extern unsigned long a;

    void print_a()

    {

        printf(“%d”,a);

    }

    编译后,a.c和b.c分别生成了a.o和b.o文件。在a.o中,数据段中为a,代码段中有main;在b.o中,代码段中有print_a函数。

    a.o中,访问了b.o中的print_a函数,而b.o中访问了a.o中的数据a。但问题是每一个.o都只能知道自已的局部数据和函数的地址,因此就需要通过链接过程,对a.o和b.o中的指令(调用print_a函数及访问a数据)进行重点位。这也是静态链接的主要目的所在。

 

    2.  链接的过程

    链接主要分为两个步骤以:

    1)  空间与地址分配

        每个.o文件中都有自己的代码段和数据段,在多个文件合并后,这些指令和数据如何组织?通常是采用相似段合并的方式,将多个.o文件中的代码段合并为一个代码段,数据段合并为一个数据段。

        这样做的好处是可以空间消耗(因为操作系统在分配空间时最小单位是页),并且可以提高内存访问的命中率。

        在进行相似段合并时,链接器会根据.o中每个段的长度、属性和位置等,计算出合并后的长度与位置,然后并每一个.o的中的符号合并到全局符号表,记录每一个符号的新的位置。

 

    2)  符号解析与重定位

        这一步是链接过程中核心,链接器通过重定位表,获取到每一个需要进行重定位的指令的位置以及符号,然后通过符号表查询符号的地址,修改指令中访问的地址。

        如果在这个过程中,无法在符号表中找到需要重定位的符号,就会出现链接失败,也就是我们常见的”undefined reference to ‘xxx’”错误。

 

        在符号表中,除了全局符号外,COMMON类型的符号也需要进行重定位,又称为COMMON块。COMMON块通常用来处理弱符号。

        编译器将未初始化的全局变量定义为弱符号。当多个源代码文件中存在相同的弱符号时,链接器采用如下策略决定弱符号的大小:

        (1)    存在同名的强符号时,以强符号为准

        (2)    不存在同名强符号时,以最大的弱符号为准

 

### Linux 中软链接和硬链接的区别及用法 #### 一、基本概念 在 Linux 文件系统中,链接是一种用于访问文件的方式。链接分为两种类型:硬链接(Hard Link)和软链接(Symbolic Link 或 Symlink)。两者都提供了对文件的额外引用方式,但在实现机制上有显著差异。 #### 二、主要区别 1. **底层结构** - 硬链接共享同一个 inode 编号,因此多个硬链接实际上指向的是同一份数据区域[^2]。 - 软链接是一个独立的文件实体,其内容存储了目标文件的路径信息[^3]。 2. **跨文件系统支持** - 硬链接无法跨越不同的文件系统,因为不同文件系统的 inode 表是相互独立的[^3]。 - 软链接可以跨越文件系统边界,因为它仅依赖于路径字符串而非实际的数据块位置[^3]。 3. **行为表现** - 如果原文件被删除,硬链接仍然有效,只要还有至少一个硬链接存在,则该文件的内容不会丢失[^1]。 - 若软链接的目标文件被移除,则软链接会变成“悬空链接”,即无效状态[^4]。 4. **适用对象** - 硬链接只能应用于普通文件,不能为目录创建硬链接(除了根目录 `/` 的特殊情况外)[^2]。 - 软链接既可以关联到文件也可以关联至整个目录树结构[^3]。 5. **权限继承** - 创建新的硬链接时,默认继承原有文件的所有属性包括读写执行权限等设置。 - 对于软链接而言,它的元数据完全由自己决定而不是参照目的端的情况;不过最终打开操作还是受限于后者的真实状况[^4]。 6. **磁盘占用情况** - 新建一个硬链并不会增加任何额外空间消耗(除非考虑到了i节点本身的大小),这是因为它们共同分享着相同的数据副本。 - 构造symlinks则需分配少量字节来保存相对或者绝对地址描述符[^4]。 7. **命令形式对比** ```bash # 创建硬链接 ln source_file hard_link_name # 创建软链接 ln -s target_path symbolic_link_name ``` 8. **应用场景举例说明** - 使用场景方面,当希望保护某些关键配置免受意外修改风险的时候可以选择通过符号连接来进行隔离处理[^4]; 同样如果想要缩短复杂指令串长度的话也能够借助这种方式达成效果——只需把对应脚本放置合适的位置再建立相应快捷入口即可完成部署工作流程优化的目的[^4]. 9. **错误恢复能力分析比较** 当发生误删事件之后如果是基于物理拷贝形成的备份方案显然更可靠些;然而考虑到效率因素以及维护成本等问题,在日常运维过程中更多时候还是会倾向于采用逻辑层面的安全措施如定期巡检制度配合版本控制系统一起运作从而达到既满足业务需求又能保障资产安全性的双重功效[^4]. --- ### 总结表 | Soft Links vs Hard Links | 属性 | 硬链接 (Hard Link) | 软链接 (Soft/Symbolic Link) | |--------------------|---------------------------------------|----------------------------------------| | 数据共享 | 是 | 否 | | 可否跨分区 | 不可以 | 可以 | | 链接失效条件 | 所有硬链接都被删除才会失效 | 目标文件不存在就会立即失效 | | 支持的对象类型 | 普通文件 | 文件 & 目录 | | 是否需要额外储存空间 | 几乎不需要 | 小量 | --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值