Added Paul Gilliam's secure PLT patch
diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c
index 30f2093..86511a9 100644
--- a/sysdeps/linux-gnu/alpha/plt.c
+++ b/sysdeps/linux-gnu/alpha/plt.c
@@ -7,7 +7,7 @@
 	return lte->plt_addr + ndx * 12 + 32;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c
index 69e0077..cc6005e 100644
--- a/sysdeps/linux-gnu/arm/plt.c
+++ b/sysdeps/linux-gnu/arm/plt.c
@@ -7,7 +7,7 @@
 	return lte->plt_addr + 20 + ndx * 12;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index 051ac00..3e11b24 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -33,7 +33,7 @@
 		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
 			unsigned char *bytes = (unsigned char *)&a;
 
-			sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
+			sbp->orig_value[i * sizeof(long) + j] = bytes[j];
 			bytes[j] = break_insn[i * sizeof(long) + j];
 		}
 		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
@@ -52,9 +52,7 @@
 {
 	unsigned int i, j;
 
-	if (opt_d > 1) {
-		output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
-	}
+	debug(2, "disable_breakpoint(%d,%p)", pid, sbp->addr);
 
 	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
 		long a =
diff --git a/sysdeps/linux-gnu/i386/plt.c b/sysdeps/linux-gnu/i386/plt.c
index 3eab56c..e8a2349 100644
--- a/sysdeps/linux-gnu/i386/plt.c
+++ b/sysdeps/linux-gnu/i386/plt.c
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 16;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
index faa3c0e..b1d1af4 100644
--- a/sysdeps/linux-gnu/ia64/plt.c
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -42,7 +42,7 @@
 	return addr;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c
index f1af366..8ee29e0 100644
--- a/sysdeps/linux-gnu/m68k/plt.c
+++ b/sysdeps/linux-gnu/m68k/plt.c
@@ -8,7 +8,7 @@
 	    * ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index 7147b97..04692c4 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -4,10 +4,18 @@
 
 #define LT_ELFCLASS	ELFCLASS32
 #define LT_ELF_MACHINE	EM_PPC
-#ifdef __powerpc64__
+#ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
 #define LT_ELFCLASS2	ELFCLASS64
 #define LT_ELF_MACHINE2	EM_PPC64
 
 #define PLT_REINITALISATION_BP    "_start"
 
+#define PPC_NOP { 0x60, 0x00, 0x00, 0x00 }
+#define PPC_NOP_LENGTH 4
+
+#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
+#error "Length of the breakpoint value not equal to the length of a nop instruction"
+#endif
+
+
 #endif
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 36c713b..e14e4c3 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -10,31 +10,49 @@
 	return rela->r_offset;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	long addr;
+	long addr = sym->enter_addr;
+	long pt_ret;
 
 	debug(3, 0);
 
-	if (proc->e_machine == EM_PPC || plt == 0)
-		return (void *)plt;
-
-	if (proc->pid == 0)
-		return (void *)0;
-
-	// On a PowerPC-64 system, a plt is three 64-bit words: the first is the
-	// 64-bit address of the routine.  Before the PLT has been initialized, this
-	// will be 0x0. In fact, the symbol table won't have the plt's address even.
-	// Ater the PLT has been initialized, but before it has been resolved, the
-	// first word will be the address of the function in the dynamic linker that
-	// will reslove the PLT.  After the PLT is resolved, this will will be the
-	// address of the routine whose symbol is in the symbol table.
-
-	addr = ptrace(PTRACE_PEEKTEXT, proc->pid, plt);
-
-	if (opt_d >= 3) {
-		xinfdump(proc->pid, plt, sizeof(void *) * 3);
+	if (sym->plt_type != LS_TOPLT_POINT) {
+		return addr;
 	}
 
-	return (void *)addr;
+	if (proc->pid == 0) {
+		return 0;
+	}
+
+	if (opt_d >= 3) {
+		xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0),
+			 sizeof(void*)*8);
+	}
+
+	// On a PowerPC-64 system, a plt is three 64-bit words: the first is the
+	// 64-bit address of the routine.  Before the PLT has been initialized,
+	// this will be 0x0. In fact, the symbol table won't have the plt's
+	// address even.  Ater the PLT has been initialized, but before it has
+	// been resolved, the first word will be the address of the function in
+	// the dynamic linker that will reslove the PLT.  After the PLT is
+	// resolved, this will will be the address of the routine whose symbol
+	// is in the symbol table.
+
+	// On a PowerPC-32 system, there are two types of PLTs: secure (new) and
+	// non-secure (old).  For the secure case, the PLT is simply a pointer
+	// and we can treat it much as we do for the PowerPC-64 case.  For the
+	// non-secure case, the PLT is executable code and we can put the
+	// break-point right in the PLT.
+
+	pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
+
+	if (proc->mask_32bit) {
+		// Assume big-endian.
+		addr = (void *)((pt_ret >> 32) & 0xffffffff);
+	} else {
+		addr = (void *)pt_ret;
+	}
+
+	return addr;
 }
diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c
index 888c285..ffe7f11 100644
--- a/sysdeps/linux-gnu/s390/plt.c
+++ b/sysdeps/linux-gnu/s390/plt.c
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 32;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c
index 68343b9..87dad8c 100644
--- a/sysdeps/linux-gnu/sparc/plt.c
+++ b/sysdeps/linux-gnu/sparc/plt.c
@@ -7,7 +7,7 @@
 	return rela->r_offset + 4;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/x86_64/plt.c b/sysdeps/linux-gnu/x86_64/plt.c
index 3eab56c..e8a2349 100644
--- a/sysdeps/linux-gnu/x86_64/plt.c
+++ b/sysdeps/linux-gnu/x86_64/plt.c
@@ -7,7 +7,7 @@
 	return lte->plt_addr + (ndx + 1) * 16;
 }
 
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
-	return (void *)plt;
+	return sym->enter_addr;
 }