我在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 ...
仍然,map-file中的.rodata(我很陌生)包含了程序中每个类的某种类型信息。一些地图文件摘录(注意.MPU6050是一个SuperSensor<>这是一个传感器<>,在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部分,以及那里存储的内容是什么?欢迎任何建议!我对编译和链接的深层工作相当新,但是学习。
答案 0 :(得分:7)
我认为你的问题可能不一定是在rodata部分 - 这只是那个没有及时坐在muscal椅子事件的人。换句话说,rodata本身并不是太大,但整个图像太大而不适合。解决方案是查看系统中的整个代码,数据和数据,并查看其中是否有任何突出显示。
一般来说,删除不必要的代码(或字符串)是关键点。如果没有什么可以删除,那么你将不得不找到一种不同的方法来解决问题。一种方法可能是压缩代码和数据,并将其解压缩到RAM中(假设目标系统上的RAM明显多于ROM)。这不是一个闻所未闻的问题,但它从来没有那么容易修复 - 除非有人做了一些非常糟糕的编码并添加了几百千字节的代码。如果你有一个版本控制系统,并且你知道一个适合的版本,那么确切地检查有多少备用空间可能是一件好事 - 如果它突然增长很多,检查是否有人添加了一些大量的静态数据结构或一些这样的。
答案 1 :(得分:6)
潜在的问题并不是.rodata
部分太大,必然 - 你通常只是耗尽了ROM空间。 (当链接在该部分中时,链接器恰好达到了极限。)
删除对perror
,strerror
和公司等函数的任何调用都应该最终删除对strerror.o
的依赖,这样可以节省你的千字节和一半你已经结束通过。可能还有其他更简单的方法可以节省相同的费用 - 这完全取决于您的申请。