Create breakpoint.h with decls related to breakpoints
diff --git a/ChangeLog b/ChangeLog
index 6107a12..dffc370 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,15 @@
 
 2012-02-07  Petr Machata  <pmachata@redhat.com>
 
+	* breakpoint.h: New header file.
+	* common.h (struct breakpoint): Move to breakpoint.h.
+	(address2bpstruct, breakpoints_init, insert_breakpoint)
+	(delete_breakpoint, enable_all_breakpoints, enable_breakpoint)
+	(disable_breakpoint, reinitialize_breakpoints): Likewise.
+	(insert_breakpoint): Now returns the created breakpoint.
+
+2012-02-07  Petr Machata  <pmachata@redhat.com>
+
 	* common.h (wait_for_proc): New interface.
 	* sysdeps/linux-gnu/trace.c: Implement it.
 	* execute_program.c: Call it.
diff --git a/breakpoint.h b/breakpoint.h
new file mode 100644
index 0000000..1b7ca84
--- /dev/null
+++ b/breakpoint.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of ltrace.
+ * Copyright (C) 2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2009 Juan Cespedes
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef BREAKPOINT_H
+#define BREAKPOINT_H
+
+/* XXX This is currently a very weak abstraction.  We would like to
+ * much expand this to allow things like breakpoints on SDT probes and
+ * such.
+ *
+ * In particular, we would like to add a tracepoint abstraction.
+ * Tracepoint is a traceable feature--e.g. an exact address, a DWARF
+ * symbol, an ELF symbol, a PLT entry, or an SDT probe.  Tracepoints
+ * are named and the user can configure which of them he wants to
+ * enable.  Realized tracepoints enable breakpoints, which are a
+ * low-level realization of high-level tracepoint.
+ *
+ * Tracepoints are provided by the main binary as well as by any
+ * opened libraries: every time an ELF file is mapped into the address
+ * space, a new set of tracepoints is extracted, and filtered
+ * according to user settings.  Those tracepoints that are left are
+ * then realized, and the tracing starts.
+ *
+ * A scheme like this would take care of gradually introducing
+ * breakpoints when the library is mapped, and therefore ready, and
+ * would avoid certain hacks.  For example on PPC64, we don't actually
+ * add breakpoints to PLT.  Instead, we read the PLT (which contains
+ * addresses, not code), to figure out where to put the breakpoints.
+ * In prelinked code, that address is non-zero, and points to an
+ * address that's not yet mapped.  ptrace then fails when we try to
+ * add the breakpoint.
+ *
+ * Ideally, return breakpoints would be just a special kind of
+ * tracepoint that has attached some magic.  Or a feature of a
+ * tracepoint.  Service breakpoints like the handling of dlopen would
+ * be a low-level breakpoint, likely without tracepoint attached.
+ *
+ * So that's for sometimes.
+ */
+
+#include "arch.h"
+
+struct Process;
+
+typedef struct breakpoint Breakpoint;
+struct breakpoint {
+	void *addr;
+	unsigned char orig_value[BREAKPOINT_LENGTH];
+	int enabled;
+	struct library_symbol *libsym;
+#ifdef __arm__
+	int thumb_mode;
+#endif
+};
+
+/* This is actually three functions rolled in one:
+ *  - breakpoint_init
+ *  - proc_insert_breakpoint
+ *  - breakpoint_enable
+ * XXX I think it should be broken up somehow.  */
+struct breakpoint *insert_breakpoint(struct Process *proc, void *addr,
+				     struct library_symbol *libsym, int enable);
+
+/* */
+void delete_breakpoint(struct Process *proc, void *addr);
+
+/* XXX some of the following belongs to proc.h/proc.c.  */
+struct breakpoint *address2bpstruct(struct Process *proc, void *addr);
+void enable_all_breakpoints(struct Process *proc);
+void disable_all_breakpoints(struct Process *proc);
+int breakpoints_init(struct Process *proc, int enable);
+
+void reinitialize_breakpoints(struct Process *proc);
+
+
+#endif /* BREAKPOINT_H */
diff --git a/breakpoints.c b/breakpoints.c
index ec84e6e..6e2f490 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -8,11 +8,12 @@
 #include <sys/ptrace.h>
 #endif
 
+#include "breakpoint.h"
 #include "common.h"
 
 /*****************************************************************************/
 
-Breakpoint *
+struct breakpoint *
 address2bpstruct(Process *proc, void *addr)
 {
 	assert(proc != NULL);
@@ -22,11 +23,11 @@
 	return dict_find_entry(proc->breakpoints, addr);
 }
 
-void
+struct breakpoint *
 insert_breakpoint(Process *proc, void *addr,
 		  struct library_symbol *libsym, int enable)
 {
-	Breakpoint *sbp;
+	struct breakpoint *sbp;
 
 	Process * leader = proc->leader;
 
@@ -45,7 +46,7 @@
 	debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr);
 
 	if (!addr)
-		return;
+		return NULL;
 
 	if (libsym)
 		libsym->needs_init = 0;
@@ -54,7 +55,7 @@
 	if (sbp == NULL) {
 		sbp = calloc(1, sizeof(*sbp));
 		if (sbp == NULL) {
-			return;	/* TODO FIXME XXX: error_mem */
+			return NULL;	/* TODO FIXME XXX: error_mem */
 		}
 		dict_enter(leader->breakpoints, addr, sbp);
 		sbp->addr = addr;
@@ -69,12 +70,14 @@
 		assert(proc->pid != 0);
 		enable_breakpoint(proc, sbp);
 	}
+
+	return sbp;
 }
 
 void
 delete_breakpoint(Process *proc, void *addr)
 {
-	Breakpoint *sbp;
+	struct breakpoint *sbp;
 
 	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
 
diff --git a/common.h b/common.h
index b6e10f2..c6c7317 100644
--- a/common.h
+++ b/common.h
@@ -26,17 +26,6 @@
 
 extern int exiting;  /* =1 if we have to exit ASAP */
 
-typedef struct Breakpoint Breakpoint;
-struct Breakpoint {
-	void * addr;
-	unsigned char orig_value[BREAKPOINT_LENGTH];
-	int enabled;
-	struct library_symbol * libsym;
-#ifdef __arm__
-	int thumb_mode;
-#endif
-};
-
 enum arg_type {
 	ARGTYPE_UNKNOWN = -1,
 	ARGTYPE_VOID,
@@ -187,7 +176,7 @@
 	pid_t pid;
 
 	/* Dictionary of breakpoints (which is a mapping
-	 * address->Breakpoint).  This is NULL for non-leader
+	 * address->breakpoint).  This is NULL for non-leader
 	 * processes.  */
 	Dict * breakpoints;
 
@@ -296,14 +285,7 @@
 
 extern pid_t execute_program(const char * command, char ** argv);
 extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
-extern Breakpoint * address2bpstruct(Process * proc, void * addr);
-extern int breakpoints_init(Process * proc, int enable);
-extern void insert_breakpoint(Process * proc, void * addr,
-			      struct library_symbol * libsym, int enable);
-extern void delete_breakpoint(Process * proc, void * addr);
-extern void enable_all_breakpoints(Process * proc);
 extern void disable_all_breakpoints(Process * proc);
-extern void reinitialize_breakpoints(Process *);
 
 extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
 extern void open_pid(pid_t pid);
@@ -322,6 +304,8 @@
 extern void destroy_library_symbol(struct library_symbol * s);
 extern void destroy_library_symbol_chain(struct library_symbol * chain);
 
+struct breakpoint;
+
 /* Arch-dependent stuff: */
 extern char * pid2name(pid_t pid);
 extern pid_t process_leader(pid_t pid);
@@ -339,13 +323,13 @@
 extern void * get_stack_pointer(Process * proc);
 extern void * get_return_addr(Process * proc, void * stack_pointer);
 extern void set_return_addr(Process * proc, void * addr);
-extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
-extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
+extern void enable_breakpoint(Process * proc, struct breakpoint *sbp);
+extern void disable_breakpoint(Process * proc, struct breakpoint *sbp);
 extern int syscall_p(Process * proc, int status, int * sysnum);
 extern void continue_process(pid_t pid);
 extern void continue_after_signal(pid_t pid, int signum);
 extern void continue_after_syscall(Process *proc, int sysnum, int ret_p);
-extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
+extern void continue_after_breakpoint(Process * proc, struct breakpoint *sbp);
 extern void continue_after_vfork(Process * proc);
 extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
 extern void save_register_args(enum tof type, Process * proc);
diff --git a/handle_event.c b/handle_event.c
index 8c3c7ce..63ed536 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -14,6 +14,7 @@
 #endif
 
 #include "common.h"
+#include "breakpoint.h"
 
 static void handle_signal(Event *event);
 static void handle_exit(Event *event);
@@ -158,10 +159,9 @@
 static void *
 breakpoint_clone(void *bp, void *data)
 {
-	Breakpoint * b;
 	Dict *map = data;
 	debug(DEBUG_FUNCTION, "breakpoint_clone(%p)", bp);
-	b = malloc(sizeof(Breakpoint));
+	struct breakpoint *b = malloc(sizeof(*b));
 	if (!b) {
 		perror("malloc()");
 		exit(1);
diff --git a/proc.c b/proc.c
index ded0c95..ec6bd3a 100644
--- a/proc.c
+++ b/proc.c
@@ -14,6 +14,7 @@
 #include <error.h>
 
 #include "common.h"
+#include "breakpoint.h"
 
 Process *
 open_program(char *filename, pid_t pid, int enable) {
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index 5a49e9d..bbfa481 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -5,6 +5,7 @@
 
 #include "common.h"
 #include "arch.h"
+#include "breakpoint.h"
 
 #ifdef ARCH_HAVE_ENABLE_BREAKPOINT
 extern void arch_enable_breakpoint(pid_t, Breakpoint *);
diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c
index b6c12ef..79f6817 100644
--- a/sysdeps/linux-gnu/events.c
+++ b/sysdeps/linux-gnu/events.c
@@ -12,6 +12,7 @@
 #include <unistd.h>
 
 #include "common.h"
+#include "breakpoint.h"
 
 static Event event;
 
diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c
index a99593c..d8d381a 100644
--- a/sysdeps/linux-gnu/proc.c
+++ b/sysdeps/linux-gnu/proc.c
@@ -17,6 +17,7 @@
 #include <sys/syscall.h>
 #include <error.h>
 
+#include "breakpoint.h"
 
 /* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
  * couldn't open it to find the executable.  So it may be necessary to
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index d962048..0751a35 100644
--- a/sysdeps/linux-gnu/trace.c
+++ b/sysdeps/linux-gnu/trace.c
@@ -16,6 +16,7 @@
 
 #include "ptrace.h"
 #include "common.h"
+#include "breakpoint.h"
 
 /* If the system headers did not provide the constants, hard-code the normal
    values.  */