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

1,146 views
Skip to first unread message

Chris Stratton

unread,
Jun 26, 2012, 11:08:04 PM6/26/12
to android-ndk
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).

Chris Stratton

unread,
Jun 27, 2012, 12:58:55 PM6/27/12
to android-ndk
On Jun 26, 11:08 pm, Chris Stratton <cs07...@gmail.com> wrote:
> 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.

It turns out that "@plt" actually is a literal string in the sources,
found in _bfd_elf_get_synthetic_symtab() of bfd/elf.c

So I need to figure out why this function is not doing the same thing
for arm as for x86 - probably it's not getting enough information from
the target-specific components.

But first I need to figuring out how to efficiently rebuild
binutils...


Chris Stratton

unread,
Jun 27, 2012, 4:39:32 PM6/27/12
to android-ndk
On Jun 26, 11:08 pm, Chris Stratton <cs07...@gmail.com> wrote:

> $arm-linux-androideabi-objdump -d obj/local/armeabi/hello
>
> 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.

Managed to solve my problem - objdump now displays the function@plt
names 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. */

Andrew Hsieh

unread,
Jun 27, 2012, 6:19:12 PM6/27/12
to andro...@googlegroups.com
Thank you for figuring out the fix!   Please submit it to AOSP toolchain repo

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.


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


Reply all
Reply to author
Forward
0 new messages