__xstat动态符号解析错误(64位)

时间:2019-02-04 16:14:32

标签: c++ linux shared-libraries

我正在尝试使用dlopen和dlsym动态加载统计信息功能。 stat familly中的函数包装在相应的函数__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

在没有-m32开关的情况下在64位计算机上编译的可执行文件将返回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组合使用,结果相同。

1 个答案:

答案 0 :(得分:0)

__ 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的原因。