【问题标题】:Is the -mx32 GCC flag implemented (correctly)?-mx32 GCC 标志是否(正确)实施?
【发布时间】:2012-06-07 06:58:00
【问题描述】:

我正在尝试构建一个与 32 位嵌入式系统通信的程序,该程序在基于 Linux 的 x86_64 机器(主机)上运行。在宿主程序上,我有一个包含一些指针的结构,这些指针反映了嵌入式系统上的相同结构。

问题是在宿主机上,指针原生是64位的,所以结构成员的偏移量和嵌入式系统中的不一样。因此,当复制结构(作为 memcpy)时,内容最终会在主机副本中的错误位置。

struct {
    float a;
    float b;
    float *p;
    float *q;
} mailbox;
// sizeof(mailbox) is 4*4=16 on the embedded, but 2*4+2*8=24 on the host

幸运的是,我发现 here gcc 有一个选项 -mx32 用于在 x86_64 机器上生成 32 位指针。但是,当尝试使用它时,我收到一条错误消息:

$ gcc -mx32 test.c -o test.e
cc1: error: unrecognized command line option "-mx32"

这适用于 gcc 版本 4.4.3 和 4.7.0 20120120(实验性)。

为什么这个选项不起作用?有没有办法解决这个问题?

编辑:根据v4.4.7 manual,没有可用的-mx32 选项,直到v4.6.3 都是如此。 OTOH,v4.7.0 确实显示了该选项,所以我使用的 Jan-20 版本可能不是最终版本?!

【问题讨论】:

  • 如果您正在与不同的系统进行通信,那么使用带有指针的结构似乎是错误的方法,因为指针仅在通信链路的一侧有效,即使在这种情况下指针具有两个系统中的大小相同。或许您可以描述一下您的“大局”问题?
  • @CharlesBailey - 我没有使用主机端的指针来引用任何数据。我只需要嵌入式系统中引用对象的地址。我将这些地址(的值)用于主机大小的某些目的。
  • @CharlesBailey - 顺便说一句,如果主机最终将使用嵌入式主机处理器(在我的情况下是这样),例如带有外部数学加速器的 ARM cpu,它们都共享相同的内存空间, 那么使用地址可能对双方都有效。
  • 您使用这些值的目的是什么?你能用索引或句柄值之类的东西来代替吗?
  • @CharlesBailey - 实际目的并不重要,是的,我最终用整数替换了指针。我想要这些指针的原因是这个结构是在一个与宿主项目和嵌入式项目相互关联的头文件中定义的——因为我不想跟踪两个问题参数(如矩阵大小)的变化地方。在嵌入式系统中,我想实际使用指针作为指针。如果编译器标志能够启用它会很好。在那之前,我会使用一些不太漂亮的代码。

标签: c pointers gcc 32bit-64bit x86-64


【解决方案1】:

不要这样做。首先,x32 是一个独立的架构。它不仅仅是一个编译器开关。您需要链接到的每个库的 x32 版本才能完成这项工作。 Linux 发行版尚未生产 x32 版本,这意味着您将要么静态链接,要么滚动您自己的库环境。

更广泛地说:那只是自找麻烦。如果您的结构包含指针,它们应该是指针。如果它包含“32 位地址”,它们应该是 32 位整数类型。

【讨论】:

  • 谢谢,安迪。如前所述,我确实将成员更改为整数类型。但是,我不同意这是“自找麻烦”,如果系统的行为被明确定义并且一个人知道他在做什么。在我们的特定情况下,这并不是生死攸关的问题,但让它工作起来会很方便。主机应用程序实际上是要在 ARM 嵌入式系统上运行。但是,此时我没有这样的系统可用,所以我在基于 Linux 的 PC 上开发了那个小应用程序。那么为 ARM 重建它应该很容易。
  • 宿主应用程序非常小,除了运行时和 newlib 并不需要任何额外的库(如 libm 左右)。您在这里所说的是 -mx32 选项虽然已记录在案,但并未真正在 GCC 中实现,这可能被视为一个错误,不是吗?或者,这是 Linux 特有的问题吗?
  • “-mx32 选项”表示为“x32”机器目标生成代码。这是一个不同的 ABI。它工作正常,AFAIK。但是,您没有这样的机器。您的 linux 发行版正在运行 x86_64。
  • 当然是不同的ABI,我同意它需要不同的库。但是文档说:“除了上述之外,在 64 位环境中的 x86-64 处理器上还支持这些 `-m' 开关。” 和 ” -mx32 选项将 int、long 和指针类型 设置为 32 位,并为 x86-64 架构“ 生成代码,这正是我正在寻找的为了。可能是我在这里遗漏了一点,但我的理解是它应该也适用于 Linux 目标(给定支持库)。
  • 无论如何,我看不出它是如何正常工作的,正如你所说,如果它给了我那个错误信息。你能举一个这样的兼容机器的例子吗?
【解决方案2】:

您可能需要更新版本的binutils

虽然我认为 gcc 4.8 是 recommended

但通常你需要一个内核编译的 multilib:https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2011-04-21
    • 2012-09-02
    相关资源
    最近更新 更多