Android二进制工具objdump/readelf不能打印出function@plt的原因和补丁. 查找原因时, google到的一点资料.

有人解决了后, Google的工程师也火急火燎地让上传补丁. :)

objdump not printing "function@plt" symbols when processing arm or mips object, but does for x86.

As one would expect of a modern toolchain targeting a shared library system, the ndk toolchain creates executables in which calls toexternal library functions are implemented with a call to a helper in the .plt section, which redirects to the address in the global offset table where the runtime linker will eventually place the address of the target function.

If I compile a simple hello-world executable with the ndk targeting both x86 and arm, then objdump the x86 version, I get something like this (trimmed a lot for brevity):

$ i686-android-linux-objdump -d obj/local/x86/hello

Disassembly of section .plt:
0804827c <puts@plt>:
804827c:ff 25 58 95 04 08 jmp *0x8049558
8048282:68 00 00 00 00 push $0x0
8048287:e9 e0 ff ff ff jmp 804826c <puts@plt-0x10>

Disassembly of section .text:
080483c0 <main>:
80483de:e8 99 fe ff ff call 804827c <puts@plt>

But, for the arm version:

$arm-linux-androideabi-objdump -d obj/local/armeabi/hello

Disassembly of section .plt:
000084f8 <.plt>:
8524:e28fc600 addip, pc, #0; 0x0
8528:e28cca02 addip, ip, #8192; 0x2000
852c:e5bcf7a4 ldrpc, [ip, #1956]!

0008590 <main>:
8590:b510 push{r4, lr}
8592:4803 ldrr0, [pc, #12](85a0 <main+0x10>)
8594:4478 addr0, pc
8596:f7ff efc6 blx8524 <_start-0x3c>

As you can see, there is no "puts@plt" synthetic symbol created, and the invocation within the program code is left as a negative address in relation to the first known symbol. Needless to say, this makes making sense of dumps very complicated - extremely so if looking at a stripped executable where the dynamic link symbols of the library functions used may be the only major clues as to what you are looking at.

So I would like to figure out why this useful feature of displaying the names of library functions called via the plt works for x86, and not for arm. I know that the necessary information to create these synthetic symbols does exist in the file, because I wrote a program which pattern matches the opcodes of the .plt, figures out the target address then searches for a dynamic symbol and at that address and prints out the corresponding stringtab name with a section suffix in
the way I assme objdump/BFD is doing for x86:

$ printplt obj/local/armeabi/hello

decoding plt...
0x0000850c: __cxa_begin_cleanup@plt
0x00008518: memcpy@plt
0x00008524: puts@plt
0x00008530: abort@plt
0x0000853c: __libc_init@plt
0x00008548: __cxa_type_match@plt
0x00008554: __gnu_Unwind_Find_exidx@plt

So my question is, why is this not working with the arm objdump? (it does not seem to work for mips either)

- Is there metadata missing from the arm object which is key to objdump / BFD deciding to try to do this?
- Is the feature just not implemented for arm?
- Is it implemented, but not available in the prebuilt toolchain due to omission of a compile-time option?
- Is it failing because the instructions used in the .plt are not of the form expected?

Unfortunately, I have not yet been able to figure out where these synthetic symbols are created in the binutils source; there's not a lot to search on since the "@plt" is presumably named from the section rather than being a static string, so it seems finding the code would require developing a degree of understanding of the codebase.

If possible, I'd like to find the area where binutils could be patched to enable this for arm, as it's a capability I would really like to have when debugging projects (and poking around on the device in general). If I can't figure out how to put it into objdump, I guess I could clean up and share my plt parsing program, but it would be a lot nicer to have the names in the disassembled output (and putting them in after the fact with sed seems a bit roundabout).

Managed to solve my problem - objdump now displays the function@pltnames is the disassembly of both the .plt and program code which calls them.

Patch follows... I suppose it's time to figure out how to use gerrit.
Which version of binutils would it be appropriate to submit against? I tried this on 2.21 but see there are lots in the git package. Or should it go upstream to someone else and only then back into android?

--- bfd/elf32-arm-orig.c2012-06-27 16:12:27.000000000 -0400
+++ bfd/elf32-arm.c2012-06-27 16:31:05.000000000 -0400
@@ -13898,6 +13898,21 @@
#define elf_backend_obj_attrs_orderelf32_arm_obj_attrs_order
#define elf_backend_obj_attrs_handle_unknown
elf32_arm_obj_attrs_handle_unknown

+/* Changes to enable decoding of function@plt symbols for android */
+#undef elf_backend_plt_sym_val
+#define elf_backend_plt_sym_valelf32_arm_android_plt_sym_val
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf32_arm_android_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + 4 * (
+ ARRAY_SIZE(elf32_arm_plt0_entry) +
+ ARRAY_SIZE(elf32_arm_plt_entry) * i);
+}
#include "elf32-target.h"

/* VxWorks Targets. */

Thank you for figuring out the fix! Please submit it to AOSP toolchain repo

repo init -u https://android.googlesource.com/toolchain/manifest.git

repo sync

You may google for how to submit patch to AOSP, but in short.

cd binutils

repo start yourbranchname .

Apply changes to binutils/binutils-2.19 and ideally also inbinutils/binutils-2.21

git commit -a # write commit message

repo upload . # then add reviewer

Your upload will appear inhttps://android-review.googlesource.com for review.

Looking forward to see it soon.

更多相关文章

  1. Android(安卓)studio 的快捷键对应 MAC 和Win版本
  2. Android如何用代码重复加载同一个xml
  3. Android数据库中查找一条数据使用的方法 query详解
  4. 代码论坛如何通过C的方式在android NDK下面查找本机的mac地址
  5. Android(安卓)Studio 使用lint工具进行代码优化
  6. Android(安卓)Studio集成友盟SDK出现的问题解决及原因分析
  7. 百度地图Android(安卓)SQLITE在本地如何实现按距离排序、范围查
  8. Android中不能在子线程中更新View视图的原因
  9. android NDK开发中,用Cygwin调试本地代码时报错“Another debug s

随机推荐

  1. Memory Analysis for Android(安卓)Appli
  2. Android(安卓)加载图片传到另一个页面 关
  3. Android巴士转发
  4. android gallery笔记
  5. [Exception Android(安卓)20] - Error:Ex
  6. android截屏并将截图缩放
  7. Android中调用摄像头并实现对焦拍照
  8. 移植unrar到Android
  9. Android(安卓)Java代码执行adb Shell命令
  10. 关于android的audiotrack播放声音断断续