Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: Get backtrace at PLT and stepi into PLT
@ 2009-07-17  8:48 Thinker Li
  2009-07-17 14:26 ` Daniel Jacobowitz
  0 siblings, 1 reply; 10+ messages in thread
From: Thinker Li @ 2009-07-17  8:48 UTC (permalink / raw)
  To: gdb-patches

Sorry for my previous message.
I resend it.

Daniel Jacobowitz writes:
 > On Thu, Jul 16, 2009 at 06:18:22PM +0800, User Thinker wrote:
 > > Hi all,
 > > 
 > > I have a patch that makes GDB can properly stepi into PLT for ARM Thumb
 > > instruction.  The patch also allow GDB to perform backtrace at PLT.
 > 
 > What version of GDB are these patches against?  Have you tried the
 > version from CVS?  This should work perfectly.
I tried it with GDB 6.8.  I had just tried the version from CVS this morning.
It can stepi into PLT, but backtrace is still not work.

I did some tests for GDB.
I configured GDB with command
	configure --build=x86_64-unknown-linux-gnu \
		--host=x86_64-unknown-linux-gnu \
		--target=arm-eabi-linux --disable-werror
for 6.8, CVS, 6.8 with the patch version, and CVS with the patch version.
I did a test for each version.  All these tests are following the
same commands, basically.
 1. I set a breakpoint at 0xa78c5424
 2. issue 3 stepi commands after inferior being stopped for the breakpoint.
 3. I also issue backtrace commands if it steps into PLT, successfully.
Logs for tests are at end of the email.

 > 
 > > It means GDB should put a invalid instruction of Thumb version at
 > > base address of the trampoline.  But, it actually puts
 > > ARM version one.  I have checked GDB source code for this issue.
 > > GDB check flags in symbol that contain memory space that breakpoint
 > > was setted at.  If the symbol is flaged as Thumb, it uses
 > > Thumb version invalid instruction code, or it would use
 > > ARM version.  It is reasonable.  But, the trampoline in PLT contains
 > > both types of instructions.  And, the result of checking is
 > > the block where the trampoline is in is not Thumb.
 > 
 > The CVS version of GDB checks ABI-defined mapping symbols ($a, $t).
 > These also allow disassembly to work correctly.
Cool! It works for me.

 > 
 > > If you try to backtrace stack when GDB stop at PLT, you would
 > > get nothing.  It is because no any unwinder can handle code in PLT.
 > 
 > arm_stub_unwinder_sniffer is supposed to handle this case.  It's been
 > there since 2005, and I've used it successfully.  What's going wrong
 > with that?
I can not even found arm_stub_unwinder_sniffer in the source tree of
GDB.  So, where is arm_stub_unwinder_sniffer?
Is it part of GDB, officially?

 > 
 > > begin 644 arm-plt.diff.gz
 > > M'XL(`#OJ7DH``YU7;4_;2!#^C'_%E)-Z`3O43D*20JDH$"A5"%62ZGKWQ?++
 > 
 > Please include patches as text.  See the list archives for examples.
 > Thanks.

-------------------- patch for 6.8 --------------------
diff -r 3a752b09834a gdb/arm-linux-tdep.c
--- a/gdb/arm-linux-tdep.c	Mon Jul 06 14:17:22 2009 +0800
+++ b/gdb/arm-linux-tdep.c	Fri Jul 17 10:32:20 2009 +0800
@@ -316,6 +316,21 @@ arm_linux_rt_sigreturn_init (const struc
 			      + ARM_SIGCONTEXT_R0);
 }
 
+static void
+arm_linux_plt_init (const struct tramp_frame *self,
+		    struct frame_info *next_frame,
+		    struct trad_frame_cache *this_cache,
+		    CORE_ADDR func)
+{
+  CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, ARM_SP_REGNUM);
+  CORE_ADDR fake_sp = sp - 4;
+  CORE_ADDR lr = frame_unwind_register_unsigned(next_frame, ARM_LR_REGNUM);
+  
+  write_memory_unsigned_integer(fake_sp, 4, lr);
+  trad_frame_set_reg_addr(this_cache, ARM_PC_REGNUM, fake_sp);
+  trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
 static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
@@ -358,6 +373,23 @@ static struct tramp_frame arm_eabi_linux
   arm_linux_rt_sigreturn_init
 };
 
+#define ARM_THUMB_BX_PC_INSN 0x00004778
+#define ARM_PLT_ADD_PC_INSN 0xe28fc600
+#define ARM_PLT_ADD_R12_INSN 0xe28cc000
+#define ARM_PLT_LDR_INSN 0xe5bcf000
+static struct tramp_frame arm_eabi_linux_plt_tramp_frame = {
+  GHOST_FRAME,
+  4,
+  {
+    { ARM_THUMB_BX_PC_INSN, 0x0000ffff },
+    { ARM_PLT_ADD_PC_INSN, -1 },
+    { ARM_PLT_ADD_R12_INSN, 0xfffff000 },
+    { ARM_PLT_LDR_INSN, 0xfffff000 },
+    { TRAMP_SENTINEL_INSN }
+  },
+  arm_linux_plt_init
+};
+
 /* Core file and register set support.  */
 
 #define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
@@ -643,6 +675,8 @@ arm_linux_init_abi (struct gdbarch_info 
 				&arm_eabi_linux_sigreturn_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
 				&arm_eabi_linux_rt_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
+				&arm_eabi_linux_plt_tramp_frame);
 
   /* Core file support.  */
   set_gdbarch_regset_from_core_section (gdbarch,
diff -r 3a752b09834a gdb/arm-tdep.c
--- a/gdb/arm-tdep.c	Mon Jul 06 14:17:22 2009 +0800
+++ b/gdb/arm-tdep.c	Fri Jul 17 10:32:20 2009 +0800
@@ -1677,9 +1677,12 @@ thumb_get_next_pc (struct frame_info *fr
       unsigned short inst2 = read_memory_unsigned_integer (pc + 2, 2);
       offset = (sbits (inst1, 0, 10) << 12) + (bits (inst2, 0, 10) << 1);
       nextpc = pc_val + offset;
-      /* For BLX make sure to clear the low bits.  */
+      /* For BLX make sure to clear the low bits, but keep LSB setted.  */
       if (bits (inst2, 11, 12) == 1)
-	nextpc = nextpc & 0xfffffffc;
+	nextpc = (nextpc & 0xfffffffc);
+      else
+	nextpc = nextpc | 1;	/* It would be fail to break on PLT without
+				 * this.  */
     }
   else if ((inst1 & 0xff00) == 0x4700)	/* bx REG, blx REG */
     {
diff -r 3a752b09834a gdb/frame.c
--- a/gdb/frame.c	Mon Jul 06 14:17:22 2009 +0800
+++ b/gdb/frame.c	Fri Jul 17 10:32:20 2009 +0800
@@ -1458,7 +1458,8 @@ get_prev_frame (struct frame_info *this_
      stop at main, we should at least stop at the entry point of the
      application.  */
   if (!backtrace_past_entry
-      && get_frame_type (this_frame) != DUMMY_FRAME && this_frame->level >= 0
+      && get_frame_type (this_frame) != DUMMY_FRAME
+      && get_frame_type (this_frame) != GHOST_FRAME && this_frame->level >= 0
       && inside_entry_func (this_frame))
     {
       frame_debug_got_null_frame (gdb_stdlog, this_frame, "inside entry func");
diff -r 3a752b09834a gdb/frame.h
--- a/gdb/frame.h	Mon Jul 06 14:17:22 2009 +0800
+++ b/gdb/frame.h	Fri Jul 17 10:32:20 2009 +0800
@@ -199,7 +199,10 @@ enum frame_type
   SIGTRAMP_FRAME,
   /* Sentinel or registers frame.  This frame obtains register values
      direct from the inferior's registers.  */
-  SENTINEL_FRAME
+  SENTINEL_FRAME,
+  /* This type of frame is not existed in the stack of inferior.
+     It can be used for frames that similar to sentinel frame.  */
+  GHOST_FRAME
 };
 
 /* For every stopped thread, GDB tracks two frames: current and
--------------------------------------------------

-------------------- patch for CVS --------------------
diff -r 92c4c442a2c6 gdb/arm-linux-tdep.c
--- a/gdb/arm-linux-tdep.c	Fri Jul 17 09:43:11 2009 +0800
+++ b/gdb/arm-linux-tdep.c	Fri Jul 17 14:17:34 2009 +0800
@@ -321,6 +321,23 @@ arm_linux_rt_sigreturn_init (const struc
 			      + ARM_SIGCONTEXT_R0);
 }
 
+static void
+arm_linux_plt_init (const struct tramp_frame *self,
+		    struct frame_info *this_frame,
+		    struct trad_frame_cache *this_cache,
+		    CORE_ADDR func)
+{
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
+  CORE_ADDR fake_sp = sp - 4;
+  CORE_ADDR lr = get_frame_register_unsigned(this_frame, ARM_LR_REGNUM);
+  struct gdbarch *gdbarch = get_frame_arch(this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order(gdbarch);
+  
+  write_memory_unsigned_integer(fake_sp, 4, byte_order, lr);
+  trad_frame_set_reg_addr(this_cache, ARM_PC_REGNUM, fake_sp);
+  trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
 static struct tramp_frame arm_linux_sigreturn_tramp_frame = {
   SIGTRAMP_FRAME,
   4,
@@ -363,6 +380,23 @@ static struct tramp_frame arm_eabi_linux
   arm_linux_rt_sigreturn_init
 };
 
+#define ARM_THUMB_BX_PC_INSN 0x00004778
+#define ARM_PLT_ADD_PC_INSN 0xe28fc600
+#define ARM_PLT_ADD_R12_INSN 0xe28cc000
+#define ARM_PLT_LDR_INSN 0xe5bcf000
+static struct tramp_frame arm_eabi_linux_plt_tramp_frame = {
+  GHOST_FRAME,
+  4,
+  {
+    { ARM_THUMB_BX_PC_INSN, 0x0000ffff },
+    { ARM_PLT_ADD_PC_INSN, -1 },
+    { ARM_PLT_ADD_R12_INSN, 0xfffff000 },
+    { ARM_PLT_LDR_INSN, 0xfffff000 },
+    { TRAMP_SENTINEL_INSN }
+  },
+  arm_linux_plt_init
+};
+
 /* Core file and register set support.  */
 
 #define ARM_LINUX_SIZEOF_GREGSET (18 * INT_REGISTER_SIZE)
@@ -651,6 +685,8 @@ arm_linux_init_abi (struct gdbarch_info 
 				&arm_eabi_linux_sigreturn_tramp_frame);
   tramp_frame_prepend_unwinder (gdbarch,
 				&arm_eabi_linux_rt_sigreturn_tramp_frame);
+  tramp_frame_prepend_unwinder (gdbarch,
+				&arm_eabi_linux_plt_tramp_frame);
 
   /* Core file support.  */
   set_gdbarch_regset_from_core_section (gdbarch,
diff -r 92c4c442a2c6 gdb/frame.c
--- a/gdb/frame.c	Fri Jul 17 09:43:11 2009 +0800
+++ b/gdb/frame.c	Fri Jul 17 14:17:34 2009 +0800
@@ -1650,6 +1650,7 @@ get_prev_frame (struct frame_info *this_
      application.  */
   if (this_frame->level >= 0
       && get_frame_type (this_frame) == NORMAL_FRAME
+      && get_frame_type (this_frame) == GHOST_FRAME
       && !backtrace_past_entry
       && inside_entry_func (this_frame))
     {
diff -r 92c4c442a2c6 gdb/frame.h
--- a/gdb/frame.h	Fri Jul 17 09:43:11 2009 +0800
+++ b/gdb/frame.h	Fri Jul 17 14:17:34 2009 +0800
@@ -207,7 +207,10 @@ enum frame_type
   ARCH_FRAME,
   /* Sentinel or registers frame.  This frame obtains register values
      direct from the inferior's registers.  */
-  SENTINEL_FRAME
+  SENTINEL_FRAME,
+  /* This type of frame is not existed in the stack of inferior.
+     It can be used for frames that similar to sentinel frame.  */
+  GHOST_FRAME
 };
 
 /* For every stopped thread, GDB tracks two frames: current and
--------------------------------------------------


------------- log for 6.8 -------------------------
warning: Lowest section in /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libicudata.so is .hash at 00000094
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:15
15	    ldmfd   sp!, {r4, r7}
Current language:  auto; currently asm
Breakpoint 1 at 0xa78c5424: file external/opencore/engines/player/src/pv_player_engine.cpp, line 1150.
[New Thread 766]
[Switching to Thread 766]

Breakpoint 1, 0xa78c5424 in PVPlayerEngine::Construct (this=0x12888, 
    aCmdStatusObserver=0xed7c, aErrorEventObserver=0xed84, 
    aInfoEventObserver=0xed80)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1150
1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5424 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+32>:	adds	r0, r5, r3
Current language:  auto; currently c++
0xa78c5426	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5426 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+34>:	movs	r1, #0
0xa78c5428	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5428 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+36>:	bl	0xa785991c

Program received signal SIGSEGV, Segmentation fault.
OsclRegistryClient::UnRegister (this=0x76be00, aComp=@0x0)
    at external/opencore/oscl/oscl/osclregcli/src/oscl_registry_client.cpp:90
90	    if (iTlsImpl)
1: x/i $pc
0xa7361504 <_ZN18OsclRegistryClient10UnRegisterER11OSCL_String+4>:	
    ldr	r0, [r0, #8]
The program is running.  Exit anyway? (y or n) 
warning: Lowest section in /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libicudata.so is .hash at 00000094
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:15
15	    ldmfd   sp!, {r4, r7}
Current language:  auto; currently asm
Breakpoint 1 at 0xa78c5424: file external/opencore/engines/player/src/pv_player_engine.cpp, line 1150.
[New Thread 766]
[Switching to Thread 766]

Breakpoint 1, 0xa78c5424 in PVPlayerEngine::Construct (this=0x12888, 
    aCmdStatusObserver=0xed7c, aErrorEventObserver=0xed84, 
    aInfoEventObserver=0xed80)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1150
1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5424 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+32>:	adds	r0, r5, r3
Current language:  auto; currently c++
0xa78c5426	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5426 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+34>:	movs	r1, #0
0xa78c5428	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5428 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+36>:	bl	0xa785991c

Program received signal SIGSEGV, Segmentation fault.
OsclRegistryClient::UnRegister (this=0x76be00, aComp=@0x0)
    at external/opencore/oscl/oscl/osclregcli/src/oscl_registry_client.cpp:90
90	    if (iTlsImpl)
1: x/i $pc
0xa7361504 <_ZN18OsclRegistryClient10UnRegisterER11OSCL_String+4>:	
    ldr	r0, [r0, #8]
The program is running.  Exit anyway? (y or n) 
----------------------------------------

-------------------- log for cvs --------------------
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:15
15	    ldmfd   sp!, {r4, r7}
Current language:  auto; currently asm
Breakpoint 1 at 0xa78c5424: file external/opencore/engines/player/src/pv_player_engine.cpp, line 1150.
[Switching to Thread 769]

Breakpoint 1, 0xa78c5424 in PVPlayerEngine::Construct (this=0x12888, 
    aCmdStatusObserver=0xed7c, aErrorEventObserver=0xed84, 
    aInfoEventObserver=0xed80)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1150
1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5424 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+32>:	adds	r0, r5, r3
Current language:  auto; currently c++
0xa78c5426	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5426 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+34>:	movs	r1, #0
0xa78c5428	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5428 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+36>:	bl	0xa785991c
0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
1: x/i $pc
0xa785991c:	bx	pc
#0  0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
#0  0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
The program is running.  Quit anyway (and kill it)? (y or n) 
----------------------------------------

-------------------- log for 6.8 with the patch --------------------
warning: Lowest section in /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libicudata.so is .hash at 00000094
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:15
15	    ldmfd   sp!, {r4, r7}
Current language:  auto; currently asm
Breakpoint 1 at 0xa78c5424: file external/opencore/engines/player/src/pv_player_engine.cpp, line 1150.
[New Thread 768]
[Switching to Thread 768]

Breakpoint 1, 0xa78c5424 in PVPlayerEngine::Construct (this=0x134a8, 
    aCmdStatusObserver=0xd434, aErrorEventObserver=0xd43c, 
    aInfoEventObserver=0xd438)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1150
1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5424 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+32>:	adds	r0, r5, r3
Current language:  auto; currently c++
0xa78c5426	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5426 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+34>:	movs	r1, #0
0xa78c5428	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5428 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+36>:	bl	0xa785991c
0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
1: x/i $pc
0xa785991c:	undefined
#0  0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
#1  PVPlayerEngine::Construct (this=0x134a8, aCmdStatusObserver=0xd434, 
    aErrorEventObserver=0xd43c, aInfoEventObserver=0xd438)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1151
#2  0xa78ca06c in PVPlayerEngine::New (aCmdStatusObserver=0xd434, 
    aErrorEventObserver=0xd43c, aInfoEventObserver=0xd438)
    at external/opencore/engines/player/src/pv_player_engine.cpp:107
#3  0xa78d4b40 in PVPlayerFactory::CreatePlayer (aCmdStatusObserver=0x135d4, 
    aErrorEventObserver=0x0, aInfoEventObserver=0x0)
    at external/opencore/engines/player/src/pv_player_factory.cpp:49
#4  0xa78d8d0e in PlayerDriver::playerThread (this=0x0)
    at external/opencore/android/playerdriver.cpp:870
#5  0xa78d8e10 in PlayerDriver::startPlayerThread (cookie=0x135d4)
    at external/opencore/android/playerdriver.cpp:847
#6  0xa9d285d6 in thread_data_t::trampoline (t=<value optimized out>)
    at frameworks/base/libs/utils/Threads.cpp:109
#7  0xafe0f884 in __thread_entry (
    func=0xa9d2856d <thread_data_t::trampoline(thread_data_t const*)+1>, 
    arg=0xd5a8, tls=0x40407f00) at bionic/libc/bionic/pthread.c:188
#8  0xafe0f3f8 in pthread_create (thread_out=0x0, attr=0xbea5f7f4, 
    start_routine=0xa9d2856d <thread_data_t::trampoline(thread_data_t const*)+1>, arg=0x0) at bionic/libc/bionic/pthread.c:324
#9  0x00000000 in ?? ()
The program is running.  Exit anyway? (y or n) 
----------------------------------------

-------------------- log for cvs with patch --------------------
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:15
15	    ldmfd   sp!, {r4, r7}
Current language:  auto; currently asm
Breakpoint 1 at 0xa78c5424: file external/opencore/engines/player/src/pv_player_engine.cpp, line 1150.
[Switching to Thread 771]

Breakpoint 1, 0xa78c5424 in PVPlayerEngine::Construct (this=0x12a50, 
    aCmdStatusObserver=0xeee4, aErrorEventObserver=0xeeec, 
    aInfoEventObserver=0xeee8)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1150
1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5424 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+32>:	adds	r0, r5, r3
Current language:  auto; currently c++
0xa78c5426	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5426 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+34>:	movs	r1, #0
0xa78c5428	1150	    iOOTSyncCommandSem.Create();
1: x/i $pc
0xa78c5428 <_ZN14PVPlayerEngine9ConstructEP23PVCommandStatusObserverP20PVErrorEventObserverP28PVInformationalEventObserver+36>:	bl	0xa785991c
0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
1: x/i $pc
0xa785991c:	bx	pc
#0  0xa785991c in ?? ()
   from /home/thinker/progm/android/out/target/product/generic/symbols/system/lib/libopencore_player.so
#1  PVPlayerEngine::Construct (this=0x12a50, aCmdStatusObserver=0xeee4, 
    aErrorEventObserver=0xeeec, aInfoEventObserver=0xeee8)
    at external/opencore/engines/player/src/pv_player_engine.cpp:1151
#2  0xa78ca06c in PVPlayerEngine::New (aCmdStatusObserver=0xeee4, 
    aErrorEventObserver=0xeeec, aInfoEventObserver=0xeee8)
    at external/opencore/engines/player/src/pv_player_engine.cpp:107
#3  0xa78d4b40 in PVPlayerFactory::CreatePlayer (aCmdStatusObserver=0x12b7c, 
    aErrorEventObserver=0x0, aInfoEventObserver=0x0)
    at external/opencore/engines/player/src/pv_player_factory.cpp:49
#4  0xa78d8d0e in PlayerDriver::playerThread (this=0x0)
    at external/opencore/android/playerdriver.cpp:870
#5  0xa78d8e10 in PlayerDriver::startPlayerThread (cookie=0x12b7c)
    at external/opencore/android/playerdriver.cpp:847
#6  0xa9d285d6 in thread_data_t::trampoline (t=<value optimized out>)
    at frameworks/base/libs/utils/Threads.cpp:109
#7  0xafe0f884 in __thread_entry (
    func=0xa9d2856d <thread_data_t::trampoline(thread_data_t const*)+1>, 
    arg=0xf0e8, tls=0x40507f00) at bionic/libc/bionic/pthread.c:188
#8  0xafe0f3f8 in pthread_create (thread_out=0x0, attr=0xbe9037f4, 
    start_routine=0xa9d2856d <thread_data_t::trampoline(thread_data_t const*)+1>, arg=0x0) at bionic/libc/bionic/pthread.c:324
#9  0x00000000 in ?? ()
The program is running.  Quit anyway (and kill it)? (y or n) 
--------------------------------------------------


^ permalink raw reply	[flat|nested] 10+ messages in thread
* Get backtrace at PLT and stepi into PLT
@ 2009-07-16 19:07 User Thinker
  2009-07-16 19:11 ` Daniel Jacobowitz
  0 siblings, 1 reply; 10+ messages in thread
From: User Thinker @ 2009-07-16 19:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: mokoko-group

Hi all,

I have a patch that makes GDB can properly stepi into PLT for ARM Thumb
instruction.  The patch also allow GDB to perform backtrace at PLT.

If you have a caller function, compiled with Thumb
instruction set with GCC, calls another callee function in another
file and you link the object containing caller to a ELF shared object,
GNU ld will generate a special trampoline in PLT section for the
callee function which is not in the same shared boject.  If you
try to stepi on bl instruction of caller and expect that GDB would
stop at first instruction of the trampoline, you would be
disappointed.

LD generates a trampoline that starts with 4 bytes
of Thumb instruction (2 instructions) followed by 14 bytes of
ARM instructins (3 instructions).  The Thumb instructions
are braches that branch to first instruction of the ARM
instructions and clear T flags.  It means switching processor to
ARM instruction set from Thumb instruction set.

It means GDB should put a invalid instruction of Thumb version at
base address of the trampoline.  But, it actually puts
ARM version one.  I have checked GDB source code for this issue.
GDB check flags in symbol that contain memory space that breakpoint
was setted at.  If the symbol is flaged as Thumb, it uses
Thumb version invalid instruction code, or it would use
ARM version.  It is reasonable.  But, the trampoline in PLT contains
both types of instructions.  And, the result of checking is
the block where the trampoline is in is not Thumb.

The solution is to check bl instructions in Thumb caller function.
If the bl instruction will not transit processor to ARM from Thumb
instruction set, we should still use Thumb version despite what
is got from the symbol.

If you try to backtrace stack when GDB stop at PLT, you would
get nothing.  It is because no any unwinder can handle code in PLT.
I add and register a tramp_frame for ARM Linux architecture, and
add a new frame type "GHOST_FRAME".  The tramp_frame can handle
PLT trampoline for ARM Thumb.  And, I can get backtrace when GDB
stop an inferior at PLT.


Following is changelog of the patch and patch itself.

2009-07-16  Thinker @ 0xlab <thinker@branda.to>

	* arm-linux-tdep.c (arm_eabi_linux_plt_tramp_frame): Add a new
	tramp_frame for ARM Linux PLT code with GHOST_FRAME type.
	* frame.h (enum frame_type): Add new frame_type GHOST_FRAME.
	* frame.c (get_prev_frame): Likewise.

	* arm-tdep.c (thumb_get_next_pc): Fix the bug that GDB does not
	make a breakpoint correctly for ARM.


begin 644 arm-plt.diff.gz
M'XL(`#OJ7DH``YU7;4_;2!#^C'_%E)-Z`3O43D*20JDH$"A5"%62ZGKWQ?++
M.EG%L2U[34`]_OO-[-J)$T*;GB6PLSLO.S//O*S/@P#J*32=SG'#-=]WFRT'
M)K[[[G+J1!/6CR=:O5X'Y]W:VMY=',&7/`2S#5;KQ.J<-!K0,,WWH)M=T]1T
M70=W@V4\S26+A2SMD^/&B6556<[/H6X93=`MPVK"^;FFTV;=[-21`<93'LU8
M"N=@/H:."Q^$6CAW4R?RG2,1?]1T3=\[!">=UT,>Y8]UX;/DR(,:KMC,<;DM
ME^TD%+9(G7EB!_B?'9S`)]\'!R*V0`&5'0CB%#X-[Z!/?/"U/P8O]ADLN)C"
MS>?[T=B^'GZZZX%X2MB15"[YCJ908U$^5[]LVBV4H(K*8E5&E1V//&'"3E+V
ML#QBG\_8@F>D9FEE:9^8YG/7)I:(/2*?A_37_!'$E(&;3_#M"+BYN@`_9AE$
ML4`)<V?&T&8W9<XLB7DDT+0T99X(GTJS214%J%LWF_5&!^!+S$*X2&.7>10*
M^."6W^>.[R`_'CV>?]1``SSAH/?7Z`2&+`D=C\&^PD$&&8_P)YVF?=39!]0<
M@U?L\:C8Z.X?:?YKP-P,<`6?FUN[P_0%YPYH;5IMHPTZO1H6(I:"4F`L%7;&
M)RD3>1K9/.(":EX<90(RD>8>^F=O#^2CDZ?MT>W-Y?U@W/L^MH?FP:D&S^A$
M/1..X!X\Q-S7])5LPN\+D0*JP#W,6!@8&&:II2!0P.-1$,.A!(I<V*1",;[:
ML3W'0P0=8J9EZGM)>WD_[-F?KJZ&$.21=Z#I/S2]NIHE<%;HRZ,%CWP[91.>
M"9;B;W1,Q'RH5<Z@G/#5'O9N!M_NT`%KT@+$JBU%XK\ZM#:VP_27RE[HZ@_7
M=-'?(N6"V7,VC].G)2.Z2[`)2VO%&0QH&:A0<55<E6'RH5;;\?VT5G&85/;U
MLE!FE*9LY><^K+$6\?)M-^<A[I%VZ6[B?J;D+`"R!0`KM*Q@6-T_@Q\:QA%Q
M-\;J\U75((.66H;"]G%78KO3-!I4C7^A:U5>2<9/\@"A?4K8_L-G`8^8],_X
M\[>["_OB.SGJ=C`:8(DW\6EU.MUU0JS`%/(*'6MT`Z]-F;R-;F@U*H2>9VXC
M[%\-ET3'KA=(HEVMW6PFTK$8VDIE-^AW2_Z76_C::K51F!W@`\]&E73#;@,;
MY2L4I<4DC`21-5M(2YM?(5.8&/4&X]M!KZ^\\TR;BN1E*4(\GA(@WQW");8!
M"'B(GHI\*#,1$."0Y4D2I^((X/`=-8EJ)/JW@V_?L0[^T[N_MF\P74:],=2L
M+AS"[6!,^7,[&O>&DN)`(K3=:A)"VYUCH[M>?.E$-H8(4T;%#PN\DWI35?MD
M\=U[NQ''K6E"E1BJT:>>G#"L,*K0H%VU0K:Q7>P:_M<EZSM+UK=)WIQB**OP
ML&L16'<X4!#LTA<8&?H9I/'<IM:-)<@3'-OE2N]/._#6WOM_NN[N_=9J=SH&
M+LBWU:"@OQA]EC&O=KL@U52WA67WR:;H&!PX,M'`G,4IR'^M]$,-I>K0,*"A
M\$!/'`2$Z#-4YW*108TD69A.!ECF`7SX`%;C`+EJJ]W&VNY*%!T<-9Q!XMD/
M3HA,2OBI5E<$&-)KG,@N^M]!3FU9CO&EJ2ED3BJ'O#!>`"E2@=9_E\W`*5'`
MC+$$^J,+0HE@_A(T]/!@PQ(+;24+S\[0%*V^MS2B^'A;%I8@\!#JJ_W:%@*5
M#/2P,&-5ZN+C7[!.]]">6P&+.,=>Z"+`'1Z2.7*"!00<C><TF<>Y4!F#I8/:
M:<609ZW0(0U2,2M.8IK2&/.QU<%/4N8^`E8=]$TH/Y9"?KR>%\7X7DF*8F7W
MC"@9=DF'%O;H#J8#O64)7+\U;$T%.6`48<U$G`!>#>8.CPQ8,$H*\BXN(4;D
M9*D(""PL$ND3J*M"'-!2(<5)DI![#M6.I:O)O6]<QYMAA?*PMJ$P6PHH,?WV
MK3QLY2ZD1A]5R^#-&5Q]N[O[N[A?(?5JM_XQ9`]X$?F(T2IQ\UOB=F>JWO%>
M/P,LQ2&@N,^4I3:-:FL2#TK\%`Q*L<_PBF9/8JQ@>1B6D4,HV)GPPWAB5-0:
ML*]4%-$@%?N8/;\`Y/0%(*>_"\CI3H!\_U[B$5^627C<N`2_,G%BKHW0'IP$
M0L""58X,67$;EG?_X@?$KD"P9JNY`BMFSK+"I3ZG&RQ03Y.81<BSE,?IGRN&
MHAP@#)?CS1(4ZRMRU,&S2>T2'@A[=0HN;]'`'DFD3]=6TH8SHS<CHE+M48$T
M+%N>$U'1RC,DI^NUE).IFWG&YSRDDAQCZ2W\4)JNRGD%A\7\7%9W1"'B@/(T
E0<EB2HW,D)=HRKP9:EC$A;(3\'*\X6/ZXF"F_0>O0T$Q]Q$`````
`
end


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-07-22 12:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-17  8:48 Get backtrace at PLT and stepi into PLT Thinker Li
2009-07-17 14:26 ` Daniel Jacobowitz
     [not found]   ` <19040.34533.656545.753721@bibi.branda.to>
2009-07-17 15:07     ` Daniel Jacobowitz
     [not found]       ` <19044.7794.607077.330791@bibi.branda.to>
2009-07-20 13:15         ` Daniel Jacobowitz
2009-07-21 15:12           ` Thinker Li
2009-07-21 18:15             ` Daniel Jacobowitz
2009-07-22 12:12               ` Thinker Li
2009-07-22 15:49                 ` Daniel Jacobowitz
  -- strict thread matches above, loose matches on Subject: below --
2009-07-16 19:07 User Thinker
2009-07-16 19:11 ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox