c - 获取库本身内动态库的文件名
问题描述
我正在做一个动态库(loader.so)并希望根据库的名称打开一个文件。这个想法是复制/符号链接库以打开不同的文件。
是否可以从库中找到使用 dlopen() 打开的库的文件名?我需要在运行时进行。
编辑:更多上下文:该库作为插件加载并充当 Python 插件的包装器。这意味着该库被同一个进程多次加载。因此,查找符号的方法失败了。(搜索匹配第一个实例,所以我得到相同的名称返回给所有库实例。)
Program -> loader_plugin1.so -> plugin1.py
-> loader_another_plugin.so -> another_plugin.py
解决方案
你可以用dl_iterate_phdr
.
示例脚本(用于构建示例项目;在空目录中运行):
#!/bin/sh -eu
cat > main.c <<EOF
void pr_libnm(void);
int main()
{
pr_libnm();
return 0;
}
EOF
cat > pr_libnm.c <<'EOF'
#define _GNU_SOURCE
#include <link.h>
#include <stdio.h>
#include <stdint.h>
static int cb_(struct dl_phdr_info *Info, size_t Sz, void *Data)
{
//printf("Name=%s\n",Info->dlpi_name);
uintptr_t a = (uintptr_t)cb_;
//for each elf-header, iterate thru program headers
for(size_t i=0; i<Info->dlpi_phnum; i++){
// [b,e) is the corresponding segment
uintptr_t b = Info->dlpi_addr + Info->dlpi_phdr[i].p_paddr;
uintptr_t e = b + Info->dlpi_phdr[i].p_memsz;
if(a>=b && a<e){
//if this is cb_'s segment, we're done
printf("NAME=%s\n", Info->dlpi_name);
//nonzero signals end of iteration
return 1;
}
}
return 0;
}
void pr_libnm(void)
{
//iterate thru elf-headers
dl_iterate_phdr(cb_ ,(void*)0);
}
EOF
: ${CC:=gcc}
for c in *.c; do $CC -fpic -c $c; done
$CC -shared -o libpr.so pr_libnm.o
$CC main.o $PWD/libpr.so
./a.out #prints NAME=$PWD/libpr.so
(当然,在 Unix 上,一个文件可以有多个名称。您将只获得用于映射它的共享对象的名称。)
dl_iterate_phdr
遍历映射对象的 elf 标头。每个 elf 标头都包含一个指向对象名称的指针。
程序遍历每个 elf 对象的段,当它找到调用共享对象的函数映射到的段时,它从 elf 标头打印名称并退出迭代。
推荐阅读
- apache-spark - 具有 nutch 数据的本地模式下的 Apache Mahout 与 Apache Spark
- java - Spring Boot 控制器不重定向
- python-3.x - pytesseract 无法从图像中识别复杂的数学公式
- tensorflow - 在 tf.data.Dataset.map 中使用 tf.keras.applications.resnet50.preprocess_input 时出错
- python - ValueError:检查目标时出错:预期 dense_1 具有形状 (7, 7) 但得到的数组具有形状 (7, 1)
- android - Retrofit2 使用 Hashmap 发布和获取 Json 数组数据
- c# - 具有 basicHttpBinding、传输安全性和基本客户端凭据类型的自定义 WCF 凭据验证器
- ios - 实施新的谷歌纸板
- java - 在 JAVA 中查找 JSON 字符串的深度
- javascript - 如何在选项卡内执行一些 JavaScript 代码以使用 chrome 扩展更改页面的某些内容?