Rename atomic singlestep to software singlestep

- The old name came from PPC implementation, where the feature was used for
  skipping atomic instructions.  But this is more useful, was reused for
  fully software singlestepping on MIPS, and will be similarly used for ARM.
  So rename the interface, and make the prototype more explicit.
- Also document the method in backend.h.
- And convert several void*'s to arch_addr_t's while there.
diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h
index 684b546..ba1220d 100644
--- a/sysdeps/linux-gnu/mipsel/arch.h
+++ b/sysdeps/linux-gnu/mipsel/arch.h
@@ -1,5 +1,6 @@
 /*
  * This file is part of ltrace.
+ * Copyright (C) 2013 Petr Machata
  * Copyright (C) 2006 Eric Vaitl
  *
  * This program is free software; you can redistribute it and/or
@@ -43,7 +44,7 @@
 #define ARCH_HAVE_GET_SYMINFO
 #define ARCH_HAVE_DYNLINK_DONE
 #define ARCH_HAVE_ADD_PLT_ENTRY
-#define ARCH_HAVE_ATOMIC_SINGLESTEP
+#define ARCH_HAVE_SW_SINGLESTEP
 #define ARCH_HAVE_SYMBOL_RET
 
 #define ARCH_HAVE_LIBRARY_SYMBOL_DATA
diff --git a/sysdeps/linux-gnu/mipsel/trace.c b/sysdeps/linux-gnu/mipsel/trace.c
index 7fa3ed4..f553166 100644
--- a/sysdeps/linux-gnu/mipsel/trace.c
+++ b/sysdeps/linux-gnu/mipsel/trace.c
@@ -1,5 +1,6 @@
 /*
  * This file is part of ltrace.
+ * Copyright (C) 2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications
  * Copyright (C) 2010 Arnaud Patard, Mandriva SA
  * Copyright (C) 2008,2009 Juan Cespedes
@@ -263,10 +264,10 @@
 	return 0;
 }
 
-int
-arch_atomic_singlestep(struct process *proc, struct breakpoint *sbp,
-		       int (*add_cb)(void *addr, void *data),
-		       void *add_cb_data)
+enum sw_singlestep_status
+arch_sw_singlestep(struct process *proc, struct breakpoint *bp,
+		   int (*add_cb)(arch_addr_t, struct sw_singlestep_data *),
+		   struct sw_singlestep_data *add_cb_data)
 {
 	uint32_t pc = (uint32_t) get_instruction_pointer(proc);
 	uint32_t newpcs[2];
@@ -283,11 +284,11 @@
 		}
 
 		if (add_cb(baddr, add_cb_data) < 0)
-			return -1;
+			return SWS_FAIL;
 	}
 
 	ptrace(PTRACE_SYSCALL, proc->pid, 0, 0);
-	return 0;
+	return SWS_OK;
 }
 
 /**
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index fb8768a..3b903ee 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2012 Petr Machata
+ * Copyright (C) 2012,2013 Petr Machata
  * Copyright (C) 2006 Paul Gilliam
  * Copyright (C) 2002,2004 Juan Cespedes
  *
@@ -37,7 +37,7 @@
 #define ARCH_SUPPORTS_OPD
 #endif
 
-#define ARCH_HAVE_ATOMIC_SINGLESTEP
+#define ARCH_HAVE_SW_SINGLESTEP
 #define ARCH_HAVE_ADD_PLT_ENTRY
 #define ARCH_HAVE_TRANSLATE_ADDRESS
 #define ARCH_HAVE_DYNLINK_DONE
diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c
index d1c28e8..396ba3d 100644
--- a/sysdeps/linux-gnu/ppc/trace.c
+++ b/sysdeps/linux-gnu/ppc/trace.c
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2010,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2010,2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2011 Andreas Schwab
  * Copyright (C) 2002,2004,2008,2009 Juan Cespedes
  * Copyright (C) 2008 Luis Machado, IBM Corporation
@@ -89,15 +89,15 @@
 /* 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),
-		       void *add_cb_data)
+enum sw_singlestep_status
+arch_sw_singlestep(struct process *proc, struct breakpoint *sbp,
+		   int (*add_cb)(arch_addr_t, struct sw_singlestep_data *),
+		   struct sw_singlestep_data *add_cb_data)
 {
 	arch_addr_t ip = get_instruction_pointer(proc);
 	struct breakpoint *other = address2bpstruct(proc->leader, ip);
 
-	debug(1, "arch_atomic_singlestep pid=%d addr=%p %s(%p)",
+	debug(1, "arch_sw_singlestep pid=%d addr=%p %s(%p)",
 	      proc->pid, ip, breakpoint_name(sbp), sbp->addr);
 
 	/* If the original instruction was lwarx/ldarx, we can't
@@ -112,12 +112,12 @@
 	} else if (read_target_4(proc, ip, &u.insn) < 0) {
 		fprintf(stderr, "couldn't read instruction at IP %p\n", ip);
 		/* Do the normal singlestep.  */
-		return 1;
+		return SWS_HW;
 	}
 
 	if ((u.insn & LWARX_MASK) != LWARX_INSTRUCTION
 	    && (u.insn & LWARX_MASK) != LDARX_INSTRUCTION)
-		return 1;
+		return SWS_HW;
 
 	debug(1, "singlestep over atomic block at %p", ip);
 
@@ -127,7 +127,7 @@
 		addr += 4;
 		unsigned long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
 		if (l == (unsigned long)-1 && errno)
-			return -1;
+			return SWS_FAIL;
 		uint32_t insn;
 #ifdef __powerpc64__
 		insn = l >> 32;
@@ -142,7 +142,7 @@
 			debug(1, "pid=%d, branch in atomic block from %p to %p",
 			      proc->pid, addr, branch_addr);
 			if (add_cb(branch_addr, add_cb_data) < 0)
-				return -1;
+				return SWS_FAIL;
 		}
 
 		/* Assume that the atomic sequence ends with a
@@ -159,18 +159,18 @@
 		if (insn_count > 16) {
 			fprintf(stderr, "[%d] couldn't find end of atomic block"
 				" at %p\n", proc->pid, ip);
-			return -1;
+			return SWS_FAIL;
 		}
 	}
 
 	/* Put the breakpoint to the next instruction.  */
 	addr += 4;
 	if (add_cb(addr, add_cb_data) < 0)
-		return -1;
+		return SWS_FAIL;
 
 	debug(1, "PTRACE_CONT");
 	ptrace(PTRACE_CONT, proc->pid, 0, 0);
-	return 0;
+	return SWS_OK;
 }
 
 size_t
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index cf72bd6..fe1f960 100644
--- a/sysdeps/linux-gnu/trace.c
+++ b/sysdeps/linux-gnu/trace.c
@@ -1,6 +1,6 @@
 /*
  * This file is part of ltrace.
- * Copyright (C) 2007,2011,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2007,2011,2012,2013 Petr Machata, Red Hat Inc.
  * Copyright (C) 2010 Joe Damato
  * Copyright (C) 1998,2002,2003,2004,2008,2009 Juan Cespedes
  * Copyright (C) 2006 Ian Wienand
@@ -540,19 +540,13 @@
 	return 1;
 }
 
-/* The protocol is: 0 for success, negative for failure, positive if
- * default singlestep is to be used.  */
-int arch_atomic_singlestep(struct process *proc, struct breakpoint *sbp,
-			   int (*add_cb)(void *addr, void *data),
-			   void *add_cb_data);
-
-#ifndef ARCH_HAVE_ATOMIC_SINGLESTEP
-int
-arch_atomic_singlestep(struct process *proc, struct breakpoint *sbp,
-		       int (*add_cb)(void *addr, void *data),
-		       void *add_cb_data)
+#ifndef ARCH_HAVE_SW_SINGLESTEP
+enum sw_singlestep_status
+arch_sw_singlestep(struct process *proc, struct breakpoint *bp,
+		   int (*add_cb)(arch_addr_t, struct sw_singlestep_data *),
+		   struct sw_singlestep_data *data)
 {
-	return 1;
+	return SWS_HW;
 }
 #endif
 
@@ -560,43 +554,46 @@
 					Event *event);
 
 static void
-remove_atomic_breakpoints(struct process *proc)
+remove_sw_breakpoints(struct process *proc)
 {
 	struct process_stopping_handler *self
 		= (void *)proc->leader->event_handler;
 	assert(self != NULL);
 	assert(self->super.on_event == process_stopping_on_event);
 
-	int ct = sizeof(self->atomic_skip_bp_addrs)
-		/ sizeof(*self->atomic_skip_bp_addrs);
+	int ct = sizeof(self->sws_bp_addrs) / sizeof(*self->sws_bp_addrs);
 	int i;
 	for (i = 0; i < ct; ++i)
-		if (self->atomic_skip_bp_addrs[i] != 0) {
-			delete_breakpoint(proc, self->atomic_skip_bp_addrs[i]);
-			self->atomic_skip_bp_addrs[i] = 0;
+		if (self->sws_bp_addrs[i] != 0) {
+			delete_breakpoint(proc, self->sws_bp_addrs[i]);
+			self->sws_bp_addrs[i] = 0;
 		}
 }
 
 static void
-atomic_singlestep_bp_on_hit(struct breakpoint *bp, struct process *proc)
+sw_singlestep_bp_on_hit(struct breakpoint *bp, struct process *proc)
 {
-	remove_atomic_breakpoints(proc);
+	remove_sw_breakpoints(proc);
 }
 
+struct sw_singlestep_data {
+	struct process_stopping_handler *self;
+};
+
 static int
-atomic_singlestep_add_bp(void *addr, void *data)
+sw_singlestep_add_bp(arch_addr_t addr, struct sw_singlestep_data *data)
 {
-	struct process_stopping_handler *self = data;
+	struct process_stopping_handler *self = data->self;
 	struct process *proc = self->task_enabling_breakpoint;
 
-	int ct = sizeof(self->atomic_skip_bp_addrs)
-		/ sizeof(*self->atomic_skip_bp_addrs);
+	int ct = sizeof(self->sws_bp_addrs)
+		/ sizeof(*self->sws_bp_addrs);
 	int i;
 	for (i = 0; i < ct; ++i)
-		if (self->atomic_skip_bp_addrs[i] == 0) {
-			self->atomic_skip_bp_addrs[i] = addr;
+		if (self->sws_bp_addrs[i] == 0) {
+			self->sws_bp_addrs[i] = addr;
 			static struct bp_callbacks cbs = {
-				.on_hit = atomic_singlestep_bp_on_hit,
+				.on_hit = sw_singlestep_bp_on_hit,
 			};
 			struct breakpoint *bp
 				= insert_breakpoint(proc, addr, NULL);
@@ -604,7 +601,7 @@
 			return 0;
 		}
 
-	assert(!"Too many atomic singlestep breakpoints!");
+	assert(!"Too many sw singlestep breakpoints!");
 	abort();
 }
 
@@ -613,9 +610,10 @@
 {
 	struct process *proc = self->task_enabling_breakpoint;
 
-	int status = arch_atomic_singlestep(self->task_enabling_breakpoint,
-					    self->breakpoint_being_enabled,
-					    &atomic_singlestep_add_bp, self);
+	struct sw_singlestep_data data = { self };
+	int status = arch_sw_singlestep(self->task_enabling_breakpoint,
+					self->breakpoint_being_enabled,
+					&sw_singlestep_add_bp, &data);
 
 	/* Propagate failure and success.  */
 	if (status <= 0)
@@ -641,7 +639,7 @@
 
 	struct process *proc = self->task_enabling_breakpoint;
 
-	remove_atomic_breakpoints(proc);
+	remove_sw_breakpoints(proc);
 	self->breakpoint_being_enabled = NULL;
 }
 
diff --git a/sysdeps/linux-gnu/trace.h b/sysdeps/linux-gnu/trace.h
index 7aed2e7..e988f70 100644
--- a/sysdeps/linux-gnu/trace.h
+++ b/sysdeps/linux-gnu/trace.h
@@ -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.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -65,7 +65,7 @@
 	struct breakpoint *breakpoint_being_enabled;
 
 	/* Artificial atomic skip breakpoint, if any needed.  */
-	void *atomic_skip_bp_addrs[2];
+	arch_addr_t sws_bp_addrs[2];
 
 	/* When all tasks are stopped, this callback gets called.  */
 	void (*on_all_stopped)(struct process_stopping_handler *);