我比较三个编译器:
- 来自 Debian (6.3.0) 的 GCC (x86) 以7.8K 生成 hugo_x86.so,
- 来自Codesourcery(4.6.0)的GCC(ppc)以6.6K生成hugo_46.so,
- 来自 Buildroot 2017.08 (7.2.0) 的 GCC (x86) 可生成7.5K的 hugo.so,
- 来自 Buildroot 2017.08 (7.2.0) 的 GCC (ppc) 生成67K的 hugo.so,
- 来自 Buildroot 2017.08 (6.4.0) 的 GCC (ppc) hugo.so 产生67K和
- 来自 Buildroot 2017.08 (4.9.4) 的 GCC (ppc) 产生67K 的 hugo.so
代码取自 eli.thegreenplace.net:
int myglob = 42;
int ml_func(int a, int b)
{
myglob += a;
return b + myglob;
}
我像这样编译了所有来源:
powerpc-linux-gcc -c -o hugo.o hugo.c
powerpc-linux-gcc --shared -o hugo.so hugo.o
文件之间的区别似乎是填充(hexdump hugo.so | wc -l
):
- Debian (6.3.0):381 行
- 代码源 (4.6.0):283 行
- 构建根 2017.08 (7.2.0):298 行
- 构建根 2017.08 (6.4.0):294 行
(objdump -s
显示类似的结果)
问题:
- 如何最好地分析对象文件中的差异?(Objdump, readelf, etc)
- 如何最好地分析编译器的差异(例如默认选项)?(例如 -转储规范)
- 炸毁共享对象的原因可能是什么?如何增加文件大小?
谢谢!
--编辑:它也独立于 GCC 规范。我已经转储(-dumpspec
)代码源代码(4.6.0)GCC的规范,它产生了一个小的共享对象,并将其与Buildroot GCC(-specs
)一起使用,并再次获得了一个67K的共享对象。
来自 如何减少 ELF 部分填充?:
看起来这是由于binutils 2.27将PowerPC目标的默认页面大小增加到64k,导致嵌入式平台上的二进制文件臃肿。
这里有一个关于crosstool-NG github的讨论。
使用 --disable-relro 配置 binutils 应该会有所改善。
你也可以在编译时将 -Wl,-z,max-page-size=0x1000 添加到 gcc 中。
将BR2_BINUTILS_EXTRA_CONFIG_OPTIONS="--disable-relro"
添加到我的构建根配置时,共享对象大小会减小。