您要查找的符号定义在/usr/lib/system/libsystem_kernel.dylib
:
$ ~ nm -g /usr/lib/system/libsystem_kernel.dylib | grep '_stat\$INODE64'
0000000000002ed0 T _stat$INODE64
可以使用dlsym
:
#include <sys/stat.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
int
(*real_stat)(const char *path, struct stat *buf);
int main() {
const char *path = "/usr/lib/system/libsystem_kernel.dylib";
int err;
struct stat st;
void *lib = dlopen(path, RTLD_LOCAL);
real_stat = dlsym(lib, "stat$INODE64");
if((err = real_stat(path, &st)))
fprintf(stderr, "Can't stat %s: %s\n", path, strerror(err));
printf("%s inode: %lld\n", path, st.st_ino);
dlclose(lib);
return 0;
}
返回的 inode 编号real_stat
与以下返回的编号匹配stat(1)
:
$ ~ cc stat.c
$ ~ ./a.out
/usr/lib/system/libsystem_kernel.dylib inode: 4335860614
$ ~ stat -r /usr/lib/system/libsystem_kernel.dylib
16777220 4335860614 0100755 1 0 0 0 545424 1564436981 1564436981 1565194657 1564436981 4096 448 524320 /usr/lib/system/libsystem_kernel.dylib
可能会出现这样stat
的错误声明:
struct stat;
int stat(const char *restrict path, struct stat *restrict buf);
int mystat(const char *path, struct stat *buf) {
return stat(path, buf);
}
该库确实引用了 legacy stat
:
$ ~ cc -dynamiclib wrong-stat.c -o libwrongstat.dylib
$ ~ nm libwrongstat.dylib
0000000000000f70 T _mystat
U _stat
U dyld_stub_binder
<sys/stat.h>
声明对带后缀的函数stat
使用特殊的汇编程序名称$INODE64
,以避免与现有的冲突stat
(详情请参阅stat(2)
)。stat
如果声明使用后缀引用新的汇编程序名称,则可以修复该库:
struct stat;
int stat(const char *path, struct stat *buf) __asm("_stat$INODE64");
int mystat(const char *path, struct stat *buf) {
return stat(path, buf);
}
$ ~ cc -dynamiclib correct-stat.c -o libcorrectstat.dylib
$ ~ nm libcorrectstat.dylib
0000000000000f70 T _mystat
U _stat$INODE64
U dyld_stub_binder
但老实说,我会<sys/stat.h>
用来提取正确的符号声明。