Android二进制工具objdump/readelf不能打印出function@plt的解决

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 to external 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         add        ip, pc, #0        ; 0x0
    8528:        e28cca02         add        ip, ip, #8192        ; 0x2000
    852c:        e5bcf7a4         ldr        pc, [ip, #1956]!

0008590 <main>:
    8590:        b510              push        {r4, lr}
    8592:        4803              ldr        r0, [pc, #12]        (85a0 <main+0x10>)
    8594:        4478              add        r0, pc
    8596:        f7ff efc6         blx        8524 <_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.c        2012-06-27 16:12:27.000000000 -0400
+++ bfd/elf32-arm.c        2012-06-27 16:31:05.000000000 -0400
@@ -13898,6 +13898,21 @@
 #define elf_backend_obj_attrs_order        elf32_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_val                elf32_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 in binutils/binutils-2.21

git commit -a  # write commit message

repo upload .  # then add reviewer

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

Looking forward to see it soon.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值