C语言 共享对象文件的大小很大



我比较三个编译器:

  • 来自 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显示类似的结果)

问题

  1. 如何最好地分析对象文件中的差异?(Objdump, readelf, etc)
  2. 如何最好地分析编译器的差异(例如默认选项)?(例如 -转储规范)
  3. 炸毁共享对象的原因可能是什么?如何增加文件大小?

谢谢!

--编辑:它也独立于 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"添加到我的构建根配置时,共享对象大小会减小。

最新更新