HotSpot笔记——共享库操作

共享库操作

  • 前言
  • Makefile
    • Hotspot的Makefile
  • 如何定义需要共享库
    • 使用编译选项
    • 使用链接器选项
    • dlopen
    • dlsym

前言

jvm启动时,libjli.so、libjvm.so、libjava.so这些共享库的加载操作,都是c语言的,我们记录一下这些操作函数。

Makefile

以下是一个简单的 Makefile,用于测试 $(CURDIR) 是否为当前目录的绝对路径

test:
    @echo $(CURDIR)
    @if [ "$(CURDIR)" = "$(abspath .)" ]; then \
        echo "CURDIR is absolute path"; \
    else \
        echo "CURDIR is not absolute path"; \
    fi

该 Makefile 包含一个名为 test 的伪目标。当运行 make test 时,它将打印出 $(CURDIR)的值并检查是否与调用abspath .返回的值相同。如果两者相同,则说明 $(CURDIR)是当前目录的绝对路径,否则不是
在这里插入图片描述
$(CURDIR)是Makefile预定义的内置变量,它会自动展开为当前工作目录的绝对路径。因此,在Makefile中不需要重新定义CURDIR变量,以调用pwd命令进行路径展开,可以直接使用$(CURDIR)来表示当前工作目录的路径。
我们可以自定义一个变量完成它相同的功能,

CURRENT_DIR := $(shell pwd)

这个语句中使用了 pwd 命令来获取当前工作目录的路径,并通过 $(shell …) 内置函数将其传递给CURRENT_DIR变量。注意,在使用 $(shell …) 函数时需要将命令放在双引号中。
当你需要在 Makefile 中使用当前工作目录的路径时,可以直接使用 ${CURRENT_DIR} 来引用该变量。

Hotspot的Makefile

/home/wanghost/jdkCompile/openjdk/Makefile

 # Locate this Makefile
ifeq ($(filter /%, $(lastword $(MAKEFILE_LIST))),)
#获取当前makefile工作目录/home/wanghost/jdkCompile/openjdk+'/'+makefile文件名
(去掉首尾空格的名字)。也就是获得makefile完整路径
  makefile_path := $(CURDIR)/$(strip $(lastword $(MAKEFILE_LIST)))
else
  makefile_path := $(lastword $(MAKEFILE_LIST))
endif
topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path))))

topdir := $(strip $(patsubst %/, %, $(dir $(makefile_path))))
具体来说,这个语句包含以下几个函数:

  • $(makefile_path): 获取当前Makefile文件的完整路径。
  • $(dir $(makefile_path)): 获取当前Makefile文件所在的目录路径。
  • $(patsubst %/, %, $(dir $(makefile_path))): 如果目录路径以/结尾,则去除最后一个字符/,否则返回原字符串。这个函数主要是为了去除目录路径的最后一个斜杠/,以便后续使用该路径时更加方便和规范。
  • $(strip ...): 去除参数前后的空白符,返回纯净的值。这个函数主要是为了去除目录路径中可能存在的多余空格。
    因此,将这些函数组合起来,就可以得到当前Makefile所在目录的上一级目录,即topdir变量的值/home/wanghost/jdkCompile/openjdk即源码根目录。

如何定义需要共享库

-wl最大优势应该是对间接引用库和直接引用库都能指定,-l只能指定直接引用库。

在Linux/Unix系统中,通过gcc/g++编译程序时,使用-l选项可以指定直接引用的库。而使用-Wl,option选项可以将option指定的选项传递给链接器ld。
因此,-Wl选项的最大优势在于它可以将其他任意的选项传递给链接器ld,包括间接引用的库和直接引用的库。这意味着我们可以使用-Wl来指定任意的链接选项,从而实现更加灵活的链接操作。
例如,如果我们需要链接一个静态库,并且该库依赖于另外一个库,我们可以使用-Wl,-Bstatic选项来指定链接静态库。同时,我们还可以使用-Wl,-lxxx选项来指定依赖库xxx的链接方式。
总之,-Wl选项对于复杂的链接操作非常有用,因为它可以传递任意的链接选项给链接器ld,从而实现更加灵活的链接操作。

无论是编译器选项还是链接器选项,都只是指定搜索共享库的路径,而到了具体使用时系统会根据这个路径加载共享库。dlopen可以运行时立即加载共享库。

使用编译选项

使用-l编译选项来指定程序需要链接的共享库名称。例如,如果你的程序需要链接 libcurl 库,那么可以使用以下命令进行编译:

gcc -o myprogram myprogram.c -lcurl

这将生成一个名为 myprogram 的可执行文件,该文件依赖于 libcurl 共享库。
注意,如果 libcurl 不在默认路径中,则还需要使用-L选项来指定共享库的路径。例如,如果 libcurl 在 /usr/local/lib 目录下,则可以使用以下命令进行编译:

gcc -o myprogram myprogram.c -L/usr/local/lib -lcurl

但是编译器选项在编译时已经确定了程序的运行方式,包括使用哪些共享库。因此,在程序运行时无法更改编译器选项以加载其他共享库。

使用链接器选项

使用-wl链接器选项也可以指定程序需要链接的共享库名称。例如,可以使用以下命令将libcurl链接到名为 myprogram 的可执行文件中:

gcc -o myprogram myprogram.o -Wl,-rpath=/usr/local/lib -lcurl

其中,-Wl选项用于将后续参数传递给链接器。-rpath选项表示在运行时搜索共享库文件的目录,这里指定为 /usr/local/lib 目录。注意,如果 libcurl 不在默认路径中,则必须使用 -rpath 选项来指定共享库的路径。
它和-l主要区别时是它可以带连接器选项-Wl,option

  • Bstatic:强制链接静态库。
  • Bdynamic:强制链接动态库。
  • export-dynamic:允许在动态库中导出符号。
  • rpath=dir:指定运行时搜索共享库的路径。
  • Ldir:添加搜索共享库的目录。
  • lfile:链接名为“libfile.so”的共享库。
  • no-as-needed:即使没有未解决的符号也链接共享库。
  • as-needed:仅在有未解决的符号时才链接共享库。
  • whole-archive:强制链接整个归档文件,而不仅仅是未解决的符号。
  • no-whole-archive:关闭–whole-archive选项。

dlopen

dlopen是一个 C 语言标准库函数,用于在程序运行时(runtime)动态加载共享库(shared library),也称为动态链接库(dynamic link library)。

void *dlopen(const char *filename, int flag);

其中 filename 参数是要加载的共享库文件名,flag 参数指定加载方式,比较常用的值有RTLD_NOW(立即解析符号)和RTLD_LAZY(在需要时再解析符号),RTLD_GLOBAL(它的含义是使得库中的解析的定义变量在随后的其它的链接库中变得可以使用)。dlopen函数返回一个指向动态库句柄的指针。
通过 dlopen 加载的共享库中的函数可以使用 dlsym 函数动态获取。例如:

void *handle = dlopen("mylib.so", RTLD_LAZY);
if (handle) {
    void (*foo)(void) = dlsym(handle, "foo");
    if (foo) {
        foo();
    }
    dlclose(handle);
}

这段代码尝试加载 mylib.so 文件,并获取其中名为 foo 的函数指针,如果成功则调用该函数。最后使用 dlclose 函数释放动态库句柄。

dlsym

dlsym是一个用于从共享库中获取符号地址的函数。它是在动态链接器库(例如linux下的libc.so)中定义的,通常通过使用 dlopen 打开共享库之后调用。具体来说,dlsym 函数可以通过在共享对象中查找相应名称的符号,并返回该符号的地址。这个地址可以被用来执行符号所代表的函数、变量等等。该函数的原型如下:

void* dlsym(void* handle, const char* symbol);

handle 参数是指向已打开共享对象的句柄的指针,而 symbol 参数则是要查找的符号名称的字符串。 如果找到了符号,则返回该符号的地址,否则返回 NULL。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python学习笔记2

使用链接: Python 3 basics - GeeksforGeeks 对应的英文是: 这里联想一下Redis的数据类型: string list set hash zset 列表 有一个细节,可以看到下面的输出里面也带了中括号: 字典 第一行定义的时候是中括号,因为…

文章八:YOLOv5车牌识别系统的Web应用与API开发

在本篇文章中,我们将探讨如何使用YOLOv5车牌识别系统开发一个Web应用,以及如何创建一个车牌识别API供其他开发者使用。我们将介绍Flask框架的基本概念,并实现一个简单的车牌识别Web应用和API。 车牌识别视频Flask框架介绍 Flask是一个轻量级的…

vue-cropper 拖动图片和截图框

现象 开发遇到vue--cropper不能拖动图片和截图框 解决方法 can-move-box设置为true,表示可以拖动截图框 can-move设置为true,表示可以拖动图片 *注意: 我外层套了一个el-col, el-col的宽高一定要大于截图框的宽高,否则移动不了…

网络安全工程师做什么?

​ 网络安全很复杂。数字化转型、远程工作和不断变化的威胁形势需要不同的工具和不同的技能组合。 系统必须到位以保护端点、身份和无边界网络边界。负责处理这种复杂安全基础设施的工作角色是网络安全工程师。 简而言之,网络安全工程师是负责设计和实施组织安全系…

ELK、ELFK企业级日志分析系统

目录 一、ELK简介 1、什么是ELK 2、ELK工作原理及过程​编辑 3、ELK相关名词介绍 ①Elasticsearch介绍 ②Logstash介绍 ③Kibana介绍 ④Fluentd介绍 ⑤Filebeat介绍 二、ELK部署 1、实验环境 2、安装elasticsearch 3、安装logstash ​编辑4、安装kiabana ​编辑…

网站是怎么屏蔽脏话的呢:简单学会SpringBoot项目敏感词、违规词过滤方案

一个社区最重要的就是交流氛围与审查违规,而这两者都少不了对于敏感词进行过滤的自动维护措施。基于这样的措施,我们才能基本保证用户在使用社区的过程中,不至于被敏感违规词汇包围,才能够正常的进行发布帖子和评论,享…

unity3d:asset store上C#代码热重载插件,不需要重运行,重新加载更新后函数

C#热重载插件地址 https://assetstore.unity.com/packages/tools/utilities/hot-reload-edit-code-without-compiling-250972?clickref1011lwHg8abv&utm_sourcepartnerize&utm_mediumaffiliate&utm_campaignunity_affiliate#description 打开热重装有两种方法 …

地库位置复杂如何导航,反向寻车系统解决方案

地库位置复杂如何导航?问路这一行为在迷路时确实比较高效,但是得到的信息往往还是过于碎片和混乱,尤其是在停车场内,通过问路去往目的地既费时又费力。而有了停车场地图,这个问题就迎刃而解了。停车场地图可以帮助驾车…

金山云最新财报的两个历史新高:毛利创新高,亏损创新高

‍数据智能产业创新服务媒体——聚焦数智 改变商业2023年3月29日,中国领先的独立云服务提供商金山云(美股代码:KC)发布了截至2022年12月31日的四季度财报与年度业绩数据。金山云首席执行官邹涛先生表示:“我们以喜人的…

【IoT】乐鑫WiFI选型指南

目录 1、简介 2、ESP32系列 2.1、ESP32-S2 2.2、ESP32-C3 2.3、ESP32-S3 最近要替换在用的wifi模组,这就涉及到选型。 1、简介 首先来到乐鑫官网:提供 Wi-Fi、蓝牙芯片和 AIoT 解决方案 I 乐鑫科技 可以看到,乐鑫的产品从大的层面分为三…

SpringBoot集成actuator监控服务-自动配置将康检查

前言 SpringBoot监控管理 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的处理和传递,出现了异常如何快速定位是哪个环节出现了…

算法设计-搜索

一、BFS 模板 ​ 如下所示 set<Node> visited;bool check(Node son);int bfs(Node start) {// initqueue<Node> q;q.push(start);visited.insert(start);while (!q.empty()){Node front q.front();q.pop();for (son : q.neigbour){// pruneif (check(son)){q.pu…

MySQL教程——基础篇

MySQL教程MySQL教程——基础篇MySQL概述关系型数据库数据模型SQLSQL通用语法SQL数据类型SQL分类DDLDMLDQL基本查询条件查询聚合函数分组查询排序查询分页查询案例训练执行顺序DCL用户管理权限控制函数字符串函数数值函数日期函数流程函数约束概述约束演示外键约束添加外键删除外…

【ChatGPT】ChatGPT 能否取代程序员?

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 前言: ChatGPT 的优势 自然语言的生成 文本自动生成 建立了更人性化的人机交互 ChatGPT 的局限性 算法的解释能力较差 程序的可实现性较差 缺乏优化和质量控制 程序员相较于 …

Spring框架核心功能手写实现

文章目录概要Spring启动以及扫描流程实现基础环境搭建扫描逻辑实现bean创建的简单实现依赖注入实现BeanNameAware回调实现初始化机制模拟实现BeanPostProcessor模拟实现AOP模拟实现概要 手写Spring启动以及扫描流程手写getBean流程手写Bean生命周期流程手写依赖注入流程手写Be…

乐鑫 ESP-IoT-Bridge 方案支持设备灵活入网

观看视频了解 ESP-IoT-Bridge 联网方案乐鑫科技推出 ESP-IoT-Bridge 联网方案&#xff0c;能够为物联网应用场景下的 Wi-Fi、蓝牙、Thread、以太网、MCU 等设备&#xff0c;提供便捷的网络服务。 ESP-IoT-Bridge 以乐鑫 SoC 为载体&#xff0c;通过实现各类网络接口&#xff08…

Java文件IO

目录 一. 文件路径 1.1 绝对路径 1.2 相对路径 二 . 文件操作 2.1 File类 2.2 字符流 Reader/Writer 2.3 字节流 InputStream/OutputStream 三. 实现一个文件的搜索功能 一. 文件路径 1.1 绝对路径 从盘符开始&#xff0c;一层一层往下找&#xff0c;得到的路径是绝对路…

nvm管理node版本粗及

步骤一&#xff1a;清理本地node cmd ——> where node ——> 删除对应文件夹下所有node.exe的父文件夹控制面板 ——> 卸载node步骤二&#xff1a;安装nvm Tags coreybutler/nvm-windows GitHub 下载解压后运行安装exe文件&#xff0c;安装完成后重新cmd打开命令…

Hive3.1.3安装及部署

目录 1 下载地址 2 安装部署 2.1 安装Hive 2.2 启动并使用Hive 2.3 MySQL安装 2.3.1 安装MySQL 2.3.2 配置MySQL 2.3.3 卸载MySQL说明 2.4 配置Hive元数据存储到MySQL 2.4.1 配置元数据到MySQL 2.4.2 验证元数据是否配置成功 2.4.3 查看MySQL中的元数据 2.5 Hive服…

中金支付经历了4个月完成主要出资人前置审批

2023年4月6日&#xff0c;中国人民银行公示了关于中金支付有限公司的《中国人民银行准予行政许可决定书》&#xff08;银许准予决字〔2023〕第41号&#xff09;&#xff0c;同意中金支付有限公司主要出资人由中金金融认证中心有限公司变更为广州广电运通金融电子股份有限公司&a…