____ stat 64位动态符号解析错误

问题描述 投票:0回答:1

我正在尝试使用dlopen和dlsym动态加载统计信息功能。stat系列的功能包装在相应的功能__xstat__xstat64中。

按照以下代码片段,在以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的组合,结果相同。

c++ linux shared-libraries
1个回答
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

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

© www.soinside.com 2019 - 2024. All rights reserved.