本文介绍了减少可执行文件大小的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在生成要在ARM处理器上运行的十六进制文件,我希望将其保持在32K以下.目前,它的体积要大得多,我想知道是否有人对减少它的最佳方法有什么建议?

I'm producing a hex file to run on an ARM processor which I want to keep below 32K. It's currently a lot larger than that and I wondered if someone might have some advice on what's the best approach to slim it down?

这是我到目前为止所做的

Here's what I've done so far

  1. 因此,我在其上执行了大小"以确定十六进制文件有多大.
  2. 然后再次单击大小"以查看用于创建十六进制文件的链接的每个目标文件有多大.似乎其中大部分是来自外部库.
  3. 然后,我使用"readelf"来查看哪些功能占用了最多的内存.
  4. 我在代码中进行了搜索,以查看是否可以消除对这些函数的调用.

在这里我被困住了,有一些我不直接调用的函数(例如_vfprintf),我找不到调用的函数,因此可以删除该调用(因为我认为我不需要它).

Here's where I get stuck, there's some functions which I don't call directly (e.g. _vfprintf) and I can't find what calls it so I can remove the call (as I think I don't need it).

那下一步是什么?

回答:

  • 正如我所看到的,有一些调用的函数占用大量内存.但是,我找不到所谓的东西.
  • 我想省略那些功能(如果可能的话),但是我找不到所谓的功能!我猜可以从任意数量的库函数中调用它.
  • 我认为链接器正在按需工作,它仅包含相关的库文件.您如何知道是否仅包含相关功能?您可以为此设置标志吗?
  • 我正在使用GCC

推荐答案

常规列表:

  • 确保已禁用编译器和链接器调试选项
  • 编译并链接所有已启用的大小选项(gcc中为-Os)
  • 在可执行文件上运行strip
  • 生成一个映射文件并检查您的函数大小.您可以使链接程序生成映射文件(使用ld时为-M),也可以在最终的可执行文件上使用objdump(请注意,这仅适用于未压缩的可执行文件!)这实际上无法解决问题. ,但它会让您知道最严重的罪犯.
  • 使用nm调查每个目标文件中调用的符号.这应该有助于查找谁不想调用的调用函数.
  • Make sure that you have the compiler and linker debug options disabled
  • Compile and link with all size options turned on (-Os in gcc)
  • Run strip on the executable
  • Generate a map file and check your function sizes. You can either get your linker to generate your map file (-M when using ld), or you can use objdump on the final executable (note that this will only work on an unstripped executable!) This won't actually fix the problem, but it will let you know of the worst offenders.
  • Use nm to investigate the symbols that are called from each of your object files. This should help in finding who's calling functions that you don't want called.

在最初的问题中,有一个仅包含相关功能的子问题. gcc将在使用的每个目标文件中包括所有功能.换句话说,如果您的目标文件包含10个函数,则即使实际调用了1个,所有10个函数也都包含在可执行文件中.

In the original question was a sub-question about including only relevant functions. gcc will include all functions within every object file that is used. To put that another way, if you have an object file that contains 10 functions, all 10 functions are included in your executable even if one 1 is actually called.

标准库(例如libc)会将函数拆分为许多单独的目标文件,然后将其归档.然后将可执行文件链接到归档文件.通过拆分为多个目标文件,链接器仅可以包含实际调用的功能. (这假设您是静态链接)

The standard libraries (eg. libc) will split functions into many separate object files, which are then archived. The executable is then linked against the archive.By splitting into many object files the linker is able to include only the functions that are actually called. (this assumes that you're statically linking)

没有理由不能做同样的事情.当然,您可能会争辩说,如果未调用函数,则可以自行删除它们.

There is no reason why you can't do the same trick. Of course, you could argue that if the functions aren't called the you can probably remove them yourself.

如果您要静态链接到其他库,则也可以在它们之上运行上面列出的工具,以确保它们遵循类似的规则.

If you're statically linking against other libraries you can run the tools listed above over them too to make sure that they're following similar rules.

这篇关于减少可执行文件大小的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 20:31