【问题标题】:Old version of libc linking with my binary旧版本的 libc 与我的二进制文件链接
【发布时间】:2012-10-04 18:44:39
【问题描述】:

我继承了一个有一些问题的软件。我认为这些问题与静态链接的 libc 版本有关。

我在 Windows XP 机器上构建它,目标是 x86 QNX Neutrino 6.3.2 机器。

以前,使用 GCC 2.95.3 构建的软件(嗯,从技术上讲,它是 QNX 的 QCC 包装和调用 GCC) 有人添加了一项功能并不得不移植它以使用 GCC 3.3.5 构建,因为新功能需要它。

现在,该软件是我的了。我需要做一些补充,但注意到 奇怪 的行为。经过一番挖掘,我发现 2.95.3 和 3.3.5 都有指向 libc 的静态链接。根据QNX's web site,:

GCC 2.95.3(来自 6.2.1 或 6.3)和 GCC 3.3.5 使用不同的 C++ ABI 并有不同的名称修饰。结果,您无法链接 C++ 使用 GCC 2.95.3 构建的二进制文件(对象、可执行文件、库) 使用 GCC 3.3.5 构建的二进制文件。

这是一个重大的 ABI 更改,所以我显然很担心。我为此写了一个小测试

#include <stdio.h>

int main()
{
    FILE *stream_ptr = popen("fakename","r"); /// use libc
    return 0;
}

并使用 3.3.5 构建它:

QCC -V3.3.5,gcc_ntox86 small.cpp -o small.out

然后使用 strings 来查看该程序静态链接的内容

strings -a small.out | grep GCC
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 2.95.3
GCC: (GNU) 3.3.5 (qnx-nto)

如您所见,GCC 2.95.3 的 libc 已被静态链接。

我的第一个问题是:如何使用 3.3.5 版本的 libc 建立此链接?

我的第二个问题是:为什么它首先与 2.95.3 链接?

我做错了什么/错过了什么?欢迎提出任何建议。

(项目中可能还有 60 个其他东西与 2.95.3 对象相关联,我需要将它们全部修复,因此我自己实现 popen() 和他最亲密的 59 个朋友并不是最好的想法...)

谢谢,

卡尔

更新:

所以我还没有想出如何解决这个问题,但是有一点 QNX 6.3.2 的背景知识,所以以后偶然发现这个问题的人不必费力地解决这个问题:

您可以为链接器使用详细选项ld --verbose 并让它吐出它所做的一切。请注意,当我这样做时,我得到了以下输出:

attempt to open C:/QNX632/host/win32/x86/usr/lib/gcc-lib/i386-pc-nto-qnx6.3.0/3.3.5//libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib/gcc/3.3.5/libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/i386-pc-nto-qnx6.3.0/lib//libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/lib/libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib//libc.a succeeded

正如你所见,链接器试图打开libc.a的3.3.5版本,但它根本不存在。我查看了其他 3 台同事的计算机,没有 3.3.5 版本的 libc.a。我不确定这在 ABI 的重大变化中是如何起作用的,但我怀疑这个项目中的某些问题与这种差异有关。

虽然这回答了我最初的问题,但

1) 你不能让它链接到不存在的 libc.a 文件,

2) 它选择 2.95.3 版本,因为 3.3.5 版本不存在,

它提出了新的问题:

3) 为什么 QNX 不提供 3.3.5 版本的 libc.a 和这个版本的 Momentics?(或者如果他们提供,他们在哪里隐藏它,因为我错过了它。)

4) 是否有任何可行的解决方法?我能够在不使用 libc 的情况下构建项目中除了两个最重要的服务器之外的所有内容,但在我修复最后两个之前,我仍在寻找解决方案

更新到更新:

与 QNX 人员合作,他们使用 GCC 3.3.5 为我构建了一个不受支持、未经测试的 libc.a、libm.a 和 libsocket.a 工程版本,此后一切都很好。

【问题讨论】:

    标签: gcc libc


    【解决方案1】:

    当我为 QNX 6.3.2 编译时,我总是将 3.3.5 与 GNU C/C++ 库一起使用。如果您不指定 GNU,您将默认获得 Dinkum 库。过去我在 Dinkum 线程安全方面遇到过问题。试试这些标志:

    qcc -V3.3.5,gcc_ntox86 -Y_gpp
    

    -Y_gpp 指示 qcc 使用 GNU 库。

    【讨论】:

      【解决方案2】:

      GCC 3.3 是史前的,QNX 没有更新的版本吗?

      编译器或链接器应该有一些选项会告诉它是冗长的,您可以使用它来查看所有库路径和链接到的库。这可能会向您展示如何链接到较旧的库。

      【讨论】:

      • 是的,有一个更新的版本(实际上有几个),但是对于嵌入式系统,有时您无法跳转到更新的版本。有了这个项目,我们肯定会停留在 3.3.5。我将详细调试。谢谢,卡尔
      【解决方案3】:

      如果其他人遇到类似问题,据我所知,这里是我提出的四个问题的答案。他们不鼓励。

      1) 你不能让它与不存在的 libc.a 文件链接。当然。

      2) 它选择 2.95.3 版本的 libc.a,因为 3.3.5 版本不存在。

      3) 在与 QNX 人员的讨论中,他们表示对于 QNX Neutrino 6.3.2,经过测试的官方编译器只有 2.95.3,即使 GCC 3.3.5 包含在Momentics 的发货版本,未经测试也不支持。它恰好在那里。

      4) 选项:

      a) Go to a newer version of QNX which uses a newer version of GCC
      b) Get source for libc (and libm as it turns out) and build it with GCC 3.3.5.
         This one may pan out. Still waiting on QNX tech support.
      c) Get already-built libraries from the QNX folks.
      d) Don't use GCC 3.3.5 to build for Neutrino 6.3.2
      

      此致
      卡尔

      【讨论】:

        猜你喜欢
        • 2011-01-06
        • 1970-01-01
        • 2014-06-11
        • 1970-01-01
        • 2012-07-09
        • 2016-05-06
        • 1970-01-01
        • 2016-01-14
        • 1970-01-01
        相关资源
        最近更新 更多