BFD_RELOC_64:使用 C++ 在 32 位 linux 上编译汇编器指令

Posted

技术标签:

【中文标题】BFD_RELOC_64:使用 C++ 在 32 位 linux 上编译汇编器指令【英文标题】:BFD_RELOC_64: Compiling assembler directives on a 32 bit linux with C++ 【发布时间】:2014-05-20 21:33:11 【问题描述】:

我正在尝试在带有 GCC 4.4.1 的 32 位 Linux 上编译以下代码。

#ifndef WIN32
    #define DEBUG_STOP_POINT()                     \
        asm ( " 0 : int3 ; "                       \
              " .pushsection embed-breakpoints ; " \
              " .quad 0b ; "                       \
              " .popsection ; " )

        #if defined ( _DEBUG ) && defined ( _ASPECT_DEBUG )
            #define THROW_BREAKPOINT()                     \
                asm ( " 0 : int3 ; "                       \
                      " .pushsection embed-breakpoints ; " \
                      " .quad 0b ; "                       \
                      " .popsection ; " )
        #else
            #define THROW_BREAKPOINT()                         \
                asm ( " 0 : .pushsection embed-breakpoints ; " \
                      " .quad 0b ; "                           \
                      " .popsection ; " )
        #endif
#else
    #define DEBUG_STOP_POINT()
    #define THROW_BREAKPOINT()
#endif

它取自在同一 Linux 的 64 位版本上运行的 64 位项目,在该版本中使用相同的 GCC 4.4.1 编译没有问题。每个使用THROW_BREAKPOINT()(从未使用过DEBUG_STOP_POINT())的地方都会出现编译错误:“无法表示重定位类型BFD_RELOC_64。”

现在是问题:

    这段代码是什么? 这些 asm 指令只有 64 位?是这样吗,请您重写它以便在我的 32 位系统(32 位 Intel Celeron M)上做同样的事情吗? 我可以怀疑编译器安装问题(编译器和所需的依赖项是使用rpm -ivh --force 选项从现有和更新的 gcc 之上的 rpms 安装的)?在这种情况下,你能给我一个使用 asm 指令的代码示例,它应该在我的 32 位机器上编译吗? 我还可以尝试什么来修复编译错误(嗯,在 WIN32 情况下使用空定义会有所不同)?

【问题讨论】:

那是一些该死的繁重代码。您正在编写自己的操作系统吗? 一些上下文会有所帮助。你从哪里得到这个代码?它有什么用? 【参考方案1】:

1) 显然,在没有上下文的情况下,很难准确说出为什么代码在那里,但这就是它“所做的”:

    asm ( " 0 : int3 ; "                       \     # INT3 = Breakpoint instruction
          " .pushsection embed-breakpoints ; " \
          " .quad 0b ; "                       \     # Trap detection address
          " .popsection ; " )

pushsection 和 popsection 改变了数据所在的部分(通过保存在堆栈上,然后恢复到原来的状态(通常是 .text,但显然其他一些内联汇编器或 #pragma 可能已经改变了)在这个特定点之前。

对于 32 位代码,您可能需要 .long 而不是 .quad 作为陷阱检测地址 - 这会使此引用成为 32 位值而不是 64 位值 - 链接器赢了'不喜欢 64 位值...我不确切知道 embed-breakpoints 部分的目的是什么 - 它可能被扫描以了解实际断点发生的位置,或类似的东西。它存储0: 的地址,也就是int3 指令的地址。

显然,#if _DEBUG ... 位只是为调试选择断点或为非调试模式选择代码无断点变化的一种方式。

2) 你真的得问问写代码的人——我预计不需要 32 位。

3) 呃?我们无法从您询问的内容中判断您安装了什么,也无法判断它是否“正确”安装。至于示例,我很确定有教程,但是将 .quad 更改为 .long 应该可以解决您帖子标题中的直接错误 - 当然,很可能还有一些其他代码实际上使用了这些内容可能还需要更改。

4) 不确定您在这里要求什么?

请注意,我试图在我的回答中读懂你的想法,所以如果我今天的“力量”不强,并且我回答的不是你所要求的,我深表歉意。如果您发布它真的会有所帮助(供将来参考):

    一些使用这些宏的代码。 假设它是一个开源项目,您从中获取源代码的“项目”是什么。然后就可以下载源代码并浏览并了解它的作用。

【讨论】:

以上是关于BFD_RELOC_64:使用 C++ 在 32 位 linux 上编译汇编器指令的主要内容,如果未能解决你的问题,请参考以下文章

C++数据类型范围

访问 x64 TEB C++ 和汇编

在 32 位系统上使用 int64_t 而不是 int32_t 对性能有何影响?

Library v7.0.0 for Visual C++ 2005_2008 Win32_64 4CD

在linux上交叉编译c++到windows

使用 C++ 从 32 位进程访问 64 位 dll