File ltrace-ppc64le_git1.patch of Package ltrace

--- proc.c.ori
+++ proc.c
@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2010 Joe Damato
  * Copyright (C) 1998,2009 Juan Cespedes
  *
@@ -1035,3 +1035,25 @@ proc_each_symbol(struct Process *proc, struct library_symbol *start_after,
 
 	return NULL;
 }
+
+#define DEF_READER(NAME, SIZE)						\
+	int								\
+	NAME(struct Process *proc, arch_addr_t addr,			\
+	     uint##SIZE##_t *lp)					\
+	{								\
+		union {							\
+			uint##SIZE##_t dst;				\
+			char buf[0];					\
+		} u;							\
+		if (umovebytes(proc, addr, &u.buf, sizeof(u.dst))	\
+		    != sizeof(u.dst))					\
+			return -1;					\
+		*lp = u.dst;						\
+		return 0;						\
+	}
+
+DEF_READER(proc_read_16, 16)
+DEF_READER(proc_read_32, 32)
+DEF_READER(proc_read_64, 64)
+
+#undef DEF_READER
--- proc.h.ori
+++ proc.h
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2010,2011,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2010,2011,2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2010 Joe Damato
  * Copyright (C) 1998,2001,2008,2009 Juan Cespedes
  *
@@ -26,6 +26,7 @@
 #include "config.h"
 
 #include <sys/time.h>
+#include <stdint.h>
 
 #if defined(HAVE_LIBUNWIND)
 # include <libunwind.h>
@@ -254,4 +255,12 @@ struct library_symbol *proc_each_symbol
 	 enum callback_status (*cb)(struct library_symbol *, void *),
 	 void *data);
 
+/* Read 16, 32 or 64-bit quantity located at ADDR in PROC.  The
+ * resulting value is stored in *LP.  0 is returned on success or a
+ * negative value on failure.  This uses umovebytes under the hood
+ * (see backend.h).  */
+int proc_read_16(struct Process *proc, arch_addr_t addr, uint16_t *lp);
+int proc_read_32(struct Process *proc, arch_addr_t addr, uint32_t *lp);
+int proc_read_64(struct Process *proc, arch_addr_t addr, uint64_t *lp);
+
 #endif /* _PROC_H_ */
--- sysdeps/linux-gnu/ppc/plt.c.ori
+++ sysdeps/linux-gnu/ppc/plt.c
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2004,2008,2009 Juan Cespedes
  * Copyright (C) 2006 Paul Gilliam
  *
@@ -125,51 +125,6 @@ host_powerpc64()
 #endif
 }
 
-int
-read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp)
-{
-	unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
-	if (l == -1UL && errno)
-		return -1;
-#ifdef __powerpc64__
-	l >>= 32;
-#endif
-	*lp = l;
-	return 0;
-}
-
-static int
-read_target_8(struct Process *proc, arch_addr_t addr, uint64_t *lp)
-{
-	unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
-	if (l == -1UL && errno)
-		return -1;
-	if (host_powerpc64()) {
-		*lp = l;
-	} else {
-		unsigned long l2 = ptrace(PTRACE_PEEKTEXT, proc->pid,
-					  addr + 4, 0);
-		if (l2 == -1UL && errno)
-			return -1;
-		*lp = ((uint64_t)l << 32) | l2;
-	}
-	return 0;
-}
-
-int
-read_target_long(struct Process *proc, arch_addr_t addr, uint64_t *lp)
-{
-	if (proc->e_machine == EM_PPC) {
-		uint32_t w;
-		int ret = read_target_4(proc, addr, &w);
-		if (ret >= 0)
-			*lp = (uint64_t)w;
-		return ret;
-	} else {
-		return read_target_8(proc, addr, lp);
-	}
-}
-
 static void
 mark_as_resolved(struct library_symbol *libsym, GElf_Addr value)
 {
@@ -184,8 +139,8 @@ arch_dynlink_done(struct Process *proc)
 	struct library_symbol *libsym = NULL;
 	while ((libsym = proc_each_symbol(proc, libsym,
 					  library_symbol_delayed_cb, NULL))) {
-		if (read_target_8(proc, libsym->enter_addr,
-				  &libsym->arch.resolved_value) < 0) {
+		if (proc_read_64(proc, libsym->enter_addr,
+				 &libsym->arch.resolved_value) < 0) {
 			fprintf(stderr,
 				"couldn't read PLT value for %s(%p): %s\n",
 				libsym->name, libsym->enter_addr,
@@ -263,7 +218,7 @@ arch_translate_address_dyn(struct Process *proc,
 {
 	if (proc->e_machine == EM_PPC64) {
 		uint64_t value;
-		if (read_target_8(proc, addr, &value) < 0) {
+		if (proc_read_64(proc, addr, &value) < 0) {
 			fprintf(stderr,
 				"dynamic .opd translation of %p: %s\n",
 				addr, strerror(errno));
@@ -568,7 +523,7 @@ read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp)
 	 * either can change.  */
 	uint64_t l;
 	/* XXX double cast.  */
-	if (read_target_8(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) {
+	if (proc_read_64(proc, (arch_addr_t)(uintptr_t)addr, &l) < 0) {
 		fprintf(stderr, "ptrace .plt slot value @%#" PRIx64": %s\n",
 			addr, strerror(errno));
 		return -1;
--- sysdeps/linux-gnu/ppc/trace.c.ori
+++ sysdeps/linux-gnu/ppc/trace.c
@@ -84,9 +84,6 @@ syscall_p(struct Process *proc, int status, int *sysnum)
 
 /* The atomic skip code is mostly taken from GDB.  */
 
-/* In plt.h.  XXX make this official interface.  */
-int read_target_4(struct Process *proc, arch_addr_t addr, uint32_t *lp);
-
 int
 arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 		       int (*add_cb)(void *addr, void *data),
@@ -107,7 +107,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 	} u;
 	if (other != NULL) {
 		memcpy(u.buf, sbp->orig_value, BREAKPOINT_LENGTH);
-	} else if (read_target_4(proc, ip, &u.insn) < 0) {
+	} else if (proc_read_32(proc, ip, &u.insn) < 0) {
 		fprintf(stderr, "couldn't read instruction at IP %p\n", ip);
 		/* Do the normal singlestep.  */
 		return 1;