gpt4 book ai didi

macos - OSX stat() 和 libffi

转载 作者:行者123 更新时间:2023-12-03 17:05:03 26 4
gpt4 key购买 nike

我正在尝试使用 libffi 在 macos (10.11) 上访问 stat()。这是 SWI-Prolog 的新的基于 FFI 的外部接口(interface)的一部分。此接口(interface)解析 <sys/stat.h>头获取函数原型(prototype)和struct stat类型。但是,我得到了虚假的值。如果我编译下面的代码并链接mystat,它工作正常从生成的.dylib .

#include <sys/stat.h>

int
mystat(const char *name, struct stat *buf)
{ return stat(name, buf);
}

我怀疑我弄错了 stat函数来自 dlsym() .在 /usr/lib/libc.dylib 上都试过了和 /usr/lib/libSystem.B.dylib .这给出了相同的结果。如果我运行 nm在上面的 dylib 上我得到 U _stat$INODE64 . dlsym不适用于 stat$INODE64 .查看 libc.dylib 我们得到
534_> nm /usr/lib/libc.dylib | grep stat
0000000000001ac5 T R8289209$_pthread_attr_setdetachstate
0000000000001af7 T R8289209$_stat
U _pthread_attr_setdetachstate
U _stat

两者有什么关系?任何人都有任何线索可能会发生什么?

最佳答案

您要查找的符号在 /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;
}
real_stat 返回的 inode 号匹配 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);
}

该库确实引用了旧版 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使用特殊 assembler names for functions$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>提取正确的符号声明。

关于macos - OSX stat() 和 libffi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48380955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com