首页 > 解决方案 > __xstat 64 位动态符号解析错误

问题描述

我正在尝试使用 dlopen 和 dlsym 动态加载 stat 函数。stat 系列中的函数被包装在相应的函数itp 中__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

-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;
}

objdump -T在 32 位和 64 位的两个可执行文件上使用 ,显示stat已解析为__xstat,因此我使用了正确的符号。我也试过组合__xstat/__xstat64, struct stat/stat64, 相同的结果。

标签: c++linuxshared-libraries

解决方案


__xstat 声明如下:

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

in documentation parameter ver is described like, ver shall be 3 or the behavior of these functions is undefined, which is not entirely true, because in source code, definition of _STAT_VER_LINUX follows:

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

That's why __xstat call on 64bits was failling, parameter ver should have been set to 1, and 3 on 32bits compilation.


推荐阅读