分析一个ELF二进制文件,以尽量减少其大小 [英] Analyzing an ELF binary to minimize its size

查看:1449
本文介绍了分析一个ELF二进制文件,以尽量减少其大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的交叉编译 V8 项目嵌入式ARM目标使用GCC臂gnueabi交叉编译器。我得到的V8库本身成功交叉编译,并作为一个烟雾测试,我想将其链接到谷歌的的hello world例如并在ARM板运行。

I'm cross-compiling a V8 project to an embedded ARM target using the GCC arm-gnueabi cross compiler. I got the V8 library itself cross-compiled successfully, and as a smoke test I wanted to link it to Google's hello world example and run it on the ARM board.

120多MB的库本身的时钟在一个位:

The libraries themselves clock in at a bit over 1.2 MB:

v8 % find out/arm.release/obj.target/ -name '*.a' -exec du -h {} + 
1.2M    out/arm.release/obj.target/tools/gyp/libv8_base.a
12K     out/arm.release/obj.target/tools/gyp/libv8_libbase.a
4.0K    out/arm.release/obj.target/tools/gyp/libv8_libplatform.a
4.0K    out/arm.release/obj.target/tools/gyp/libv8_snapshot.a
4.0K    out/arm.release/obj.target/tools/gyp/libv8_nosnapshot.a
4.0K    out/arm.release/obj.target/third_party/icu/libicudata.a
164K    out/arm.release/obj.target/third_party/icu/libicuuc.a
336K    out/arm.release/obj.target/third_party/icu/libicui18n.

然而,当我构建和

Yet when I build and link with

arm-linux-gnueabi-g++ -pthread -Iv8/include hi.cpp -Os -o hi_v8 -Wl,--start-group v8/out/arm.release/obj.target/{tools/gyp/libv8_{base,libbase,snapshot},third_party/icu/libicu{uc,i18n,data}}.a -Wl,--end-group

我得到一个可执行这是20 MB。剥离它只是让我下到17 MB

I get an executable that's 20 MB. Stripping it only gets me down to 17 MB

什么是被链接在气球文件大小这么多?我怎样才能避免呢?我可以使用哪些工具来诊断问题?此大小可能是我的目标平台上有问题。

What is being linked in that balloons the file size so much? How can I avoid it? What tools can I use to diagnose the problem? This size may be problematic on the platform I am targeting.

我已经采取了看看 readelf --sections ,但它只是告诉我多大的.text 部分是整体,这不是特别有用的。我也看了看建议这里和使用尝试纳米 ,但它的的具体的 - 我只是一个像一堆名字 - 错位的符号 _ZN2v88internal11FLAG_log_gcE

I've taken a look at readelf --sections, but it just tells me how large the .text section is overall, which isn't particularly helpful. I also took a look at the suggestions here and tried using nm, but it's too specific - I just a bunch of name-mangled symbols like _ZN2v88internal11FLAG_log_gcE.

推荐答案

首先,如果你还没有,可以使用尺寸-A hi_v8 来确定哪些部分或节比你期望更大。这并不总是文本部分。

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.

接下来,添加轮候册,-Map,hi_v8.map G ++ 命令行。这将生成文件中的链接程序映射 hi_v8.map 。该文件的内容将是非常冗长,但它会显示每个对象的文件的,以可执行的每个部分的贡献。

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.

链接程序脚本和存储器映射部分是你想成为集中你的注意力。它本质上是用来生成可执行链接脚本的痕迹。首先检查 LOAD 语句在一开始,他们表现出每一个可执行文件与链接文件。检查是否有任何文件,你没想到看到的,但库将在这里提到的,甚至没有自己的目标文件被链接到可执行文件。

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.

现在你必须通过每一个链接的目标文件和符号被添加到可执行文件的每个部分的痕迹涉水。因为它只是一个Hello World的问题应该不会太糟糕。跳转到你已经确定为问题的部分。现在,通过对象的列表扫描,看看你是否能找到既那里有大量的没有明显必要对目标文件进行或者被链接的地址突然被大量的跳跃。后来应该是比较容易被发现,但前者可能很难辨认。如果您在本机平台上生成静态链接的Hello World程序连接地图上看到的那种库函数它链接它可能的帮助。

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.

我的猜测是,您的问题将显示在地址或者一个大的跳跃,或某些文件显然是不应该的联系。所以,不要被映射文件的冗长推迟。 C ++的符号,也应该demangled所以它不会像纳米坏。 (虽然你可以得到纳米也还原函数与 -C 选项的名字。)

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.)

这篇关于分析一个ELF二进制文件,以尽量减少其大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆