Blame SOURCES/gdb-rhbz1125820-ppc64le-enablement-04of37.patch

01917d
commit 845d47080b7d7e068e4ec3d11fe6e27b403ac6e3
01917d
Author: Alan Modra <amodra@gmail.com>
01917d
Date:   Tue Jun 4 02:44:35 2013 +0000
01917d
01917d
    	* ppc-tdep.h (ppc_insns_match_pattern): Update prototype.
01917d
    	* rs6000-tdep.c (read_insn): Add frame param, don't assume big-endian.
01917d
    	(ppc_insns_match_pattern): Add frame param.  Avoid multiple
01917d
    	target mem reads on optional insns.
01917d
    	* ppc-linux-tdep.c (ppc_skip_trampoline_code): Update
01917d
    	ppc_insns_match_pattern calls.
01917d
    	* ppc64-tdep.c (ppc64_standard_linkage2, ppc64_standard_linkage3):
01917d
    	Add match for power7 thread safety insns, and new order of
01917d
    	std 2,40(1) insn.  Correct code shown for _dl_runtime_resolve
01917d
    	invocation in comment, and update rest of comment.
01917d
    	(PPC64_STANDARD_LINKAGE1_LEN, PPC64_STANDARD_LINKAGE2_LEN,
01917d
    	PPC64_STANDARD_LINKAGE3_LEN): Delete.
01917d
    	(ppc64_standard_linkage2_target): Update insn offsets.
01917d
    	(ppc64_skip_trampoline_code): Use a single insn buffer.  Match newer
01917d
    	stubs first.  Update calls.
01917d
01917d
Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
01917d
+++ gdb-7.6.1/gdb/ppc-linux-tdep.c
01917d
@@ -360,7 +360,7 @@ ppc_skip_trampoline_code (struct frame_i
01917d
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
01917d
   CORE_ADDR target = 0;
01917d
 
01917d
-  if (ppc_insns_match_pattern (pc, powerpc32_plt_stub, insnbuf))
01917d
+  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
01917d
     {
01917d
       /* Insn pattern is
01917d
 		lis   r11, xxxx
01917d
@@ -372,7 +372,7 @@ ppc_skip_trampoline_code (struct frame_i
01917d
       target = read_memory_unsigned_integer (target, 4, byte_order);
01917d
     }
01917d
 
01917d
-  if (ppc_insns_match_pattern (pc, powerpc32_plt_stub_so, insnbuf))
01917d
+  if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
01917d
     {
01917d
       /* Insn pattern is
01917d
 		lwz   r11, xxxx(r30)
01917d
Index: gdb-7.6.1/gdb/ppc-tdep.h
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/ppc-tdep.h
01917d
+++ gdb-7.6.1/gdb/ppc-tdep.h
01917d
@@ -300,9 +300,9 @@ struct ppc_insn_pattern
01917d
   int optional;                 /* If non-zero, this insn may be absent.  */
01917d
 };
01917d
 
01917d
-extern int ppc_insns_match_pattern (CORE_ADDR pc,
01917d
+extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
01917d
 				    struct ppc_insn_pattern *pattern,
01917d
-				    unsigned int *insn);
01917d
+				    unsigned int *insns);
01917d
 extern CORE_ADDR ppc_insn_d_field (unsigned int insn);
01917d
 
01917d
 extern CORE_ADDR ppc_insn_ds_field (unsigned int insn);
01917d
Index: gdb-7.6.1/gdb/ppc64-tdep.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/ppc64-tdep.c
01917d
+++ gdb-7.6.1/gdb/ppc64-tdep.c
01917d
@@ -59,9 +59,10 @@ ppc64_desc_entry_point (struct gdbarch *
01917d
   return (CORE_ADDR) read_memory_unsigned_integer (desc, 8, byte_order);
01917d
 }
01917d
 
01917d
-/* Pattern for the standard linkage function.  These are built by
01917d
-   build_plt_stub in elf64-ppc.c, whose GLINK argument is always
01917d
-   zero.  */
01917d
+/* Patterns for the standard linkage functions.  These are built by
01917d
+   build_plt_stub in bfd/elf64-ppc.c.  */
01917d
+
01917d
+/* Old PLT call stub.  */
01917d
 
01917d
 static struct ppc_insn_pattern ppc64_standard_linkage1[] =
01917d
   {
01917d
@@ -95,15 +96,23 @@ static struct ppc_insn_pattern ppc64_sta
01917d
     { 0, 0, 0 }
01917d
   };
01917d
 
01917d
-#define PPC64_STANDARD_LINKAGE1_LEN ARRAY_SIZE (ppc64_standard_linkage1)
01917d
+/* Current PLT call stub to access PLT entries more than +/- 32k from r2.
01917d
+   Also supports older stub with different placement of std 2,40(1),
01917d
+   a stub that omits the std 2,40(1), and both versions of power7
01917d
+   thread safety read barriers.  Note that there are actually two more
01917d
+   instructions following "cmpldi r2, 0", "bnectr+" and "b <glink_i>",
01917d
+   but there isn't any need to match them.  */
01917d
 
01917d
 static struct ppc_insn_pattern ppc64_standard_linkage2[] =
01917d
   {
01917d
+    /* std r2, 40(r1) <optional> */
01917d
+    { -1, insn_ds (62, 2, 1, 40, 0), 1 },
01917d
+
01917d
     /* addis r12, r2, <any> */
01917d
     { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
01917d
 
01917d
-    /* std r2, 40(r1) */
01917d
-    { -1, insn_ds (62, 2, 1, 40, 0), 0 },
01917d
+    /* std r2, 40(r1) <optional> */
01917d
+    { -1, insn_ds (62, 2, 1, 40, 0), 1 },
01917d
 
01917d
     /* ld r11, <any>(r12) */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
01917d
@@ -114,24 +123,33 @@ static struct ppc_insn_pattern ppc64_sta
01917d
     /* mtctr r11 */
01917d
     { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
01917d
 
01917d
+    /* xor r11, r11, r11 <optional> */
01917d
+    { -1, 0x7d6b5a78, 1 },
01917d
+
01917d
+    /* add r12, r12, r11 <optional> */
01917d
+    { -1, 0x7d8c5a14, 1 },
01917d
+
01917d
     /* ld r2, <any>(r12) */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
01917d
 
01917d
     /* ld r11, <any>(r12) <optional> */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 1 },
01917d
 
01917d
-    /* bctr */
01917d
-    { -1, 0x4e800420, 0 },
01917d
+    /* bctr <optional> */
01917d
+    { -1, 0x4e800420, 1 },
01917d
+
01917d
+    /* cmpldi r2, 0 <optional> */
01917d
+    { -1, 0x28220000, 1 },
01917d
 
01917d
     { 0, 0, 0 }
01917d
   };
01917d
 
01917d
-#define PPC64_STANDARD_LINKAGE2_LEN ARRAY_SIZE (ppc64_standard_linkage2)
01917d
+/* Current PLT call stub to access PLT entries within +/- 32k of r2.  */
01917d
 
01917d
 static struct ppc_insn_pattern ppc64_standard_linkage3[] =
01917d
   {
01917d
-    /* std r2, 40(r1) */
01917d
-    { -1, insn_ds (62, 2, 1, 40, 0), 0 },
01917d
+    /* std r2, 40(r1) <optional> */
01917d
+    { -1, insn_ds (62, 2, 1, 40, 0), 1 },
01917d
 
01917d
     /* ld r11, <any>(r2) */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 0 },
01917d
@@ -142,56 +160,71 @@ static struct ppc_insn_pattern ppc64_sta
01917d
     /* mtctr r11 */
01917d
     { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467), 0 },
01917d
 
01917d
+    /* xor r11, r11, r11 <optional> */
01917d
+    { -1, 0x7d6b5a78, 1 },
01917d
+
01917d
+    /* add r2, r2, r11 <optional> */
01917d
+    { -1, 0x7c425a14, 1 },
01917d
+
01917d
     /* ld r11, <any>(r2) <optional> */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 2, 0, 0), 1 },
01917d
 
01917d
     /* ld r2, <any>(r2) */
01917d
     { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 2, 0, 0), 0 },
01917d
 
01917d
-    /* bctr */
01917d
-    { -1, 0x4e800420, 0 },
01917d
+    /* bctr <optional> */
01917d
+    { -1, 0x4e800420, 1 },
01917d
+
01917d
+    /* cmpldi r2, 0 <optional> */
01917d
+    { -1, 0x28220000, 1 },
01917d
 
01917d
     { 0, 0, 0 }
01917d
   };
01917d
 
01917d
-#define PPC64_STANDARD_LINKAGE3_LEN ARRAY_SIZE (ppc64_standard_linkage3)
01917d
-
01917d
 /* When the dynamic linker is doing lazy symbol resolution, the first
01917d
    call to a function in another object will go like this:
01917d
 
01917d
    - The user's function calls the linkage function:
01917d
 
01917d
-	 100007c4:	4b ff fc d5		bl	10000498
01917d
-	 100007c8:	e8 41 00 28		ld	r2,40(r1)
01917d
+	100003d4:   4b ff ff ad     bl      10000380 <nnnn.plt_call.printf>
01917d
+	100003d8:   e8 41 00 28     ld      r2,40(r1)
01917d
 
01917d
-   - The linkage function loads the entry point (and other stuff) from
01917d
-	 the function descriptor in the PLT, and jumps to it:
01917d
+   - The linkage function loads the entry point and toc pointer from
01917d
+     the function descriptor in the PLT, and jumps to it:
01917d
 
01917d
-	 10000498:	3d 82 00 00		addis	r12,r2,0
01917d
-	 1000049c:	f8 41 00 28		std	r2,40(r1)
01917d
-	 100004a0:	e9 6c 80 98		ld	r11,-32616(r12)
01917d
-	 100004a4:	e8 4c 80 a0		ld	r2,-32608(r12)
01917d
-	 100004a8:	7d 69 03 a6		mtctr	r11
01917d
-	 100004ac:	e9 6c 80 a8		ld	r11,-32600(r12)
01917d
-	 100004b0:	4e 80 04 20		bctr
01917d
+     <nnnn.plt_call.printf>:
01917d
+	10000380:   f8 41 00 28     std     r2,40(r1)
01917d
+	10000384:   e9 62 80 78     ld      r11,-32648(r2)
01917d
+	10000388:   7d 69 03 a6     mtctr   r11
01917d
+	1000038c:   e8 42 80 80     ld      r2,-32640(r2)
01917d
+	10000390:   28 22 00 00     cmpldi  r2,0
01917d
+	10000394:   4c e2 04 20     bnectr+ 
01917d
+	10000398:   48 00 03 a0     b       10000738 <printf@plt>
01917d
 
01917d
    - But since this is the first time that PLT entry has been used, it
01917d
-	 sends control to its glink entry.  That loads the number of the
01917d
-	 PLT entry and jumps to the common glink0 code:
01917d
+     sends control to its glink entry.  That loads the number of the
01917d
+     PLT entry and jumps to the common glink0 code:
01917d
 
01917d
-	 10000c98:	38 00 00 00		li	r0,0
01917d
-	 10000c9c:	4b ff ff dc		b	10000c78
01917d
+     <printf@plt>:
01917d
+	10000738:   38 00 00 01     li      r0,1
01917d
+	1000073c:   4b ff ff bc     b       100006f8 <__glink_PLTresolve>
01917d
 
01917d
    - The common glink0 code then transfers control to the dynamic
01917d
-	 linker's fixup code:
01917d
+     linker's fixup code:
01917d
 
01917d
-	 10000c78:	e8 41 00 28		ld	r2,40(r1)
01917d
-	 10000c7c:	3d 82 00 00		addis	r12,r2,0
01917d
-	 10000c80:	e9 6c 80 80		ld	r11,-32640(r12)
01917d
-	 10000c84:	e8 4c 80 88		ld	r2,-32632(r12)
01917d
-	 10000c88:	7d 69 03 a6		mtctr	r11
01917d
-	 10000c8c:	e9 6c 80 90		ld	r11,-32624(r12)
01917d
-	 10000c90:	4e 80 04 20		bctr
01917d
+	100006f0:   0000000000010440 .quad plt0 - (. + 16)
01917d
+     <__glink_PLTresolve>:
01917d
+	100006f8:   7d 88 02 a6     mflr    r12
01917d
+	100006fc:   42 9f 00 05     bcl     20,4*cr7+so,10000700
01917d
+	10000700:   7d 68 02 a6     mflr    r11
01917d
+	10000704:   e8 4b ff f0     ld      r2,-16(r11)
01917d
+	10000708:   7d 88 03 a6     mtlr    r12
01917d
+	1000070c:   7d 82 5a 14     add     r12,r2,r11
01917d
+	10000710:   e9 6c 00 00     ld      r11,0(r12)
01917d
+	10000714:   e8 4c 00 08     ld      r2,8(r12)
01917d
+	10000718:   7d 69 03 a6     mtctr   r11
01917d
+	1000071c:   e9 6c 00 10     ld      r11,16(r12)
01917d
+	10000720:   4e 80 04 20     bctr
01917d
 
01917d
    Eventually, this code will figure out how to skip all of this,
01917d
    including the dynamic linker.  At the moment, we just get through
01917d
@@ -234,8 +267,8 @@ ppc64_standard_linkage2_target (struct f
01917d
   CORE_ADDR desc
01917d
     = ((CORE_ADDR) get_frame_register_unsigned (frame,
01917d
 						tdep->ppc_gp0_regnum + 2)
01917d
-       + (ppc_insn_d_field (insn[0]) << 16)
01917d
-       + ppc_insn_ds_field (insn[2]));
01917d
+       + (ppc_insn_d_field (insn[1]) << 16)
01917d
+       + ppc_insn_ds_field (insn[3]));
01917d
 
01917d
   /* The first word of the descriptor is the entry point.  Return that.  */
01917d
   return ppc64_desc_entry_point (gdbarch, desc);
01917d
@@ -266,23 +299,20 @@ ppc64_standard_linkage3_target (struct f
01917d
 CORE_ADDR
01917d
 ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
01917d
 {
01917d
-  unsigned int ppc64_standard_linkage1_insn[PPC64_STANDARD_LINKAGE1_LEN];
01917d
-  unsigned int ppc64_standard_linkage2_insn[PPC64_STANDARD_LINKAGE2_LEN];
01917d
-  unsigned int ppc64_standard_linkage3_insn[PPC64_STANDARD_LINKAGE3_LEN];
01917d
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
01917d
+  unsigned int insns[MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
01917d
+			       ARRAY_SIZE (ppc64_standard_linkage2)),
01917d
+			  ARRAY_SIZE (ppc64_standard_linkage3)) - 1];
01917d
   CORE_ADDR target;
01917d
 
01917d
-  if (ppc_insns_match_pattern (pc, ppc64_standard_linkage1,
01917d
-			       ppc64_standard_linkage1_insn))
01917d
-    pc = ppc64_standard_linkage1_target (frame, pc,
01917d
-					 ppc64_standard_linkage1_insn);
01917d
-  else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage2,
01917d
-				    ppc64_standard_linkage2_insn))
01917d
-    pc = ppc64_standard_linkage2_target (frame, pc,
01917d
-					 ppc64_standard_linkage2_insn);
01917d
-  else if (ppc_insns_match_pattern (pc, ppc64_standard_linkage3,
01917d
-				    ppc64_standard_linkage3_insn))
01917d
-    pc = ppc64_standard_linkage3_target (frame, pc,
01917d
-					 ppc64_standard_linkage3_insn);
01917d
+  if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
01917d
+      && (insns[8] != 0 || insns[9] != 0))
01917d
+    pc = ppc64_standard_linkage3_target (frame, pc, insns);
01917d
+  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
01917d
+	   && (insns[10] != 0 || insns[11] != 0))
01917d
+    pc = ppc64_standard_linkage2_target (frame, pc, insns);
01917d
+  else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
01917d
+    pc = ppc64_standard_linkage1_target (frame, pc, insns);
01917d
   else
01917d
     return 0;
01917d
 
01917d
Index: gdb-7.6.1/gdb/rs6000-tdep.c
01917d
===================================================================
01917d
--- gdb-7.6.1.orig/gdb/rs6000-tdep.c
01917d
+++ gdb-7.6.1/gdb/rs6000-tdep.c
01917d
@@ -4289,14 +4289,15 @@ show_powerpc_exact_watchpoints (struct u
01917d
   fprintf_filtered (file, _("Use of exact watchpoints is %s.\n"), value);
01917d
 }
01917d
 
01917d
-/* Read a PPC instruction from memory.  PPC instructions are always
01917d
-   big-endian, no matter what endianness the program is running in, so
01917d
-   we can hardcode BFD_ENDIAN_BIG for read_memory_unsigned_integer.  */
01917d
+/* Read a PPC instruction from memory.  */
01917d
 
01917d
 static unsigned int
01917d
-read_insn (CORE_ADDR pc)
01917d
+read_insn (struct frame_info *frame, CORE_ADDR pc)
01917d
 {
01917d
-  return read_memory_unsigned_integer (pc, 4, BFD_ENDIAN_BIG);
01917d
+  struct gdbarch *gdbarch = get_frame_arch (frame);
01917d
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
01917d
+
01917d
+  return read_memory_unsigned_integer (pc, 4, byte_order);
01917d
 }
01917d
 
01917d
 /* Return non-zero if the instructions at PC match the series
01917d
@@ -4313,19 +4314,25 @@ read_insn (CORE_ADDR pc)
01917d
    i'th instruction in memory.  */
01917d
 
01917d
 int
01917d
-ppc_insns_match_pattern (CORE_ADDR pc, struct ppc_insn_pattern *pattern,
01917d
-			 unsigned int *insn)
01917d
+ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
01917d
+			 struct ppc_insn_pattern *pattern,
01917d
+			 unsigned int *insns)
01917d
 {
01917d
   int i;
01917d
+  unsigned int insn;
01917d
 
01917d
-  for (i = 0; pattern[i].mask; i++)
01917d
+  for (i = 0, insn = 0; pattern[i].mask; i++)
01917d
     {
01917d
-      insn[i] = read_insn (pc);
01917d
-      if ((insn[i] & pattern[i].mask) == pattern[i].data)
01917d
-	pc += 4;
01917d
-      else if (pattern[i].optional)
01917d
-	insn[i] = 0;
01917d
-      else
01917d
+      if (insn == 0)
01917d
+	insn = read_insn (frame, pc);
01917d
+      insns[i] = 0;
01917d
+      if ((insn & pattern[i].mask) == pattern[i].data)
01917d
+	{
01917d
+	  insns[i] = insn;
01917d
+	  pc += 4;
01917d
+	  insn = 0;
01917d
+	}
01917d
+      else if (!pattern[i].optional)
01917d
 	return 0;
01917d
     }
01917d