Analyzing an ELF binary to minimize its size

两盒软妹~` 提交于 2019-12-05 10:43:11
Ross Ridge

First, if you haven't already, use size -A hi_v8 to determine what section or sections are bigger than you expect. It's not always the text section.

Next add -Wl,-Map,hi_v8.map to the g++ command line. This will generate a linker map in the file hi_v8.map. The contents of the file will be very verbose, but it'll will show the contribution of each of object files to each section in the executable.

The linker map will have a number of sections. The first section "Archive member included because of file (symbol)" is helpful for figuring what caused an object be linked into the executable, but not so much what's inflating the size of the executable. Once you figured that out, and it turns to be an errant library, you can come back to this section. The "Allocating common symbols", "Discarded input sections", "Memory Configuration" sections are probably not going to be very helpful.

The "Linker script and memory map" section is where you want to be focusing your attention. It's essentially a trace of the linker script used to produce the executable. First check the LOAD statements at the start, they show every file that the executable was linked with. Check to see if there's any files you didn't expect to see, however libraries will be mentioned here even none of their object files were linked into the executable.

Now you'll have to wade through the trace of every linked object file and its symbols being adding to every section of the executable. Since it's just a "Hello World" problem it shouldn't be too bad. Skip to the section that you've identified as being the problem. Now scan through the list of objects and see if you can find either where a large number of not obviously necessary object files are being linked in or where the address suddenly jumps by a large amount. The later should be relatively easy to spot, but the former can be hard to identify. It might help if you generate linker map for a statically linked "Hello World" program on your native platform to see the sort of library routines it links in.

My guess is that your problem will show up as either a large jump in the address, or some file that obviously that shouldn't be linked in. So don't be put off by the verboseness of the map file. The C++ symbols should also be demangled so it won't be as bad as nm. (Though you can get nm to also demangle the names with the -C option.)

I do not know ARM, so pmap may not be available to you.... Sorry if this cannot fly for you. Gnu distributions usually have the pmap command.

Rewrite & compile hello world to remain running (memory resident) until you hit return, an fgets call will work.

Next, in a separate window, execute

pmap -d pid

Where pid is the pid of the hello world process. pmap -d shows sizes of every linked object.

It's also possibly worth enabling linker garbage collection, assuming the toolchain supports it, it isn't already enabled by default, and the linker script is written correctly. See https://sourceware.org/binutils/docs/ld/Options.html#index-g_t_002d_002dgc_002dsections-173.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!