【问题标题】:Cygwin: Relocation truncated to fit R_X86_64_32S against '.data'Cygwin:重定位被截断以适应“.data”的 R_X86_64_32S
【发布时间】:2014-08-25 18:07:45
【问题描述】:

我最近试图从“从头开始编程”一书中编译“找到最大值”程序。由于我使用的是 Windows,因此我使用 Cygwin 编译程序集文件。但是,我收到以下错误:

/tmp/ccuamKmO.o:fake:(.text+0xc): relocation truncated to fit: R_X86_64_32S against `.data'
/tmp/ccuamKmO.o:fake:(.text+0x1d): relocation truncated to fit: R_X86_64_32S against `.data'
collect2: error: ld returned 1 exit status


这可能是一些愚蠢的错误,我真的无法识别。 这是程序的代码:

.section .data
    data_items: 
        .long 3, 67, 34, 222, 45, 75, 54, 34, 44, 33, 22, 11, 66, 0

.section .text
    .globl main

main:
    jmp find_largest
  ret_find_largest:

    ret

/* 
 * %edi - Holds the index of the item being examined
 * %ebx - Largest item found
 * %eax - Current item
 */
find_largest:
    movl $0, %edi
    movl data_items(,%edi,4), %eax /* load eax with first item */
    movl %eax, %ebx

  start_loop:
    cmpl $0, %eax
    je loop_exit
    incl %edi
    movl data_items(,%edi,4), %eax
    cmpl %ebx, %eax
    jle start_loop
    movl %eax, %ebx
    jmp start_loop

  loop_exit:
    jmp ret_find_largest

【问题讨论】:

    标签: assembly cygwin linker-errors


    【解决方案1】:

    您的汇编代码似乎是为 32 位机器设计的,但您正在为 x64 进行汇编。尝试在命令行中添加-m32

    【讨论】:

    • 用“gcc -m32 cmp.S -o cmp”编译给了我一个巨大的链接器错误列表,比如:/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/。 ./../../../x86_64-pc-cygwin/bin/ld: 搜索时跳过不兼容的 /usr/lib/gcc/x86_64-pc-cygwin/4.8.2//libgcc_s.dll.a - lgcc_s
    • 我相信您还需要指定一个链接器选项。类似于-mi386pe 的东西。要从 GCC 传递它,您可以使用 -Wl,-mi386pe
    • @DrewMcGowen 谢谢,我找到的选项是-Wl,-mi386pep。我得到了与第一篇文章相同的两个错误,但有一些新错误:/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/libcygwin.a (libcmain.o): 在函数main': /usr/src/debug/cygwin-1.7.25-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to WinMain'/usr/src/debug/cygwin-1.7.25-1/winsup/cygwin/lib/libcmain.c:39:(.text.startup+0x7e): 重定位截断以适应:R_X86_64_PC32 针对未定义符号“WinMain”
    • OK 所以看来这行代码会导致重定位错误:movl data_items(,%edi,4), %eax。但它不应该是有效的代码行吗?
    • 我仍然坚持这一点,我正在寻找解决方案......有人可以提供一些帮助吗?
    【解决方案2】:

    我面临这个问题。试着用gcc -no-pie file.s -o file编译 它对我来说很好。然后./file为了运行可执行文件

    【讨论】:

    • 请不要添加same answer to multiple questions。一旦您获得足够的声誉,就回答最好的一个并将其余的标记为重复项。如果不是重复的,请根据问题调整帖子
    【解决方案3】:

    这似乎是 Windows 错误。我有同样的问题,无法弄清楚如何解决它。 在 linux 上尝试完全相同的操作。

    对于 x64 和 nasm:

    nasm -f elf64 -o <asm_name>.o <asm_name>.asm
    

    如果您正在使用 c 程序调用它,请按照以下说明:

    gcc -m64 -o <c_name> <c_name>.c <asm_name>.asm
    

    你终于可以用./&lt;c_name&gt;调用它了

    我知道,这并不能真正解决您的问题,但至少是一种可行的方法。

    【讨论】:

    • 这听起来更像是一个问题而不是一个答案。如果你在 Windows 上遇到 R_X86_64_32S 重定位错误,如果你的 gcc 配置为默认 -pie(就像在最近的发行版上一样),你也会在 Linux 上得到它们。 Avoiding 32-bit absolute addressing 是这里显而易见的解决方案,或者在 Windows 上制作非 PIE 可执行文件。 (假设您实际上首先有 64 位代码,这与这个问题不同,在这个问题中,32 位寻址模式是它适用于 32 位模式的线索。)。
    【解决方案4】:

    当我遇到这个问题时,答案很简单,我试图编译错误。

    一旦我创建了目标文件: gcc -g -O -c main.c functions.c

    我可以编译程序: gcc main.o functions.o -o prog

    对不起,我不知道汇编所以我不知道这是否适用于 OP。希望这对某人有所帮助。

    【讨论】:

    • 不,这根本没用。使用默认的 -m64 编译会在许多设置中出现此代码的错误,因为它是为 32 位模式编写的。如果你有实际的 64 位代码给出了这个错误,这个答案是没有帮助的。另外,你不需要单独编译成.o,你可以gcc -g -O3 -o prog *.c
    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 2016-04-03
    • 2018-04-06
    • 2020-05-23
    • 2015-10-20
    相关资源
    最近更新 更多