public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH]  PowerPC 32 with Secure PLT
@ 2012-01-18  4:00 Michael Eager
  2012-01-18 12:18 ` Joel Brobecker
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Eager @ 2012-01-18  4:00 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 857 bytes --]

This patch adds support for stepping into/over the PLT stubs generated
for secure PLT on PowerPC 32.  It requires a recent binutils which
generates symbols for the stubs.

This has been tested on PowerPC 32-bit systems with and without PAX.

2012-01-17  Michael Eager  <eager@eagercon.com>

          * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
          * ppc-linux-tdep.c: Include glibc-tdep.h.
          (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
          (powerpc_linux_in_plt_stub): New function.
          (powerpc_linux_in_dynsym_resolve_code): New function.
          (ppc_skip_trampoline_code): New function.
          (ppc_linux_init_abi): Use PPC specific functions rather than generic.
	Use glibc_skip_solib_resolver.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: securePLT.patch --]
[-- Type: text/x-patch, Size: 5486 bytes --]

Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.249
diff -u -p -r1.249 configure.tgt
--- configure.tgt	10 Jan 2012 16:30:43 -0000	1.249
+++ configure.tgt	18 Jan 2012 02:52:00 -0000
@@ -399,7 +399,7 @@ powerpc-*-linux* | powerpc64-*-linux*)
 	# Target: PowerPC running Linux
 	gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
 			solib-svr4.o solib-spu.o spu-multiarch.o \
-			symfile-mem.o linux-tdep.o"
+			glibc-tdep.o symfile-mem.o linux-tdep.o"
 	gdb_sim=../sim/ppc/libsim.a
 	build_gdbserver=yes
 	;;
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.133
diff -u -p -r1.133 ppc-linux-tdep.c
--- ppc-linux-tdep.c	4 Jan 2012 13:51:36 -0000	1.133
+++ ppc-linux-tdep.c	18 Jan 2012 02:52:01 -0000
@@ -37,6 +37,7 @@
 #include "solist.h"
 #include "ppc-tdep.h"
 #include "ppc-linux-tdep.h"
+#include "glibc-tdep.h"
 #include "trad-frame.h"
 #include "frame-unwind.h"
 #include "tramp-frame.h"
@@ -65,6 +66,9 @@
 #include "features/rs6000/powerpc-isa205-vsx64l.c"
 #include "features/rs6000/powerpc-e500l.c"
 
+/* Shared library operations for PowerPC-Linux.  */
+static struct target_so_ops powerpc_so_ops;
+
 /* The syscall's XML filename for PPC and PPC64.  */
 #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
 #define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml"
@@ -599,6 +603,87 @@ ppc64_standard_linkage3_target (struct f
   return ppc64_desc_entry_point (gdbarch, desc);
 }
 
+/* PLT stub in executable.  */
+static struct insn_pattern powerpc32_plt_stub[] =
+  {
+    { 0xffff0000, 0x3d600000, 0 },	/* lis   r11, xxxx	 */
+    { 0xffff0000, 0x816b0000, 0 },	/* lwz   r11, xxxx(r11)  */
+    { 0xffffffff, 0x7d6903a6, 0 },	/* mtctr r11		 */
+    { 0xffffffff, 0x4e800420, 0 },	/* bctr			 */
+    {          0,          0, 0 }
+  };
+
+/* PLT stub in shared library.  */
+static struct insn_pattern powerpc32_plt_stub_so[] =
+  {
+    { 0xffff0000, 0x817e0000, 0 },	/* lwz   r11, xxxx(r30)  */
+    { 0xffffffff, 0x7d6903a6, 0 },	/* mtctr r11		 */
+    { 0xffffffff, 0x4e800420, 0 },	/* bctr			 */
+    { 0xffffffff, 0x60000000, 0 },	/* nop			 */
+    {          0,          0, 0 }
+  };
+#define POWERPC32_PLT_STUB_LEN 	\
+  (sizeof powerpc32_plt_stub / sizeof (powerpc32_plt_stub[0]))
+
+/* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt 
+   section.  For secure PLT, stub is in .text and we need to check
+   instruction patterns.  */
+
+static int
+powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  struct objfile *objfile;
+  struct minimal_symbol *sym;
+
+  /* Check whether PC is in the dynamic linker.  This also checks
+     whether it is in the .plt section, used by non-PIC executables.  */
+  if (svr4_in_dynsym_resolve_code (pc))
+    return 1;
+
+  /* Check if we are in the resolver.  */
+  sym = lookup_minimal_symbol_by_pc (pc);
+  if ((strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink") == 0)
+      || (strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink_PLTresolve") == 0))
+    return 1;
+
+  return 0;
+}
+
+/* Follow PLT stub to actual routine.  */
+
+static CORE_ADDR
+ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+{
+  int insnbuf[POWERPC32_PLT_STUB_LEN];
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  CORE_ADDR target = 0;
+
+  if (insns_match_pattern (pc, powerpc32_plt_stub, insnbuf))
+    {
+      /* Insn pattern is 
+		lis   r11, xxxx	
+		lwz   r11, xxxx(r11) 
+	 Branch target is in r11.  */
+
+      target = (insn_d_field (insnbuf[0]) << 16) | insn_d_field (insnbuf[1]);
+      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
+    } 
+        
+  if (insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf))
+    {
+      /* Insn pattern is 
+		lwz   r11, xxxx(r30) 
+	 Branch target is in r11.  */
+      target = (CORE_ADDR) get_frame_register_unsigned (frame,
+						        tdep->ppc_gp0_regnum + 30)
+       	  + insn_d_field (insnbuf[0]);
+      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
+    }
+  
+  return target;
+}
 
 /* Given that we've begun executing a call trampoline at PC, return
    the entry point of the function the trampoline will go to.  */
@@ -1524,7 +1609,7 @@ ppc_linux_init_abi (struct gdbarch_info 
                                             ppc_linux_memory_remove_breakpoint);
 
       /* Shared library handling.  */
-      set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+      set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets
         (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 
@@ -1555,6 +1640,17 @@ ppc_linux_init_abi (struct gdbarch_info 
       else
 	set_gdbarch_core_regset_sections (gdbarch,
 					  ppc_linux_fp_regset_sections);
+
+      if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
+	{
+	  powerpc_so_ops = svr4_so_ops;
+	  /* Override dynamic resolve function.  */
+	  powerpc_so_ops.in_dynsym_resolve_code =
+	    powerpc_linux_in_dynsym_resolve_code;
+	}
+      set_solib_ops (gdbarch, &powerpc_so_ops);
+
+      set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
     }
   
   if (tdep->wordsize == 8)


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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18  4:00 [PATCH] PowerPC 32 with Secure PLT Michael Eager
@ 2012-01-18 12:18 ` Joel Brobecker
  2012-01-18 16:37   ` Michael Eager
  0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2012-01-18 12:18 UTC (permalink / raw)
  To: Michael Eager; +Cc: gdb-patches

> 2012-01-17  Michael Eager  <eager@eagercon.com>
> 
>          * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
>          * ppc-linux-tdep.c: Include glibc-tdep.h.
>          (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
>          (powerpc_linux_in_plt_stub): New function.
>          (powerpc_linux_in_dynsym_resolve_code): New function.
>          (ppc_skip_trampoline_code): New function.
>          (ppc_linux_init_abi): Use PPC specific functions rather than generic.
> 	Use glibc_skip_solib_resolver.

Overall, this looks good to me, but I am not a Linux specialist,
so please give it another week before checking in to give the other
maintainers a chance to comment as well.

Below are some comments.

> +#define POWERPC32_PLT_STUB_LEN 	\
> +  (sizeof powerpc32_plt_stub / sizeof (powerpc32_plt_stub[0]))

There is a macro, ARRAY_SIZE, that does this for you.

> +/* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt 

Trailing space at the end of this line...

> +/* Follow PLT stub to actual routine.  */
> +
> +static CORE_ADDR
> +ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)

There are several lines in the code and the comments of this funtion
that have trailing spaces. Can you get rid of them?

Also, several lines are too long. The absolute limit is 80 characters,
but the recommended limit is 70 characters. Can you reformat some of
the lines where it doesn't make the code uglier?

> +      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);

This is an area where I am not sure, but I think it would be better
to use read_memory_typed_address. I think the address type that you
want is: builtin_type (gdbarch)->builtin_func_ptr.

Same below.

-- 
Joel

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18 12:18 ` Joel Brobecker
@ 2012-01-18 16:37   ` Michael Eager
  2012-01-18 16:45     ` Michael Eager
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Eager @ 2012-01-18 16:37 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On 01/18/2012 04:08 AM, Joel Brobecker wrote:
>> 2012-01-17  Michael Eager<eager@eagercon.com>
>>
>>           * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
>>           * ppc-linux-tdep.c: Include glibc-tdep.h.
>>           (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
>>           (powerpc_linux_in_plt_stub): New function.
>>           (powerpc_linux_in_dynsym_resolve_code): New function.
>>           (ppc_skip_trampoline_code): New function.
>>           (ppc_linux_init_abi): Use PPC specific functions rather than generic.
>> 	Use glibc_skip_solib_resolver.
>
> Overall, this looks good to me, but I am not a Linux specialist,
> so please give it another week before checking in to give the other
> maintainers a chance to comment as well.
>
> Below are some comments.
>
>> +#define POWERPC32_PLT_STUB_LEN 	\
>> +  (sizeof powerpc32_plt_stub / sizeof (powerpc32_plt_stub[0]))
>
> There is a macro, ARRAY_SIZE, that does this for you.
>
>> +/* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt
>
> Trailing space at the end of this line...
>
>> +/* Follow PLT stub to actual routine.  */
>> +
>> +static CORE_ADDR
>> +ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
>
> There are several lines in the code and the comments of this funtion
> that have trailing spaces. Can you get rid of them?
>
> Also, several lines are too long. The absolute limit is 80 characters,
> but the recommended limit is 70 characters. Can you reformat some of
> the lines where it doesn't make the code uglier?
>
>> +      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
>
> This is an area where I am not sure, but I think it would be better
> to use read_memory_typed_address. I think the address type that you
> want is: builtin_type (gdbarch)->builtin_func_ptr.

Thanks.  I'll fix all of these.


-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18 16:37   ` Michael Eager
@ 2012-01-18 16:45     ` Michael Eager
  2012-01-18 17:03       ` Joel Brobecker
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Eager @ 2012-01-18 16:45 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On 01/18/2012 07:33 AM, Michael Eager wrote:
> On 01/18/2012 04:08 AM, Joel Brobecker wrote:

>>> + target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
>>
>> This is an area where I am not sure, but I think it would be better
>> to use read_memory_typed_address. I think the address type that you
>> want is: builtin_type (gdbarch)->builtin_func_ptr.

I think I'd rather leave the size explicit, rather than making
it indirect (and unclear).  This routine is only for PowerPC 32 and
the size of the value is always four bytes.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18 16:45     ` Michael Eager
@ 2012-01-18 17:03       ` Joel Brobecker
  2012-01-18 18:23         ` Michael Eager
  0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2012-01-18 17:03 UTC (permalink / raw)
  To: Michael Eager; +Cc: gdb-patches

> >>This is an area where I am not sure, but I think it would be better
> >>to use read_memory_typed_address. I think the address type that you
> >>want is: builtin_type (gdbarch)->builtin_func_ptr.
> 
> I think I'd rather leave the size explicit, rather than making
> it indirect (and unclear).  This routine is only for PowerPC 32 and
> the size of the value is always four bytes.

That would be fine with me. You should be able to get rid of the cast,
though. No?

-- 
Joel

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18 17:03       ` Joel Brobecker
@ 2012-01-18 18:23         ` Michael Eager
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Eager @ 2012-01-18 18:23 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On 01/18/2012 08:49 AM, Joel Brobecker wrote:
>>>> This is an area where I am not sure, but I think it would be better
>>>> to use read_memory_typed_address. I think the address type that you
>>>> want is: builtin_type (gdbarch)->builtin_func_ptr.
>>
>> I think I'd rather leave the size explicit, rather than making
>> it indirect (and unclear).  This routine is only for PowerPC 32 and
>> the size of the value is always four bytes.
>
> That would be fine with me. You should be able to get rid of the cast,
> though. No?

Yep, and the cast above on the call to get_frame_register_unsigned().

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18  3:36 Michael Eager
  2012-01-25  0:37 ` Michael Eager
@ 2012-01-30 17:19 ` Michael Eager
  1 sibling, 0 replies; 11+ messages in thread
From: Michael Eager @ 2012-01-30 17:19 UTC (permalink / raw)
  To: gdb-patches

On 01/17/2012 07:04 PM, Michael Eager wrote:
> This patch adds support for stepping into/over the PLT stubs generated
> for secure PLT on PowerPC 32. It requires a recent binutils which
> generates symbols for the stubs.
>
> This has been tested on PowerPC 32-bit systems with and without PAX.
>
> 2012-01-17 Michael Eager <eager@eagercon.com>
>
> * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
> * ppc-linux-tdep.c: Include glibc-tdep.h.
> (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
> (powerpc_linux_in_plt_stub): New function.
> (powerpc_linux_in_dynsym_resolve_code): New function.
> (ppc_skip_trampoline_code): New function.
> (ppc_linux_init_abi): Use PPC specific functions rather than generic.
> Use glibc_skip_solib_resolver.

Applied with suggested changes.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-25  1:12   ` Ryan Arnold
@ 2012-01-25  1:55     ` Michael Eager
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Eager @ 2012-01-25  1:55 UTC (permalink / raw)
  To: rsa; +Cc: gdb-patches, Mark Kettenis, Joseph S. Myers, Pedro Alves

On 01/24/2012 04:37 PM, Ryan Arnold wrote:
> On Tue, 2012-01-24 at 15:49 -0800, Michael Eager wrote:
>> On 01/17/2012 07:04 PM, Michael Eager wrote:
>>> This patch adds support for stepping into/over the PLT stubs generated
>>> for secure PLT on PowerPC 32. It requires a recent binutils which
>>> generates symbols for the stubs.
>>>
>>> This has been tested on PowerPC 32-bit systems with and without PAX.
>>>
>>> 2012-01-17 Michael Eager<eager@eagercon.com>
>>>
>>> * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
>>> * ppc-linux-tdep.c: Include glibc-tdep.h.
>>> (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
>>> (powerpc_linux_in_plt_stub): New function.
>>> (powerpc_linux_in_dynsym_resolve_code): New function.
>>> (ppc_skip_trampoline_code): New function.
>>> (ppc_linux_init_abi): Use PPC specific functions rather than generic.
>>> Use glibc_skip_solib_resolver.
>>
>> Will check in in a couple days, unless I hear additional comments.
>
> I'm not familiar with the GDB code at all so I couldn't tell from the
> patch whether it addresses my concern.
>
> Prior to resolving the PLT entries will this trap in the loader's
> resolver code or does it 'continue' until the PLT entry is populated and
> the target symbol address has been branched to?

It works in two phases: first steps over the stub to where ever it points
(which may be the target function), then it skips over the resolver code
if it still hasn't reached the function.

> It's fine with me if it skips the PLT stubs and the resolver trampoline
> code but being able to step into the resolver code is still useful to me
> as a GLIBC developer.

Most users don't want to see gdb stepping through symbol resolution
on the way to their library function.

I didn't run tests with a glibc which had debug symbols, but I think
that it will skip over the resolver if you say step.  If you want to
stop at _dl_resolve, you will need to put a breakpoint at that location.

Naturally, if you do stepi, you see each instruction executed.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-25  0:37 ` Michael Eager
@ 2012-01-25  1:12   ` Ryan Arnold
  2012-01-25  1:55     ` Michael Eager
  0 siblings, 1 reply; 11+ messages in thread
From: Ryan Arnold @ 2012-01-25  1:12 UTC (permalink / raw)
  To: Michael Eager; +Cc: gdb-patches, Mark Kettenis, Joseph S. Myers, Pedro Alves

On Tue, 2012-01-24 at 15:49 -0800, Michael Eager wrote:
> On 01/17/2012 07:04 PM, Michael Eager wrote:
> > This patch adds support for stepping into/over the PLT stubs generated
> > for secure PLT on PowerPC 32. It requires a recent binutils which
> > generates symbols for the stubs.
> >
> > This has been tested on PowerPC 32-bit systems with and without PAX.
> >
> > 2012-01-17 Michael Eager <eager@eagercon.com>
> >
> > * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
> > * ppc-linux-tdep.c: Include glibc-tdep.h.
> > (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
> > (powerpc_linux_in_plt_stub): New function.
> > (powerpc_linux_in_dynsym_resolve_code): New function.
> > (ppc_skip_trampoline_code): New function.
> > (ppc_linux_init_abi): Use PPC specific functions rather than generic.
> > Use glibc_skip_solib_resolver.
> 
> Will check in in a couple days, unless I hear additional comments.

I'm not familiar with the GDB code at all so I couldn't tell from the
patch whether it addresses my concern.

Prior to resolving the PLT entries will this trap in the loader's
resolver code or does it 'continue' until the PLT entry is populated and
the target symbol address has been branched to?

It's fine with me if it skips the PLT stubs and the resolver trampoline
code but being able to step into the resolver code is still useful to me
as a GLIBC developer.

Ryan S. Arnold
IBM Linux Technology Center
Linux Toolchain Development


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

* Re: [PATCH]  PowerPC 32 with Secure PLT
  2012-01-18  3:36 Michael Eager
@ 2012-01-25  0:37 ` Michael Eager
  2012-01-25  1:12   ` Ryan Arnold
  2012-01-30 17:19 ` Michael Eager
  1 sibling, 1 reply; 11+ messages in thread
From: Michael Eager @ 2012-01-25  0:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Mark Kettenis, Joseph S. Myers, Ryan S.Arnold, Pedro Alves

On 01/17/2012 07:04 PM, Michael Eager wrote:
> This patch adds support for stepping into/over the PLT stubs generated
> for secure PLT on PowerPC 32. It requires a recent binutils which
> generates symbols for the stubs.
>
> This has been tested on PowerPC 32-bit systems with and without PAX.
>
> 2012-01-17 Michael Eager <eager@eagercon.com>
>
> * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
> * ppc-linux-tdep.c: Include glibc-tdep.h.
> (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
> (powerpc_linux_in_plt_stub): New function.
> (powerpc_linux_in_dynsym_resolve_code): New function.
> (ppc_skip_trampoline_code): New function.
> (ppc_linux_init_abi): Use PPC specific functions rather than generic.
> Use glibc_skip_solib_resolver.

Will check in in a couple days, unless I hear additional comments.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

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

* [PATCH]  PowerPC 32 with Secure PLT
@ 2012-01-18  3:36 Michael Eager
  2012-01-25  0:37 ` Michael Eager
  2012-01-30 17:19 ` Michael Eager
  0 siblings, 2 replies; 11+ messages in thread
From: Michael Eager @ 2012-01-18  3:36 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 850 bytes --]

This patch adds support for stepping into/over the PLT stubs generated
for secure PLT on PowerPC 32.  It requires a recent binutils which
generates symbols for the stubs.

This has been tested on PowerPC 32-bit systems with and without PAX.

2012-01-17  Michael Eager  <eager@eagercon.com>

         * configure.tgt (powerpc-*-linux*): Add glibc-tdep.o.
         * ppc-linux-tdep.c: Include glibc-tdep.h.
         (powerpc32_plt_stub, powerpc32_plt_stub_so): Add PLT stub templates.
         (powerpc_linux_in_plt_stub): New function.
         (powerpc_linux_in_dynsym_resolve_code): New function.
         (ppc_skip_trampoline_code): New function.
         (ppc_linux_init_abi): Use PPC specific functions rather than generic.
	Use glibc_skip_solib_resolver.

-- 
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077

[-- Attachment #2: securePLT.patch --]
[-- Type: text/x-patch, Size: 5485 bytes --]

Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.249
diff -u -p -r1.249 configure.tgt
--- configure.tgt	10 Jan 2012 16:30:43 -0000	1.249
+++ configure.tgt	18 Jan 2012 02:52:00 -0000
@@ -399,7 +399,7 @@ powerpc-*-linux* | powerpc64-*-linux*)
 	# Target: PowerPC running Linux
 	gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
 			solib-svr4.o solib-spu.o spu-multiarch.o \
-			symfile-mem.o linux-tdep.o"
+			glibc-tdep.o symfile-mem.o linux-tdep.o"
 	gdb_sim=../sim/ppc/libsim.a
 	build_gdbserver=yes
 	;;
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.133
diff -u -p -r1.133 ppc-linux-tdep.c
--- ppc-linux-tdep.c	4 Jan 2012 13:51:36 -0000	1.133
+++ ppc-linux-tdep.c	18 Jan 2012 02:52:01 -0000
@@ -37,6 +37,7 @@
 #include "solist.h"
 #include "ppc-tdep.h"
 #include "ppc-linux-tdep.h"
+#include "glibc-tdep.h"
 #include "trad-frame.h"
 #include "frame-unwind.h"
 #include "tramp-frame.h"
@@ -65,6 +66,9 @@
 #include "features/rs6000/powerpc-isa205-vsx64l.c"
 #include "features/rs6000/powerpc-e500l.c"
 
+/* Shared library operations for PowerPC-Linux.  */
+static struct target_so_ops powerpc_so_ops;
+
 /* The syscall's XML filename for PPC and PPC64.  */
 #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
 #define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml"
@@ -599,6 +603,87 @@ ppc64_standard_linkage3_target (struct f
   return ppc64_desc_entry_point (gdbarch, desc);
 }
 
+/* PLT stub in executable.  */
+static struct insn_pattern powerpc32_plt_stub[] =
+  {
+    { 0xffff0000, 0x3d600000, 0 },	/* lis   r11, xxxx	 */
+    { 0xffff0000, 0x816b0000, 0 },	/* lwz   r11, xxxx(r11)  */
+    { 0xffffffff, 0x7d6903a6, 0 },	/* mtctr r11		 */
+    { 0xffffffff, 0x4e800420, 0 },	/* bctr			 */
+    {          0,          0, 0 }
+  };
+
+/* PLT stub in shared library.  */
+static struct insn_pattern powerpc32_plt_stub_so[] =
+  {
+    { 0xffff0000, 0x817e0000, 0 },	/* lwz   r11, xxxx(r30)  */
+    { 0xffffffff, 0x7d6903a6, 0 },	/* mtctr r11		 */
+    { 0xffffffff, 0x4e800420, 0 },	/* bctr			 */
+    { 0xffffffff, 0x60000000, 0 },	/* nop			 */
+    {          0,          0, 0 }
+  };
+#define POWERPC32_PLT_STUB_LEN 	\
+  (sizeof powerpc32_plt_stub / sizeof (powerpc32_plt_stub[0]))
+
+/* Check if PC is in PLT stub.  For non-secure PLT, stub is in .plt 
+   section.  For secure PLT, stub is in .text and we need to check
+   instruction patterns.  */
+
+static int
+powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  struct objfile *objfile;
+  struct minimal_symbol *sym;
+
+  /* Check whether PC is in the dynamic linker.  This also checks
+     whether it is in the .plt section, used by non-PIC executables.  */
+  if (svr4_in_dynsym_resolve_code (pc))
+    return 1;
+
+  /* Check if we are in the resolver.  */
+  sym = lookup_minimal_symbol_by_pc (pc);
+  if ((strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink") == 0)
+      || (strcmp (SYMBOL_LINKAGE_NAME (sym), "__glink_PLTresolve") == 0))
+    return 1;
+
+  return 0;
+}
+
+/* Follow PLT stub to actual routine.  */
+
+static CORE_ADDR
+ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+{
+  int insnbuf[POWERPC32_PLT_STUB_LEN];
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  CORE_ADDR target = 0;
+
+  if (insns_match_pattern (pc, powerpc32_plt_stub, insnbuf))
+    {
+      /* Insn pattern is 
+		lis   r11, xxxx	
+		lwz   r11, xxxx(r11) 
+	 Branch target is in r11.  */
+
+      target = (insn_d_field (insnbuf[0]) << 16) | insn_d_field (insnbuf[1]);
+      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
+    } 
+        
+  if (insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf))
+    {
+      /* Insn pattern is 
+		lwz   r11, xxxx(r30) 
+	 Branch target is in r11.  */
+      target = (CORE_ADDR) get_frame_register_unsigned (frame,
+						        tdep->ppc_gp0_regnum + 30)
+       	  + insn_d_field (insnbuf[0]);
+      target = (CORE_ADDR) read_memory_unsigned_integer (target, 4, byte_order);
+    }
+  
+  return target;
+}
 
 /* Given that we've begun executing a call trampoline at PC, return
    the entry point of the function the trampoline will go to.  */
@@ -1524,7 +1609,7 @@ ppc_linux_init_abi (struct gdbarch_info 
                                             ppc_linux_memory_remove_breakpoint);
 
       /* Shared library handling.  */
-      set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+      set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets
         (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 
@@ -1555,6 +1640,17 @@ ppc_linux_init_abi (struct gdbarch_info 
       else
 	set_gdbarch_core_regset_sections (gdbarch,
 					  ppc_linux_fp_regset_sections);
+
+      if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
+	{
+	  powerpc_so_ops = svr4_so_ops;
+	  /* Override dynamic resolve function.  */
+	  powerpc_so_ops.in_dynsym_resolve_code =
+	    powerpc_linux_in_dynsym_resolve_code;
+	}
+      set_solib_ops (gdbarch, &powerpc_so_ops);
+
+      set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
     }
   
   if (tdep->wordsize == 8)

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

end of thread, other threads:[~2012-01-30 17:11 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-18  4:00 [PATCH] PowerPC 32 with Secure PLT Michael Eager
2012-01-18 12:18 ` Joel Brobecker
2012-01-18 16:37   ` Michael Eager
2012-01-18 16:45     ` Michael Eager
2012-01-18 17:03       ` Joel Brobecker
2012-01-18 18:23         ` Michael Eager
  -- strict thread matches above, loose matches on Subject: below --
2012-01-18  3:36 Michael Eager
2012-01-25  0:37 ` Michael Eager
2012-01-25  1:12   ` Ryan Arnold
2012-01-25  1:55     ` Michael Eager
2012-01-30 17:19 ` Michael Eager

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).