【问题标题】:"file not recognized" while using the GNU linker使用 GNU 链接器时出现“文件无法识别”
【发布时间】:2009-05-19 23:40:03
【问题描述】:

作为新手,我可能做错了什么。你能帮帮我吗?

我用 C 语言编写了一个名为 hello.c 的简单 Hello World 程序,并运行以下命令:

gcc -S hello.c

这产生了hello.s。然后我将该文件与 GNU 汇编程序一起使用,as:

as hello.s

哪个产生了不可执行的a.out,还需要链接,我明白了吗?

我尝试使用ld 链接它,如下所示:

ld a.out

但是得到以下错误:

a.out: file not recognized: File truncated

然后ld 删除了我的文件。

这是一个 x86 Ubuntu 系统。我究竟做错了什么?非常感谢!

【问题讨论】:

    标签: linker-errors gnu-toolchain


    【解决方案1】:

    我的第一个问题是:为什么要组装代码?如果你想要汇编代码,无论如何,使用gcc -S 来获取它(我猜是为了查看)。

    但您无需通过as 继续运行,只需使用:

    gcc -o hello hello.c
    gcc -S hello.c
    

    第一步会将 C 源代码直接转换为可执行文件,第二步将为您提供汇编源代码。

    您的具体问题可能是ld 尝试将其输出写入a.out。如果这也是您的输入文件,那么它很可能在运行ld 的过程中被破坏。在运行 ld 命令之前,您可以尝试将 a.out 重命名为 a.inld a.in

    【讨论】:

    • 我意识到这一点,但我希望独立于 gcc 使用 as 和 ld。我正在学习 x86 汇编。 gcc -S 的输出帮助我了解 gcc 如何在汇编中实现各种 C 程序。然后我可以修改和使用该汇编代码,最后使用 as 和 ld 自己组装和链接它。我意识到 gcc 可以为我组装和链接这些文件,但它只代表我使用 as 和 ld。我希望直接使用 as 和 ld。
    【解决方案2】:

    这是我的做法:

    > gcc -S forums.c 
    > as forums.s -o forums.o
    > gcc forums.o -o forums
    > ./forums 
    test
    

    为什么我调用gcc 而不是ld?因为 GCC 负责链接 C 运行时,并做其他与实现相关的事情。如果你想看到,请使用--verbose 选项:

    > gcc --verbose forums.o -o forums
    Using built-in specs.
    Target: i686-pc-linux-gnu
    Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++ --enable-threads=posix --mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic
    Thread model: posix
    gcc version 4.4.0 (GCC) 
    COMPILER_PATH=/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/
    LIBRARY_PATH=/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/:/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../:/lib/:/usr/lib/
    COLLECT_GCC_OPTIONS='-v' '-o' 'forums' '-mtune=generic'
     /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker /lib/ld-linux.so.2 -o forums /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../.. forums.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../crtn.o
    

    【讨论】:

      【解决方案3】:

      编辑:好的,我在我的系统上尝试了这一切,我想我知道问题出在哪里。 ld 正在写入a.out(它的默认输出文件),同时从它读取。试试这样的:

      ld a.out -o myprog
      

      【讨论】:

      • a.out 可以是任何类型的文件。通过使用-S 标志调用gcc,它只输出汇编、人类可读的代码。它不会组装或链接它。 as 绝对不应该链接它,那是 ld 的工作。 -o 标志只允许您更改结果的文件名,无论结果是什么。
      • 是的 .. 但重点是,如果您不为 ld 指定输出文件名,它首先要做的就是截断 a.out。然后它将查看其输入文件。如果其中之一是 a.out ,它将发现它已将其截断并失败。然后它会删除不完整的输出文件 a.out。在 as 上使用 -o something 并将其交给 ld。 ld 需要不同的输入和输出文件,它不能“就地”链接。
      【解决方案4】:

      无论如何都可以重新安装 glibc-devel 并检查它是否有效。这个过程对我有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-29
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 2012-06-01
        • 1970-01-01
        • 2021-07-31
        • 1970-01-01
        相关资源
        最近更新 更多