musl libc ldso 动态加载研究笔记:动态库的搜索路径

前言

  • 在手动设置动态库的存放路径的情况下,发现 musl ldso 依旧可以加载位于 /lib 目录下的 动态共享库

  • 动态库的存放路径或者说搜索路径,是否可以手动配置?比如 Linux 上 有个配置文件可以配置,可以改变 动态库的搜索次序,musl ldso 是否也可以做到这一点?

搜索路径

  • 通过查看 musl 的代码: ldso\dynlink.c 中的 load_library 函数中实现,了解到,musl 的动态库默认是以 lib 作为前缀的,并且不能使用系统预留的 动态库名字,比如 libc.so

在这里插入图片描述

  • musl ldso 通过应用程序的 动态库依赖列表获取依赖的动态库名字,大部分是没有路径的。

在这里插入图片描述

  • 下面是动态库路径的处理:

在这里插入图片描述
在这里插入图片描述

  • 通过这里发现,当前 平台 LDSO_ARCH 如果为 aarch64 时,如果存在 /etc/ld-musl-aarch64.path 文件,就读取这个文件,获取 sys_path,也就是动态库的搜索路径

  • 动态库的搜索路径不只是一个,可以使用 : 冒号分隔多个路径,这个 sys_path 路径是有先后次序的,前面的优先搜索。

在这里插入图片描述

环境变量

  • ldso\dynlink.c 中的 __dls3 函数中,可以发现, env_path 与 env_preload 也是动态库搜索路径的环境变量,系统如果通过 setenv 设置了 LD_LIBRARY_PATH 或者 LD_PRELOAD,也会改变 musl ldso 的搜索路径的次序
		env_path = getenv("LD_LIBRARY_PATH");env_preload = getenv("LD_PRELOAD");
  • 当前了解到 LD_PRELOAD 设置的是动态库,这里的动态库也是使用: 冒号分隔,优先加载

  • 如果设置了 LD_LIBRARY_PATH,是动态库的搜索路径,可以是多个,: 冒号分隔,在 ldso\dynlink.c 中的 load_library 函数 发现比 系统路径执行的早。

  • 以上都没有设置,并且有了 /etc/ld-musl-aarch64.path 文件,就读取 /etc/ld-musl-aarch64.path 里面的路径作为系统动态库搜索路径

  • 如果没有 /etc/ld-musl-aarch64.path 文件,就搜索 默认的 sys_path = "/lib:/usr/local/lib:/usr/lib",这说明即使不设置, /lib 目录下的动态库可以被 musl ldso 搜索得到。

  • "/lib:/usr/local/lib:/usr/lib" 路径搜索次序为: /lib -> /usr/local/lib -> /usr/lib

LD_LIBRARY_PATH 设置方法

  • setenv("LD_LIBRARY_PATH", "/kernel:/home/lib:/hello/app", 1);,这里设置环境变量 LD_LIBRARY_PATH,这样可以搜索的路径为: /kernel -> /home/lib -> /hello/app

  • 注意 LD_LIBRARY_PATH 的设置不影响系统的动态库搜索路径,也就是 LD_LIBRARY_PATH 搜索不到,依旧去系统的动态库路径下搜索

ld-musl-aarch64.path 设置方法

  • 注意 ld-musl-aarch64.path 表示 aarch64 平台下的,不同的平台,注意名字 "/etc/ld-musl-" LDSO_ARCH ".path"

  • 测试方法: 把共享库 libt0.so 移动到其他的位置,如 /hello 目录下,此时运行 应用程序(依赖共享库 libt0.so),提示无法找到 依赖的共享库

  • 新建 /etc 目录, 在 /etc 目录下 新建 ld-musl-aarch64.path,内容 :/lib:/usr/local/lib:/usr/lib:/hello,也就是增加了 /hello 的路径

  • 此时再次运行应用程序,正常运行,发现加载的共享库位置: /hello/libt0.so

msh />./t0_test_s.elf
msh />Error loading shared library libt0.so: No such file or directory (needed by ./t0_test_s.elf)
librtthread.so : load map : 0x212000 
Error relocating ./t0_test_s.elf: t0_data_set: symbol not found
Error relocating ./t0_test_s.elf: t0_data_get: symbol not foundmsh />mkdir /etcmsh />cd /etc/msh /etc>echo /lib:/usr/local/lib:/usr/lib:/hello /etc/ld-musl-aarch64.pathmsh /etc>cat ld-musl-aarch64.path
/lib:/usr/local/lib:/usr/lib:/hellomsh />./t0_test_s.elf
msh />libt0.so : load map : 0x212000 
librtthread.so : load map : 0x233000 /lib/librtthread.so : init_array : 0x235a60 /hello/libt0.so : init_array : 0x212750 ./t0_test_s.elf : init_array : 0x2015d0 
main : test start
main : -----------dlopen enter -----------
dl_test : ------------get-----------
dl_test : [get] ts.name = rt-smart_t0_lib_default
dl_test : [get] ts.cmd = 0xaabbccdd
dl_test : [get] ts.data = 0x8999eeff
main : -----------dlopen exit -----------
main : ------------get-----------
main : [get] ts.name = rt-smart_t0_lib_default
main : [get] ts.cmd = 0xaabbccdd
main : [get] ts.data = 0x8999eeff
main : ------------set->get-----------
main : [set-get] ts.name = t2_name_is_ok
main : [set-get] ts.cmd = 0x33559977
main : [set-get] ts.data = 0x4499aabb
main : test end

预加载库 LD_PRELOAD

  • 当前 musl ldso 支持 "LD_PRELOAD" 环境变量,可以通过 setenv("LD_PRELOAD", "/lib/aa.so:/lib/bb.so", 1); 设置需要提前加载的共享库。

小结

  • 如果应用程序共享的库有优先级,可以把优先级高的放在搜索路径的前面,可以通过配置 /etc/ld-musl-aarch64.path 文件或者设置环境变量: setenv("LD_LIBRARY_PATH", "/kernel:/home/lib:/hello/app", 1);

  • 如果几个动态库需要提前加载初始化,可以通过 设置 "LD_PRELOAD" 环境变量,这样提前加载的共享库优先加载

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

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

相关文章

【1-3章】Spark编程基础(Python版)

课程资源:(林子雨)Spark编程基础(Python版)_哔哩哔哩_bilibili 第1章 大数据技术概述(8节) 第三次信息化浪潮:以物联网、云计算、大数据为标志 (一)大数据 大数据时代到来的原因…

Unity之 Vector3 的详细介绍以及方法的介绍

文章目录 总的介绍小试牛刀相关的描述的参数看个小例子 总的介绍 当涉及到Unity中的Vector3类时,以下是一些常用的方法和操作: magnitude 方法:返回向量的长度。 float length vector.magnitude;sqrMagnitude 方法:返回向量的平…

恒运资本:信创概念再度活跃,华是科技再创新高,南天信息等涨停

信创概念21日盘中再度活跃,截至发稿,华是科技涨超17%,盘中一度触及涨停再创新高,中亦科技涨超13%亦创出新高,久其软件、南天信息、新炬网络、英飞拓均涨停。 音讯面上,自8月3日以来,财政部官网连…

Dockerfile制作镜像与搭建LAMP环境

1、编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私有仓库。 具体要求如下: (1)基于centos基础镜像; (2)指定作者信息; (3&#x…

Window Server 与 Windows 系统开关机日志查看方法

目录 Windows/Windows Server 查看日志Windows 系统常用的事件 ID 环境:Windows Server 2019 (也适用于 Windows 其他系统)。 不同版本的 Windows 图标可能有所不同,但是服务器级 Windows Server 与普通桌面级 Windows 还会有些操…

CTFshow——web入门——反序列化web254-web278 详细Writeup

前言 在做题之前先简要总结一下知识点 private变量会被序列化为:\x00类名\x00变量名 protected变量会被序列化为: \x00\*\x00变量名 public变量会被序列化为:变量名__sleep() ://在对象被序列化之前运行__wakeup() //将在反序列化之后立即…

Spring6.0官方文档示例:(27)配置文件中bean定义的继承关系

一、实体类 package cn.edu.tju.domain;public class DerivedTestBean {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {t…

洗涤护理门店小程序DIY制作教程

随着移动互联网的快速发展,小程序成为了各行各业推广和服务的新平台。对于干洗店来说,拥有一个专属的洗护小程序不仅可以提升用户体验,还能增加店铺的曝光度和销售额。那么,如何DIY制作一个干洗店洗护小程序呢? 首先&a…

SpringBoot利用ConstraintValidator实现自定义注解校验

一、前言 ConstraintValidator是Java Bean Validation(JSR-303)规范中的一个接口,用于实现自定义校验注解的校验逻辑。ConstraintValidator定义了两个泛型参数,分别是注解类型和被校验的值类型。在实现ConstraintValidator接口时&…

控制Unity发布的PC包的窗体

大家好,我是阿赵。   用Unity发布PC包接入某些渠道时,有时候会收到一些特殊的需求,比如控制窗口最大化(比如某些情况强制显示窗体)、最小化(比如老板键)、强制规定窗体置顶等。虽然我一直认为这些需求都是流氓软件行为,但作为一…

基于Spark+django的国漫推荐系统--计算机毕业设计项目

近年来,随着互联网的蓬勃发展,企事业单位对信息的管理提出了更高的要求。以传统的管理方式已无法满足现代人们的需求。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,随着各行业的不断发展,基…

【Java架构-包管理工具】-Maven基础(一)

本文摘要 Maven作为Java后端使用频率非常高的一款依赖管理工具,在此咱们由浅入深,分三篇文章(Maven基础、Maven进阶、私服搭建)来深入学习Maven,此篇为开篇主要介绍Maven概念、模型、安装配置、基本命令 文章目录 本文…

Nexus(Maven管理器)下载和安装

我们以 Nexus 2.x 为例,演示 Nexus 的安装过程。 官方下载地址 1. 进入 Nexus 2.x 下载页面,根据本机操作系统,选择对应的版本进行下载,如下图所示。 2. 将下载 Nexus 安装包解压到本地磁盘,可获得 nexus-2.14.20-0…

内网穿透实战应用-windwos10系统搭建我的世界服务器,内网穿透实现联机游戏Minecraft

文章目录 1. Java环境搭建2.安装我的世界Minecraft服务3. 启动我的世界服务4.局域网测试连接我的世界服务器5. 安装cpolar内网穿透6. 创建隧道映射内网端口7. 测试公网远程联机8. 配置固定TCP端口地址8.1 保留一个固定tcp地址8.2 配置固定tcp地址 9. 使用固定公网地址远程联机 …

【c语言】文件操作 万字详解

目录 一,为什么使用文件 二,什么是文件 1,程序文件 2,数据文件 3,文件名 三,文件的打开和关闭 1,文件指针 2,文件的打开和关闭 四, 文件的顺序读写 1,顺序…

stm32控制蜂鸣器源代码(附带proteus线路图)

说明: 1 PB0输出0时,蜂鸣器发生; 2 蜂鸣器电阻值如果太大会导致电流太小,发不出声音; 3蜂鸣器额定电压需要设置得低一点,可以是2V,但不能高于3V,这更右上角的电阻值有关系&#x…

【算法专题突破】双指针 - 移动零(1)

目录 写在前面 1. 题目解析 2. 算法原理 3. 代码编写 写在最后: 写在前面 在进行了剑指Offer和LeetCode hot100的毒打之后, 我决心系统地学习一些经典算法,增强我的综合算法能力。 1. 题目解析 题目链接:283. 移动零 - 力…

一网打尽java注解-克隆-面向对象设计原则-设计模式

文章目录 注解内置注解元注解 对象克隆为什么要克隆?如何克隆浅克隆深克隆 Java设计模式什么是设计模式?为什么要学习设计模式? 建模语言类接口类之间的关系依赖关系关联关系聚合关系组合关系继承关系实现关系 面向对象设计原则单一职责开闭原…

无涯教程-PHP - 移除的扩展

以下扩展已从PHP 7开始删除- eregmssqlmysqlsybase_ct 以下SAPI已从PHP 7开始删除- aolserverapacheapache_hooksapache2filtercaudiumcontinuityisapimilternsapiphttpdpi3webroxenthttpdtuxwebjames PHP - 移除的扩展 - 无涯教程网无涯教程网提供以下扩展已从PHP 7开始删除…

【SVN内网穿透】远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…