Android动态连接器linker与静态连接器ld

本文详细解析了动态连接器与静态连接器在程序编译、连接过程中的区别,包括连接时机、地址分配方式等核心概念,并通过实例展示了如何使用readelf命令查看动态链接器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、静态连接器ld

  静态连接器ld是GNU编译工具链的一部分,包含在binutils中;其中,collect2是对ld的一层包装、我们在静态连接时常用collect2。

  静态连接是在程序的编译连接中完成的。

  静态连接中,连接器会把引用其他目标文件的函数进行地址重定位、进而分配地址;这叫连接时重定位。

  eg:静态库编译进程序就是这样。

二、动态连接器linker

  android linker 浅析

  动态连接器linker,是指程序所调用库部分并不是在连接阶段就包含在可执行镜像中;而是在实际运行时由linker连接。这样可以大大提高磁盘及内存的使用效率。

  动态连接是在程序装载的过程中完成的。

  动态连接中,连接器只是给引用其他目标文件的函数分配一个动态连接符号;地址分配在程序装载时进行,这叫装载时重定位。

  eg:程序在执行过程中将共享库链接进进程地址空间就是这样。

  我们用readelf -a打开需要用到动态连接的可执行镜像,会发现动态连接器。

  arm-none-linux-gnueabi-readelf -a ../../out/target/product/generic/system/bin/testinput

[Requesting program interpreter: /system/bin/linker]

  看看ubuntu下的动态链接器:readelf -a main

[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

  为了提高动态连接效率,出现了延迟绑定的说法:即不是在装载时一次性确定地址,而是在用到某一个变量或函数时、才为该变量或函数重定位地址。

说明:程序是按照一个整体被装载的。

====

补充:

三、动态连接器自举

  上面遇到一个问题,和用C语言去编写C编译器一样的问题?

  1.动态连接器本身不可以依赖于其他任何共享对象;

  2.动态连接器本身所需要的全局和静态变量的重定位工作由它本身完成——在启动时有一段非常精巧的代码、完成动态连接,同时又不能用到全局和静态变量、不可以调用函数。

动态库的静态装载:在可执行文件运行时、进入main函数之前,已经把要用到动态库的变量或函数重定位。

动态库的动态加载:即使用dlopen函数簇,程序初始化完后、直接进入main函数;在需要时才连接。

  3.动态链接器linker更新导致的一个HAL加载问题

《Android系统学习》第六章:Android4.1 HAL段错误问题—linker与prelink


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值