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,一经查实,立即删除!

相关文章

算法随笔:Floyd

Floyd算法是一种对所有点对最短路径算法、多源最短路径算法,以此计算能得到图中每一对节点之间的最短路径。Floyd不仅可以用来求多源最短路,也可以用于解决传递闭包问题。 算法思想: Floyd求最短路径用的是“从小图到全图”的动态规划思想&a…

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

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

Flowable 7.0.0.M2 版本功能

CMMN 支持批量迁移重复支持案例重新激活支持停止内务处理批处理Http 任务支持 HTTP HEAD and OPTIONS for the Http Tasks移除了 Spring Boot 启动器 flowable-spring-boot-starter-basic - 切换为 flowable-spring-boot-starter-process flowable-spring-boot-starter-rest-ap…

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…

ChatGPT在智能旅行和行程规划中的应用如何?

ChatGPT在智能旅行和行程规划领域具有广泛的应用潜力。作为一种强大的自然语言处理模型,ChatGPT可以通过与用户进行实时的语音或文本交互,提供个性化的旅行建议、行程规划、旅游信息等服务。本文将详细探讨ChatGPT在智能旅行和行程规划中的应用&#xff…

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() //将在反序列化之后立即…

Redis的数据持久化(概念版)

前言 本文主要介绍Redis的三种持久化方式、AOF持久化策略等 什么是持久化 持久化是指将数据在内存中的状态保存到非易失性介质(如硬盘、固态硬盘等)上的过程。在计算机中,内存中的数据属于易失性数据,一旦断电或重启系统&#…

vue uniapp 防止按钮多次点击(类似于防抖节流)

common文件并创建anti-shake.js文件 // 防止处理多次点击 function noMultipleClicks(methods, info) {// methods是需要点击后需要执行的函数, info是点击需要传的参数let that this;if (that.noClick) {// 第一次点击that.noClick false;if(info && inf…

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接口时&…

Android中正确使用Handler的姿势

在Android中,Handler是一种用于在不同线程之间传递消息和任务的机制。以下是在Android中正确使用Handler的一些姿势: 1. 在主线程中创建Handler对象 在Android中,只有主线程(也称为UI线程)可以更新UI。因此&#xff…

控制Unity发布的PC包的窗体

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

【微信小程序】小程序之间的跳转方式总结

想要从该小程序跳转到其他小程序怎么做? 方式 小程序之间的跳转方法有: wx.navigateTo:保留当前页面,跳转到应用内的某个页面,然后从该页面返回上一页的时候使用wx.navigateBack返回。wx.switchTab:跳转…

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

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

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

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

动态规划入门之洛谷创始人kk偷懒摆烂

P2392 kkksc03考前临时抱佛脚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这个题目的难点在于我们该怎么尽量让左右大脑均分题目时间呢,我们这样想,我们先将所有题目的时间总和累加起来,取其一半。我们知道如果将这n道题目进行时间的尽量…