7

我在 Gentoo 中为 ARM Cortex M3 (Maple Mini) 交叉编译 C++,但在链接 elf 文件时似乎内存资源达到了顶峰

/usr/libexec/gcc/arm-none-eabi/ld: build/maple_mini.elf section `.rodata' will not fit in region `rom'
/usr/libexec/gcc/arm-none-eabi/ld: region `rom' overflowed by 1508 bytes

这篇文章是关于如何减少.rodata内容的大小,以便能够完成elf文件的链接的问题。

我已经剥离了包含的代码,并正在使用以下相关选项进行编译。

CXXFLAGS = -fno-rtti -fno-exceptions -Os -fdata-sections -ffunction-sections -Wl,-gc-sections ...
LDFLAGS = -Wl,-gc-sections -fno-exceptions -fno-rtti ...

尽管如此,映射文件中的 .rodata (我对此非常陌生)包含似乎是程序中每个类的某种类型信息。一些地图文件摘录(注意。MPU6050 是一个 SuperSensor<>,它是一个 Sensor<>,在 C++ 意义上)

    0x000000000801d6c0       0x28 .../libsyrup.a(MPU6050.o)
    0x000000000801d6c0    _ZTVN5syrup6SensorILi6EEE
.rodata._ZTVN5syrup11SuperSensorILi6EEE    0x000000000801d6e8       0x28 .../libsyrup.a(MPU6050.o)
    0x000000000801d6e8                _ZTVN5syrup11SuperSensorILi6EEE
.rodata._ZTVN5syrup7MPU6050E  0x000000000801d710       0x28 .../libsyrup.a(MPU6050.o)
     0x000000000801d710                _ZTVN5syrup7MPU6050E
.rodata._ZTVN5syrup6SensorILi1EEE
     0x000000000801d738                 0x28 .../libsyrup.a(MS5611.o)
     0x000000000801d738                _ZTVN5syrup6SensorILi1EEE
.rodata._ZTVN5syrup11SuperSensorILi1EEE
            0x000000000801d760          0x28 .../libsyrup.a(MS5611.o)
            0x000000000801d760                _ZTVN5syrup11SuperSensorILi1EEE
...
            0x000000000801ee24          0x6f3 .../libstdc++.a(cp-demangle.o)
                                        0x730 (size before relaxing)
*fill*         0x000000000801f517       0x1 
.rodata        0x000000000801f518       0x14 .../libgcc.a(unwind-arm.o)
.rodata        0x000000000801f52c       0x23c .../libc.a(lib_a-strerror.o)
.rodata.str1.4    0x000000000801f768    0x635 .../libc.a(lib_a-strerror.o)
                                        0x63c (size before relaxing)

所以,lib_a-strerror.o 和 cp-demangle.o 似乎占据了大部分空间,尽管我猜这些是非常重要的。

所以,我的问题是,我可以采取哪些进一步的步骤来减少(或重构代码) .rodata 部分,以及那里究竟存储了什么?欢迎任何建议!我对编译和链接的更深层次的工作相当陌生,但正在学习。

4

2 回答 2

7

我认为你的问题可能不一定在rodata部分——只是那个人没有在muscal chairs活动中及时坐下来。换句话说,rodata 本身并不是太大,但整个图像太大而无法容纳。解决方案是查看系统中的整个代码、数据和rodata,看看其中是否有任何突出。

一般来说,删除不必要的代码(或字符串)将是这里的关键点。如果没有可以删除的东西,那么您将不得不找到一种不同的方法来解决问题。一种方法可能是压缩代码和数据,然后将其解压缩到 RAM 中(假设目标系统上的 RAM 比 ROM 多得多)。这不是一个闻所未闻的问题,但它从来没有那么容易解决 - 除非有人做了一些非常糟糕的编码并添加了数百千字节的代码。如果你有一个版本控制系统,并且你知道一个合适的版本,那么检查到底有多少空闲空间可能是一件好事——如果它突然变大了,检查是否有人添加了一些海量的静态数据结构或一些这样的。

于 2012-12-25T19:06:29.783 回答
6

根本的问题不是该.rodata部分太大,必然 - 通常你只是用完了ROM空间。(链接器恰好在该部分中链接时达到了限制。)

perror删除对,和 company等函数的任何调用strerror最终应该会放弃对 的依赖strerror.o,这应该会为您节省千字节半。不过,您可能还有其他更简单的方法可以节省同样的费用——这完全取决于您的应用程序。

于 2012-12-25T19:02:47.520 回答