2

我有生成大于 2GB 的可执行文件的代码(它是生成的代码)。

在带有 gcc 4.3.2 的 x64 上,我收到如下错误:

crtstuff.c:(.text+0x20): relocation truncated to fit: 
  R_X86_64_32S against `.dtors'

所以我知道我需要这个-mcmodel=large选项。然而,这并没有做任何事情或解决我系统上的问题。

确定我在某处读到,它仅受特定版本的 gcc 支持,并且该选项在之前的版本中被忽略。如果我知道它是什么,我会告诉我的运营团队安装那个版本的 gcc。但是我现在找不到任何证据来告诉我这个假设是否正确,如果是,那么该功能是在哪个版本中引入的。

例如

(1)这里声明该选项不做任何事情。有问题的书声称涵盖“GCC 4.x”。该书于 2006 年出版。

(2)这里针对该选项报告了一个编译器错误,因此我得出结论,在该版本中它至少必须做一些事情。那似乎是 gcc 4.6.1。

因此,尽管我无法再找到该功能在哪个版本中实现的确切证据,但至少有证据表明这种情况随着时间的推移而发生了变化。

我尝试查看所有各种 GCC 4.x 版本的变更日志,但无济于事(通常它们都很好,所以那里缺少信息几乎意味着我错了,版本之间没有任何变化。)

编辑: 似乎暗示它可能确实有效,但我需要“重新编译 crtstuff.c”,但我真的不知道我在哪里找到该文件或我如何做到这一点。

4

1 回答 1

1

我相信 4.4 是增加了对这个特性的支持的版本。我在下面演示了 4.1 在需要大数据块(而不是代码)的情况下无法工作,而 4.4 可以。我不确定 4.2 和 4.3,但是您的示例和我的记忆都表明 4.3 对此没有工作支持。我的示例应该让您验证特定安装是否有效,但在其他易于编译的代码上。

作为背景,我维护了一个程序,它是流基准测试的一个分支,经过专门修改以使用 64 位结构来测试更大的系统。在我开始使用“-mcmodel=large”之前,我一直被这些“重定位截断以适应”错误所困扰,并且我的 fork 不会编译/运行,除非它确实有效。我绝对发现我的程序兼容的最旧版本的 gcc 是 Debian Squeeze 附带的 4.4.5。

这是一个完整的测试用例,显示了我的流编译分支并在大型模型中使用 >4GB 的 RAM,在没有选项的情况下失败后:

$ gcc --version
gcc (Debian 4.4.5-8) 4.4.5
...
$ git clone https://github.com/gregs1104/stream-scaling.git
$ cd stream-scaling
$ gcc -O3 -DN=200000000 -fopenmp stream.c -o stream
/tmp/cca8rR1I.o: In function `checkSTREAMresults':
stream.c:(.text+0x34): relocation truncated to fit: R_X86_64_32S against `.bss'
...
stream.c:(.text+0x6ab): additional relocation overflows omitted from the output
collect2: ld returned 1 exit status
$ gcc -O3 -DN=200000000 -fopenmp stream.c -o stream -mcmodel=large
$ ./stream
-------------------------------------------------------------
STREAM version $Revision: 5.9 $
-------------------------------------------------------------
This system uses 8 bytes per DOUBLE PRECISION word.
-------------------------------------------------------------
Array size = 200000000, Offset = 0
Total memory required = 4577.6 MB.
...

这是在没有大型模型的 gcc 版本上发生的情况,一个运行 RedHat 5 派生软件(CentOS 5.8)的版本:

$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)
    ...
$ gcc -O3 -DN=200000000 -fopenmp stream.c -o stream -mcmodel=large
stream.c:1: sorry, unimplemented: code model ‘large’ not supported yet

因此,在旧版本的 gcc 上,它应该抛出该错误,而不仅仅是忽略该选项。

crtstuff 是 gcc 附带的库。您在 gcc 邮件列表中链接到的错误报告来自试图为 RedHat 5 系统构建自己的 gcc 的人,正如您在最后一个示例中看到的 gcc 4.1 附带的那样。他们用大模型重建了 gcc 的一部分,但它仍然链接到原始的 4.1 构建的 crtstuff 库。如果您使用的是正确打包的 gcc,则不应该遇到这个问题,这就是为什么 gcc 开发人员不认为它是一个真正的错误。我认为您只需要 gcc 4.4 或更高版本。

于 2012-07-17T22:38:24.980 回答