dladdr - 获取某个地址的符号信息

名称 dladdr() - 获取某个地址的符号信息 概要 cc [ flag]... cfile ... -ldl [library]... #include dlfcn.h int dladdr(void *address, Dl_info *dlip); 多线程应用信息 该例行程序是线程安全的。 说明 dladdr() 是使用户能够直接访问动态链接设备(在编译
名称
dladdr() - 获取某个地址的符号信息
 
概要
cc [ flag]... cfile ... -ldl [library]...
#include <dlfcn.h>
int dladdr(void *address, Dl_info *dlip);
多线程应用信息
该例行程序是线程安全的。
 
说明
dladdr() 是使用户能够直接访问动态链接设备(在编译程序或ld 命令行上使用-ldl 选项)的一系列例行程序之
一。进程可通过dladdr() 获取有关最近定义给定address 的符号的信息。dladdr() 可确定指定的address 是否位
于构成进程的进址空间的其中一个加载模块(可执行库或共享库)内。如果某个地址位于在其上面映射加载模块
的基址和为该加载模块映射的最高虚拟地址之间(包括两端),则认为该地址在加载模块的范围内。如果某个加
载模块符合这个条件,则会搜索其动态符号表,以查找与指定的address 最接近的符号。最接近的符号是指其值
等于,或最为接近但小于指定的address 的符号。
dlip 是指向Dl_info 结构的指针。该结构必须由用户分配。如果指定的address 在其中一个加载模块的范围内,则
结构成员由dladdr() 设置。Dl_info 结构包含下列成员:
struct {
const char *dli_fname;
void *dli_fbase;
const char *dli_sname;
void *dli_saddr;
size_t dli_size; /* ELF only */
int dli_bind; /* ELF only */
int dli_type;
};
Dl_info 结构包含以下字段:
dli_fname 一个指针,指向包含address
的加载模块的文件名。每次调用dladdr() 后,该内存位置的内容都可能发生更改。
dli_fbase 加载模块的句柄。该句柄可用作dlsym() 的第一个参数。
dli_sname 一个指针,指向与指定的address
最接近的符号的名称。该符号要么带有相同的地址,要么是带有低位地址的最接近符号。
两次调用dladdr() 后,该内存位置的内容可能发生更改。
Section 3-264 Hewlett-Packard Company − 1 − HP-UX 11i Version 3: February 2007
dladdr(3C) dladdr(3C)
dli_saddr 最接近符号的实际地址。对于代码符号,它包含最接近代码符号的OPD(正式Plabel 描
述符)的地址。
dli_size (仅限ELF 进程)动态符号表中定义的最接近符号的大小。
dli_bind (仅限ELF 进程)动态符号表中定义的最接近符号的绑定属性。其值用于ELF 符号表
(请参阅<elf.h> )中的符号的绑定。
dli_type 最接近符号的类型。对于ELF 进程,这与动态符号表中的类型的值相同。其值用于ELF
符号表(请参阅<elf.h> )中的符号的类型。对于SOM 进程,这可能包括<dl.h> 中定义
的值TYPE_DAT A 或TYPE_PROCEDURE 。
 
返回值
如果指定的address 不在其中一个加载模块的范围内,则返回0 ;且不修改Dl_info 结构的内容。否则,将返回
一个非零值,同时设置Dl_info 结构的字段。
诊断信息
如果在包含address 的加载模块内,找不到其值小于或等于address 的符号,则dli_sname 、dli_saddr 和dli_size
字段将设置为0 ; dli_bind 字段设置为STB_LOCAL , dli_type 字段设置为STT_NOTYPE 。
对于a.out ,通常只导出一部分可见符号:尤其是链接了a.out 的加载模块引用的那些符号。可以使用链接程序
(请参阅ld(1) )来控制任何共享库或a.out 的输出符号的确切集合。
 
错误
如果dladdr() 失败,则随后对dlerrno() 的调用返回下列值之一:
[RTLD_ERR_BAD_DLL] 加载模块中的符号地址无效。
[RTLD_ERR_CANT_APPLY_RELOC] 不能在库中进行重定位。
[RTLD_ERR_DLADDR_NOTFOUND] 在所有加载模块中都找不到该地址。
[RTLD_ERR_NO_MEMORY] 内存不足。
[RTLD_ERR_SETCANCELSTATE_FAILED] 进入或退出dladdr() 时__thread_setcancelstate 失败。
[RTLD_ERR_SIGENABLE_FAILED] 退出dladdr() 时sigenable 失败。
[RTLD_ERR_SIGINHIBIT_FAILED] 进入dladdr() 时siginhibit 失败。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
获取某个动态库的加载地址,可以使用 `dlopen` 函数以及其他一些辅助函数来实现。以下是获取动态库加载地址的一种方法: ```objective-c #include <dlfcn.h> void *getLibraryBaseAddress(const char *libraryName) { void *handle = dlopen(libraryName, RTLD_LAZY); if (handle != NULL) { Dl_info info; if (dladdr((const void *)getLibraryBaseAddress, &info) != 0) { dlclose(handle); return info.dli_fbase; } dlclose(handle); } return NULL; } ``` 在上述代码中,我们定义了一个名为 `getLibraryBaseAddress` 的函数,它接受一个参数 `libraryName` 表示要获取加载地址的动态库的名称。 在函数内部,我们使用 `dlopen` 函数来打开指定的动态库,并获取对应的句柄(handle)。如果成功打开动态库,则使用 `dladdr` 函数来获取当前函数(`getLibraryBaseAddress`)的符号信息。通过 `info.dli_fbase` 可以获取到动态库的加载地址。最后,我们使用 `dlclose` 函数关闭动态库。 如果成功获取到动态库的加载地址,则该地址将被返回。否则,返回 `NULL`。 使用示例: ```objective-c const char *libraryName = "libYourLibrary.dylib"; void *baseAddress = getLibraryBaseAddress(libraryName); if (baseAddress != NULL) { printf("The base address of %s is %p\n", libraryName, baseAddress); } else { printf("Failed to get the base address of %s\n", libraryName); } ``` 注意,这种方法在 iOS 应用程序中可能会受到沙盒限制,并且需要对目标动态库具有访问权限。另外,确保提供正确的动态库名称,并链接 `dlfcn.h` 头文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值