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;