__xstat 64 位上的动态符号解析错误

__xstat dynamic symbol resolving error on 64bit

本文关键字:符号 错误 动态 xstat      更新时间:2023-10-16

我正在尝试使用 dlopen 和 dlsym 动态加载统计函数。stat 系列中的函数被包装在相应的函数__xstat__xstat64 itp 中。

遵循代码的狙击,在 32 位模式下编译和工作(例如,包含 sys/stat.h 以获取统计信息结构(

#include <iostream>
#include <dlfcn.h>
#include <sys/stat.h>
typedef int (*xstat_f) (int __ver, const char *__filename, struct stat *__stat_buf);
int main()
{
    auto* h = dlopen("libc.so.6", RTLD_LAZY);
    if(!h)
    {
        return 1; // invalid handle
    }
    auto f = (xstat_f)dlsym(h, "__xstat");
    if(!f)
    {
        return 1; // invalid handle
    }
    struct stat s = {};
    const auto r = f(3, "/tmp", &s);
    if (r != 0)
    {
        perror("stat");
        return errno;
    }
    return 0;
}

g++ main.cpp -o main -ldl -m32

在 64 位计算机上没有-m32开关的情况下编译的可执行文件返回 EINVAL(无效参数(。

原因是什么?

我也做了一个最小的测试

#include <iostream>
#include <sys/stat.h>
int main(){
    struct stat s;
    const auto x = stat("/tmp", &s);
    if(x != 0) return errno;
    return 0;
}

并且在两个可执行文件(32 位和 64 位(上使用 objdump -T 表明stat解析为 __xstat ,所以我使用了正确的符号。我也尝试了__xstat/__xstat64struct stat/stat64的组合,结果相同。

__xstat声明如下:

int __xstat(int ver, const char *path, (struct stat *stat_buf))

在文档中,参数ver被描述为ver shall be 3 or the behavior of these functions is undefined,这并不完全正确,因为在源代码中,_STAT_VER_LINUX的定义如下:

#ifndef __x86_64__
# define _STAT_VER_LINUX    3
#else
# define _STAT_VER_LINUX    1
#endif

这就是为什么__xstat 64 位调用失败的原因,参数 ver 应该设置为 1,32 位编译时应设置为 3。

相关文章: