Blob Blame History Raw
diff --git a/Makefile.am b/Makefile.am
index 6e46949..c3356de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,7 +60,8 @@ libltrace_la_SOURCES = \
 	zero.c \
 	lens.c \
 	lens_default.c \
-	lens_enum.c
+	lens_enum.c \
+	memstream.c
 
 libltrace_la_LIBADD = \
 	$(libelf_LIBS) \
@@ -112,7 +113,8 @@ noinst_HEADERS = \
 	zero.h \
 	lens.h \
 	lens_default.h \
-	lens_enum.h
+	lens_enum.h \
+	memstream.h
 
 dist_man1_MANS = ltrace.1
 dist_man5_MANS = ltrace.conf.5
diff --git a/backend.h b/backend.h
index 89c05c3..cfac65e 100644
--- a/backend.h
+++ b/backend.h
@@ -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.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -27,12 +27,12 @@
 #include <gelf.h>
 
 enum process_status {
-	ps_invalid,	/* Failure.  */
-	ps_stop,	/* Job-control stop.  */
-	ps_tracing_stop,
-	ps_sleeping,
-	ps_zombie,
-	ps_other,	/* Necessary other states can be added as needed.  */
+	PS_INVALID,	/* Failure.  */
+	PS_STOP,	/* Job-control stop.  */
+	PS_TRACING_STOP,
+	PS_SLEEPING,
+	PS_ZOMBIE,
+	PS_OTHER,	/* Necessary other states can be added as needed.  */
 };
 
 /*
@@ -70,7 +70,7 @@ int wait_for_proc(pid_t pid);
 int task_kill(pid_t pid, int sig);
 
 /* Called after PID is attached, but before it is continued.  */
-void trace_set_options(struct Process *proc);
+void trace_set_options(struct process *proc);
 
 /* Called after ltrace forks.  Should attach the newly created child,
  * in whose context this function is called.  */
@@ -86,7 +86,7 @@ void untrace_pid(pid_t pid);
 /* The back end may need to store arbitrary data to a process.  This
  * is a place where it can initialize PROC->arch_dep.  XXX this should
  * be dropped in favor of arhc_process_init on pmachata/libs.  */
-void get_arch_dep(struct Process *proc);
+void get_arch_dep(struct process *proc);
 
 /* Return current instruction pointer of PROC.
  *
@@ -95,34 +95,34 @@ void get_arch_dep(struct Process *proc);
  * that would otherwise support this.  Above we have a definition of
  * arch_addr_t.  This should be converted to an integral type and
  * used for target addresses throughout.  */
-void *get_instruction_pointer(struct Process *proc);
+void *get_instruction_pointer(struct process *proc);
 
 /* Set instruction pointer of PROC to ADDR.  XXX see above.  */
-void set_instruction_pointer(struct Process *proc, void *addr);
+void set_instruction_pointer(struct process *proc, void *addr);
 
 /* Return current stack pointer of PROC.  XXX see above.  */
-void *get_stack_pointer(struct Process *proc);
+void *get_stack_pointer(struct process *proc);
 
 /* Find and return caller address, i.e. the address where the current
  * function returns.  */
-void *get_return_addr(struct Process *proc, void *stack_pointer);
+void *get_return_addr(struct process *proc, void *stack_pointer);
 
 /* Adjust PROC so that when the current function returns, it returns
  * to ADDR.  */
-void set_return_addr(struct Process *proc, void *addr);
+void set_return_addr(struct process *proc, void *addr);
 
 /* Enable breakpoint SBP in process PROC.  */
-void enable_breakpoint(struct Process *proc, struct breakpoint *sbp);
+void enable_breakpoint(struct process *proc, struct breakpoint *sbp);
 
 /* Disable breakpoint SBP in process PROC.  */
-void disable_breakpoint(struct Process *proc, struct breakpoint *sbp);
+void disable_breakpoint(struct process *proc, struct breakpoint *sbp);
 
 /* Determine whether the event that we have just seen (and that is
  * recorded in STATUS) was a syscall.  If it was, return 1.  If it was
  * a return from syscall, return 2.  In both cases, set *SYSNUM to the
  * number of said syscall.  If it wasn't a syscall, return 0.  If
  * there was an error, return -1.  */
-int syscall_p(struct Process *proc, int status, int *sysnum);
+int syscall_p(struct process *proc, int status, int *sysnum);
 
 /* Continue execution of the process with given PID.  */
 void continue_process(pid_t pid);
@@ -136,17 +136,21 @@ void continue_after_signal(pid_t pid, int signum);
  * is system call, otherwise it's return from a system call.  The
  * callback should do whatever book-keeping is necessary and continue
  * the process if necessary.  */
-void continue_after_syscall(struct Process *proc, int sysnum, int ret_p);
+void continue_after_syscall(struct process *proc, int sysnum, int ret_p);
 
 /* Called after we hit a breakpoint SBP.  Should do whatever
  * book-keeping is necessary and then continue the process.  */
-void continue_after_breakpoint(struct Process *proc, struct breakpoint *sbp);
+void continue_after_breakpoint(struct process *proc, struct breakpoint *sbp);
 
 /* Called after we received a vfork.  Should do whatever book-keeping
  * is necessary and continue the process if necessary.  N.B. right
  * now, with Linux/GNU the only back end, this is not necessary.  I
  * imagine other systems may be different.  */
-void continue_after_vfork(struct Process *proc);
+void continue_after_vfork(struct process *proc);
+
+/* Called after the process exec's.  Should do whatever book-keeping
+ * is necessary and then continue the process.  */
+void continue_after_exec(struct process *proc);
 
 /* Called when trace_me or primary trace_pid fail.  This may plug in
  * any platform-specific knowledge of why it could be so.  */
@@ -171,14 +175,14 @@ void os_ltrace_exiting(void);
 
 /* Should copy COUNT bytes from address ADDR of process PROC to local
  * buffer BUF.  */
-size_t umovebytes (struct Process *proc, void *addr, void *buf, size_t count);
+size_t umovebytes(struct process *proc, void *addr, void *buf, size_t count);
 
 /* Find out an address of symbol SYM in process PROC, and return.
  * Returning NULL delays breakpoint insertion and enables heaps of
  * arch-specific black magic that we should clean up some day.
  *
  * XXX the same points as for get_instruction_pointer apply. */
-void *sym2addr(struct Process *proc, struct library_symbol *sym);
+void *sym2addr(struct process *proc, struct library_symbol *sym);
 
 /* Obtain address of PLT entry corresponding to relocation RELA in
  * file LTE.  This is NDX-th PLT entry in the file.
@@ -189,7 +193,7 @@ GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela);
 /* Called at some point after we have attached to PROC.  This callback
  * should insert an introspection breakpoint for handling dynamic
  * linker library loads.  */
-int linkmap_init(struct Process *proc, arch_addr_t dyn_addr);
+int linkmap_init(struct process *proc, arch_addr_t dyn_addr);
 
 /* This should produce and return the next event of one of the traced
  * processes.  The returned pointer will not be freed by the core and
@@ -198,14 +202,14 @@ int linkmap_init(struct Process *proc, arch_addr_t dyn_addr);
 struct Event *next_event(void);
 
 /* Called when process PROC was removed.  */
-void process_removed(struct Process *proc);
+void process_removed(struct process *proc);
 
 /* This should extract entry point address and interpreter (dynamic
  * linker) bias if possible.  Returns 0 if there were no errors, -1
  * otherwise.  Sets *ENTRYP and *INTERP_BIASP to non-zero values if
  * the corresponding value is known, or zero otherwise; this is not
  * done for pointers that are NULL.  */
-int process_get_entry(struct Process *proc,
+int process_get_entry(struct process *proc,
 		      arch_addr_t *entryp,
 		      arch_addr_t *interp_biasp);
 
@@ -232,7 +236,7 @@ void arch_elf_destroy(struct ltelf *lte);
  * destroy, and clone SBP->arch.  arch_breakpoint_init and
  * arch_breakpoint_clone return 0 on success or a negative value on
  * failure.  */
-int arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp);
+int arch_breakpoint_init(struct process *proc, struct breakpoint *sbp);
 void arch_breakpoint_destroy(struct breakpoint *sbp);
 int arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp);
 
@@ -259,19 +263,19 @@ int arch_library_symbol_clone(struct library_symbol *retp,
  * PROC->arch in case that PROC underwent an exec.  See notes at
  * process_init, process_destroy, process_clone and process_exec in
  * proc.h.  */
-int arch_process_init(struct Process *proc);
-void arch_process_destroy(struct Process *proc);
-int arch_process_clone(struct Process *retp, struct Process *proc);
-int arch_process_exec(struct Process *proc);
+int arch_process_init(struct process *proc);
+void arch_process_destroy(struct process *proc);
+int arch_process_clone(struct process *retp, struct process *proc);
+int arch_process_exec(struct process *proc);
 
 /* The following callbacks have to be implemented in OS backend if
  * os.h defines OS_HAVE_PROCESS_DATA.  The protocol is same as for,
  * respectively, arch_process_init, arch_process_destroy,
  * arch_process_clone and arch_process_exec.  */
-int os_process_init(struct Process *proc);
-void os_process_destroy(struct Process *proc);
-int os_process_clone(struct Process *retp, struct Process *proc);
-int os_process_exec(struct Process *proc);
+int os_process_init(struct process *proc);
+void os_process_destroy(struct process *proc);
+int os_process_clone(struct process *retp, struct process *proc);
+int os_process_exec(struct process *proc);
 
 /* The following callback has to be implemented in backend if arch.h
  * defines ARCH_HAVE_GET_SYM_INFO.
@@ -289,9 +293,9 @@ int arch_get_sym_info(struct ltelf *lte, const char *filename,
 		      size_t sym_index, GElf_Rela *rela, GElf_Sym *sym);
 
 enum plt_status {
-	plt_fail,
-	plt_ok,
-	plt_default,
+	PLT_FAIL,
+	PLT_OK,
+	PLT_DEFAULT,
 };
 
 /* The following callback has to be implemented in backend if arch.h
@@ -302,22 +306,22 @@ enum plt_status {
  * The corresponding PLT entry is for symbol called NAME, and it's
  * I-th relocation in the file.
  *
- * If this function returns plt_default, PLT address is obtained by
- * calling arch_plt_sym_val, and symbol is allocated.  If plt_ok or
- * plt_default are returned, the chain of symbols passed back in RET
+ * If this function returns PLT_DEFAULT, PLT address is obtained by
+ * calling arch_plt_sym_val, and symbol is allocated.  If PLT_OK or
+ * PLT_DEFAULT are returned, the chain of symbols passed back in RET
  * is added to library under construction.  */
-enum plt_status arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+enum plt_status arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
 				       const char *name, GElf_Rela *rela,
 				       size_t i, struct library_symbol **ret);
 
 /* This callback needs to be implemented if arch.h defines
  * ARCH_HAVE_DYNLINK_DONE.  It is called after the dynamic linker is
  * done with the process startup.  */
-void arch_dynlink_done(struct Process *proc);
+void arch_dynlink_done(struct process *proc);
 
 /* This callback needs to be implemented if arch.h defines
  * ARCH_HAVE_SYMBOL_RET.  It is called after a traced call returns.  */
-void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym);
+void arch_symbol_ret(struct process *proc, struct library_symbol *libsym);
 
 
 /* This callback needs to be implemented if arch.h defines
@@ -327,7 +331,7 @@ void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym);
  * DYN_ADDR holds the address of the dynamic section.
  * If the debug area is found, return 0 and fill in the address in *RET.
  * If the debug area is not found, return a negative value.  */
-int arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
+int arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
 		       arch_addr_t *ret);
 
 /* If arch.h defines ARCH_HAVE_FETCH_ARG, the following callbacks have
@@ -340,4 +344,34 @@ int arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
  * implemented: arch_fetch_param_pack_start,
  * arch_fetch_param_pack_end.  See fetch.h for details.  */
 
+enum sw_singlestep_status {
+	SWS_FAIL,
+	SWS_OK,
+	SWS_HW,
+};
+struct sw_singlestep_data;
+
+/* The following callback has to be implemented in backend if arch.h
+ * defines ARCH_HAVE_SW_SINGLESTEP.
+ *
+ * This is called before the OS backend requests hardware singlestep.
+ * arch_sw_singlestep should consider whether a singlestep needs to be
+ * done in software.  If not, it returns SWS_HW.  Otherwise it needs
+ * to add one or several breakpoints by calling ADD_CB.  When it is
+ * done, it continues the process as appropriate, and answers either
+ * SWS_OK, or SWS_FAIL, depending on how it went.
+ *
+ * PROC is the process that should perform the singlestep, BP the
+ * breakpoint that we are singlestepping over.  ADD_CB is a callback
+ * to request adding breakpoints that should trap the process after
+ * it's continued.  The arguments to ADD_CB are the address where the
+ * breakpoint should be added, and DATA.  ADD_CB returns 0 on success
+ * or a negative value on failure.  It is expected that
+ * arch_sw_singlestep returns SWS_FAIL if ADD_CB returns error.  */
+enum sw_singlestep_status arch_sw_singlestep(struct process *proc,
+					     struct breakpoint *bp,
+					     int (*add_cb)(arch_addr_t addr,
+						   struct sw_singlestep_data *),
+					     struct sw_singlestep_data *data);
+
 #endif /* BACKEND_H */
diff --git a/breakpoint.h b/breakpoint.h
index 7cd914e..18af7a9 100644
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -41,14 +41,12 @@
 
 #include "sysdep.h"
 #include "library.h"
-
-struct Process;
-struct breakpoint;
+#include "forward.h"
 
 struct bp_callbacks {
-	void (*on_hit)(struct breakpoint *bp, struct Process *proc);
-	void (*on_continue)(struct breakpoint *bp, struct Process *proc);
-	void (*on_retract)(struct breakpoint *bp, struct Process *proc);
+	void (*on_hit)(struct breakpoint *bp, struct process *proc);
+	void (*on_continue)(struct breakpoint *bp, struct process *proc);
+	void (*on_retract)(struct breakpoint *bp, struct process *proc);
 };
 
 struct breakpoint {
@@ -61,11 +59,11 @@ struct breakpoint {
 };
 
 /* Call on-hit handler of BP, if any is set.  */
-void breakpoint_on_hit(struct breakpoint *bp, struct Process *proc);
+void breakpoint_on_hit(struct breakpoint *bp, struct process *proc);
 
 /* Call on-continue handler of BP.  If none is set, call
  * continue_after_breakpoint.  */
-void breakpoint_on_continue(struct breakpoint *bp, struct Process *proc);
+void breakpoint_on_continue(struct breakpoint *bp, struct process *proc);
 
 /* Call on-retract handler of BP, if any is set.  This should be
  * called before the breakpoints are destroyed.  The reason for a
@@ -74,21 +72,21 @@ void breakpoint_on_continue(struct breakpoint *bp, struct Process *proc);
  * be called every time we disable the breakpoint, which is too often
  * (a breakpoint has to be disabled every time that we need to execute
  * the instruction underneath it).  */
-void breakpoint_on_retract(struct breakpoint *bp, struct Process *proc);
+void breakpoint_on_retract(struct breakpoint *bp, struct process *proc);
 
 /* Initialize a breakpoint structure.  That doesn't actually realize
  * the breakpoint.  The breakpoint is initially assumed to be
  * disabled.  orig_value has to be set separately.  CBS may be
  * NULL.  */
-int breakpoint_init(struct breakpoint *bp, struct Process *proc,
+int breakpoint_init(struct breakpoint *bp, struct process *proc,
 		    arch_addr_t addr, struct library_symbol *libsym);
 
 /* Make a clone of breakpoint BP into the area of memory pointed to by
  * RETP.  The original breakpoint was assigned to process OLD_PROC,
  * the cloned breakpoint will be attached to process NEW_PROC.
  * Returns 0 on success or a negative value on failure.  */
-int breakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
-		     struct breakpoint *bp, struct Process *old_proc);
+int breakpoint_clone(struct breakpoint *retp, struct process *new_proc,
+		     struct breakpoint *bp, struct process *old_proc);
 
 /* Set callbacks.  If CBS is non-NULL, then BP->cbs shall be NULL.  */
 void breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs);
@@ -98,12 +96,12 @@ void breakpoint_destroy(struct breakpoint *bp);
 
 /* Call enable_breakpoint the first time it's called.  Returns 0 on
  * success and a negative value on failure.  */
-int breakpoint_turn_on(struct breakpoint *bp, struct Process *proc);
+int breakpoint_turn_on(struct breakpoint *bp, struct process *proc);
 
 /* Call disable_breakpoint when turned off the same number of times
  * that it was turned on.  Returns 0 on success and a negative value
  * on failure.  */
-int breakpoint_turn_off(struct breakpoint *bp, struct Process *proc);
+int breakpoint_turn_off(struct breakpoint *bp, struct process *proc);
 
 /* Utility function that does what typically needs to be done when a
  * breakpoint is to be inserted.  It checks whether there is another
@@ -113,7 +111,7 @@ int breakpoint_turn_off(struct breakpoint *bp, struct Process *proc);
  * added as well as preexisting breakpoints, it then calls
  * BREAKPOINT_TURN_ON.  If anything fails, it cleans up and returns
  * NULL.  Otherwise it returns the breakpoint for ADDR.  */
-struct breakpoint *insert_breakpoint(struct Process *proc, void *addr,
+struct breakpoint *insert_breakpoint(struct process *proc, void *addr,
 				     struct library_symbol *libsym);
 
 /* Name of a symbol associated with BP.  May be NULL.  */
@@ -127,12 +125,12 @@ struct library *breakpoint_library(const struct breakpoint *bp);
  *  - proc_remove_breakpoint
  *  - breakpoint_destroy
  * XXX */
-void delete_breakpoint(struct Process *proc, void *addr);
+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);
+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);
 
 #endif /* BREAKPOINT_H */
diff --git a/breakpoints.c b/breakpoints.c
index 258be93..8db4e26 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -42,7 +42,7 @@
 
 #ifndef ARCH_HAVE_TRANSLATE_ADDRESS
 int
-arch_translate_address_dyn(struct Process *proc,
+arch_translate_address_dyn(struct process *proc,
 		       arch_addr_t addr, arch_addr_t *ret)
 {
 	*ret = addr;
@@ -60,7 +60,7 @@ arch_translate_address(struct ltelf *lte,
 #endif
 
 void
-breakpoint_on_hit(struct breakpoint *bp, struct Process *proc)
+breakpoint_on_hit(struct breakpoint *bp, struct process *proc)
 {
 	assert(bp != NULL);
 	if (bp->cbs != NULL && bp->cbs->on_hit != NULL)
@@ -68,7 +68,7 @@ breakpoint_on_hit(struct breakpoint *bp, struct Process *proc)
 }
 
 void
-breakpoint_on_continue(struct breakpoint *bp, struct Process *proc)
+breakpoint_on_continue(struct breakpoint *bp, struct process *proc)
 {
 	assert(bp != NULL);
 	if (bp->cbs != NULL && bp->cbs->on_continue != NULL)
@@ -78,7 +78,7 @@ breakpoint_on_continue(struct breakpoint *bp, struct Process *proc)
 }
 
 void
-breakpoint_on_retract(struct breakpoint *bp, struct Process *proc)
+breakpoint_on_retract(struct breakpoint *bp, struct process *proc)
 {
 	assert(bp != NULL);
 	if (bp->cbs != NULL && bp->cbs->on_retract != NULL)
@@ -88,7 +88,7 @@ breakpoint_on_retract(struct breakpoint *bp, struct Process *proc)
 /*****************************************************************************/
 
 struct breakpoint *
-address2bpstruct(Process *proc, void *addr)
+address2bpstruct(struct process *proc, void *addr)
 {
 	assert(proc != NULL);
 	assert(proc->breakpoints != NULL);
@@ -99,7 +99,7 @@ address2bpstruct(Process *proc, void *addr)
 
 #ifndef ARCH_HAVE_BREAKPOINT_DATA
 int
-arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp)
+arch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
 {
 	return 0;
 }
@@ -117,7 +117,7 @@ arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
 #endif
 
 static void
-breakpoint_init_base(struct breakpoint *bp, struct Process *proc,
+breakpoint_init_base(struct breakpoint *bp, struct process *proc,
 		     arch_addr_t addr, struct library_symbol *libsym)
 {
 	bp->cbs = NULL;
@@ -132,7 +132,7 @@ breakpoint_init_base(struct breakpoint *bp, struct Process *proc,
  * static lookups of various sections in the ELF file.  We shouldn't
  * need process for anything.  */
 int
-breakpoint_init(struct breakpoint *bp, struct Process *proc,
+breakpoint_init(struct breakpoint *bp, struct process *proc,
 		arch_addr_t addr, struct library_symbol *libsym)
 {
 	breakpoint_init_base(bp, proc, addr, libsym);
@@ -156,8 +156,8 @@ breakpoint_destroy(struct breakpoint *bp)
 }
 
 int
-breakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
-		 struct breakpoint *bp, struct Process *old_proc)
+breakpoint_clone(struct breakpoint *retp, struct process *new_proc,
+		 struct breakpoint *bp, struct process *old_proc)
 {
 	struct library_symbol *libsym = NULL;
 	if (bp->libsym != NULL) {
@@ -175,7 +175,7 @@ breakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
 }
 
 int
-breakpoint_turn_on(struct breakpoint *bp, struct Process *proc)
+breakpoint_turn_on(struct breakpoint *bp, struct process *proc)
 {
 	bp->enabled++;
 	if (bp->enabled == 1) {
@@ -186,7 +186,7 @@ breakpoint_turn_on(struct breakpoint *bp, struct Process *proc)
 }
 
 int
-breakpoint_turn_off(struct breakpoint *bp, struct Process *proc)
+breakpoint_turn_off(struct breakpoint *bp, struct process *proc)
 {
 	bp->enabled--;
 	if (bp->enabled == 0)
@@ -196,10 +196,10 @@ breakpoint_turn_off(struct breakpoint *bp, struct Process *proc)
 }
 
 struct breakpoint *
-insert_breakpoint(struct Process *proc, void *addr,
+insert_breakpoint(struct process *proc, void *addr,
 		  struct library_symbol *libsym)
 {
-	Process *leader = proc->leader;
+	struct process *leader = proc->leader;
 
 	/* Only the group leader should be getting the breakpoints and
 	 * thus have ->breakpoint initialized.  */
@@ -243,11 +243,11 @@ insert_breakpoint(struct Process *proc, void *addr,
 }
 
 void
-delete_breakpoint(Process *proc, void *addr)
+delete_breakpoint(struct process *proc, void *addr)
 {
 	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
 
-	Process * leader = proc->leader;
+	struct process *leader = proc->leader;
 	assert(leader != NULL);
 
 	struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
@@ -285,13 +285,14 @@ breakpoint_library(const struct breakpoint *bp)
 static void
 enable_bp_cb(void *addr, void *sbp, void *proc)
 {
-	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid);
+	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)",
+	      ((struct process *)proc)->pid);
 	if (((struct breakpoint *)sbp)->enabled)
 		enable_breakpoint(proc, sbp);
 }
 
 void
-enable_all_breakpoints(Process *proc)
+enable_all_breakpoints(struct process *proc)
 {
 	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
 
@@ -305,13 +306,15 @@ enable_all_breakpoints(Process *proc)
 static void
 disable_bp_cb(void *addr, void *sbp, void *proc)
 {
-	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
+	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)",
+	      ((struct process *)proc)->pid);
 	if (((struct breakpoint *)sbp)->enabled)
 		disable_breakpoint(proc, sbp);
 }
 
 void
-disable_all_breakpoints(Process *proc) {
+disable_all_breakpoints(struct process *proc)
+{
 	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
 	assert(proc->leader == proc);
 	dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
@@ -330,7 +333,7 @@ struct entry_breakpoint {
 };
 
 static void
-entry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
+entry_breakpoint_on_hit(struct breakpoint *a, struct process *proc)
 {
 	struct entry_breakpoint *bp = (void *)a;
 	if (proc == NULL || proc->leader == NULL)
@@ -342,7 +345,7 @@ entry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
 }
 
 int
-entry_breakpoint_init(struct Process *proc,
+entry_breakpoint_init(struct process *proc,
 		      struct entry_breakpoint *bp, arch_addr_t addr,
 		      struct library *lib)
 {
@@ -360,7 +363,7 @@ entry_breakpoint_init(struct Process *proc,
 }
 
 int
-breakpoints_init(Process *proc)
+breakpoints_init(struct process *proc)
 {
 	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
 
diff --git a/configure.ac b/configure.ac
index 20c84f4..47bd87e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,9 +21,9 @@
 # 02110-1301 USA
 
 # Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.65)
+AC_PREREQ([2.65])
 
-AC_INIT([ltrace],[0.7.2],[ltrace-devel@lists.alioth.debian.org])
+AC_INIT([ltrace],[0.7.90-git],[ltrace-devel@lists.alioth.debian.org])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_SRCDIR(libltrace.c)
 AC_CONFIG_MACRO_DIR([config/m4])
@@ -245,23 +246,48 @@ AC_CHECK_SIZEOF([long])
 
 
 # Checks for library functions.
-AC_FUNC_ERROR_AT_LINE
 AC_FUNC_FORK
 AC_CHECK_FUNCS([ \
 	alarm \
 	atexit \
-	getcwd \
 	gettimeofday \
 	memset \
-	mkdir \
-	rmdir \
 	strchr \
 	strdup \
 	strerror \
+	strsignal \
 	strtol \
 	strtoul \
 ])
 
+#
+# Define HAVE_OPEN_MEMSTREAM if open_memstream is available.  glibc
+# before 2.10, eglibc and uClibc all need _GNU_SOURCE defined for
+# open_memstream to become visible, so check for that as well.  If
+# unavailable, require that tmpfile be present.  There's no
+# HAVE_TMPFILE, as we plain require that to be present as a fallback.
+#
+AC_CHECK_FUNCS([open_memstream], [],
+	[AC_MSG_CHECKING([for open_memstream with _GNU_SOURCE])
+	 AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[#define _GNU_SOURCE 1
+				   #include <stdio.h>]],
+				 [[char *buf; size_t sz;
+				   return open_memstream(&buf, &sz) != 0;]])],
+
+		 [AC_MSG_RESULT([yes])
+		  AC_DEFINE([HAVE_OPEN_MEMSTREAM], [1],
+			[Define if open_memstream exists.])],
+
+		 [AC_MSG_RESULT([no])
+		  AC_CHECK_FUNC([tmpfile], [],
+			[AC_MSG_ERROR(
+			    [Either open_memstream or tmpfile required.])])])])
+
+#
+# Define HAVE_GETOPT_LONG if that is available.
+#
+AC_CHECK_HEADER([getopt.h], [AC_CHECK_FUNCS([getopt_long])])
 
 #
 # Debugging
diff --git a/debug.c b/debug.c
index 1b03189..ce220fe 100644
--- a/debug.c
+++ b/debug.c
@@ -1,5 +1,6 @@
 /*
  * This file is part of ltrace.
+ * Copyright (C) 2012 Petr Machata, Red Hat Inc.
  * Copyright (C) 2003,2008,2009 Juan Cespedes
  * Copyright (C) 2006 Ian Wienand
  *
@@ -23,6 +24,7 @@
 #include <stdarg.h>
 
 #include "common.h"
+#include "backend.h"
 
 void
 debug_(int level, const char *file, int line, const char *fmt, ...) {
@@ -40,95 +42,26 @@ debug_(int level, const char *file, int line, const char *fmt, ...) {
 	fflush(options.output);
 }
 
-/*
- * The following section provides a way to print things, like hex dumps,
- * with out using buffered output.  This was written by Steve Munroe of IBM.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ptrace.h>
-
-static int
-xwritehexl(long i) {
-	int rc = 0;
-	char text[17];
-	int j;
-	unsigned long temp = (unsigned long)i;
-
-	for (j = 15; j >= 0; j--) {
-		char c;
-		c = (char)((temp & 0x0f) + '0');
-		if (c > '9') {
-			c = (char)(c + ('a' - '9' - 1));
-		}
-		text[j] = c;
-		temp = temp >> 4;
-	}
-
-	rc = write(1, text, 16);
-	return rc;
-}
-
-static int
-xwritec(char c) {
-	char temp = c;
-	char *text = &temp;
-	int rc = 0;
-	rc = write(1, text, 1);
-	return rc;
-}
-
-static int
-xwritecr(void) {
-	return xwritec('\n');
-}
-
 static int
-xwritedump(void *ptr, long addr, int len) {
-	int rc = 0;
-	long *tprt = (long *)ptr;
-	int i;
-
-	for (i = 0; i < len; i += 8) {
-		xwritehexl(addr);
-		xwritec('-');
-		xwritec('>');
-		xwritehexl(*tprt++);
-		xwritecr();
+xwritedump(long *ptr, arch_addr_t addr, size_t count)
+{
+	size_t i;
+	for (i = 0; i < count; ++i) {
+		if (fprintf(stderr, "%p->%0*lx\n",
+			    addr, 2 * (int)sizeof(long), ptr[i]) < 0)
+			return -1;
 		addr += sizeof(long);
 	}
 
-	return rc;
+	return 0;
 }
 
 int
-xinfdump(long pid, void *ptr, int len) {
-	int rc;
-	int i;
-	long wrdcnt;
-	long *infwords;
-	long addr;
-
-	wrdcnt = len / sizeof(long) + 1;
-	infwords = malloc(wrdcnt * sizeof(long));
-	if (!infwords) {
-		perror("ltrace: malloc");
-		exit(1);
-	}
-	addr = (long)ptr;
-
-	addr = ((addr + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
-
-	for (i = 0; i < wrdcnt; ++i) {
-		infwords[i] = ptrace(PTRACE_PEEKTEXT, pid, (void *)addr, NULL);
-		addr += sizeof(long);
-	}
-
-	rc = xwritedump(infwords, (long)ptr, len);
-
-	free(infwords);
-	return rc;
+xinfdump(struct process *proc, arch_addr_t addr, size_t length)
+{
+	unsigned char buf[length];
+	size_t got = umovebytes(proc, addr, buf, length);
+	if (got == (size_t)-1)
+		return -1;
+	return xwritedump((long *)buf, addr, got / sizeof(long));
 }
diff --git a/debug.h b/debug.h
index 4775d2f..542dda5 100644
--- a/debug.h
+++ b/debug.h
@@ -1,5 +1,6 @@
 /*
  * This file is part of ltrace.
+ * Copyright (C) 2012 Petr Machata, Red Hat Inc.
  * Copyright (C) 2003,2009 Juan Cespedes
  *
  * This program is free software; you can redistribute it and/or
@@ -21,6 +22,9 @@
 #ifndef _DEBUG_H
 #define _DEBUG_H
 
+#include "backend.h"
+#include "forward.h"
+
 /* debug levels:
  */
 enum {
@@ -32,8 +36,10 @@ enum {
 void debug_(int level, const char *file, int line,
 		const char *fmt, ...) __attribute__((format(printf,4,5)));
 
-int xinfdump(long, void *, int);
+/* Dump LENGTH bytes of memory starting on address ADDR of inferior
+ * PID.  */
+int xinfdump(struct process *proc, arch_addr_t addr, size_t length);
 
-# define debug(level, expr...) debug_(level, __FILE__, __LINE__, expr)
+#define debug(level, expr...) debug_(level, __FILE__, __LINE__, expr)
 
 #endif
diff --git a/expr.c b/expr.c
index 32860fd..552a53c 100644
--- a/expr.c
+++ b/expr.c
@@ -21,7 +21,6 @@
 #include <string.h>
 #include <assert.h>
 #include <errno.h>
-#include <error.h>
 #include <stdlib.h>
 
 #include "expr.h"
@@ -327,12 +326,11 @@ expr_eval_constant(struct expr_node *node, long *valuep)
 struct expr_node *
 expr_self(void)
 {
-	static struct expr_node *node = NULL;
-	if (node == NULL) {
-		node = malloc(sizeof(*node));
-		if (node == NULL)
-			error(1, errno, "malloc expr_self");
-		expr_init_self(node);
+	static struct expr_node *nodep = NULL;
+	if (nodep == NULL) {
+		static struct expr_node node;
+		expr_init_self(&node);
+		nodep = &node;
 	}
-	return node;
+	return nodep;
 }
diff --git a/fetch.c b/fetch.c
index 88966a5..cbceefb 100644
--- a/fetch.c
+++ b/fetch.c
@@ -27,18 +27,18 @@
 #include "type.h"
 
 #ifdef ARCH_HAVE_FETCH_ARG
-struct fetch_context *arch_fetch_arg_init(enum tof type, struct Process *proc,
+struct fetch_context *arch_fetch_arg_init(enum tof type, struct process *proc,
 					  struct arg_type_info *ret_info);
 
-struct fetch_context *arch_fetch_arg_clone(struct Process *proc,
+struct fetch_context *arch_fetch_arg_clone(struct process *proc,
 					   struct fetch_context *context);
 
 int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
-			struct Process *proc, struct arg_type_info *info,
+			struct process *proc, struct arg_type_info *info,
 			struct value *valuep);
 
 int arch_fetch_retval(struct fetch_context *ctx, enum tof type,
-		      struct Process *proc, struct arg_type_info *info,
+		      struct process *proc, struct arg_type_info *info,
 		      struct value *valuep);
 
 void arch_fetch_arg_done(struct fetch_context *context);
@@ -53,7 +53,7 @@ void arch_fetch_param_pack_end(struct fetch_context *context);
 #else
 /* Fall back to gimme_arg.  */
 
-long gimme_arg(enum tof type, struct Process *proc, int arg_num,
+long gimme_arg(enum tof type, struct process *proc, int arg_num,
 	       struct arg_type_info *info);
 
 struct fetch_context {
@@ -61,14 +61,14 @@ struct fetch_context {
 };
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	return calloc(sizeof(struct fetch_context), 1);
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
+arch_fetch_arg_clone(struct process *proc, struct fetch_context *context)
 {
 	struct fetch_context *ret = malloc(sizeof(*ret));
 	if (ret == NULL)
@@ -78,7 +78,7 @@ arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
 
 int
 arch_fetch_arg_next(struct fetch_context *context, enum tof type,
-		    struct Process *proc,
+		    struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	long l = gimme_arg(type, proc, context->argnum++, info);
@@ -88,7 +88,7 @@ arch_fetch_arg_next(struct fetch_context *context, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *context, enum tof type,
-		  struct Process *proc,
+		  struct process *proc,
 		  struct arg_type_info *info, struct value *valuep)
 {
 	long l = gimme_arg(type, proc, -1, info);
@@ -118,21 +118,21 @@ arch_fetch_param_pack_end(struct fetch_context *context)
 #endif
 
 struct fetch_context *
-fetch_arg_init(enum tof type, struct Process *proc,
+fetch_arg_init(enum tof type, struct process *proc,
 	       struct arg_type_info *ret_info)
 {
 	return arch_fetch_arg_init(type, proc, ret_info);
 }
 
 struct fetch_context *
-fetch_arg_clone(struct Process *proc, struct fetch_context *context)
+fetch_arg_clone(struct process *proc, struct fetch_context *context)
 {
 	return arch_fetch_arg_clone(proc, context);
 }
 
 int
 fetch_arg_next(struct fetch_context *context, enum tof type,
-	       struct Process *proc,
+	       struct process *proc,
 	       struct arg_type_info *info, struct value *valuep)
 {
 	return arch_fetch_arg_next(context, type, proc, info, valuep);
@@ -140,7 +140,7 @@ fetch_arg_next(struct fetch_context *context, enum tof type,
 
 int
 fetch_retval(struct fetch_context *context, enum tof type,
-	     struct Process *proc,
+	     struct process *proc,
 	     struct arg_type_info *info, struct value *valuep)
 {
 	return arch_fetch_retval(context, type, proc, info, valuep);
diff --git a/fetch.h b/fetch.h
index 2a13214..3a1644a 100644
--- a/fetch.h
+++ b/fetch.h
@@ -38,24 +38,24 @@ struct fetch_context;
 
 /* Initialize argument fetching.  Returns NULL on failure.  RET_INFO
  * is the return type of the function.  */
-struct fetch_context *fetch_arg_init(enum tof type, struct Process *proc,
+struct fetch_context *fetch_arg_init(enum tof type, struct process *proc,
 				     struct arg_type_info *ret_info);
 
 /* Make a clone of context.  */
-struct fetch_context *fetch_arg_clone(struct Process *proc,
+struct fetch_context *fetch_arg_clone(struct process *proc,
 				      struct fetch_context *context);
 
 /* Load next argument.  The function returns 0 on success or a
  * negative value on failure.  The extracted value is stored in
  * *VALUEP.  */
 int fetch_arg_next(struct fetch_context *context, enum tof type,
-		   struct Process *proc,
+		   struct process *proc,
 		   struct arg_type_info *info, struct value *valuep);
 
 /* Load return value.  The function returns 0 on success or a negative
  * value on failure.  The extracted value is stored in *VALUEP.  */
 int fetch_retval(struct fetch_context *context, enum tof type,
-		 struct Process *proc,
+		 struct process *proc,
 		 struct arg_type_info *info, struct value *valuep);
 
 /* Destroy fetch context.  CONTEXT shall be the same memory location
@@ -74,15 +74,15 @@ void fetch_param_pack_end(struct fetch_context *context);
 /* The following callbacks have to be implemented in backend if arch.h
  * defines ARCH_HAVE_FETCH_ARG.  These backend callbacks correspond to
  * above functions.  */
-struct fetch_context *arch_fetch_arg_init(enum tof type, struct Process *proc,
+struct fetch_context *arch_fetch_arg_init(enum tof type, struct process *proc,
 					  struct arg_type_info *ret_info);
-struct fetch_context *arch_fetch_arg_clone(struct Process *proc,
+struct fetch_context *arch_fetch_arg_clone(struct process *proc,
 					   struct fetch_context *context);
 int arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
-			struct Process *proc, struct arg_type_info *info,
+			struct process *proc, struct arg_type_info *info,
 			struct value *valuep);
 int arch_fetch_retval(struct fetch_context *ctx, enum tof type,
-		      struct Process *proc, struct arg_type_info *info,
+		      struct process *proc, struct arg_type_info *info,
 		      struct value *valuep);
 void arch_fetch_arg_done(struct fetch_context *context);
 
diff --git a/forward.h b/forward.h
index 85a0630..d334339 100644
--- a/forward.h
+++ b/forward.h
@@ -21,7 +21,7 @@
 /* Important types defined in other header files are declared
    here.  */
 struct Event;
-struct Process;
+struct process;
 struct arg_type_info;
 struct breakpoint;
 struct expr_node;
diff --git a/glob.c b/glob.c
index 9af633f..b26637f 100644
--- a/glob.c
+++ b/glob.c
@@ -180,7 +180,7 @@ glob_to_regex(const char *glob, char **retp)
 			goto fail;
 	}
 	*retp = buf;
-	return REG_NOERROR;
+	return 0;
 }
 
 int
@@ -188,7 +188,7 @@ globcomp(regex_t *preg, const char *glob, int cflags)
 {
 	char *regex = NULL;
 	int status = glob_to_regex(glob, &regex);
-	if (status != REG_NOERROR)
+	if (status != 0)
 		return status;
 	assert(regex != NULL);
 	status = regcomp(preg, regex, cflags);
diff --git a/handle_event.c b/handle_event.c
index 42a7a05..9dbb696 100644
--- a/handle_event.c
+++ b/handle_event.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 Arnaud Patard, Mandriva SA
  * Copyright (C) 1998,2001,2002,2003,2004,2007,2008,2009 Juan Cespedes
  * Copyright (C) 2008 Luis Machado, IBM Corporation
@@ -54,20 +54,20 @@ static void handle_exec(Event *event);
 static void handle_breakpoint(Event *event);
 static void handle_new(Event *event);
 
-static void callstack_push_syscall(Process *proc, int sysnum);
-static void callstack_push_symfunc(Process *proc,
+static void callstack_push_syscall(struct process *proc, int sysnum);
+static void callstack_push_symfunc(struct process *proc,
 				   struct library_symbol *sym);
 /* XXX Stack maintenance should be moved to a dedicated module, or to
  * proc.c, and push/pop should be visible outside this module.  For
  * now, because we need this in proc.c, this is non-static.  */
-void callstack_pop(struct Process *proc);
+void callstack_pop(struct process *proc);
 
-static char * shortsignal(Process *proc, int signum);
-static char * sysname(Process *proc, int sysnum);
-static char * arch_sysname(Process *proc, int sysnum);
+static char *shortsignal(struct process *proc, int signum);
+static char *sysname(struct process *proc, int sysnum);
+static char *arch_sysname(struct process *proc, int sysnum);
 
 static Event *
-call_handler(Process * proc, Event * event)
+call_handler(struct process *proc, Event *event)
 {
 	assert(proc != NULL);
 
@@ -256,7 +256,7 @@ handle_clone(Event *event)
 {
 	debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid);
 
-	struct Process *proc = malloc(sizeof(*proc));
+	struct process *proc = malloc(sizeof(*proc));
 	if (proc == NULL) {
 	fail:
 		free(proc);
@@ -297,12 +297,11 @@ handle_clone(Event *event)
 }
 
 static void
-handle_new(Event * event) {
-	Process * proc;
-
+handle_new(Event *event)
+{
 	debug(DEBUG_FUNCTION, "handle_new(pid=%d)", event->e_un.newpid);
 
-	proc = pid2proc(event->e_un.newpid);
+	struct process *proc = pid2proc(event->e_un.newpid);
 	if (!proc) {
 		pending_new_insert(event->e_un.newpid);
 	} else {
@@ -317,7 +316,8 @@ handle_new(Event * event) {
 }
 
 static char *
-shortsignal(Process *proc, int signum) {
+shortsignal(struct process *proc, int signum)
+{
 	static char *signalent0[] = {
 #include "signalent.h"
 	};
@@ -341,7 +341,8 @@ shortsignal(Process *proc, int signum) {
 }
 
 static char *
-sysname(Process *proc, int sysnum) {
+sysname(struct process *proc, int sysnum)
+{
 	static char result[128];
 	static char *syscalent0[] = {
 #include "syscallent.h"
@@ -369,7 +370,8 @@ sysname(Process *proc, int sysnum) {
 }
 
 static char *
-arch_sysname(Process *proc, int sysnum) {
+arch_sysname(struct process *proc, int sysnum)
+{
 	static char result[128];
 	static char *arch_syscalent[] = {
 #include "arch_syscallent.h"
@@ -388,6 +390,10 @@ arch_sysname(Process *proc, int sysnum) {
 	}
 }
 
+#ifndef HAVE_STRSIGNAL
+# define strsignal(SIGNUM) "???"
+#endif
+
 static void
 handle_signal(Event *event) {
 	debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
@@ -420,8 +426,8 @@ handle_exit_signal(Event *event) {
 }
 
 static void
-output_syscall(struct Process *proc, const char *name, enum tof tof,
-	       void (*output)(enum tof, struct Process *,
+output_syscall(struct process *proc, const char *name, enum tof tof,
+	       void (*output)(enum tof, struct process *,
 			      struct library_symbol *))
 {
 	struct library_symbol syscall;
@@ -432,13 +438,13 @@ output_syscall(struct Process *proc, const char *name, enum tof tof,
 }
 
 static void
-output_syscall_left(struct Process *proc, const char *name)
+output_syscall_left(struct process *proc, const char *name)
 {
 	output_syscall(proc, name, LT_TOF_SYSCALL, &output_left);
 }
 
 static void
-output_syscall_right(struct Process *proc, const char *name)
+output_syscall_right(struct process *proc, const char *name)
 {
 	output_syscall(proc, name, LT_TOF_SYSCALLR, &output_right);
 }
@@ -457,8 +463,9 @@ handle_syscall(Event *event) {
 }
 
 static void
-handle_exec(Event * event) {
-	Process * proc = event->proc;
+handle_exec(Event *event)
+{
+	struct process *proc = event->proc;
 
 	/* Save the PID so that we can use it after unsuccessful
 	 * process_exec.  */
@@ -479,18 +486,7 @@ handle_exec(Event * event) {
 		goto untrace;
 	}
 
-	continue_process(proc->pid);
-
-	/* After the exec, we expect to hit the first executable
-	 * instruction.
-	 *
-	 * XXX TODO It would be nice to have this removed, but then we
-	 * need to do that also for initial call to wait_for_proc in
-	 * execute_program.  In that case we could generate a
-	 * EVENT_FIRST event or something, or maybe this could somehow
-	 * be rolled into EVENT_NEW.  */
-	wait_for_proc(proc->pid);
-	continue_process(proc->pid);
+	continue_after_exec(proc);
 }
 
 static void
@@ -510,7 +506,8 @@ handle_arch_syscall(Event *event) {
 struct timeval current_time_spent;
 
 static void
-calc_time_spent(Process *proc) {
+calc_time_spent(struct process *proc)
+{
 	struct timeval tv;
 	struct timezone tz;
 	struct timeval diff;
@@ -568,7 +565,7 @@ handle_arch_sysret(Event *event) {
 }
 
 static void
-output_right_tos(struct Process *proc)
+output_right_tos(struct process *proc)
 {
 	size_t d = proc->callstack_depth;
 	struct callstack_element *elem = &proc->callstack[d - 1];
@@ -577,7 +574,7 @@ output_right_tos(struct Process *proc)
 }
 
 #ifndef ARCH_HAVE_SYMBOL_RET
-void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym)
+void arch_symbol_ret(struct process *proc, struct library_symbol *libsym)
 {
 }
 #endif
@@ -587,7 +584,7 @@ handle_breakpoint(Event *event)
 {
 	int i, j;
 	struct breakpoint *sbp;
-	Process *leader = event->proc->leader;
+	struct process *leader = event->proc->leader;
 	void *brk_addr = event->e_un.brk_addr;
 
 	/* The leader has terminated.  */
@@ -682,7 +679,8 @@ handle_breakpoint(Event *event)
 }
 
 static void
-callstack_push_syscall(Process *proc, int sysnum) {
+callstack_push_syscall(struct process *proc, int sysnum)
+{
 	struct callstack_element *elem;
 
 	debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum);
@@ -707,7 +705,8 @@ callstack_push_syscall(Process *proc, int sysnum) {
 }
 
 static void
-callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
+callstack_push_symfunc(struct process *proc, struct library_symbol *sym)
+{
 	struct callstack_element *elem;
 
 	debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
@@ -734,7 +733,7 @@ callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
 }
 
 void
-callstack_pop(struct Process *proc)
+callstack_pop(struct process *proc)
 {
 	struct callstack_element *elem;
 	assert(proc->callstack_depth > 0);
diff --git a/libltrace.c b/libltrace.c
index 559edfa..b69a0c9 100644
--- a/libltrace.c
+++ b/libltrace.c
@@ -21,6 +21,7 @@
 
 #include "config.h"
 
+#include <limits.h>
 #include <sys/param.h>
 #include <sys/wait.h>
 #include <errno.h>
@@ -40,13 +41,13 @@ char *command = NULL;
 int exiting = 0;		/* =1 if a SIGINT or SIGTERM has been received */
 
 static enum callback_status
-stop_non_p_processes(Process *proc, void *data)
+stop_non_p_processes(struct process *proc, void *data)
 {
 	int stop = 1;
 
 	struct opt_p_t *it;
 	for (it = opt_p; it != NULL; it = it->next) {
-		Process * p_proc = pid2proc(it->pid);
+		struct process *p_proc = pid2proc(it->pid);
 		if (p_proc == NULL) {
 			printf("stop_non_p_processes: %d terminated?\n", it->pid);
 			continue;
@@ -141,7 +142,7 @@ ltrace_init(int argc, char **argv) {
 		do_close_elf(&lte);
 
 		pid_t pid = execute_program(command, argv);
-		struct Process *proc = open_program(command, pid);
+		struct process *proc = open_program(command, pid);
 		if (proc == NULL) {
 			fprintf(stderr, "couldn't open program '%s': %s\n",
 				command, strerror(errno));
diff --git a/library.c b/library.c
index 594472b..b5f6386 100644
--- a/library.c
+++ b/library.c
@@ -412,7 +412,7 @@ library_add_symbol(struct library *lib, struct library_symbol *first)
 }
 
 enum callback_status
-library_named_cb(struct Process *proc, struct library *lib, void *name)
+library_named_cb(struct process *proc, struct library *lib, void *name)
 {
 	if (name == lib->soname
 	    || strcmp(lib->soname, (char *)name) == 0)
@@ -422,7 +422,7 @@ library_named_cb(struct Process *proc, struct library *lib, void *name)
 }
 
 enum callback_status
-library_with_key_cb(struct Process *proc, struct library *lib, void *keyp)
+library_with_key_cb(struct process *proc, struct library *lib, void *keyp)
 {
 	return lib->key == *(arch_addr_t *)keyp ? CBS_STOP : CBS_CONT;
 }
diff --git a/library.h b/library.h
index 555fa80..74e1df2 100644
--- a/library.h
+++ b/library.h
@@ -23,12 +23,11 @@
 #define _LIBRARY_H_
 
 #include <stdint.h>
+
 #include "callback.h"
+#include "forward.h"
 #include "sysdep.h"
 
-struct Process;
-struct library;
-
 enum toplt {
 	LS_TOPLT_NONE = 0,	/* PLT not used for this symbol. */
 	LS_TOPLT_EXEC,		/* PLT for this symbol is executable. */
@@ -195,7 +194,7 @@ void library_add_symbol(struct library *lib, struct library_symbol *sym);
 
 /* A function that can be used as proc_each_library callback.  Looks
  * for a library with the name passed in DATA.  PROC is ignored.  */
-enum callback_status library_named_cb(struct Process *proc,
+enum callback_status library_named_cb(struct process *proc,
 				      struct library *lib, void *name);
 
 /* A function that can be used as proc_each_library callback.  Looks
@@ -203,7 +202,7 @@ enum callback_status library_named_cb(struct Process *proc,
  *
  * NOTE: The key is passed as a POINTER to arch_addr_t (that
  * because in general, arch_addr_t doesn't fit in void*).  */
-enum callback_status library_with_key_cb(struct Process *proc,
+enum callback_status library_with_key_cb(struct process *proc,
 					 struct library *lib, void *keyp);
 
 /* XXX this should really be in backend.h (as on pmachata/revamp
@@ -220,7 +219,7 @@ int arch_translate_address(struct ltelf *lte,
 			   arch_addr_t addr, arch_addr_t *ret);
 /* This is the same function as arch_translate_address, except it's
  * used at the point that we don't have ELF available anymore.  */
-int arch_translate_address_dyn(struct Process *proc,
+int arch_translate_address_dyn(struct process *proc,
 			       arch_addr_t addr, arch_addr_t *ret);
 
 #endif /* _LIBRARY_H_ */
diff --git a/ltrace-elf.c b/ltrace-elf.c
index c571d2a..1d0f769 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -40,6 +40,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <unistd.h>
 
 #include "backend.h"
@@ -64,7 +65,7 @@ arch_elf_destroy(struct ltelf *lte)
 #endif
 
 int
-default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+default_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
 			  const char *a_name, GElf_Rela *rela, size_t ndx,
 			  struct library_symbol **ret)
 {
@@ -101,11 +102,11 @@ default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 
 #ifndef ARCH_HAVE_ADD_PLT_ENTRY
 enum plt_status
-arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
 		       const char *a_name, GElf_Rela *rela, size_t ndx,
 		       struct library_symbol **ret)
 {
-	return plt_default;
+	return PLT_DEFAULT;
 }
 #endif
 
@@ -540,7 +541,7 @@ mark_chain_latent(struct library_symbol *libsym)
 }
 
 static int
-populate_plt(struct Process *proc, const char *filename,
+populate_plt(struct process *proc, const char *filename,
 	     struct ltelf *lte, struct library *lib,
 	     int latent_plts)
 {
@@ -565,14 +566,14 @@ populate_plt(struct Process *proc, const char *filename,
 		struct library_symbol *libsym = NULL;
 		switch (arch_elf_add_plt_entry(proc, lte, name,
 					       &rela, i, &libsym)) {
-		case plt_default:
+		case PLT_DEFAULT:
 			if (default_elf_add_plt_entry(proc, lte, name,
 						      &rela, i, &libsym) < 0)
 			/* fall-through */
-		case plt_fail:
+		case PLT_FAIL:
 				return -1;
 			/* fall-through */
-		case plt_ok:
+		case PLT_OK:
 			if (libsym != NULL) {
 				/* If we are adding those symbols just
 				 * for tracing exports, mark them all
@@ -614,7 +615,7 @@ symbol_with_address(struct library_symbol *sym, void *addrptr)
 }
 
 static int
-populate_this_symtab(struct Process *proc, const char *filename,
+populate_this_symtab(struct process *proc, const char *filename,
 		     struct ltelf *lte, struct library *lib,
 		     Elf_Data *symtab, const char *strtab, size_t size,
 		     struct library_exported_name **names)
@@ -777,7 +778,7 @@ populate_this_symtab(struct Process *proc, const char *filename,
 }
 
 static int
-populate_symtab(struct Process *proc, const char *filename,
+populate_symtab(struct process *proc, const char *filename,
 		struct ltelf *lte, struct library *lib,
 		int symtabs, int exports)
 {
@@ -802,7 +803,7 @@ populate_symtab(struct Process *proc, const char *filename,
 }
 
 static int
-read_module(struct library *lib, struct Process *proc,
+read_module(struct library *lib, struct process *proc,
 	    const char *filename, GElf_Addr bias, int main)
 {
 	struct ltelf lte = {};
@@ -942,7 +943,7 @@ fail:
 }
 
 int
-ltelf_read_library(struct library *lib, struct Process *proc,
+ltelf_read_library(struct library *lib, struct process *proc,
 		   const char *filename, GElf_Addr bias)
 {
 	return read_module(lib, proc, filename, bias, 0);
@@ -950,7 +951,7 @@ ltelf_read_library(struct library *lib, struct Process *proc,
 
 
 struct library *
-ltelf_read_main_binary(struct Process *proc, const char *path)
+ltelf_read_main_binary(struct process *proc, const char *path)
 {
 	struct library *lib = malloc(sizeof(*lib));
 	if (lib == NULL)
diff --git a/ltrace-elf.h b/ltrace-elf.h
index 1a1321e..b76d1eb 100644
--- a/ltrace-elf.h
+++ b/ltrace-elf.h
@@ -26,11 +26,9 @@
 
 #include <gelf.h>
 #include <stdlib.h>
-#include "sysdep.h"
 
-struct Process;
-struct library;
-struct library_symbol;
+#include "forward.h"
+#include "sysdep.h"
 
 /* XXX Ok, the original idea was to separate the low-level ELF data
  * from the abstract "struct library" object, but we use some of the
@@ -73,21 +71,21 @@ void do_close_elf(struct ltelf *lte);
 /* XXX is it possible to put breakpoints in VDSO and VSYSCALL
  * pseudo-libraries?  For now we assume that all libraries can be
  * opened via a filesystem.  BASE is ignored for ET_EXEC files.  */
-int ltelf_read_library(struct library *lib, struct Process *proc,
+int ltelf_read_library(struct library *lib, struct process *proc,
 		       const char *filename, GElf_Addr bias);
 
 /* Create a library object representing the main binary.  The entry
  * point address is stored to *ENTRYP.  */
-struct library *ltelf_read_main_binary(struct Process *proc, const char *path);
+struct library *ltelf_read_main_binary(struct process *proc, const char *path);
 
 /* Create a default PLT entry.  This can be used instead (or in
- * addition to) returning plt_default from arch_elf_add_plt_entry.
+ * addition to) returning PLT_DEFAULT from arch_elf_add_plt_entry.
  * RET shall be initialized, the created symbol will be added to the
  * beginning of the linked list at *RET.  This function doesn't add
  * the symbol to LTE.  arch_elf_add_plt_entry has the chance to adjust
- * symbol internals to its liking, and then return either plt_default
- * or plt_ok.  */
-int default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+ * symbol internals to its liking, and then return either PLT_DEFAULT
+ * or PLT_OK.  */
+int default_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
 			      const char *a_name, GElf_Rela *rela, size_t ndx,
 			      struct library_symbol **ret);
 
diff --git a/ltrace.1 b/ltrace.1
index 8b459ee..7f3c5bc 100644
--- a/ltrace.1
+++ b/ltrace.1
@@ -1,5 +1,5 @@
 .\" -*-nroff-*-
-.\" Copyright (c) 2012 Petr Machata, Red Hat Inc.
+.\" Copyright (c) 2012, 2013 Petr Machata, Red Hat Inc.
 .\" Copyright (c) 1997-2005 Juan Cespedes <cespedes@debian.org>
 .\"
 .\" This program is free software; you can redistribute it and/or
@@ -17,13 +17,65 @@
 .\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 .\" 02110-1301 USA
 .\"
-.TH LTRACE "1" "October 2012" "" "User Commands"
+.TH LTRACE "1" "January 2013" "" "User Commands"
 .SH NAME
 ltrace \- A library call tracer
 
 .SH SYNOPSIS
+.\"
+.\" ---------------------------------------------------------------------------
+.\"
+.PP
 .B ltrace
-.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l library_pattern] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=library_pattern] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
+.\"
+.\" What events to trace:
+.\"
+[\-e \fIfilter\fR|\-L] [\-l|\-\-library=\fIlibrary_pattern\fR]
+[\-x \fIfilter\fR] [\-S] [\-b|\-\-no-signals]
+.\"
+.\" What to display with each event:
+.\"
+[\-i] [\-w|\-\-where=\fInr\fR] [\-r|\-t|\-tt|\-ttt] [\-T]
+.\"
+.\" Output formatting:
+.\"
+[\-F \fIfilename\fR]
+[\-A \fImaxelts\fR] [\-s \fIstrsize\fR] [\-C|\-\-demangle]
+[\-a|\-\-align \fIcolumn\fR] [\-n|\-\-indent \fInr\fR]
+[\-o|\-\-output \fIfilename\fR]
+.\"
+.\" Various:
+.\"
+[\-D|\-\-debug \fImask\fR] [\-u \fIusername\fR]
+.\"
+.\" What processes to trace:
+.\"
+[\-f] [\-p \fIpid\fR] [[\-\-] \fIcommand [arg ...]\fR]
+.\"
+.\" ---------------------------------------------------------------------------
+.\"
+.PP
+.BR ltrace " -c"
+.\"
+.\" What events to trace:
+.\"
+[\-e \fIfilter\fR|\-L] [\-l|\-\-library=\fIlibrary_pattern\fR]
+[\-x \fIfilter\fR] [\-S]
+.\"
+.\" Output formatting:
+.\"
+[\-o|\-\-output \fIfilename\fR]
+.\"
+.\" What processes to trace:
+.\"
+[\-f] [\-p \fIpid\fR] [[\-\-] \fIcommand [arg ...]\fR]
+.\"
+.\" ---------------------------------------------------------------------------
+.\"
+.PP
+.BR ltrace " \-V|\-\-version"
+.PP
+.BR ltrace " \-h|\-\-help"
 
 .SH DESCRIPTION
 .B ltrace
@@ -38,77 +90,51 @@ Its use is very similar to
 .BR strace(1) .
 
 .SH OPTIONS
-.TP
-.I \-a, \-\-align column
+.PP
+.IP "\-a, \-\-align \fIcolumn"
 Align return values in a specific
 .IR column
 (default column is 5/8 of screen width).
-.TP
-.I \-A maxelts
+.IP "\-A \fImaxelts"
 Maximum number of array elements to print before suppressing the rest
 with an ellipsis ("...").  This also limits number of recursive
 structure expansions.
-.TP
-.I \-b, \-\-no-signals
+.IP "\-b, \-\-no-signals"
 Disable printing of signals recieved by the traced process.
-.TP
-.I \-c
-Count time and calls for each library call and report a summary on program exit.
-.TP
-.I \-C, \-\-demangle
+.IP \-c
+Count time and calls for each library call and report a summary on
+program exit.
+.IP "\-C, \-\-demangle"
 Decode (demangle) low-level symbol names into user-level names.
 Besides removing any initial underscore prefix used by the system,
 this makes C++ function names readable.
-.TP
-.I \-D, \-\-debug level
-Show debugging output of
-.B ltrace
-itself.
-.I level
-must be a sum of some of the following numbers:
-.RS
-.TP
-.B 01
-DEBUG_GENERAL.  Shows helpful progress information
-.TP
-.B 010
-DEBUG_EVENT.  Shows every event received by a traced program
-.TP
-.B 020
-DEBUG_PROCESS.  Shows every action
-.B ltrace
-carries upon a traced process
-.TP
-.B 040
-DEBUG_FUNCTION.  Shows every entry to internal functions
-.RE
-.TP
-.I \-e filter
+.IP "\-D, \-\-debug \fRmask\fI"
+Show debugging output of \fBltrace\fR itself.  \fImask\fR is a number
+with internal meaning that's not really well defined at all.
+\fImask\fR of 77 shows all debug messages, which is what you usually
+need.
+.IP "\-e \fIfilter"
 A qualifying expression which modifies which library calls to trace.
 The format of the filter expression is described in the section
 \fBFILTER EXPRESSIONS\fR.  If more than one \-e option appears on the
 command line, the library calls that match any of them are traced.  If
 no \-e is given, \fB@MAIN\fR is assumed as a default.
-.TP
-.I \-f
+.IP \-f
 Trace child processes as they are created by
 currently traced processes as a result of the fork(2)
 or clone(2) system calls.
 The new process is attached immediately.
-.TP
-.I \-F
+.IP "\-F \fIfilename"
 Load an alternate config file. Normally, /etc/ltrace.conf and
-~/.ltrace.conf will be read (the latter only if it exists).
-Use this option to load the given file or files instead of
-those two default files.
-.TP
-.I \-h, \-\-help
+~/.ltrace.conf will be read (the latter only if it exists).  Use this
+option to load the given file or files instead of those two default
+files.  See ltrace.conf(5) for details on the syntax of ltrace
+configuration files.
+.IP "\-h, \-\-help"
 Show a summary of the options to ltrace and exit.
-.TP
-.I \-i
+.IP \-i
 Print the instruction pointer at the time of the library call.
-.TP
-.I \-l, \-\-library library_pattern
+.IP "\-l, \-\-library \fIlibrary_pattern"
 Display only calls to functions implemented by libraries that match
 .I library_pattern.
 Multiple library patters can be specified with several instances of
@@ -120,71 +146,55 @@ the selected libraries, there's no actual guarantee that the call
 won't be directed elsewhere due to e.g. LD_PRELOAD or simply
 dependency ordering.  If you want to make sure that symbols in given
 library are actually called, use \fB-x @\fIlibrary_pattern\fR instead.
-.TP
-.I \-L
+.IP \-L
 When no -e option is given, don't assume the default action of
 \fB@MAIN\fR.
-.TP
-.I \-n, \-\-indent nr
-Indent trace output by
-.I nr
-number of spaces for each new nested call. Using this option makes
-the program flow visualization easy to follow.
-.TP
-.I \-o, \-\-output filename
-Write the trace output to the file
-.I filename
-rather than to stderr.
-.TP
-.I \-p pid
-Attach to the process with the process ID
-.I pid
-and begin tracing.
-.TP
-.I \-r
-Print a relative timestamp with each line of the trace.
-This records the time difference between the beginning of
-successive lines.
-.TP
-.I \-s strsize
+.IP "\-n, \-\-indent \fInr"
+Indent trace output by \fInr\fR spaces for each level of call
+nesting. Using this option makes the program flow visualization easy
+to follow.  This indents uselessly also functions that never return,
+such as service functions for throwing exceptions in the C++ runtime.
+.IP "\-o, \-\-output \fIfilename"
+Write the trace output to the file \fIfilename\fR rather than to
+stderr.
+.IP "\-p \fIpid"
+Attach to the process with the process ID \fIpid\fR and begin tracing.
+This option can be used together with passing a command to execute.
+It is possible to attach to several processes by passing more than one
+option \-p.
+.IP \-r
+Print a relative timestamp with each line of the trace.  This records
+the time difference between the beginning of successive lines.
+.IP "\-s \fIstrsize"
 Specify the maximum string size to print (the default is 32).
-.TP
-.I \-S
+.IP \-S
 Display system calls as well as library calls
-.TP
-.I \-t
+.IP \-t
 Prefix each line of the trace with the time of day.
-.TP
-.I \-tt
+.IP \-tt
 If given twice, the time printed will include the microseconds.
-.TP
-.I \-ttt
+.IP \-ttt
 If given thrice, the time printed will include the microseconds and
 the leading portion will be printed as the number of seconds since the
 epoch.
-.TP
-.I \-T
+.IP \-T
 Show  the  time  spent inside each call. This records the time difference
 between the beginning and the end of each call.
-.TP
-.I \-u username
+.IP "\-u \fIusername"
 Run command with the userid, groupid and supplementary groups of
 .IR username .
 This option is only useful when running as root and enables the
 correct execution of setuid and/or setgid binaries.
-.TP
-.I \-w, --where NR
-Show backtrace of NR stack frames for each traced function. This option enabled
-only if libunwind support was enabled at compile time.
-.TP
-.I \-x filter
+.IP "\-w, --where \fInr"
+Show backtrace of \fInr\fR stack frames for each traced function. This
+option enabled only if libunwind support was enabled at compile time.
+.IP "\-x \fIfilter"
 A qualifying expression which modifies which symbol table entry points
 to trace.  The format of the filter expression is described in the
 section \fBFILTER EXPRESSIONS\fR.  If more than one \-x option appears
 on the command line, the symbols that match any of them are traced.
 No entry points are traced if no \-x is given.
-.TP
-.I \-V, \-\-version
+.IP "\-V, \-\-version"
 Show the version number of ltrace and exit.
 
 .SH FILTER EXPRESSIONS
@@ -235,7 +245,8 @@ path name.
 
 The first rule may lack a sign, in which case \fB+\fR is assumed.  If,
 on the other hand, the first rule has a \fB-\fR sign, it is as if
-there was another rule \fB@*\fR in front of it.
+there was another rule \fB@\fR in front of it, which has the effect of
+tracing complement of given rule.
 
 The above rules are used to construct the set of traced symbols.  Each
 candidate symbol is passed through the chain of above rules.
diff --git a/ltrace.h b/ltrace.h
index ee7e27b..3e714a8 100644
--- a/ltrace.h
+++ b/ltrace.h
@@ -44,7 +44,7 @@ enum Event_type {
 typedef struct Event Event;
 struct Event {
 	struct Event * next;
-	struct Process * proc;
+	struct process *proc;
 	Event_type type;
 	union {
 		int ret_val;     /* EVENT_EXIT */
diff --git a/ltrace.spec b/ltrace.spec
deleted file mode 100644
index 3740190..0000000
--- a/ltrace.spec
+++ /dev/null
@@ -1,164 +0,0 @@
-Summary: Tracks runtime library calls from dynamically linked executables.
-Name: ltrace
-Version: 0.3.36
-Release: 4.2
-Source: ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_%{version}.orig.tar.gz
-Patch1: ftp://ftp.debian.org/debian/pool/main/l/ltrace/ltrace_0.3.36-2.diff.gz
-Patch2: ltrace-ppc64.patch
-Patch3: ltrace-ppc64-2.patch
-Patch4: ltrace-s390x.patch
-Patch5: ltrace-syscallent-update.patch
-Patch6: ltrace-fixes.patch
-Patch7: ltrace-ia64.patch
-License: GPL
-Group: Development/Debuggers
-ExclusiveArch: i386 x86_64 ia64 ppc ppc64 s390 s390x alpha sparc
-Prefix: %{_prefix}
-BuildRoot: /var/tmp/%{name}-root
-BuildRequires: elfutils-libelf-devel
-
-%description
-Ltrace is a debugging program which runs a specified command until the
-command exits.  While the command is executing, ltrace intercepts and
-records both the dynamic library calls called by the executed process
-and the signals received by the executed process.  Ltrace can also
-intercept and print system calls executed by the process.
-
-You should install ltrace if you need a sysadmin tool for tracking the
-execution of processes.
-
-%prep
-%setup -q
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
-%patch6 -p1
-%patch7 -p1
-sed -i -e 's/-o root -g root//' Makefile.in
-
-%build
-export CC="gcc`echo $RPM_OPT_FLAGS | sed -n 's/^.*\(-m[36][124]\).*$/ \1/p'`"
-%configure CC="$CC"
-make
-
-%install
-make DESTDIR=$RPM_BUILD_ROOT mandir=%{_mandir} install
-rm -f ChangeLog; mv -f debian/changelog ChangeLog
-rm -rf $RPM_BUILD_ROOT/%{_prefix}/doc
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc COPYING README TODO BUGS ChangeLog
-%{_prefix}/bin/ltrace
-%{_mandir}/man1/ltrace.1*
-%config /etc/ltrace.conf
-
-%changelog
-* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 0.3.36-4.2
-- bump again for double-long bug on ppc(64)
-
-* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 0.3.36-4.1
-- rebuilt for new gcc4.1 snapshot and glibc changes
-
-* Mon Jan  9 2006 Jakub Jelinek <jakub@redhat.com> 0.3.36-4
-- added ppc64 and s390x support (IBM)
-- added ia64 support (Ian Wienand)
-
-* Sat Mar  5 2005 Jakub Jelinek <jakub@redhat.com> 0.3.36-3
-- rebuilt with GCC 4
-
-* Tue Dec 14 2004 Jakub Jelinek <jakub@redhat.com> 0.3.36-2
-- make x86_64 ltrace trace both 32-bit and 64-bit binaries (#141955,
-  IT#55600)
-- fix tracing across execve
-- fix printf-style format handling on 64-bit arches
-
-* Thu Nov 18 2004 Jakub Jelinek <jakub@redhat.com> 0.3.36-1
-- update to 0.3.36
-
-* Mon Oct 11 2004 Jakub Jelinek <jakub@redhat.com> 0.3.35-1
-- update to 0.3.35
-- update syscall tables from latest kernel source
-
-* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Tue Jun  8 2004 Jakub Jelinek <jakub@redhat.com> 0.3.32-3
-- buildreq elfutils-libelf-devel (#124921)
-
-* Thu Apr 22 2004 Jakub Jelinek <jakub@redhat.com> 0.3.32-2
-- fix demangling
-
-* Thu Apr 22 2004 Jakub Jelinek <jakub@redhat.com> 0.3.32-1
-- update to 0.3.32
-  - fix dict.c assertion (#114359)
-  - x86_64 support
-- rewrite elf.[ch] using libelf
-- don't rely on st_value of SHN_UNDEF symbols in binaries,
-  instead walk .rel{,a}.plt and compute the addresses (#115299)
-- fix x86-64 support
-- some ltrace.conf additions
-- some format string printing fixes
-
-* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Mon Feb  3 2003 Jakub Jelinek <jakub@redhat.com> 0.3.29-1
-- update to 0.3.29
-
-* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
-- rebuilt
-
-* Sun Sep  1 2002 Jakub Jelinek <jakub@redhat.com> 0.3.10-12
-- add a bunch of missing functions to ltrace.conf
-  (like strlen, ugh)
-
-* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Tue May 28 2002 Phil Knirsch <pknirsch@redhat.com>
-- Added the 'official' s390 patch.
-
-* Thu May 23 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Wed Jan 09 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Fri Jul 20 2001 Jakub Jelinek <jakub@redhat.com>
-- fix stale symlink in documentation directory (#47749)
-
-* Sun Jun 24 2001 Elliot Lee <sopwith@redhat.com>
-- Bump release + rebuild.
-
-* Thu Aug  2 2000 Tim Waugh <twaugh@redhat.com>
-- fix off-by-one problem in checking syscall number
-
-* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
-- automatic rebuild
-
-* Mon Jun 19 2000 Matt Wilson <msw@redhat.com>
-- rebuilt for next release
-- patched Makefile.in to take a hint on mandir (patch2)
-- use %%{_mandir} and %%makeinstall
-
-* Wed Feb 02 2000 Cristian Gafton <gafton@redhat.com>
-- fix description
-
-* Fri Jan  7 2000 Jeff Johnson <jbj@redhat.com>
-- update to 0.3.10.
-- include (but don't apply) sparc patch from Jakub Jellinek.
-
-* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com> 
-- auto rebuild in the new build environment (release 2)
-
-* Fri Mar 12 1999 Jeff Johnson <jbj@redhat.com>
-- update to 0.3.6.
-
-* Mon Sep 21 1998 Preston Brown <pbrown@redhat.com>
-- upgraded to 0.3.4
diff --git a/memstream.c b/memstream.c
new file mode 100644
index 0000000..ac3f31a
--- /dev/null
+++ b/memstream.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of ltrace.
+ * Copyright (C) 2012 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
+ * 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
+ */
+
+/* _GNU_SOURCE may be necessary for open_memstream visibility (see
+ * configure.ac), and there's no harm defining it just in case.  */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "memstream.h"
+
+int
+memstream_init(struct memstream *memstream)
+{
+#if HAVE_OPEN_MEMSTREAM
+	memstream->stream = open_memstream(&memstream->buf,
+					   &memstream->size);
+#else
+	memstream->stream = tmpfile();
+#endif
+	memstream->buf = NULL;
+	return memstream->stream != NULL ? 0 : -1;
+}
+
+int
+memstream_close(struct memstream *memstream)
+{
+#if !defined(HAVE_OPEN_MEMSTREAM) || !HAVE_OPEN_MEMSTREAM
+	if (fseek(memstream->stream, 0, SEEK_END) < 0) {
+	fail:
+		fclose(memstream->stream);
+		return -1;
+	}
+	memstream->size = ftell(memstream->stream);
+	if (memstream->size == (size_t)-1)
+		goto fail;
+	memstream->buf = malloc(memstream->size);
+	if (memstream->buf == NULL)
+		goto fail;
+
+	rewind(memstream->stream);
+	if (fread(memstream->buf, 1, memstream->size, memstream->stream)
+	    < memstream->size)
+		goto fail;
+#endif
+
+	return fclose(memstream->stream) == 0 ? 0 : -1;
+}
+
+void
+memstream_destroy(struct memstream *memstream)
+{
+	free(memstream->buf);
+}
diff --git a/memstream.h b/memstream.h
new file mode 100644
index 0000000..eb06541
--- /dev/null
+++ b/memstream.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of ltrace.
+ * Copyright (C) 2012 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
+ * 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
+ */
+
+#include <stdio.h>
+
+/* Portability wrapper for platforms that don't have
+ * open_memstream.  */
+
+struct memstream
+{
+	FILE *stream;
+	char *buf;
+	size_t size;
+};
+
+int memstream_init(struct memstream *memstream);
+int memstream_close(struct memstream *memstream);
+void memstream_destroy(struct memstream *memstream);
diff --git a/options.c b/options.c
index e8fd2a2..eaf32fa 100644
--- a/options.c
+++ b/options.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) 2009,2010 Joe Damato
  * Copyright (C) 1998,1999,2002,2003,2004,2007,2008,2009 Juan Cespedes
  * Copyright (C) 2006 Ian Wienand
@@ -86,27 +86,27 @@ usage(void) {
 	fprintf(stdout, "Usage: %s [option ...] [command [arg ...]]\n"
 		"Trace library calls of a given program.\n\n"
 		"  -a, --align=COLUMN  align return values in a secific column.\n"
-		"  -A ARRAYLEN         maximum number of array elements to print.\n"
+		"  -A MAXELTS          maximum number of array elements to print.\n"
 		"  -b, --no-signals    don't print signals.\n"
 		"  -c                  count time and calls, and report a summary on exit.\n"
 # ifdef USE_DEMANGLE
 		"  -C, --demangle      decode low-level symbol names into user-level names.\n"
 # endif
-		"  -D, --debug=LEVEL   enable debugging (see -Dh or --debug=help).\n"
+		"  -D, --debug=MASK    enable debugging (see -Dh or --debug=help).\n"
 		"  -Dh, --debug=help   show help on debugging.\n"
-		"  -e expr             modify which events to trace.\n"
+		"  -e FILTER           modify which library calls to trace.\n"
 		"  -f                  trace children (fork() and clone()).\n"
 		"  -F, --config=FILE   load alternate configuration file (may be repeated).\n"
 		"  -h, --help          display this help and exit.\n"
 		"  -i                  print instruction pointer at time of library call.\n"
-		"  -l, --library=FILE  only trace symbols implemented by this library.\n"
+		"  -l, --library=LIBRARY_PATTERN only trace symbols implemented by this library.\n"
 		"  -L                  do NOT display library calls.\n"
 		"  -n, --indent=NR     indent output by NR spaces for each call level nesting.\n"
-		"  -o, --output=FILE   write the trace output to that file.\n"
+		"  -o, --output=FILENAME write the trace output to file with given name.\n"
 		"  -p PID              attach to the process with the process ID pid.\n"
 		"  -r                  print relative timestamps.\n"
-		"  -s STRLEN           specify the maximum string size to print.\n"
-		"  -S                  display system calls.\n"
+		"  -s STRSIZE          specify the maximum string size to print.\n"
+		"  -S                  trace system calls as well as library calls.\n"
 		"  -t, -tt, -ttt       print absolute timestamps.\n"
 		"  -T                  show the time spent inside each call.\n"
 		"  -u USERNAME         run command with the userid, groupid of username.\n"
@@ -114,7 +114,7 @@ usage(void) {
 #if defined(HAVE_LIBUNWIND)
 		"  -w, --where=NR      print backtrace showing NR stack frames at most.\n"
 #endif /* defined(HAVE_LIBUNWIND) */
-		"  -x NAME             treat the global NAME like a library subroutine.\n"
+		"  -x FILTER           modify which static functions to trace.\n"
 		"\nReport bugs to ltrace-devel@lists.alioth.debian.org\n",
 		progname);
 }
@@ -204,7 +204,7 @@ compile_libname(const char *expr, const char *a_lib, int lib_re_p,
 
 		regex_t lib_re;
 		int status = (lib_re_p ? regcomp : globcomp)(&lib_re, lib, 0);
-		if (status != REG_NOERROR) {
+		if (status != 0) {
 			char buf[100];
 			regerror(status, &lib_re, buf, sizeof buf);
 			fprintf(stderr, "Rule near '%s' will be ignored: %s.\n",
@@ -459,6 +459,7 @@ process_options(int argc, char **argv)
 	while (1) {
 		int c;
 		char *p;
+#ifdef HAVE_GETOPT_LONG
 		int option_index = 0;
 		static struct option long_options[] = {
 			{"align", 1, 0, 'a'},
@@ -466,28 +467,34 @@ process_options(int argc, char **argv)
 			{"debug", 1, 0, 'D'},
 # ifdef USE_DEMANGLE
 			{"demangle", 0, 0, 'C'},
-#endif
+# endif
 			{"indent", 1, 0, 'n'},
 			{"help", 0, 0, 'h'},
 			{"library", 1, 0, 'l'},
 			{"output", 1, 0, 'o'},
 			{"version", 0, 0, 'V'},
 			{"no-signals", 0, 0, 'b'},
-#if defined(HAVE_LIBUNWIND)
+# if defined(HAVE_LIBUNWIND)
 			{"where", 1, 0, 'w'},
-#endif /* defined(HAVE_LIBUNWIND) */
+# endif /* defined(HAVE_LIBUNWIND) */
 			{0, 0, 0, 0}
 		};
-		c = getopt_long(argc, argv, "+cfhiLrStTVb"
-# ifdef USE_DEMANGLE
-				"C"
-# endif
+#endif
+
+		const char *opts = "+"
+#ifdef USE_DEMANGLE
+			"C"
+#endif
 #if defined(HAVE_LIBUNWIND)
-				"a:A:D:e:F:l:n:o:p:s:u:x:X:w:", long_options,
-#else /* !defined(HAVE_LIBUNWIND) */
-				"a:A:D:e:F:l:n:o:p:s:u:x:X:", long_options,
+			"w:"
+#endif
+			"cfhiLrStTVba:A:D:e:F:l:n:o:p:s:u:x:X:";
+
+#ifdef HAVE_GETOPT_LONG
+		c = getopt_long(argc, argv, opts, long_options, &option_index);
+#else
+		c = getopt(argc, argv, opts);
 #endif
-				&option_index);
 		if (c == -1) {
 			break;
 		}
@@ -610,10 +617,12 @@ process_options(int argc, char **argv)
 			options.user = optarg;
 			break;
 		case 'V':
-			printf("ltrace version " PACKAGE_VERSION ".\n"
-					"Copyright (C) 1997-2009 Juan Cespedes <cespedes@debian.org>.\n"
-					"This is free software; see the GNU General Public Licence\n"
-					"version 2 or later for copying conditions.  There is NO warranty.\n");
+			printf("ltrace " PACKAGE_VERSION "\n"
+			       "Copyright (C) 2010-2012 Petr Machata, Red Hat Inc.\n"
+			       "Copyright (C) 1997-2009 Juan Cespedes <cespedes@debian.org>.\n"
+			       "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
+			       "This is free software: you are free to change and redistribute it.\n"
+			       "There is NO WARRANTY, to the extent permitted by law.\n");
 			exit(0);
 			break;
 #if defined(HAVE_LIBUNWIND)
diff --git a/output.c b/output.c
index 1d01d31..fe62bb4 100644
--- a/output.c
+++ b/output.c
@@ -22,10 +22,6 @@
  * 02110-1301 USA
  */
 
-/* glibc before 2.10, eglibc and uClibc all need _GNU_SOURCE defined
- * for open_memstream to become visible.  */
-#define _GNU_SOURCE
-
 #include "config.h"
 
 #include <stdio.h>
@@ -47,25 +43,26 @@
 #include "param.h"
 #include "fetch.h"
 #include "lens_default.h"
+#include "memstream.h"
 
 /* TODO FIXME XXX: include in common.h: */
 extern struct timeval current_time_spent;
 
 Dict *dict_opt_c = NULL;
 
-static Process *current_proc = 0;
+static struct process *current_proc = 0;
 static size_t current_depth = 0;
 static int current_column = 0;
 
 static void
-output_indent(struct Process *proc)
+output_indent(struct process *proc)
 {
 	int d = options.indent * (proc->callstack_depth - 1);
 	current_column += fprintf(options.output, "%*s", d, "");
 }
 
 static void
-begin_of_line(Process *proc, int is_func, int indent)
+begin_of_line(struct process *proc, int is_func, int indent)
 {
 	current_column = 0;
 	if (!proc) {
@@ -208,7 +205,7 @@ name2func(char const *name) {
 }
 
 void
-output_line(struct Process *proc, const char *fmt, ...)
+output_line(struct process *proc, const char *fmt, ...)
 {
 	if (options.summary)
 		return;
@@ -248,7 +245,8 @@ output_error(FILE *stream)
 }
 
 static int
-fetch_simple_param(enum tof type, Process *proc, struct fetch_context *context,
+fetch_simple_param(enum tof type, struct process *proc,
+		   struct fetch_context *context,
 		   struct value_dict *arguments,
 		   struct arg_type_info *info, int own,
 		   struct value *valuep)
@@ -290,7 +288,8 @@ fetch_param_stop(struct value_dict *arguments, ssize_t *params_leftp)
 }
 
 static int
-fetch_param_pack(enum tof type, Process *proc, struct fetch_context *context,
+fetch_param_pack(enum tof type, struct process *proc,
+		 struct fetch_context *context,
 		 struct value_dict *arguments, struct param *param,
 		 ssize_t *params_leftp)
 {
@@ -343,7 +342,8 @@ fetch_param_pack(enum tof type, Process *proc, struct fetch_context *context,
 }
 
 static int
-fetch_one_param(enum tof type, Process *proc, struct fetch_context *context,
+fetch_one_param(enum tof type, struct process *proc,
+		struct fetch_context *context,
 		struct value_dict *arguments, struct param *param,
 		ssize_t *params_leftp)
 {
@@ -372,7 +372,8 @@ fetch_one_param(enum tof type, Process *proc, struct fetch_context *context,
 }
 
 static int
-fetch_params(enum tof type, Process *proc, struct fetch_context *context,
+fetch_params(enum tof type, struct process *proc,
+	     struct fetch_context *context,
 	     struct value_dict *arguments, Function *func, ssize_t *params_leftp)
 {
 	size_t i;
@@ -424,7 +425,7 @@ output_params(struct value_dict *arguments, size_t start, size_t end,
 }
 
 void
-output_left(enum tof type, struct Process *proc,
+output_left(enum tof type, struct process *proc,
 	    struct library_symbol *libsym)
 {
 	const char *function_name = libsym->name;
@@ -499,7 +500,7 @@ output_left(enum tof type, struct Process *proc,
 }
 
 void
-output_right(enum tof type, struct Process *proc, struct library_symbol *libsym)
+output_right(enum tof type, struct process *proc, struct library_symbol *libsym)
 {
 	const char *function_name = libsym->name;
 	Function *func = name2func(function_name);
@@ -640,18 +641,18 @@ delim_output(FILE *stream, int *need_delimp,
 		o = writer(stream, data);
 
 	} else {
-		char *buf;
-		size_t bufsz;
-		FILE *tmp = open_memstream(&buf, &bufsz);
-		o = writer(tmp, data);
-		fclose(tmp);
-
+		struct memstream ms;
+		if (memstream_init(&ms) < 0)
+			return -1;
+		o = writer(ms.stream, data);
+		if (memstream_close(&ms) < 0)
+			o = -1;
 		if (o > 0 && ((*need_delimp
 			       && account_output(&o, fprintf(stream, ", ")) < 0)
-			      || fwrite(buf, 1, bufsz, stream) != bufsz))
+			      || fwrite(ms.buf, 1, ms.size, stream) != ms.size))
 			o = -1;
 
-		free(buf);
+		memstream_destroy(&ms);
 	}
 
 	if (o < 0)
diff --git a/output.h b/output.h
index 0d16657..b9f0518 100644
--- a/output.h
+++ b/output.h
@@ -24,10 +24,10 @@
 #include "fetch.h"
 #include "forward.h"
 
-void output_line(struct Process *proc, const char *fmt, ...);
-void output_left(enum tof type, struct Process *proc,
+void output_line(struct process *proc, const char *fmt, ...);
+void output_left(enum tof type, struct process *proc,
 		 struct library_symbol *libsym);
-void output_right(enum tof type, struct Process *proc,
+void output_right(enum tof type, struct process *proc,
 		  struct library_symbol *libsym);
 
 /* This function is for emitting lists of comma-separated strings.
diff --git a/proc.c b/proc.c
index 3b4bfdb..db3f645 100644
--- a/proc.c
+++ b/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
  *
@@ -43,24 +43,24 @@
 
 #ifndef ARCH_HAVE_PROCESS_DATA
 int
-arch_process_init(struct Process *proc)
+arch_process_init(struct process *proc)
 {
 	return 0;
 }
 
 void
-arch_process_destroy(struct Process *proc)
+arch_process_destroy(struct process *proc)
 {
 }
 
 int
-arch_process_clone(struct Process *retp, struct Process *proc)
+arch_process_clone(struct process *retp, struct process *proc)
 {
 	return 0;
 }
 
 int
-arch_process_exec(struct Process *proc)
+arch_process_exec(struct process *proc)
 {
 	return 0;
 }
@@ -68,24 +68,24 @@ arch_process_exec(struct Process *proc)
 
 #ifndef OS_HAVE_PROCESS_DATA
 int
-os_process_init(struct Process *proc)
+os_process_init(struct process *proc)
 {
 	return 0;
 }
 
 void
-os_process_destroy(struct Process *proc)
+os_process_destroy(struct process *proc)
 {
 }
 
 int
-os_process_clone(struct Process *retp, struct Process *proc)
+os_process_clone(struct process *retp, struct process *proc)
 {
 	return 0;
 }
 
 int
-os_process_exec(struct Process *proc)
+os_process_exec(struct process *proc)
 {
 	return 0;
 }
@@ -93,16 +93,16 @@ os_process_exec(struct Process *proc)
 
 #ifndef ARCH_HAVE_DYNLINK_DONE
 void
-arch_dynlink_done(struct Process *proc)
+arch_dynlink_done(struct process *proc)
 {
 }
 #endif
 
-static void add_process(struct Process *proc, int was_exec);
-static void unlist_process(struct Process *proc);
+static void add_process(struct process *proc, int was_exec);
+static void unlist_process(struct process *proc);
 
 static void
-destroy_unwind(struct Process *proc)
+destroy_unwind(struct process *proc)
 {
 #if defined(HAVE_LIBUNWIND)
 	_UPT_destroy(proc->unwind_priv);
@@ -111,7 +111,7 @@ destroy_unwind(struct Process *proc)
 }
 
 static int
-process_bare_init(struct Process *proc, const char *filename,
+process_bare_init(struct process *proc, const char *filename,
 		  pid_t pid, int was_exec)
 {
 	if (!was_exec) {
@@ -151,7 +151,7 @@ process_bare_init(struct Process *proc, const char *filename,
 }
 
 static void
-process_bare_destroy(struct Process *proc, int was_exec)
+process_bare_destroy(struct process *proc, int was_exec)
 {
 	dict_clear(proc->breakpoints);
 	if (!was_exec) {
@@ -162,7 +162,7 @@ process_bare_destroy(struct Process *proc, int was_exec)
 }
 
 static int
-process_init_main(struct Process *proc)
+process_init_main(struct process *proc)
 {
 	if (breakpoints_init(proc) < 0) {
 		fprintf(stderr, "failed to init breakpoints %d\n",
@@ -174,7 +174,7 @@ process_init_main(struct Process *proc)
 }
 
 int
-process_init(struct Process *proc, const char *filename, pid_t pid)
+process_init(struct process *proc, const char *filename, pid_t pid)
 {
 	if (process_bare_init(proc, filename, pid, 0) < 0) {
 	fail:
@@ -204,7 +204,7 @@ process_init(struct Process *proc, const char *filename, pid_t pid)
 }
 
 static enum callback_status
-destroy_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data)
+destroy_breakpoint_cb(struct process *proc, struct breakpoint *bp, void *data)
 {
 	breakpoint_destroy(bp);
 	free(bp);
@@ -212,10 +212,10 @@ destroy_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data)
 }
 
 // XXX see comment in handle_event.c
-void callstack_pop(struct Process *proc);
+void callstack_pop(struct process *proc);
 
 static void
-private_process_destroy(struct Process *proc, int was_exec)
+private_process_destroy(struct process *proc, int was_exec)
 {
 	/* Pop remaining stack elements.  */
 	while (proc->callstack_depth > 0) {
@@ -257,7 +257,7 @@ private_process_destroy(struct Process *proc, int was_exec)
 }
 
 void
-process_destroy(struct Process *proc)
+process_destroy(struct process *proc)
 {
 	arch_process_destroy(proc);
 	os_process_destroy(proc);
@@ -265,7 +265,7 @@ process_destroy(struct Process *proc)
 }
 
 int
-process_exec(struct Process *proc)
+process_exec(struct process *proc)
 {
 	/* Call exec handlers first, before we destroy the main
 	 * state.  */
@@ -284,11 +284,11 @@ process_exec(struct Process *proc)
 	return 0;
 }
 
-struct Process *
+struct process *
 open_program(const char *filename, pid_t pid)
 {
 	assert(pid != 0);
-	struct Process *proc = malloc(sizeof(*proc));
+	struct process *proc = malloc(sizeof(*proc));
 	if (proc == NULL || process_init(proc, filename, pid) < 0) {
 		free(proc);
 		return NULL;
@@ -297,8 +297,8 @@ open_program(const char *filename, pid_t pid)
 }
 
 struct clone_single_bp_data {
-	struct Process *old_proc;
-	struct Process *new_proc;
+	struct process *old_proc;
+	struct process *new_proc;
 	int error;
 };
 
@@ -327,7 +327,7 @@ clone_single_bp(void *key, void *value, void *u)
 }
 
 int
-process_clone(struct Process *retp, struct Process *proc, pid_t pid)
+process_clone(struct process *retp, struct process *proc, pid_t pid)
 {
 	if (process_bare_init(retp, proc->filename, pid, 0) < 0) {
 	fail1:
@@ -456,20 +456,18 @@ process_clone(struct Process *retp, struct Process *proc, pid_t pid)
 static int
 open_one_pid(pid_t pid)
 {
-	Process *proc;
-	char *filename;
 	debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid);
 
 	/* Get the filename first.  Should the trace_pid fail, we can
 	 * easily free it, untracing is more work.  */
-	if ((filename = pid2name(pid)) == NULL
-	    || trace_pid(pid) < 0) {
+	char *filename = pid2name(pid);
+	if (filename == NULL || trace_pid(pid) < 0) {
 	fail:
 		free(filename);
 		return -1;
 	}
 
-	proc = open_program(filename, pid);
+	struct process *proc = open_program(filename, pid);
 	if (proc == NULL)
 		goto fail;
 	free(filename);
@@ -479,7 +477,7 @@ open_one_pid(pid_t pid)
 }
 
 static enum callback_status
-start_one_pid(Process * proc, void * data)
+start_one_pid(struct process *proc, void *data)
 {
 	continue_process(proc->pid);
 	return CBS_CONT;
@@ -537,7 +535,7 @@ open_pid(pid_t pid)
 		old_ntasks = ntasks;
 	}
 
-	struct Process *leader = pid2proc(pid)->leader;
+	struct process *leader = pid2proc(pid)->leader;
 
 	/* XXX Is there a way to figure out whether _start has
 	 * actually already been hit?  */
@@ -548,29 +546,29 @@ open_pid(pid_t pid)
 }
 
 static enum callback_status
-find_proc(Process * proc, void * data)
+find_proc(struct process *proc, void *data)
 {
 	pid_t pid = (pid_t)(uintptr_t)data;
 	return proc->pid == pid ? CBS_STOP : CBS_CONT;
 }
 
-Process *
-pid2proc(pid_t pid) {
+struct process *
+pid2proc(pid_t pid)
+{
 	return each_process(NULL, &find_proc, (void *)(uintptr_t)pid);
 }
 
-static Process * list_of_processes = NULL;
+static struct process *list_of_processes = NULL;
 
 static void
-unlist_process(Process * proc)
+unlist_process(struct process *proc)
 {
-	Process *tmp;
-
 	if (list_of_processes == proc) {
 		list_of_processes = list_of_processes->next;
 		return;
 	}
 
+	struct process *tmp;
 	for (tmp = list_of_processes; ; tmp = tmp->next) {
 		/* If the following assert fails, the process wasn't
 		 * in the list.  */
@@ -583,17 +581,17 @@ unlist_process(Process * proc)
 	}
 }
 
-struct Process *
-each_process(struct Process *start_after,
-	     enum callback_status(*cb)(struct Process *proc, void *data),
+struct process *
+each_process(struct process *start_after,
+	     enum callback_status(*cb)(struct process *proc, void *data),
 	     void *data)
 {
-	struct Process *it = start_after == NULL ? list_of_processes
+	struct process *it = start_after == NULL ? list_of_processes
 		: start_after->next;
 
 	while (it != NULL) {
 		/* Callback might call remove_process.  */
-		struct Process *next = it->next;
+		struct process *next = it->next;
 		switch ((*cb)(it, data)) {
 		case CBS_FAIL:
 			/* XXX handle me */
@@ -607,20 +605,20 @@ each_process(struct Process *start_after,
 	return NULL;
 }
 
-Process *
-each_task(struct Process *proc, struct Process *start_after,
-	  enum callback_status(*cb)(struct Process *proc, void *data),
+struct process *
+each_task(struct process *proc, struct process *start_after,
+	  enum callback_status(*cb)(struct process *proc, void *data),
 	  void *data)
 {
 	assert(proc != NULL);
-	struct Process *it = start_after == NULL ? proc->leader
+	struct process *it = start_after == NULL ? proc->leader
 		: start_after->next;
 
 	if (it != NULL) {
-		struct Process *leader = it->leader;
+		struct process *leader = it->leader;
 		while (it != NULL && it->leader == leader) {
 			/* Callback might call remove_process.  */
-			struct Process *next = it->next;
+			struct process *next = it->next;
 			switch ((*cb)(it, data)) {
 			case CBS_FAIL:
 				/* XXX handle me */
@@ -636,19 +634,19 @@ each_task(struct Process *proc, struct Process *start_after,
 }
 
 static void
-add_process(struct Process *proc, int was_exec)
+add_process(struct process *proc, int was_exec)
 {
-	Process ** leaderp = &list_of_processes;
+	struct process **leaderp = &list_of_processes;
 	if (proc->pid) {
 		pid_t tgid = process_leader(proc->pid);
 		if (tgid == 0)
 			/* Must have been terminated before we managed
 			 * to fully attach.  */
 			return;
-		if (tgid == proc->pid)
+		if (tgid == proc->pid) {
 			proc->leader = proc;
-		else {
-			Process * leader = pid2proc(tgid);
+		} else {
+			struct process *leader = pid2proc(tgid);
 			proc->leader = leader;
 			if (leader != NULL)
 				leaderp = &leader->next;
@@ -662,9 +660,9 @@ add_process(struct Process *proc, int was_exec)
 }
 
 void
-change_process_leader(Process * proc, Process * leader)
+change_process_leader(struct process *proc, struct process *leader)
 {
-	Process ** leaderp = &list_of_processes;
+	struct process **leaderp = &list_of_processes;
 	if (proc->leader == leader)
 		return;
 
@@ -679,7 +677,7 @@ change_process_leader(Process * proc, Process * leader)
 }
 
 static enum callback_status
-clear_leader(struct Process *proc, void *data)
+clear_leader(struct process *proc, void *data)
 {
 	debug(DEBUG_FUNCTION, "detach_task %d from leader %d",
 	      proc->pid, proc->leader->pid);
@@ -688,7 +686,7 @@ clear_leader(struct Process *proc, void *data)
 }
 
 void
-remove_process(Process *proc)
+remove_process(struct process *proc)
 {
 	debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid);
 
@@ -702,7 +700,7 @@ remove_process(Process *proc)
 }
 
 void
-install_event_handler(Process *proc, struct event_handler *handler)
+install_event_handler(struct process *proc, struct event_handler *handler)
 {
 	debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler);
 	assert(proc->event_handler == NULL);
@@ -710,7 +708,7 @@ install_event_handler(Process *proc, struct event_handler *handler)
 }
 
 void
-destroy_event_handler(Process * proc)
+destroy_event_handler(struct process *proc)
 {
 	struct event_handler *handler = proc->event_handler;
 	debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler);
@@ -722,7 +720,7 @@ destroy_event_handler(Process * proc)
 }
 
 static int
-breakpoint_for_symbol(struct library_symbol *libsym, struct Process *proc)
+breakpoint_for_symbol(struct library_symbol *libsym, struct process *proc)
 {
 	arch_addr_t bp_addr;
 	assert(proc->leader == proc);
@@ -799,7 +797,7 @@ cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data)
 }
 
 static int
-proc_activate_latent_symbol(struct Process *proc,
+proc_activate_latent_symbol(struct process *proc,
 			    struct library_symbol *libsym)
 {
 	assert(libsym->latent);
@@ -809,7 +807,7 @@ proc_activate_latent_symbol(struct Process *proc,
 }
 
 int
-proc_activate_delayed_symbol(struct Process *proc,
+proc_activate_delayed_symbol(struct process *proc,
 			     struct library_symbol *libsym)
 {
 	assert(libsym->delayed);
@@ -819,7 +817,7 @@ proc_activate_delayed_symbol(struct Process *proc,
 }
 
 static enum callback_status
-activate_latent_in(struct Process *proc, struct library *lib, void *data)
+activate_latent_in(struct process *proc, struct library *lib, void *data)
 {
 	struct library_exported_name *exported;
 	for (exported = data; exported != NULL; exported = exported->next) {
@@ -836,7 +834,7 @@ activate_latent_in(struct Process *proc, struct library *lib, void *data)
 }
 
 void
-proc_add_library(struct Process *proc, struct library *lib)
+proc_add_library(struct process *proc, struct library *lib)
 {
 	assert(lib->next == NULL);
 	lib->next = proc->libraries;
@@ -864,7 +862,7 @@ proc_add_library(struct Process *proc, struct library *lib)
 }
 
 int
-proc_remove_library(struct Process *proc, struct library *lib)
+proc_remove_library(struct process *proc, struct library *lib)
 {
 	struct library **libp;
 	for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next)
@@ -876,8 +874,8 @@ proc_remove_library(struct Process *proc, struct library *lib)
 }
 
 struct library *
-proc_each_library(struct Process *proc, struct library *it,
-		  enum callback_status (*cb)(struct Process *proc,
+proc_each_library(struct process *proc, struct library *it,
+		  enum callback_status (*cb)(struct process *proc,
 					     struct library *lib, void *data),
 		  void *data)
 {
@@ -903,7 +901,7 @@ proc_each_library(struct Process *proc, struct library *it,
 }
 
 static void
-check_leader(struct Process *proc)
+check_leader(struct process *proc)
 {
 	/* Only the group leader should be getting the breakpoints and
 	 * thus have ->breakpoint initialized.  */
@@ -913,7 +911,7 @@ check_leader(struct Process *proc)
 }
 
 int
-proc_add_breakpoint(struct Process *proc, struct breakpoint *bp)
+proc_add_breakpoint(struct process *proc, struct breakpoint *bp)
 {
 	debug(DEBUG_FUNCTION, "proc_add_breakpoint(pid=%d, %s@%p)",
 	      proc->pid, breakpoint_name(bp), bp->addr);
@@ -935,7 +933,7 @@ proc_add_breakpoint(struct Process *proc, struct breakpoint *bp)
 }
 
 void
-proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp)
+proc_remove_breakpoint(struct process *proc, struct breakpoint *bp)
 {
 	debug(DEBUG_FUNCTION, "proc_remove_breakpoint(pid=%d, %s@%p)",
 	      proc->pid, breakpoint_name(bp), bp->addr);
@@ -950,8 +948,8 @@ struct each_breakpoint_data
 {
 	void *start;
 	void *end;
-	struct Process *proc;
-	enum callback_status (*cb)(struct Process *proc,
+	struct process *proc;
+	enum callback_status (*cb)(struct process *proc,
 				   struct breakpoint *bp,
 				   void *data);
 	void *cb_data;
@@ -979,8 +977,8 @@ each_breakpoint_cb(void *key, void *value, void *d)
 }
 
 void *
-proc_each_breakpoint(struct Process *proc, void *start,
-		     enum callback_status (*cb)(struct Process *proc,
+proc_each_breakpoint(struct process *proc, void *start,
+		     enum callback_status (*cb)(struct process *proc,
 						struct breakpoint *bp,
 						void *data), void *data)
 {
@@ -995,7 +993,7 @@ proc_each_breakpoint(struct Process *proc, void *start,
 }
 
 int
-proc_find_symbol(struct Process *proc, struct library_symbol *sym,
+proc_find_symbol(struct process *proc, struct library_symbol *sym,
 		 struct library **retlib, struct library_symbol **retsym)
 {
 	struct library *lib = sym->lib;
@@ -1021,7 +1019,7 @@ proc_find_symbol(struct Process *proc, struct library_symbol *sym,
 }
 
 struct library_symbol *
-proc_each_symbol(struct Process *proc, struct library_symbol *start_after,
+proc_each_symbol(struct process *proc, struct library_symbol *start_after,
 		 enum callback_status (*cb)(struct library_symbol *, void *),
 		 void *data)
 {
@@ -1035,3 +1033,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
diff --git a/proc.h b/proc.h
index a97796c..04c0ef7 100644
--- a/proc.h
+++ b/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>
@@ -75,13 +76,12 @@ struct callstack_element {
 #define MAX_CALLDEPTH 64
 
 /* XXX We would rather have this all organized a little differently,
- * have Process for the whole group and Task for what's there for
- * per-thread stuff.  But for now this is the less invasive way of
- * structuring it.  */
-typedef struct Process Process;
-struct Process {
+ * have struct process for the whole group and struct task (or struct
+ * lwp, struct thread) for what's there for per-thread stuff.  But for
+ * now this is the less invasive way of structuring it.  */
+struct process {
 	enum process_state state;
-	Process * parent;         /* needed by STATE_BEING_CREATED */
+	struct process *parent;         /* needed by STATE_BEING_CREATED */
 	char * filename;
 	pid_t pid;
 
@@ -133,15 +133,15 @@ struct Process {
 	/**
 	 * Process chaining.
 	 **/
-	Process * next;
+	struct process *next;
 
 	/* LEADER points to the leader thread of the POSIX.1 process.
 	   If X->LEADER == X, then X is the leader thread and the
-	   Process structures chained by NEXT represent other threads,
+	   process structures chained by NEXT represent other threads,
 	   up until, but not including, the next leader thread.
 	   LEADER may be NULL after the leader has already exited.  In
 	   that case this process is waiting to be collected.  */
-	Process * leader;
+	struct process *leader;
 
 	struct os_process_data os;
 	struct arch_process_data arch;
@@ -149,12 +149,12 @@ struct Process {
 
 /* Initialize a process given a path to binary FILENAME, with a PID,
  * and add the process to an internal chain of traced processes.  */
-int process_init(struct Process *proc, const char *filename, pid_t pid);
+int process_init(struct process *proc, const char *filename, pid_t pid);
 
 /* PROC underwent an exec.  This is a bit like process_destroy
  * followed by process_init, except that some state is kept and the
  * process doesn't lose it's place in the list of processes.  */
-int process_exec(struct Process *proc);
+int process_exec(struct process *proc);
 
 /* Release any memory allocated for PROC (but not PROC itself).  Does
  * NOT remove PROC from internal chain.
@@ -162,74 +162,74 @@ int process_exec(struct Process *proc);
  * XXX clearly this init/destroy pair is different than others and
  * should be fixed.  process_init should presumably be separate from
  * process_add.  */
-void process_destroy(struct Process *proc);
+void process_destroy(struct process *proc);
 
-struct Process *open_program(const char *filename, pid_t pid);
+struct process *open_program(const char *filename, pid_t pid);
 void open_pid(pid_t pid);
-Process * pid2proc(pid_t pid);
+struct process *pid2proc(pid_t pid);
 
 /* Clone the contents of PROC into the memory referenced by RETP.
  * Returns 0 on success or a negative value on failure.  */
-int process_clone(struct Process *retp, struct Process *proc, pid_t pid);
+int process_clone(struct process *retp, struct process *proc, pid_t pid);
 
 /* Iterate through the processes that ltrace currently traces.  Tasks
  * are considered to be processes for the purpose of this iterator.
  * See callback.h for notes on iteration interfaces.  */
-Process *each_process(Process *start_after,
-		      enum callback_status (*cb)(struct Process *proc,
-						 void *data),
-		      void *data);
+struct process *each_process(struct process *start_after,
+			     enum callback_status (*cb)(struct process *proc,
+							void *data),
+			     void *data);
 
 /* Iterate through list of tasks of given process PROC.  See
  * callback.h for notes on iteration interfaces.  */
-Process *each_task(struct Process *proc, struct Process *start_after,
-		   enum callback_status (*cb)(struct Process *proc,
-					      void *data),
-		   void *data);
+struct process *each_task(struct process *proc, struct process *start_after,
+			  enum callback_status (*cb)(struct process *proc,
+						     void *data),
+			  void *data);
 
-void change_process_leader(Process *proc, Process *leader);
+void change_process_leader(struct process *proc, struct process *leader);
 
 /* Remove process from the list of traced processes, drop any events
  * in the event queue, destroy it and free memory.  */
-void remove_process(struct Process *proc);
+void remove_process(struct process *proc);
 
-void install_event_handler(Process *proc, struct event_handler *handler);
-void destroy_event_handler(Process *proc);
+void install_event_handler(struct process *proc, struct event_handler *handler);
+void destroy_event_handler(struct process *proc);
 
 /* Add a library LIB to the list of PROC's libraries.  */
-void proc_add_library(struct Process *proc, struct library *lib);
+void proc_add_library(struct process *proc, struct library *lib);
 
 /* Remove LIB from list of PROC's libraries.  Returns 0 if the library
  * was found and unlinked, otherwise returns a negative value.  */
-int proc_remove_library(struct Process *proc, struct library *lib);
+int proc_remove_library(struct process *proc, struct library *lib);
 
 /* Clear a delayed flag.  If a symbol is neither latent, nor delayed,
  * a breakpoint is inserted for it.  Returns 0 if the activation was
  * successful or a negative value if it failed.  Note that if a symbol
  * is both latent and delayed, this will not enable the corresponding
  * breakpoint.  */
-int proc_activate_delayed_symbol(struct Process *proc,
+int proc_activate_delayed_symbol(struct process *proc,
 				 struct library_symbol *libsym);
 
 /* Iterate through the libraries of PROC.  See callback.h for notes on
  * iteration interfaces.  */
-struct library *proc_each_library(struct Process *proc, struct library *start,
-				  enum callback_status (*cb)(struct Process *p,
+struct library *proc_each_library(struct process *proc, struct library *start,
+				  enum callback_status (*cb)(struct process *p,
 							     struct library *l,
 							     void *data),
 				  void *data);
 
 /* Insert BP into PROC.  */
-int proc_add_breakpoint(struct Process *proc, struct breakpoint *bp);
+int proc_add_breakpoint(struct process *proc, struct breakpoint *bp);
 
 /* Remove BP from PROC.  This has no reason to fail in runtime.  If it
  * does not find BP in PROC, it's hard error guarded by assertion.  */
-void proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp);
+void proc_remove_breakpoint(struct process *proc, struct breakpoint *bp);
 
 /* Iterate through the breakpoints of PROC.  See callback.h for notes
  * on iteration interfaces.  */
-void *proc_each_breakpoint(struct Process *proc, void *start,
-			   enum callback_status (*cb)(struct Process *proc,
+void *proc_each_breakpoint(struct process *proc, void *start,
+			   enum callback_status (*cb)(struct process *proc,
 						      struct breakpoint *bp,
 						      void *data),
 			   void *data);
@@ -237,21 +237,29 @@ void *proc_each_breakpoint(struct Process *proc, void *start,
 /* Iterate through the dynamic section at src_addr looking for D_TAG.
  * If tag is found, fill it's value in RET and return 0.
  * If tag is not found, return a negative value.  */
-int proc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr,
+int proc_find_dynamic_entry_addr(struct process *proc, arch_addr_t src_addr,
 				 int d_tag, arch_addr_t *ret);
 
 /* Finds a symbol corresponding to LIBSYM in a process PROC.  Returns
  * 0 and sets *RETLIB and *RETSYM if the corresponding pointer is
  * non-NULL.  Returns a negative value when the symbols couldn't be
  * found.  */
-int proc_find_symbol(struct Process *proc, struct library_symbol *sym,
+int proc_find_symbol(struct process *proc, struct library_symbol *sym,
 		     struct library **retlib, struct library_symbol **retsym);
 
 /* Iterate through all symbols in all libraries of PROC.  See
  * callback.h for notes on this interface.  */
 struct library_symbol *proc_each_symbol
-	(struct Process *proc, struct library_symbol *start_after,
+	(struct process *proc, struct library_symbol *start_after,
 	 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_ */
diff --git a/read_config_file.c b/read_config_file.c
index e247436..015be50 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -27,7 +27,6 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
-#include <error.h>
 #include <assert.h>
 
 #include "common.h"
@@ -41,6 +40,19 @@
 #include "lens_default.h"
 #include "lens_enum.h"
 
+/* Lifted from GCC: The ctype functions are often implemented as
+ * macros which do lookups in arrays using the parameter as the
+ * offset.  If the ctype function parameter is a char, then gcc will
+ * (appropriately) warn that a "subscript has type char".  Using a
+ * (signed) char as a subscript is bad because you may get negative
+ * offsets and thus it is not 8-bit safe.  The CTYPE_CONV macro
+ * ensures that the parameter is cast to an unsigned char when a char
+ * is passed in.  When an int is passed in, the parameter is left
+ * alone so we don't lose EOF.  */
+
+#define CTYPE_CONV(CH) \
+  (sizeof(CH) == sizeof(unsigned char) ? (int)(unsigned char)(CH) : (int)(CH))
+
 static int line_no;
 static char *filename;
 struct typedef_node_t;
@@ -97,7 +109,7 @@ parse_arg_type(char **name, enum arg_type *ret)
 #undef KEYWORD
 
 ok:
-	if (isalnum(*rest))
+	if (isalnum(CTYPE_CONV(*rest)))
 		return -1;
 
 	*name = rest;
@@ -128,12 +140,12 @@ static char *
 parse_ident(char **str) {
 	char *ident = *str;
 
-	if (!isalpha(**str) && **str != '_') {
+	if (!isalpha(CTYPE_CONV(**str)) && **str != '_') {
 		report_error(filename, line_no, "bad identifier");
 		return NULL;
 	}
 
-	while (**str && (isalnum(**str) || **str == '_')) {
+	while (**str && (isalnum(CTYPE_CONV(**str)) || **str == '_')) {
 		++(*str);
 	}
 
@@ -280,7 +292,7 @@ parse_argnum(char **str, int *ownp, int zero)
 	if (expr == NULL)
 		return NULL;
 
-	if (isdigit(**str)) {
+	if (isdigit(CTYPE_CONV(**str))) {
 		long l;
 		if (parse_int(str, &l) < 0
 		    || check_nonnegative(l) < 0
@@ -381,7 +393,7 @@ static struct arg_type_info *
 parse_typedef_name(char **str)
 {
 	char *end = *str;
-	while (*end && (isalnum(*end) || *end == '_'))
+	while (*end && (isalnum(CTYPE_CONV(*end)) || *end == '_'))
 		++end;
 	if (end == *str)
 		return NULL;
@@ -568,7 +580,7 @@ parse_string(char **str, struct arg_type_info **retp, int *ownp)
 	int own_length;
 	int with_arg = 0;
 
-	if (isdigit(**str)) {
+	if (isdigit(CTYPE_CONV(**str))) {
 		/* string0 is string[retval], length is zero(retval)
 		 * stringN is string[argN], length is zero(argN) */
 		long l;
@@ -683,7 +695,7 @@ try_parse_kwd(char **str, const char *kwd)
 {
 	size_t len = strlen(kwd);
 	if (strncmp(*str, kwd, len) == 0
-	    && !isalnum((*str)[len])) {
+	    && !isalnum(CTYPE_CONV((*str)[len]))) {
 		(*str) += len;
 		return 0;
 	}
@@ -1258,8 +1270,11 @@ void
 init_global_config(void)
 {
 	struct arg_type_info *info = malloc(2 * sizeof(*info));
-	if (info == NULL)
-		error(1, errno, "malloc in init_global_config");
+	if (info == NULL) {
+		fprintf(stderr, "Couldn't init global config: %s\n",
+			strerror(errno));
+		exit(1);
+	}
 
 	memset(info, 0, 2 * sizeof(*info));
 	info[0].type = ARGTYPE_POINTER;
diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c
index c7ce9fe..1185363 100644
--- a/sysdeps/linux-gnu/alpha/plt.c
+++ b/sysdeps/linux-gnu/alpha/plt.c
@@ -23,11 +23,13 @@
 #include "common.h"
 
 GElf_Addr
-arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela)
+{
 	return lte->plt_addr + ndx * 12 + 32;
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/alpha/regs.c b/sysdeps/linux-gnu/alpha/regs.c
index 0b46afd..c197225 100644
--- a/sysdeps/linux-gnu/alpha/regs.c
+++ b/sysdeps/linux-gnu/alpha/regs.c
@@ -36,26 +36,31 @@
 #endif
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 64 /* REG_PC */ , 0);
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, 64 /* REG_PC */ , addr);
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 30 /* REG_FP */ , 0);
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 26 /* RA */ , 0);
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, 26 /* RA */ , addr);
 }
diff --git a/sysdeps/linux-gnu/alpha/trace.c b/sysdeps/linux-gnu/alpha/trace.c
index a7c5e59..c6f7494 100644
--- a/sysdeps/linux-gnu/alpha/trace.c
+++ b/sysdeps/linux-gnu/alpha/trace.c
@@ -40,13 +40,15 @@
 #endif
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 }
 
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		char *ip = get_instruction_pointer(proc) - 4;
@@ -69,7 +71,8 @@ syscall_p(Process *proc, int status, int *sysnum) {
 }
 
 long
-gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info)
+gimme_arg(enum tof type, struct process *proc, int arg_num,
+	  struct arg_type_info *info)
 {
 	if (arg_num == -1) {	/* return value */
 		return ptrace(PTRACE_PEEKUSER, proc->pid, 0 /* REG_R0 */ , 0);
diff --git a/sysdeps/linux-gnu/arm/breakpoint.c b/sysdeps/linux-gnu/arm/breakpoint.c
index 5748401..2fb9578 100644
--- a/sysdeps/linux-gnu/arm/breakpoint.c
+++ b/sysdeps/linux-gnu/arm/breakpoint.c
@@ -92,7 +92,7 @@ arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
 }
 
 int
-arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp)
+arch_breakpoint_init(struct process *proc, struct breakpoint *sbp)
 {
 	/* XXX That uintptr_t cast is there temporarily until
 	 * arch_addr_t becomes integral type.  */
diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c
index 1b97705..d1bf7ca 100644
--- a/sysdeps/linux-gnu/arm/plt.c
+++ b/sysdeps/linux-gnu/arm/plt.c
@@ -43,6 +43,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/arm/regs.c b/sysdeps/linux-gnu/arm/regs.c
index 484de7f..377df62 100644
--- a/sysdeps/linux-gnu/arm/regs.c
+++ b/sysdeps/linux-gnu/arm/regs.c
@@ -41,24 +41,28 @@
 #define off_sp ((void *)52)
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
 }
 
 /* really, this is given the *stack_pointer expecting
  * a CISC architecture; in our case, we don't need that */
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	long addr = ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
 
 	/* Remember & unset the thumb mode bit.  XXX This is really a
@@ -74,7 +78,8 @@ get_return_addr(Process *proc, void *stack_pointer) {
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	long iaddr = (int)addr | proc->thumb_mode;
 	ptrace(PTRACE_POKEUSER, proc->pid, off_lr, (void *)iaddr);
 }
diff --git a/sysdeps/linux-gnu/arm/trace.c b/sysdeps/linux-gnu/arm/trace.c
index c528cfb..fbbf676 100644
--- a/sysdeps/linux-gnu/arm/trace.c
+++ b/sysdeps/linux-gnu/arm/trace.c
@@ -48,7 +48,8 @@
 #define off_pc ((void *)60)
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 	proc_archdep *a;
 
 	if (!proc->arch_ptr)
@@ -63,7 +64,8 @@ get_arch_dep(Process *proc) {
  *         -1 on error.
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		/* get the user's pc (plus 8) */
@@ -104,7 +106,8 @@ syscall_p(Process *proc, int status, int *sysnum) {
 }
 
 long
-gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info)
+gimme_arg(enum tof type, struct process *proc, int arg_num,
+	  struct arg_type_info *info)
 {
 	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
 
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index fe336b1..c28d745 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -79,7 +79,7 @@ arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp)
 #endif				/* ARCH_HAVE_ENABLE_BREAKPOINT */
 
 void
-enable_breakpoint(Process *proc, struct breakpoint *sbp)
+enable_breakpoint(struct process *proc, struct breakpoint *sbp)
 {
 	debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s",
 	      proc->pid, sbp->addr, breakpoint_name(sbp));
@@ -127,7 +127,7 @@ arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
 #endif				/* ARCH_HAVE_DISABLE_BREAKPOINT */
 
 void
-disable_breakpoint(Process *proc, struct breakpoint *sbp)
+disable_breakpoint(struct process *proc, struct breakpoint *sbp)
 {
 	debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s",
 	      proc->pid, sbp->addr, breakpoint_name(sbp));
diff --git a/sysdeps/linux-gnu/cris/plt.c b/sysdeps/linux-gnu/cris/plt.c
index 427ae93..fcc18d2 100644
--- a/sysdeps/linux-gnu/cris/plt.c
+++ b/sysdeps/linux-gnu/cris/plt.c
@@ -28,7 +28,7 @@ GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
 	return lte->plt_addr + 0x20 + (ndx * 26);
 }
 
-void *sym2addr(Process *proc, struct library_symbol *sym)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
 {
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/cris/regs.c b/sysdeps/linux-gnu/cris/regs.c
index 7028b9e..4cf1fbf 100644
--- a/sysdeps/linux-gnu/cris/regs.c
+++ b/sysdeps/linux-gnu/cris/regs.c
@@ -37,22 +37,22 @@
 # define PTRACE_POKEUSER PTRACE_POKEUSR
 #endif
 
-void *get_instruction_pointer(Process *proc)
+void *get_instruction_pointer(struct process *proc)
 {
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PPC, 0);
 }
 
-void set_instruction_pointer(Process *proc, void *addr)
+void set_instruction_pointer(struct process *proc, void *addr)
 {
 	ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PPC, addr);
 }
 
-void *get_stack_pointer(Process *proc)
+void *get_stack_pointer(struct process *proc)
 {
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
 }
 
-void *get_return_addr(Process *proc, void *stack_pointer)
+void *get_return_addr(struct process *proc, void *stack_pointer)
 {
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_SRP, 0);
 }
diff --git a/sysdeps/linux-gnu/cris/trace.c b/sysdeps/linux-gnu/cris/trace.c
index 98cb7d8..7d8cca6 100644
--- a/sysdeps/linux-gnu/cris/trace.c
+++ b/sysdeps/linux-gnu/cris/trace.c
@@ -40,14 +40,14 @@
 # define PTRACE_POKEUSER PTRACE_POKEUSR
 #endif
 
-void get_arch_dep(Process *proc)
+void get_arch_dep(struct process *proc)
 {
 }
 
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
  */
 #define SYSCALL_INSN   0xe93d
-int syscall_p(Process *proc, int status, int *sysnum)
+int syscall_p(struct process *proc, int status, int *sysnum)
 {
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
@@ -71,7 +71,7 @@ int syscall_p(Process *proc, int status, int *sysnum)
 	return 0;
 }
 
-long gimme_arg(enum tof type, Process *proc, int arg_num,
+long gimme_arg(enum tof type, struct process *proc, int arg_num,
 	       struct arg_type_info *info)
 {
 	int pid = proc->pid;
diff --git a/sysdeps/linux-gnu/events.c b/sysdeps/linux-gnu/events.c
index 077a656..6cda97e 100644
--- a/sysdeps/linux-gnu/events.c
+++ b/sysdeps/linux-gnu/events.c
@@ -48,7 +48,7 @@ static Event * delayed_events = NULL;
 static Event * end_delayed_events = NULL;
 
 static enum callback_status
-first (Process * proc, void * data)
+first(struct process *proc, void *data)
 {
 	return CBS_STOP;
 }
@@ -83,12 +83,12 @@ each_qd_event(enum ecb_status (*pred)(Event *, void *), void * data)
 	Event * event;
 	for (event = prev; event != NULL; ) {
 		switch ((*pred)(event, data)) {
-		case ecb_cont:
+		case ECB_CONT:
 			prev = event;
 			event = event->next;
 			continue;
 
-		case ecb_deque:
+		case ECB_DEQUE:
 			debug(DEBUG_FUNCTION, "dequeuing event %d for %d",
 			      event->type,
 			      event->proc != NULL ? event->proc->pid : -1);
@@ -106,7 +106,7 @@ each_qd_event(enum ecb_status (*pred)(Event *, void *), void * data)
 				end_delayed_events = NULL;
 			/* fall-through */
 
-		case ecb_yield:
+		case ECB_YIELD:
 			return event;
 		}
 	}
@@ -120,9 +120,9 @@ event_process_not_reenabling(Event * event, void * data)
 	if (event->proc == NULL
 	    || event->proc->leader == NULL
 	    || event->proc->leader->event_handler == NULL)
-		return ecb_deque;
+		return ECB_DEQUE;
 	else
-		return ecb_cont;
+		return ECB_CONT;
 }
 
 static Event *
@@ -188,7 +188,7 @@ next_event(void)
 		 * now) the pain of figuring this out all over again.
 		 * Petr Machata 2011-11-22.  */
 		int i = 0;
-		for (; i < 100 && process_status(pid) != ps_tracing_stop; ++i) {
+		for (; i < 100 && process_status(pid) != PS_TRACING_STOP; ++i) {
 			debug(2, "waiting for %d to stop", pid);
 			usleep(10000);
 		}
@@ -199,7 +199,7 @@ next_event(void)
 	}
 	get_arch_dep(event.proc);
 	debug(3, "event from pid %u", pid);
-	Process *leader = event.proc->leader;
+	struct process *leader = event.proc->leader;
 
 	/* The process should be stopped after the waitpid call.  But
 	 * when the whole thread group is terminated, we see
@@ -341,13 +341,13 @@ static enum ecb_status
 event_for_proc(struct Event *event, void *data)
 {
 	if (event->proc == data)
-		return ecb_deque;
+		return ECB_DEQUE;
 	else
-		return ecb_cont;
+		return ECB_CONT;
 }
 
 void
-delete_events_for(struct Process *proc)
+delete_events_for(struct process *proc)
 {
 	struct Event *event;
 	while ((event = each_qd_event(&event_for_proc, proc)) != NULL)
diff --git a/sysdeps/linux-gnu/events.h b/sysdeps/linux-gnu/events.h
index 3802aff..51ef309 100644
--- a/sysdeps/linux-gnu/events.h
+++ b/sysdeps/linux-gnu/events.h
@@ -26,16 +26,16 @@
 /* Declarations for event que functions.  */
 
 enum ecb_status {
-	ecb_cont, /* The iteration should continue.  */
-	ecb_yield, /* The iteration should stop, yielding this
+	ECB_CONT, /* The iteration should continue.  */
+	ECB_YIELD, /* The iteration should stop, yielding this
 		    * event.  */
-	ecb_deque, /* Like ecb_stop, but the event should be removed
+	ECB_DEQUE, /* Like ECB_STOP, but the event should be removed
 		    * from the queue.  */
 };
 
 struct Event *each_qd_event(enum ecb_status (*cb)(struct Event *event,
 						  void *data), void *data);
-void delete_events_for(struct Process * proc);
+void delete_events_for(struct process *proc);
 void enque_event(struct Event *event);
 
 #endif /* SYSDEPS_LINUX_GNU_EVENTS_H */
diff --git a/sysdeps/linux-gnu/ia64/fetch.c b/sysdeps/linux-gnu/ia64/fetch.c
index 54dc5b8..e90dbed 100644
--- a/sysdeps/linux-gnu/ia64/fetch.c
+++ b/sysdeps/linux-gnu/ia64/fetch.c
@@ -63,7 +63,7 @@ union cfm_t {
 };
 
 static int
-fetch_context_init(struct Process *proc, struct fetch_context *context)
+fetch_context_init(struct process *proc, struct fetch_context *context)
 {
 	context->slot_n = 0;
 	context->flt = 8;
@@ -76,7 +76,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context)
 }
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	struct fetch_context *context = malloc(sizeof(*context));
@@ -91,7 +91,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc,
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc,
+arch_fetch_arg_clone(struct process *proc,
 		     struct fetch_context *context)
 {
 	struct fetch_context *clone = malloc(sizeof(*context));
@@ -102,7 +102,7 @@ arch_fetch_arg_clone(struct Process *proc,
 }
 
 int
-allocate_stack_slot(struct fetch_context *ctx, struct Process *proc,
+allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	size_t al = type_alignof(proc, info);
@@ -121,7 +121,7 @@ allocate_stack_slot(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_reg(struct fetch_context *ctx, struct Process *proc,
+allocate_reg(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep)
 {
 	if (ctx->slot_n >= 8)
@@ -152,7 +152,7 @@ allocate_reg(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-copy_aggregate_part(struct fetch_context *ctx, struct Process *proc,
+copy_aggregate_part(struct fetch_context *ctx, struct process *proc,
 		    unsigned char *buf, size_t size)
 {
 	size_t slots = (size + 7) / 8;
@@ -176,7 +176,7 @@ copy_aggregate_part(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_arg(struct fetch_context *ctx, struct Process *proc,
+allocate_arg(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -213,7 +213,7 @@ fpreg_to_double (struct ia64_fpreg *fp) {
 }
 
 static int
-allocate_float(struct fetch_context *ctx, struct Process *proc,
+allocate_float(struct fetch_context *ctx, struct process *proc,
 	       struct arg_type_info *info, struct value *valuep,
 	       int take_slot)
 {
@@ -281,7 +281,7 @@ get_hfa_type(struct arg_type_info *info, size_t *countp)
 }
 
 static int
-allocate_hfa(struct fetch_context *ctx, struct Process *proc,
+allocate_hfa(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep,
 	     enum arg_type hfa_type, size_t hfa_count)
 {
@@ -366,7 +366,7 @@ allocate_hfa(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_ret(struct fetch_context *ctx, struct Process *proc,
+allocate_ret(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -405,7 +405,7 @@ allocate_ret(struct fetch_context *ctx, struct Process *proc,
 
 int
 arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
-		    struct Process *proc,
+		    struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	switch (info->type) {
@@ -446,7 +446,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *ctx, enum tof type,
-		  struct Process *proc, struct arg_type_info *info,
+		  struct process *proc, struct arg_type_info *info,
 		  struct value *valuep)
 {
 	if (fetch_context_init(proc, ctx) < 0)
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
index a29488f..f6bc939 100644
--- a/sysdeps/linux-gnu/ia64/plt.c
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -68,12 +68,13 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
 
 int
-arch_translate_address_dyn(struct Process *proc,
+arch_translate_address_dyn(struct process *proc,
 			   arch_addr_t addr, arch_addr_t *ret)
 {
 	errno = 0;
diff --git a/sysdeps/linux-gnu/ia64/regs.c b/sysdeps/linux-gnu/ia64/regs.c
index cbc2744..fb79e8a 100644
--- a/sysdeps/linux-gnu/ia64/regs.c
+++ b/sysdeps/linux-gnu/ia64/regs.c
@@ -34,7 +34,8 @@
 #include "common.h"
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	unsigned long ip = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IIP, 0);
 	unsigned long slot =
 	    (ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0) >> 41) & 3;
@@ -43,7 +44,8 @@ get_instruction_pointer(Process *proc) {
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 
 	unsigned long newip = (unsigned long)addr;
 	unsigned long slot = (unsigned long)addr & 0xf;
@@ -59,7 +61,8 @@ set_instruction_pointer(Process *proc, void *addr) {
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_R12, 0);
 	if (l == -1 && errno)
 		return NULL;
@@ -67,7 +70,8 @@ get_stack_pointer(Process *proc) {
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_B0, 0);
 	if (l == -1 && errno)
 		return NULL;
@@ -75,6 +79,7 @@ get_return_addr(Process *proc, void *stack_pointer) {
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, PT_B0, addr);
 }
diff --git a/sysdeps/linux-gnu/ia64/trace.c b/sysdeps/linux-gnu/ia64/trace.c
index e608275..9e554ef 100644
--- a/sysdeps/linux-gnu/ia64/trace.c
+++ b/sysdeps/linux-gnu/ia64/trace.c
@@ -70,7 +70,8 @@ union cfm_t {
 };
 
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		long l = ptrace(PTRACE_PEEKUSER, proc->pid, PT_CR_IPSR, 0);
@@ -141,5 +142,6 @@ syscall_p(Process *proc, int status, int *sysnum) {
 }
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 }
diff --git a/sysdeps/linux-gnu/m68k/fetch.c b/sysdeps/linux-gnu/m68k/fetch.c
index f6d8a0b..24bd8f0 100644
--- a/sysdeps/linux-gnu/m68k/fetch.c
+++ b/sysdeps/linux-gnu/m68k/fetch.c
@@ -43,7 +43,7 @@ struct fetch_context
 };
 
 static int
-fetch_register_banks(struct Process *proc, struct fetch_context *context,
+fetch_register_banks(struct process *proc, struct fetch_context *context,
 		     int floating)
 {
 	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->regs) < 0)
@@ -57,7 +57,7 @@ fetch_register_banks(struct Process *proc, struct fetch_context *context,
 }
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	struct fetch_context *context = malloc(sizeof(*context));
@@ -92,7 +92,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc,
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
+arch_fetch_arg_clone(struct process *proc, struct fetch_context *context)
 {
 	struct fetch_context *ret = malloc(sizeof(*ret));
 	if (ret == NULL)
@@ -103,7 +103,7 @@ arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
 
 int
 arch_fetch_arg_next(struct fetch_context *context, enum tof type,
-		    struct Process *proc, struct arg_type_info *info,
+		    struct process *proc, struct arg_type_info *info,
 		    struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -143,7 +143,7 @@ arch_fetch_arg_next(struct fetch_context *context, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *context, enum tof type,
-		  struct Process *proc, struct arg_type_info *info,
+		  struct process *proc, struct arg_type_info *info,
 		  struct value *valuep)
 {
 	if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0)
diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c
index c1b37dd..dcd6878 100644
--- a/sysdeps/linux-gnu/m68k/plt.c
+++ b/sysdeps/linux-gnu/m68k/plt.c
@@ -30,6 +30,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/m68k/regs.c b/sysdeps/linux-gnu/m68k/regs.c
index 4afdfbb..c2fafe1 100644
--- a/sysdeps/linux-gnu/m68k/regs.c
+++ b/sysdeps/linux-gnu/m68k/regs.c
@@ -36,26 +36,31 @@
 #endif
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PC, 0);
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PC, addr);
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr);
 }
diff --git a/sysdeps/linux-gnu/m68k/trace.c b/sysdeps/linux-gnu/m68k/trace.c
index 311ffd5..01b5253 100644
--- a/sysdeps/linux-gnu/m68k/trace.c
+++ b/sysdeps/linux-gnu/m68k/trace.c
@@ -40,13 +40,15 @@
 #endif
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 }
 
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	int depth;
 
 	if (WIFSTOPPED(status)
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 @@ struct arch_ltelf_data {
 #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/plt.c b/sysdeps/linux-gnu/mipsel/plt.c
index b277fbc..ce33406 100644
--- a/sysdeps/linux-gnu/mipsel/plt.c
+++ b/sysdeps/linux-gnu/mipsel/plt.c
@@ -104,7 +104,8 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela)
    breakpoint changes I just add a new breakpoint for the new address.
  */
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
     long ret;
 
     if (sym->arch.pltalways
@@ -125,7 +126,7 @@ sym2addr(Process *proc, struct library_symbol *sym) {
 /* Address of run time loader map, used for debugging.  */
 #define DT_MIPS_RLD_MAP         0x70000016
 int
-arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
+arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
 		   arch_addr_t *ret)
 {
 	arch_addr_t rld_addr;
@@ -251,11 +252,11 @@ arch_elf_destroy(struct ltelf *lte)
 
 /* When functions return we check if the symbol needs an updated
    breakpoint with the resolved address.  */
-void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym)
+void arch_symbol_ret(struct process *proc, struct library_symbol *libsym)
 {
 	struct breakpoint *bp;
 	arch_addr_t resolved_addr;
-	struct Process *leader = proc->leader;
+	struct process *leader = proc->leader;
 
 	/* Only deal with unresolved symbols.  */
 	if (libsym->arch.type != MIPS_PLT_UNRESOLVED)
@@ -302,7 +303,7 @@ err:
 static enum callback_status
 cb_enable_breakpoint_sym(struct library_symbol *libsym, void *data)
 {
-	struct Process *proc = data;
+	struct process *proc = data;
 	arch_addr_t bp_addr;
 
 	if (!libsym->arch.gotonly)
@@ -329,19 +330,19 @@ cb_enable_breakpoint_sym(struct library_symbol *libsym, void *data)
 }
 
 static enum callback_status
-cb_enable_breakpoint_lib(struct Process *proc, struct library *lib, void *data)
+cb_enable_breakpoint_lib(struct process *proc, struct library *lib, void *data)
 {
 	library_each_symbol(lib, NULL, cb_enable_breakpoint_sym, proc);
 	return CBS_CONT;
 }
 
-void arch_dynlink_done(struct Process *proc)
+void arch_dynlink_done(struct process *proc)
 {
 	proc_each_library(proc->leader, NULL, cb_enable_breakpoint_lib, NULL);
 }
 
 enum plt_status
-arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
                        const char *a_name, GElf_Rela *rela, size_t ndx,
                        struct library_symbol **ret)
 {
@@ -350,7 +351,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 
 	struct library_symbol *libsym = malloc(sizeof(*libsym));
 	if (libsym == NULL)
-		return plt_fail;
+		return PLT_FAIL;
 
 	GElf_Addr addr = arch_plt_sym_val(lte, sym_index, 0);
 
@@ -389,12 +390,12 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 	}
 
 	*ret = libsym;
-	return plt_ok;
+	return PLT_OK;
 
 fail:
 	free(name);
 	free(libsym);
-	return plt_fail;
+	return PLT_FAIL;
 }
 
 int
diff --git a/sysdeps/linux-gnu/mipsel/regs.c b/sysdeps/linux-gnu/mipsel/regs.c
index 8731ac5..19f97cb 100644
--- a/sysdeps/linux-gnu/mipsel/regs.c
+++ b/sysdeps/linux-gnu/mipsel/regs.c
@@ -49,7 +49,8 @@
    \return The current instruction pointer.
  */
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
 }
 
@@ -63,7 +64,8 @@ get_instruction_pointer(Process *proc) {
    we \c continue_process() after a breakpoint. Check if this is OK.
  */
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, off_pc, addr);
 }
 
@@ -72,7 +74,8 @@ set_instruction_pointer(Process *proc, void *addr) {
    \return The current stack pointer.
  */
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_sp, 0);
 }
 
@@ -87,11 +90,13 @@ get_stack_pointer(Process *proc) {
    unused.
  */
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, off_lr, 0);
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr);
 }
diff --git a/sysdeps/linux-gnu/mipsel/trace.c b/sysdeps/linux-gnu/mipsel/trace.c
index db9ec21..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
@@ -64,7 +65,8 @@
    private data area.
  */
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 }
 
 /**
@@ -85,7 +87,8 @@ get_arch_dep(Process *proc) {
    for the system calls is 4000.
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 			&& WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		/* get the user's pc (plus 8) */
@@ -141,7 +144,7 @@ mips32_relative_offset (uint32_t inst)
   return ((itype_immediate(inst) ^ 0x8000) - 0x8000) << 2;
 }
 
-int mips_next_pcs(struct Process *proc, uint32_t pc, uint32_t *newpc)
+int mips_next_pcs(struct process *proc, uint32_t pc, uint32_t *newpc)
 {
 	uint32_t inst, rx;
 	int op;
@@ -261,10 +264,10 @@ fail:
 	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];
@@ -281,11 +284,11 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 		}
 
 		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;
 }
 
 /**
@@ -317,7 +320,8 @@ I'm not doing any floating point support here.
 
 */
 long
-gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info)
+gimme_arg(enum tof type, struct process *proc, int arg_num,
+	  struct arg_type_info *info)
 {
 	long ret;
 	long addr;
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/fetch.c b/sysdeps/linux-gnu/ppc/fetch.c
index 9963a1e..ed38336 100644
--- a/sysdeps/linux-gnu/ppc/fetch.c
+++ b/sysdeps/linux-gnu/ppc/fetch.c
@@ -31,7 +31,7 @@
 #include "proc.h"
 #include "value.h"
 
-static int allocate_gpr(struct fetch_context *ctx, struct Process *proc,
+static int allocate_gpr(struct fetch_context *ctx, struct process *proc,
 			struct arg_type_info *info, struct value *valuep);
 
 /* Floating point registers have the same width on 32-bit as well as
@@ -66,7 +66,7 @@ struct fetch_context {
 };
 
 static int
-fetch_context_init(struct Process *proc, struct fetch_context *context)
+fetch_context_init(struct process *proc, struct fetch_context *context)
 {
 	context->greg = 3;
 	context->freg = 1;
@@ -108,7 +108,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context)
 }
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	struct fetch_context *context = malloc(sizeof(*context));
@@ -132,7 +132,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc,
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc,
+arch_fetch_arg_clone(struct process *proc,
 		     struct fetch_context *context)
 {
 	struct fetch_context *clone = malloc(sizeof(*context));
@@ -143,7 +143,7 @@ arch_fetch_arg_clone(struct Process *proc,
 }
 
 static int
-allocate_stack_slot(struct fetch_context *ctx, struct Process *proc,
+allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -170,7 +170,7 @@ allocate_stack_slot(struct fetch_context *ctx, struct Process *proc,
 }
 
 static uint64_t
-read_gpr(struct fetch_context *ctx, struct Process *proc, int reg_num)
+read_gpr(struct fetch_context *ctx, struct process *proc, int reg_num)
 {
 	if (proc->e_machine == EM_PPC)
 		return ctx->regs.r32[reg_num];
@@ -215,7 +215,7 @@ align_small_int(unsigned char *buf, size_t w, size_t sz)
 }
 
 static int
-allocate_gpr(struct fetch_context *ctx, struct Process *proc,
+allocate_gpr(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep)
 {
 	if (ctx->greg > 10)
@@ -245,7 +245,7 @@ allocate_gpr(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_float(struct fetch_context *ctx, struct Process *proc,
+allocate_float(struct fetch_context *ctx, struct process *proc,
 	       struct arg_type_info *info, struct value *valuep)
 {
 	int pool = proc->e_machine == EM_PPC64 ? 13 : 8;
@@ -276,7 +276,7 @@ allocate_float(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_argument(struct fetch_context *ctx, struct Process *proc,
+allocate_argument(struct fetch_context *ctx, struct process *proc,
 		  struct arg_type_info *info, struct value *valuep)
 {
 	/* Floating point types and void are handled specially.  */
@@ -400,7 +400,7 @@ allocate_argument(struct fetch_context *ctx, struct Process *proc,
 
 int
 arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
-		    struct Process *proc,
+		    struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	return allocate_argument(ctx, proc, info, valuep);
@@ -408,7 +408,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *ctx, enum tof type,
-		  struct Process *proc, struct arg_type_info *info,
+		  struct process *proc, struct arg_type_info *info,
 		  struct value *valuep)
 {
 	if (ctx->ret_struct) {
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index f83f087..439b8e8 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/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)
 {
@@ -178,14 +133,14 @@ mark_as_resolved(struct library_symbol *libsym, GElf_Addr value)
 }
 
 void
-arch_dynlink_done(struct Process *proc)
+arch_dynlink_done(struct process *proc)
 {
 	/* On PPC32 with BSS PLT, we need to enable delayed symbols.  */
 	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,
@@ -258,12 +213,12 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela)
  * ourselves with bias, as the values in OPD have been resolved
  * already.  */
 int
-arch_translate_address_dyn(struct Process *proc,
+arch_translate_address_dyn(struct process *proc,
 			   arch_addr_t addr, arch_addr_t *ret)
 {
 	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));
@@ -324,7 +279,7 @@ load_opd_data(struct ltelf *lte, struct library *lib)
 }
 
 void *
-sym2addr(struct Process *proc, struct library_symbol *sym)
+sym2addr(struct process *proc, struct library_symbol *sym)
 {
 	return sym->enter_addr;
 }
@@ -560,7 +515,7 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
 }
 
 static int
-read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp)
+read_plt_slot_value(struct process *proc, GElf_Addr addr, GElf_Addr *valp)
 {
 	/* On PPC64, we read from .plt, which contains 8 byte
 	 * addresses.  On PPC32 we read from .plt, which contains 4
@@ -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;
@@ -579,7 +534,7 @@ read_plt_slot_value(struct Process *proc, GElf_Addr addr, GElf_Addr *valp)
 }
 
 static int
-unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value)
+unresolve_plt_slot(struct process *proc, GElf_Addr addr, GElf_Addr value)
 {
 	/* We only modify plt_entry[0], which holds the resolved
 	 * address of the routine.  We keep the TOC and environment
@@ -594,18 +549,18 @@ unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value)
 }
 
 enum plt_status
-arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
+arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
 		       const char *a_name, GElf_Rela *rela, size_t ndx,
 		       struct library_symbol **ret)
 {
 	if (lte->ehdr.e_machine == EM_PPC) {
 		if (lte->arch.secure_plt)
-			return plt_default;
+			return PLT_DEFAULT;
 
 		struct library_symbol *libsym = NULL;
 		if (default_elf_add_plt_entry(proc, lte, a_name, rela, ndx,
 					      &libsym) < 0)
-			return plt_fail;
+			return PLT_FAIL;
 
 		/* On PPC32 with BSS PLT, delay the symbol until
 		 * dynamic linker is done.  */
@@ -613,7 +568,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 		libsym->delayed = 1;
 
 		*ret = libsym;
-		return plt_ok;
+		return PLT_OK;
 	}
 
 	/* PPC64.  If we have stubs, we return a chain of breakpoint
@@ -636,7 +591,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 
 	if (chain != NULL) {
 		*ret = chain;
-		return plt_ok;
+		return PLT_OK;
 	}
 
 	/* We don't have stub symbols.  Find corresponding .plt slot,
@@ -653,7 +608,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 
 	GElf_Addr plt_slot_value;
 	if (read_plt_slot_value(proc, plt_slot_addr, &plt_slot_value) < 0)
-		return plt_fail;
+		return PLT_FAIL;
 
 	char *name = strdup(a_name);
 	struct library_symbol *libsym = malloc(sizeof(*libsym));
@@ -663,7 +618,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 	fail:
 		free(name);
 		free(libsym);
-		return plt_fail;
+		return PLT_FAIL;
 	}
 
 	/* XXX The double cast should be removed when
@@ -696,7 +651,7 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
 	}
 
 	*ret = libsym;
-	return plt_ok;
+	return PLT_OK;
 }
 
 void
@@ -712,7 +667,7 @@ arch_elf_destroy(struct ltelf *lte)
 }
 
 static void
-dl_plt_update_bp_on_hit(struct breakpoint *bp, struct Process *proc)
+dl_plt_update_bp_on_hit(struct breakpoint *bp, struct process *proc)
 {
 	debug(DEBUG_PROCESS, "pid=%d dl_plt_update_bp_on_hit %s(%p)",
 	      proc->pid, breakpoint_name(bp), bp->addr);
@@ -752,7 +707,7 @@ cb_on_all_stopped(struct process_stopping_handler *self)
 static enum callback_status
 cb_keep_stepping_p(struct process_stopping_handler *self)
 {
-	struct Process *proc = self->task_enabling_breakpoint;
+	struct process *proc = self->task_enabling_breakpoint;
 	struct library_symbol *libsym = self->breakpoint_being_enabled->libsym;
 
 	GElf_Addr value;
@@ -799,7 +754,7 @@ cb_keep_stepping_p(struct process_stopping_handler *self)
 	/* Install breakpoint to the address where the change takes
 	 * place.  If we fail, then that just means that we'll have to
 	 * singlestep the next time around as well.  */
-	struct Process *leader = proc->leader;
+	struct process *leader = proc->leader;
 	if (leader == NULL || leader->arch.dl_plt_update_bp != NULL)
 		goto done;
 
@@ -827,7 +782,7 @@ done:
 }
 
 static void
-jump_to_entry_point(struct Process *proc, struct breakpoint *bp)
+jump_to_entry_point(struct process *proc, struct breakpoint *bp)
 {
 	/* XXX The double cast should be removed when
 	 * arch_addr_t becomes integral type.  */
@@ -837,10 +792,10 @@ jump_to_entry_point(struct Process *proc, struct breakpoint *bp)
 }
 
 static void
-ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc)
+ppc_plt_bp_continue(struct breakpoint *bp, struct process *proc)
 {
 	switch (bp->libsym->arch.type) {
-		struct Process *leader;
+		struct process *leader;
 		void (*on_all_stopped)(struct process_stopping_handler *);
 		enum callback_status (*keep_stepping_p)
 			(struct process_stopping_handler *);
@@ -899,7 +854,7 @@ ppc_plt_bp_continue(struct breakpoint *bp, struct Process *proc)
  * detect both cases and do any fix-ups necessary to mend this
  * situation.  */
 static enum callback_status
-detach_task_cb(struct Process *task, void *data)
+detach_task_cb(struct process *task, void *data)
 {
 	struct breakpoint *bp = data;
 
@@ -919,7 +874,7 @@ detach_task_cb(struct Process *task, void *data)
 }
 
 static void
-ppc_plt_bp_retract(struct breakpoint *bp, struct Process *proc)
+ppc_plt_bp_retract(struct breakpoint *bp, struct process *proc)
 {
 	/* On PPC64, we rewrite .plt with PLT entry addresses.  This
 	 * needs to be undone.  Unfortunately, the program may have
@@ -975,7 +930,7 @@ arch_library_symbol_clone(struct library_symbol *retp,
  * don't need PROC here, we can store the data in BP if it is of
  * interest to us.  */
 int
-arch_breakpoint_init(struct Process *proc, struct breakpoint *bp)
+arch_breakpoint_init(struct process *proc, struct breakpoint *bp)
 {
 	/* Artificial and entry-point breakpoints are plain.  */
 	if (bp->libsym == NULL || bp->libsym->plt_type != LS_TOPLT_EXEC)
@@ -1012,7 +967,7 @@ arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
 }
 
 int
-arch_process_init(struct Process *proc)
+arch_process_init(struct process *proc)
 {
 	proc->arch.dl_plt_update_bp = NULL;
 	proc->arch.handler = NULL;
@@ -1020,19 +975,19 @@ arch_process_init(struct Process *proc)
 }
 
 void
-arch_process_destroy(struct Process *proc)
+arch_process_destroy(struct process *proc)
 {
 }
 
 int
-arch_process_clone(struct Process *retp, struct Process *proc)
+arch_process_clone(struct process *retp, struct process *proc)
 {
 	retp->arch = proc->arch;
 	return 0;
 }
 
 int
-arch_process_exec(struct Process *proc)
+arch_process_exec(struct process *proc)
 {
 	return arch_process_init(proc);
 }
diff --git a/sysdeps/linux-gnu/ppc/regs.c b/sysdeps/linux-gnu/ppc/regs.c
index 37f89a4..ed9b398 100644
--- a/sysdeps/linux-gnu/ppc/regs.c
+++ b/sysdeps/linux-gnu/ppc/regs.c
@@ -40,35 +40,32 @@
 #endif
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_NIP, 0);
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr)
+set_instruction_pointer(struct process *proc, void *addr)
 {
 	if (ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_NIP, addr) != 0)
 		error(0, errno, "set_instruction_pointer");
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_R1, 0);
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, sizeof(long)*PT_LNK, 0);
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	ptrace(PTRACE_POKEUSER, proc->pid, sizeof(long)*PT_LNK, addr);
 }
-
-/* Grab the value of CTR registers.  */
-void *
-get_count_register (Process *proc) {
-	return (void *) ptrace (PTRACE_PEEKUSER, proc->pid,
-				sizeof (long) * PT_CTR, 0);
-}
diff --git a/sysdeps/linux-gnu/ppc/trace.c b/sysdeps/linux-gnu/ppc/trace.c
index 4357a1e..ee9a6b5 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
@@ -49,7 +49,8 @@
 #endif
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 #ifdef __powerpc64__
 	proc->mask_32bit = (proc->e_machine == EM_PPC);
 #endif
@@ -59,7 +60,8 @@ get_arch_dep(Process *proc) {
 
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		long pc = (long)get_instruction_pointer(proc);
@@ -84,18 +86,15 @@ syscall_p(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),
-		       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
@@ -107,15 +106,15 @@ 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;
+		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);
 
@@ -125,7 +124,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 		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;
@@ -140,7 +139,7 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 			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
@@ -157,22 +156,22 @@ arch_atomic_singlestep(struct Process *proc, struct breakpoint *sbp,
 		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
-arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
+arch_type_sizeof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
@@ -215,7 +214,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
 }
 
 size_t
-arch_type_alignof(struct Process *proc, struct arg_type_info *info)
+arch_type_alignof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c
index 5adfb16..d69c985 100644
--- a/sysdeps/linux-gnu/proc.c
+++ b/sysdeps/linux-gnu/proc.c
@@ -177,44 +177,45 @@ process_status_cb(const char *line, const char *prefix, void *data)
 	} while (0)
 
 	switch (c) {
-	case 'Z': RETURN(ps_zombie);
-	case 't': RETURN(ps_tracing_stop);
+	case 'Z': RETURN(PS_ZOMBIE);
+	case 't': RETURN(PS_TRACING_STOP);
 	case 'T':
 		/* This can be either "T (stopped)" or, for older
 		 * kernels, "T (tracing stop)".  */
 		if (!strcmp(status, "T (stopped)\n"))
-			RETURN(ps_stop);
+			RETURN(PS_STOP);
 		else if (!strcmp(status, "T (tracing stop)\n"))
-			RETURN(ps_tracing_stop);
+			RETURN(PS_TRACING_STOP);
 		else {
 			fprintf(stderr, "Unknown process status: %s",
 				status);
-			RETURN(ps_stop); /* Some sort of stop
+			RETURN(PS_STOP); /* Some sort of stop
 					  * anyway.  */
 		}
 	case 'D':
-	case 'S': RETURN(ps_sleeping);
+	case 'S': RETURN(PS_SLEEPING);
 	}
 
-	RETURN(ps_other);
+	RETURN(PS_OTHER);
 #undef RETURN
 }
 
 enum process_status
 process_status(pid_t pid)
 {
-	enum process_status ret = ps_invalid;
+	enum process_status ret = PS_INVALID;
 	FILE * file = open_status_file(pid);
 	if (file != NULL) {
 		each_line_starting(file, "State:\t", &process_status_cb, &ret);
 		fclose(file);
-		if (ret == ps_invalid)
+		if (ret == PS_INVALID)
 			fprintf(stderr, "process_status %d: %s", pid,
 				strerror(errno));
-	} else
+	} else {
 		/* If the file is not present, the process presumably
 		 * exited already.  */
-		ret = ps_zombie;
+		ret = PS_ZOMBIE;
+	}
 
 	return ret;
 }
@@ -279,7 +280,7 @@ process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
  * ABI object, as theorized about somewhere on pmachata/revamp
  * branch.  */
 static void *
-select_32_64(struct Process *proc, void *p32, void *p64)
+select_32_64(struct process *proc, void *p32, void *p64)
 {
 	if (sizeof(long) == 4 || proc->mask_32bit)
 		return p32;
@@ -288,7 +289,7 @@ select_32_64(struct Process *proc, void *p32, void *p64)
 }
 
 static int
-fetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
+fetch_dyn64(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
 {
 	if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret))
 		return -1;
@@ -297,7 +298,7 @@ fetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
 }
 
 static int
-fetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
+fetch_dyn32(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
 {
 	Elf32_Dyn dyn;
 	if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn))
@@ -311,14 +312,14 @@ fetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
 }
 
 static int (*
-dyn_fetcher(struct Process *proc))(struct Process *,
+dyn_fetcher(struct process *proc))(struct process *,
 				   arch_addr_t *, Elf64_Dyn *)
 {
 	return select_32_64(proc, fetch_dyn32, fetch_dyn64);
 }
 
 int
-proc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr,
+proc_find_dynamic_entry_addr(struct process *proc, arch_addr_t src_addr,
 			     int d_tag, arch_addr_t *ret)
 {
 	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
@@ -364,7 +365,7 @@ struct lt_link_map_32 LT_LINK_MAP(32);
 struct lt_link_map_64 LT_LINK_MAP(64);
 
 static int
-fetch_lm64(struct Process *proc, arch_addr_t addr,
+fetch_lm64(struct process *proc, arch_addr_t addr,
 	   struct lt_link_map_64 *ret)
 {
 	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
@@ -373,7 +374,7 @@ fetch_lm64(struct Process *proc, arch_addr_t addr,
 }
 
 static int
-fetch_lm32(struct Process *proc, arch_addr_t addr,
+fetch_lm32(struct process *proc, arch_addr_t addr,
 	   struct lt_link_map_64 *ret)
 {
 	struct lt_link_map_32 lm;
@@ -390,7 +391,7 @@ fetch_lm32(struct Process *proc, arch_addr_t addr,
 }
 
 static int (*
-lm_fetcher(struct Process *proc))(struct Process *,
+lm_fetcher(struct process *proc))(struct process *,
 				  arch_addr_t, struct lt_link_map_64 *)
 {
 	return select_32_64(proc, fetch_lm32, fetch_lm64);
@@ -410,7 +411,7 @@ struct lt_r_debug_32 LT_R_DEBUG(32);
 struct lt_r_debug_64 LT_R_DEBUG(64);
 
 static int
-fetch_rd64(struct Process *proc, arch_addr_t addr,
+fetch_rd64(struct process *proc, arch_addr_t addr,
 	   struct lt_r_debug_64 *ret)
 {
 	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
@@ -419,7 +420,7 @@ fetch_rd64(struct Process *proc, arch_addr_t addr,
 }
 
 static int
-fetch_rd32(struct Process *proc, arch_addr_t addr,
+fetch_rd32(struct process *proc, arch_addr_t addr,
 	   struct lt_r_debug_64 *ret)
 {
 	struct lt_r_debug_32 rd;
@@ -436,7 +437,7 @@ fetch_rd32(struct Process *proc, arch_addr_t addr,
 }
 
 static int (*
-rdebug_fetcher(struct Process *proc))(struct Process *,
+rdebug_fetcher(struct process *proc))(struct process *,
 				      arch_addr_t, struct lt_r_debug_64 *)
 {
 	return select_32_64(proc, fetch_rd32, fetch_rd64);
@@ -463,13 +464,13 @@ fetch_auxv32_entry(int fd, Elf64_auxv_t *ret)
 }
 
 static int (*
-auxv_fetcher(struct Process *proc))(int, Elf64_auxv_t *)
+auxv_fetcher(struct process *proc))(int, Elf64_auxv_t *)
 {
 	return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry);
 }
 
 static void
-crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
+crawl_linkmap(struct process *proc, struct lt_r_debug_64 *dbg)
 {
 	debug (DEBUG_FUNCTION, "crawl_linkmap()");
 
@@ -551,7 +552,7 @@ crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
 }
 
 static int
-load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
+load_debug_struct(struct process *proc, struct lt_r_debug_64 *ret)
 {
 	debug(DEBUG_FUNCTION, "load_debug_struct");
 
@@ -564,7 +565,7 @@ load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
 }
 
 static void
-rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
+rdebug_bp_on_hit(struct breakpoint *bp, struct process *proc)
 {
 	debug(DEBUG_FUNCTION, "arch_check_dbg");
 
@@ -595,7 +596,7 @@ rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
 
 #ifndef ARCH_HAVE_FIND_DL_DEBUG
 int
-arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
+arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
 		   arch_addr_t *ret)
 {
 	return proc_find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, ret);
@@ -603,7 +604,7 @@ arch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
 #endif
 
 int
-linkmap_init(struct Process *proc, arch_addr_t dyn_addr)
+linkmap_init(struct process *proc, arch_addr_t dyn_addr)
 {
 	debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr);
 
@@ -648,13 +649,13 @@ task_kill (pid_t pid, int sig)
 }
 
 void
-process_removed(struct Process *proc)
+process_removed(struct process *proc)
 {
 	delete_events_for(proc);
 }
 
 int
-process_get_entry(struct Process *proc,
+process_get_entry(struct process *proc,
 		  arch_addr_t *entryp,
 		  arch_addr_t *interp_biasp)
 {
@@ -706,7 +707,7 @@ process_get_entry(struct Process *proc,
 }
 
 int
-os_process_init(struct Process *proc)
+os_process_init(struct process *proc)
 {
 	proc->os.debug_addr = 0;
 	proc->os.debug_state = 0;
@@ -714,19 +715,19 @@ os_process_init(struct Process *proc)
 }
 
 void
-os_process_destroy(struct Process *proc)
+os_process_destroy(struct process *proc)
 {
 }
 
 int
-os_process_clone(struct Process *retp, struct Process *proc)
+os_process_clone(struct process *retp, struct process *proc)
 {
 	retp->os = proc->os;
 	return 0;
 }
 
 int
-os_process_exec(struct Process *proc)
+os_process_exec(struct process *proc)
 {
 	return 0;
 }
diff --git a/sysdeps/linux-gnu/s390/fetch.c b/sysdeps/linux-gnu/s390/fetch.c
index fa8f42d..0b68dbc 100644
--- a/sysdeps/linux-gnu/s390/fetch.c
+++ b/sysdeps/linux-gnu/s390/fetch.c
@@ -61,7 +61,7 @@ s390x(struct fetch_context *ctx)
 }
 
 static int
-fetch_register_banks(struct Process *proc, struct fetch_context *ctx)
+fetch_register_banks(struct process *proc, struct fetch_context *ctx)
 {
 	ptrace_area parea;
 	parea.len = sizeof(ctx->regs);
@@ -76,7 +76,7 @@ fetch_register_banks(struct Process *proc, struct fetch_context *ctx)
 }
 
 static int
-fetch_context_init(struct Process *proc, struct fetch_context *context)
+fetch_context_init(struct process *proc, struct fetch_context *context)
 {
 	context->greg = 2;
 	context->freg = 0;
@@ -84,7 +84,7 @@ fetch_context_init(struct Process *proc, struct fetch_context *context)
 }
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	struct fetch_context *context = malloc(sizeof(*context));
@@ -105,7 +105,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc,
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc,
+arch_fetch_arg_clone(struct process *proc,
 		     struct fetch_context *context)
 {
 	struct fetch_context *clone = malloc(sizeof(*context));
@@ -116,7 +116,7 @@ arch_fetch_arg_clone(struct Process *proc,
 }
 
 static int
-allocate_stack_slot(struct fetch_context *ctx, struct Process *proc,
+allocate_stack_slot(struct fetch_context *ctx, struct process *proc,
 		    struct arg_type_info *info, struct value *valuep,
 		    size_t sz)
 {
@@ -148,7 +148,7 @@ copy_gpr(struct fetch_context *ctx, struct value *valuep, int regno)
 }
 
 static int
-allocate_gpr(struct fetch_context *ctx, struct Process *proc,
+allocate_gpr(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep,
 	     size_t sz)
 {
@@ -160,7 +160,7 @@ allocate_gpr(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc,
+allocate_gpr_pair(struct fetch_context *ctx, struct process *proc,
 		  struct arg_type_info *info, struct value *valuep,
 		  size_t sz)
 {
@@ -191,7 +191,7 @@ allocate_gpr_pair(struct fetch_context *ctx, struct Process *proc,
 }
 
 static int
-allocate_fpr(struct fetch_context *ctx, struct Process *proc,
+allocate_fpr(struct fetch_context *ctx, struct process *proc,
 	     struct arg_type_info *info, struct value *valuep,
 	     size_t sz)
 {
@@ -212,7 +212,7 @@ allocate_fpr(struct fetch_context *ctx, struct Process *proc,
 
 int
 arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
-		    struct Process *proc,
+		    struct process *proc,
 		    struct arg_type_info *info, struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -267,7 +267,7 @@ arch_fetch_arg_next(struct fetch_context *ctx, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *ctx, enum tof type,
-		  struct Process *proc, struct arg_type_info *info,
+		  struct process *proc, struct arg_type_info *info,
 		  struct value *valuep)
 {
 	if (info->type == ARGTYPE_STRUCT) {
diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c
index 5f612e5..8893d45 100644
--- a/sysdeps/linux-gnu/s390/plt.c
+++ b/sysdeps/linux-gnu/s390/plt.c
@@ -29,6 +29,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/s390/regs.c b/sysdeps/linux-gnu/s390/regs.c
index 0592ccd..44e8f67 100644
--- a/sysdeps/linux-gnu/s390/regs.c
+++ b/sysdeps/linux-gnu/s390/regs.c
@@ -46,7 +46,8 @@
 #endif
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0) & PSW_MASK;
 #ifdef __s390x__
 	if (proc->mask_32bit)
@@ -56,7 +57,8 @@ get_instruction_pointer(Process *proc) {
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 #ifdef __s390x__
 	if (proc->mask_32bit)
 		addr = (void *)((long)addr & PSW_MASK31);
@@ -65,7 +67,8 @@ set_instruction_pointer(Process *proc, void *addr) {
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR15, 0) & PSW_MASK;
 #ifdef __s390x__
 	if (proc->mask_32bit)
@@ -75,7 +78,8 @@ get_stack_pointer(Process *proc) {
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	long ret = ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR14, 0) & PSW_MASK;
 #ifdef __s390x__
 	if (proc->mask_32bit)
@@ -85,7 +89,8 @@ get_return_addr(Process *proc, void *stack_pointer) {
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 #ifdef __s390x__
 	if (proc->mask_32bit)
 		addr = (void *)((long)addr & PSW_MASK31);
diff --git a/sysdeps/linux-gnu/s390/trace.c b/sysdeps/linux-gnu/s390/trace.c
index b9e05ff..78b04c3 100644
--- a/sysdeps/linux-gnu/s390/trace.c
+++ b/sysdeps/linux-gnu/s390/trace.c
@@ -43,7 +43,8 @@
 #endif
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 #ifdef __s390x__
 	unsigned long psw;
 
@@ -64,7 +65,8 @@ get_arch_dep(Process *proc) {
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	long pc, opcode, offset_reg, scno, tmp;
 	void *svc_addr;
 	int gpr_offset[16] = { PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
@@ -175,7 +177,7 @@ syscall_p(Process *proc, int status, int *sysnum) {
 }
 
 size_t
-arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
+arch_type_sizeof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
@@ -217,7 +219,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
 }
 
 size_t
-arch_type_alignof(struct Process *proc, struct arg_type_info *info)
+arch_type_alignof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c
index 40bbabc..3d2e589 100644
--- a/sysdeps/linux-gnu/sparc/plt.c
+++ b/sysdeps/linux-gnu/sparc/plt.c
@@ -28,6 +28,7 @@ arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/sparc/regs.c b/sysdeps/linux-gnu/sparc/regs.c
index 5e5ad20..8431c9b 100644
--- a/sysdeps/linux-gnu/sparc/regs.c
+++ b/sysdeps/linux-gnu/sparc/regs.c
@@ -27,7 +27,8 @@
 #include "common.h"
 
 void *
-get_instruction_pointer(Process *proc) {
+get_instruction_pointer(struct process *proc)
+{
 	proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
 	if (a->valid)
 		return (void *)a->regs.pc;
@@ -35,14 +36,16 @@ get_instruction_pointer(Process *proc) {
 }
 
 void
-set_instruction_pointer(Process *proc, void *addr) {
+set_instruction_pointer(struct process *proc, void *addr)
+{
 	proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
 	if (a->valid)
 		a->regs.pc = (long)addr;
 }
 
 void *
-get_stack_pointer(Process *proc) {
+get_stack_pointer(struct process *proc)
+{
 	proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
 	if (a->valid)
 		return (void *)a->regs.u_regs[UREG_I5];
@@ -50,7 +53,8 @@ get_stack_pointer(Process *proc) {
 }
 
 void *
-get_return_addr(Process *proc, void *stack_pointer) {
+get_return_addr(struct process *proc, void *stack_pointer)
+{
 	proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
 	unsigned int t;
 	if (!a->valid)
@@ -63,7 +67,8 @@ get_return_addr(Process *proc, void *stack_pointer) {
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	proc_archdep *a = (proc_archdep *) (proc->arch_ptr);
 	if (!a->valid)
 		return;
diff --git a/sysdeps/linux-gnu/sparc/trace.c b/sysdeps/linux-gnu/sparc/trace.c
index e1725ff..078d406 100644
--- a/sysdeps/linux-gnu/sparc/trace.c
+++ b/sysdeps/linux-gnu/sparc/trace.c
@@ -31,7 +31,8 @@
 #include "common.h"
 
 void
-get_arch_dep(Process *proc) {
+get_arch_dep(struct process *proc)
+{
 	proc_archdep *a;
 	if (!proc->arch_ptr)
 		proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
@@ -43,7 +44,8 @@ get_arch_dep(Process *proc) {
  * Returns -1 otherwise
  */
 int
-syscall_p(Process *proc, int status, int *sysnum) {
+syscall_p(struct process *proc, int status, int *sysnum)
+{
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
 		void *ip = get_instruction_pointer(proc);
@@ -66,7 +68,8 @@ syscall_p(Process *proc, int status, int *sysnum) {
 }
 
 long
-gimme_arg(enum tof type, Process *proc, int arg_num, struct arg_type_info *info)
+gimme_arg(enum tof type, struct process *proc, int arg_num,
+	  struct arg_type_info *info)
 {
 	proc_archdep *a = (proc_archdep *) proc->arch_ptr;
 	if (!a->valid) {
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c
index e13b761..e57a5ed 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
@@ -111,7 +111,7 @@ trace_pid(pid_t pid)
 }
 
 void
-trace_set_options(struct Process *proc)
+trace_set_options(struct process *proc)
 {
 	if (proc->tracesysgood & 0x80)
 		return;
@@ -148,8 +148,8 @@ static enum ecb_status
 event_for_pid(Event *event, void *data)
 {
 	if (event->proc != NULL && event->proc->pid == (pid_t)(uintptr_t)data)
-		return ecb_yield;
-	return ecb_cont;
+		return ECB_YIELD;
+	return ECB_CONT;
 }
 
 static int
@@ -206,7 +206,7 @@ add_task_info(struct pid_set *pids, pid_t pid)
 }
 
 static enum callback_status
-task_stopped(struct Process *task, void *data)
+task_stopped(struct process *task, void *data)
 {
 	enum process_status st = process_status(task->pid);
 	if (data != NULL)
@@ -217,13 +217,13 @@ task_stopped(struct Process *task, void *data)
 	 * the meantime.  This can happen when the whole thread group
 	 * is terminating.  */
 	switch (st) {
-	case ps_invalid:
-	case ps_tracing_stop:
-	case ps_zombie:
+	case PS_INVALID:
+	case PS_TRACING_STOP:
+	case PS_ZOMBIE:
 		return CBS_CONT;
-	case ps_sleeping:
-	case ps_stop:
-	case ps_other:
+	case PS_SLEEPING:
+	case PS_STOP:
+	case PS_OTHER:
 		return CBS_STOP;
 	}
 
@@ -232,7 +232,7 @@ task_stopped(struct Process *task, void *data)
 
 /* Task is blocked if it's stopped, or if it's a vfork parent.  */
 static enum callback_status
-task_blocked(struct Process *task, void *data)
+task_blocked(struct process *task, void *data)
 {
 	struct pid_set *pids = data;
 	struct pid_task *task_info = get_task_info(pids, task->pid);
@@ -246,7 +246,7 @@ task_blocked(struct Process *task, void *data)
 static Event *process_vfork_on_event(struct event_handler *super, Event *event);
 
 static enum callback_status
-task_vforked(struct Process *task, void *data)
+task_vforked(struct process *task, void *data)
 {
 	if (task->event_handler != NULL
 	    && task->event_handler->on_event == &process_vfork_on_event)
@@ -255,15 +255,15 @@ task_vforked(struct Process *task, void *data)
 }
 
 static int
-is_vfork_parent(struct Process *task)
+is_vfork_parent(struct process *task)
 {
 	return each_task(task->leader, NULL, &task_vforked, NULL) != NULL;
 }
 
 static enum callback_status
-send_sigstop(struct Process *task, void *data)
+send_sigstop(struct process *task, void *data)
 {
-	struct Process *leader = task->leader;
+	struct process *leader = task->leader;
 	struct pid_set *pids = data;
 
 	/* Look for pre-existing task record, or add new.  */
@@ -299,8 +299,8 @@ send_sigstop(struct Process *task, void *data)
 	 * vforked process.  We set up event handler specially to hint
 	 * us.  In that case parent is in D state, which we use to
 	 * weed out unnecessary looping.  */
-	if (st == ps_sleeping
-	    && is_vfork_parent (task)) {
+	if (st == PS_SLEEPING
+	    && is_vfork_parent(task)) {
 		task_info->vforked = 1;
 		return CBS_CONT;
 	}
@@ -321,7 +321,7 @@ send_sigstop(struct Process *task, void *data)
    breakpoint where IP points and let the process continue.  After
    this the breakpoint can be retracted and the process detached.  */
 static void
-ugly_workaround(struct Process *proc)
+ugly_workaround(struct process *proc)
 {
 	void *ip = get_instruction_pointer(proc);
 	struct breakpoint *sbp = dict_find_entry(proc->leader->breakpoints, ip);
@@ -334,7 +334,7 @@ ugly_workaround(struct Process *proc)
 
 static void
 process_stopping_done(struct process_stopping_handler *self,
-		      struct Process *leader)
+		      struct process *leader)
 {
 	debug(DEBUG_PROCESS, "process stopping done %d",
 	      self->task_enabling_breakpoint->pid);
@@ -351,7 +351,7 @@ process_stopping_done(struct process_stopping_handler *self,
 
 	if (self->exiting) {
 	ugly_workaround:
-		self->state = psh_ugly_workaround;
+		self->state = PSH_UGLY_WORKAROUND;
 		ugly_workaround(self->task_enabling_breakpoint);
 	} else {
 		switch ((self->ugly_workaround_p)(self)) {
@@ -377,11 +377,11 @@ undo_breakpoint(Event *event, void *data)
 	    && event->proc->leader == data
 	    && event->type == EVENT_BREAKPOINT)
 		set_instruction_pointer(event->proc, event->e_un.brk_addr);
-	return ecb_cont;
+	return ECB_CONT;
 }
 
 static enum callback_status
-untrace_task(struct Process *task, void *data)
+untrace_task(struct process *task, void *data)
 {
 	if (task != data)
 		untrace_pid(task->pid);
@@ -389,7 +389,7 @@ untrace_task(struct Process *task, void *data)
 }
 
 static enum callback_status
-remove_task(struct Process *task, void *data)
+remove_task(struct process *task, void *data)
 {
 	/* Don't untrace leader just yet.  */
 	if (task != data)
@@ -398,14 +398,14 @@ remove_task(struct Process *task, void *data)
 }
 
 static enum callback_status
-retract_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data)
+retract_breakpoint_cb(struct process *proc, struct breakpoint *bp, void *data)
 {
 	breakpoint_on_retract(bp, proc);
 	return CBS_CONT;
 }
 
 static void
-detach_process(struct Process *leader)
+detach_process(struct process *leader)
 {
 	each_qd_event(&undo_breakpoint, leader);
 	disable_all_breakpoints(leader);
@@ -414,7 +414,7 @@ detach_process(struct Process *leader)
 	/* Now untrace the process, if it was attached to by -p.  */
 	struct opt_p_t *it;
 	for (it = opt_p; it != NULL; it = it->next) {
-		struct Process *proc = pid2proc(it->pid);
+		struct process *proc = pid2proc(it->pid);
 		if (proc == NULL)
 			continue;
 		if (proc->leader == leader) {
@@ -540,19 +540,13 @@ all_stops_accountable(struct pid_set *pids)
 	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 @@ static Event *process_stopping_on_event(struct event_handler *super,
 					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 *proc = self->task_enabling_breakpoint;
+	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,30 +601,35 @@ atomic_singlestep_add_bp(void *addr, void *data)
 			return 0;
 		}
 
-	assert(!"Too many atomic singlestep breakpoints!");
+	assert(!"Too many sw singlestep breakpoints!");
 	abort();
 }
 
 static int
 singlestep(struct process_stopping_handler *self)
 {
-	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 process *proc = self->task_enabling_breakpoint;
+
+	struct sw_singlestep_data data = { self };
+	switch (arch_sw_singlestep(self->task_enabling_breakpoint,
+				   self->breakpoint_being_enabled,
+				   &sw_singlestep_add_bp, &data)) {
+	case SWS_HW:
+		/* Otherwise do the default action: singlestep.  */
+		debug(1, "PTRACE_SINGLESTEP");
+		if (ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0)) {
+			perror("PTRACE_SINGLESTEP");
+			return -1;
+		}
+		return 0;
 
-	/* Propagate failure and success.  */
-	if (status <= 0)
-		return status;
+	case SWS_OK:
+		return 0;
 
-	/* Otherwise do the default action: singlestep.  */
-	debug(1, "PTRACE_SINGLESTEP");
-	if (ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0)) {
-		perror("PTRACE_SINGLESTEP");
+	case SWS_FAIL:
 		return -1;
 	}
-	return 0;
+	abort();
 }
 
 static void
@@ -639,16 +641,16 @@ post_singlestep(struct process_stopping_handler *self,
 	if (*eventp != NULL && (*eventp)->type == EVENT_BREAKPOINT)
 		*eventp = NULL; // handled
 
-	struct Process *proc = self->task_enabling_breakpoint;
+	struct process *proc = self->task_enabling_breakpoint;
 
-	remove_atomic_breakpoints(proc);
+	remove_sw_breakpoints(proc);
 	self->breakpoint_being_enabled = NULL;
 }
 
 static void
 singlestep_error(struct process_stopping_handler *self)
 {
-	struct Process *teb = self->task_enabling_breakpoint;
+	struct process *teb = self->task_enabling_breakpoint;
 	struct breakpoint *sbp = self->breakpoint_being_enabled;
 	fprintf(stderr, "%d couldn't continue when handling %s (%p) at %p\n",
 		teb->pid, breakpoint_name(sbp),	sbp->addr,
@@ -659,7 +661,7 @@ singlestep_error(struct process_stopping_handler *self)
 static void
 pt_continue(struct process_stopping_handler *self)
 {
-	struct Process *teb = self->task_enabling_breakpoint;
+	struct process *teb = self->task_enabling_breakpoint;
 	debug(1, "PTRACE_CONT");
 	ptrace(PTRACE_CONT, teb->pid, 0, 0);
 }
@@ -675,12 +677,12 @@ static void
 disable_and(struct process_stopping_handler *self,
 	    void (*do_this)(struct process_stopping_handler *self))
 {
-	struct Process *teb = self->task_enabling_breakpoint;
+	struct process *teb = self->task_enabling_breakpoint;
 	debug(DEBUG_PROCESS, "all stopped, now singlestep/cont %d", teb->pid);
 	if (self->breakpoint_being_enabled->enabled)
 		disable_breakpoint(teb, self->breakpoint_being_enabled);
 	(do_this)(self);
-	self->state = psh_singlestep;
+	self->state = PSH_SINGLESTEP;
 }
 
 void
@@ -705,9 +707,9 @@ static Event *
 process_stopping_on_event(struct event_handler *super, Event *event)
 {
 	struct process_stopping_handler *self = (void *)super;
-	struct Process *task = event->proc;
-	struct Process *leader = task->leader;
-	struct Process *teb = self->task_enabling_breakpoint;
+	struct process *task = event->proc;
+	struct process *leader = task->leader;
+	struct process *teb = self->task_enabling_breakpoint;
 
 	debug(DEBUG_PROCESS,
 	      "process_stopping_on_event: pid %d; event type %d; state %d",
@@ -737,7 +739,7 @@ process_stopping_on_event(struct event_handler *super, Event *event)
 	}
 
 	switch (state) {
-	case psh_stopping:
+	case PSH_STOPPING:
 		/* If everyone is stopped, singlestep.  */
 		if (each_task(leader, NULL, &task_blocked,
 			      &self->pids) == NULL) {
@@ -746,7 +748,7 @@ process_stopping_on_event(struct event_handler *super, Event *event)
 		}
 		break;
 
-	case psh_singlestep:
+	case PSH_SINGLESTEP:
 		/* In singlestep state, breakpoint signifies that we
 		 * have now stepped, and can re-enable the breakpoint.  */
 		if (event != NULL && task == teb) {
@@ -801,13 +803,14 @@ process_stopping_on_event(struct event_handler *super, Event *event)
 		break;
 
 	psh_sinking:
-		state = self->state = psh_sinking;
-	case psh_sinking:
+		state = self->state = PSH_SINKING;
+		/* Fall through.  */
+	case PSH_SINKING:
 		if (await_sigstop_delivery(&self->pids, task_info, event))
 			process_stopping_done(self, leader);
 		break;
 
-	case psh_ugly_workaround:
+	case PSH_UGLY_WORKAROUND:
 		if (event == NULL)
 			break;
 		if (event->type == EVENT_BREAKPOINT) {
@@ -845,7 +848,7 @@ no(struct process_stopping_handler *self)
 }
 
 int
-process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp,
+process_install_stopping_handler(struct process *proc, struct breakpoint *sbp,
 				 void (*as)(struct process_stopping_handler *),
 				 enum callback_status (*ks)
 					 (struct process_stopping_handler *),
@@ -894,7 +897,7 @@ process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp,
 }
 
 void
-continue_after_breakpoint(Process *proc, struct breakpoint *sbp)
+continue_after_breakpoint(struct process *proc, struct breakpoint *sbp)
 {
 	debug(DEBUG_PROCESS,
 	      "continue_after_breakpoint: pid=%d, addr=%p",
@@ -937,8 +940,8 @@ static Event *
 ltrace_exiting_on_event(struct event_handler *super, Event *event)
 {
 	struct ltrace_exiting_handler *self = (void *)super;
-	struct Process *task = event->proc;
-	struct Process *leader = task->leader;
+	struct process *task = event->proc;
+	struct process *leader = task->leader;
 
 	debug(DEBUG_PROCESS,
 	      "ltrace_exiting_on_event: pid %d; event type %d",
@@ -970,7 +973,7 @@ ltrace_exiting_destroy(struct event_handler *super)
 }
 
 static int
-ltrace_exiting_install_handler(struct Process *proc)
+ltrace_exiting_install_handler(struct process *proc)
 {
 	/* Only install to leader.  */
 	if (proc->leader != proc)
@@ -1087,7 +1090,7 @@ process_vfork_on_event(struct event_handler *super, Event *event)
 }
 
 void
-continue_after_vfork(struct Process *proc)
+continue_after_vfork(struct process *proc)
 {
 	debug(DEBUG_PROCESS, "continue_after_vfork: pid=%d", proc->pid);
 	struct process_vfork_handler *handler = calloc(sizeof(*handler), 1);
@@ -1116,7 +1119,7 @@ continue_after_vfork(struct Process *proc)
 }
 
 static int
-is_mid_stopping(Process *proc)
+is_mid_stopping(struct process *proc)
 {
 	return proc != NULL
 		&& proc->event_handler != NULL
@@ -1124,7 +1127,7 @@ is_mid_stopping(Process *proc)
 }
 
 void
-continue_after_syscall(struct Process *proc, int sysnum, int ret_p)
+continue_after_syscall(struct process *proc, int sysnum, int ret_p)
 {
 	/* Don't continue if we are mid-stopping.  */
 	if (ret_p && (is_mid_stopping(proc) || is_mid_stopping(proc->leader))) {
@@ -1136,6 +1139,23 @@ continue_after_syscall(struct Process *proc, int sysnum, int ret_p)
 	continue_process(proc->pid);
 }
 
+void
+continue_after_exec(struct process *proc)
+{
+	continue_process(proc->pid);
+
+	/* After the exec, we expect to hit the first executable
+	 * instruction.
+	 *
+	 * XXX TODO It would be nice to have this removed, but then we
+	 * need to do that also for initial call to wait_for_proc in
+	 * execute_program.  In that case we could generate a
+	 * EVENT_FIRST event or something, or maybe this could somehow
+	 * be rolled into EVENT_NEW.  */
+	wait_for_proc(proc->pid);
+	continue_process(proc->pid);
+}
+
 /* If ltrace gets SIGINT, the processes directly or indirectly run by
  * ltrace get it too.  We just have to wait long enough for the signal
  * to be delivered and the process terminated, which we notice and
@@ -1152,7 +1172,7 @@ os_ltrace_exiting(void)
 {
 	struct opt_p_t *it;
 	for (it = opt_p; it != NULL; it = it->next) {
-		struct Process *proc = pid2proc(it->pid);
+		struct process *proc = pid2proc(it->pid);
 		if (proc == NULL || proc->leader == NULL)
 			continue;
 		if (ltrace_exiting_install_handler(proc->leader) < 0)
@@ -1174,7 +1194,8 @@ os_ltrace_exiting_sighandler(void)
 }
 
 size_t
-umovebytes(Process *proc, void *addr, void *laddr, size_t len) {
+umovebytes(struct process *proc, void *addr, void *laddr, size_t len)
+{
 
 	union {
 		long a;
diff --git a/sysdeps/linux-gnu/trace.h b/sysdeps/linux-gnu/trace.h
index 88ac33d..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
@@ -59,13 +59,13 @@ struct process_stopping_handler
 	struct event_handler super;
 
 	/* The task that is doing the re-enablement.  */
-	struct Process *task_enabling_breakpoint;
+	struct process *task_enabling_breakpoint;
 
 	/* The pointer being re-enabled.  */
 	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 *);
@@ -84,17 +84,17 @@ struct process_stopping_handler
 
 	enum {
 		/* We are waiting for everyone to land in t/T.  */
-		psh_stopping = 0,
+		PSH_STOPPING = 0,
 
 		/* We are doing the PTRACE_SINGLESTEP.  */
-		psh_singlestep,
+		PSH_SINGLESTEP,
 
 		/* We are waiting for all the SIGSTOPs to arrive so
 		 * that we can sink them.  */
-		psh_sinking,
+		PSH_SINKING,
 
 		/* This is for tracking the ugly workaround.  */
-		psh_ugly_workaround,
+		PSH_UGLY_WORKAROUND,
 	} state;
 
 	int exiting;
@@ -108,7 +108,7 @@ struct process_stopping_handler
  * ON_ALL_STOPPED is LINUX_PTRACE_DISABLE_AND_SINGLESTEP, the default
  * for KEEP_STEPPING_P and UGLY_WORKAROUND_P is "no".  */
 int process_install_stopping_handler
-	(struct Process *proc, struct breakpoint *sbp,
+	(struct process *proc, struct breakpoint *sbp,
 	 void (*on_all_stopped)(struct process_stopping_handler *),
 	 enum callback_status (*keep_stepping_p)
 		 (struct process_stopping_handler *),
diff --git a/sysdeps/linux-gnu/x86/fetch.c b/sysdeps/linux-gnu/x86/fetch.c
index 4dab4cc..aa02a0a 100644
--- a/sysdeps/linux-gnu/x86/fetch.c
+++ b/sysdeps/linux-gnu/x86/fetch.c
@@ -323,13 +323,13 @@ allocate_class(enum arg_class cls, struct fetch_context *context,
 }
 
 static ssize_t
-classify(struct Process *proc, struct fetch_context *context,
+classify(struct process *proc, struct fetch_context *context,
 	 struct arg_type_info *info, struct value *valuep, enum arg_class classes[],
 	 size_t sz, size_t eightbytes);
 
 /* This classifies one eightbyte part of an array or struct.  */
 static ssize_t
-classify_eightbyte(struct Process *proc, struct fetch_context *context,
+classify_eightbyte(struct process *proc, struct fetch_context *context,
 		   struct arg_type_info *info, struct value *valuep,
 		   enum arg_class *classp, size_t start, size_t end,
 		   struct arg_type_info *(*getter)(struct arg_type_info *,
@@ -364,7 +364,7 @@ classify_eightbyte(struct Process *proc, struct fetch_context *context,
 
 /* This classifies small arrays and structs.  */
 static ssize_t
-classify_eightbytes(struct Process *proc, struct fetch_context *context,
+classify_eightbytes(struct process *proc, struct fetch_context *context,
 		    struct arg_type_info *info, struct value *valuep,
 		    enum arg_class classes[], size_t elements,
 		    size_t eightbytes,
@@ -432,7 +432,7 @@ flatten_structure(struct arg_type_info *flattened, struct arg_type_info *info)
 }
 
 static ssize_t
-classify(struct Process *proc, struct fetch_context *context,
+classify(struct process *proc, struct fetch_context *context,
 	 struct arg_type_info *info, struct value *valuep, enum arg_class classes[],
 	 size_t sz, size_t eightbytes)
 {
@@ -517,7 +517,7 @@ pass_by_reference(struct value *valuep, enum arg_class classes[])
 }
 
 static ssize_t
-classify_argument(struct Process *proc, struct fetch_context *context,
+classify_argument(struct process *proc, struct fetch_context *context,
 		  struct arg_type_info *info, struct value *valuep,
 		  enum arg_class classes[], size_t *sizep)
 {
@@ -545,7 +545,7 @@ classify_argument(struct Process *proc, struct fetch_context *context,
 }
 
 static int
-fetch_register_banks(struct Process *proc, struct fetch_context *context,
+fetch_register_banks(struct process *proc, struct fetch_context *context,
 		     int floating)
 {
 	if (ptrace(PTRACE_GETREGS, proc->pid, 0, &context->iregs) < 0)
@@ -566,7 +566,7 @@ fetch_register_banks(struct Process *proc, struct fetch_context *context,
 
 static int
 arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
-		       struct Process *proc, struct arg_type_info *info,
+		       struct process *proc, struct arg_type_info *info,
 		       struct value *valuep)
 {
 	size_t sz = type_sizeof(proc, info);
@@ -580,7 +580,7 @@ arch_fetch_arg_next_32(struct fetch_context *context, enum tof type,
 
 static int
 arch_fetch_retval_32(struct fetch_context *context, enum tof type,
-		     struct Process *proc, struct arg_type_info *info,
+		     struct process *proc, struct arg_type_info *info,
 		     struct value *valuep)
 {
 	if (fetch_register_banks(proc, context, type == LT_TOF_FUNCTIONR) < 0)
@@ -646,7 +646,7 @@ fetch_stack_pointer(struct fetch_context *context)
 
 struct fetch_context *
 arch_fetch_arg_init_32(struct fetch_context *context,
-		       enum tof type, struct Process *proc,
+		       enum tof type, struct process *proc,
 		       struct arg_type_info *ret_info)
 {
 	context->stack_pointer = fetch_stack_pointer(context) + 4;
@@ -673,7 +673,7 @@ arch_fetch_arg_init_32(struct fetch_context *context,
 
 struct fetch_context *
 arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type,
-		       struct Process *proc, struct arg_type_info *ret_info)
+		       struct process *proc, struct arg_type_info *ret_info)
 {
 	/* The first stack slot holds a return address.  */
 	ctx->stack_pointer = fetch_stack_pointer(ctx) + 8;
@@ -698,7 +698,7 @@ arch_fetch_arg_init_64(struct fetch_context *ctx, enum tof type,
 }
 
 struct fetch_context *
-arch_fetch_arg_init(enum tof type, struct Process *proc,
+arch_fetch_arg_init(enum tof type, struct process *proc,
 		    struct arg_type_info *ret_info)
 {
 	struct fetch_context *ctx = malloc(sizeof(*ctx));
@@ -724,7 +724,7 @@ arch_fetch_arg_init(enum tof type, struct Process *proc,
 }
 
 struct fetch_context *
-arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
+arch_fetch_arg_clone(struct process *proc, struct fetch_context *context)
 {
 	struct fetch_context *ret = malloc(sizeof(*ret));
 	if (ret == NULL)
@@ -734,7 +734,7 @@ arch_fetch_arg_clone(struct Process *proc, struct fetch_context *context)
 
 static int
 arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type,
-			 struct Process *proc, struct arg_type_info *info,
+			 struct process *proc, struct arg_type_info *info,
 			 struct value *valuep, enum reg_pool pool)
 {
 	enum arg_class classes[2];
@@ -776,7 +776,7 @@ arch_fetch_pool_arg_next(struct fetch_context *context, enum tof type,
 
 int
 arch_fetch_fun_retval(struct fetch_context *context, enum tof type,
-		      struct Process *proc, struct arg_type_info *info,
+		      struct process *proc, struct arg_type_info *info,
 		      struct value *valuep)
 {
 	assert(type != LT_TOF_FUNCTION
@@ -808,7 +808,7 @@ arch_fetch_fun_retval(struct fetch_context *context, enum tof type,
 
 int
 arch_fetch_arg_next(struct fetch_context *context, enum tof type,
-		    struct Process *proc, struct arg_type_info *info,
+		    struct process *proc, struct arg_type_info *info,
 		    struct value *valuep)
 {
 	if (proc->e_machine == EM_386)
@@ -832,7 +832,7 @@ arch_fetch_arg_next(struct fetch_context *context, enum tof type,
 
 int
 arch_fetch_retval(struct fetch_context *context, enum tof type,
-		  struct Process *proc, struct arg_type_info *info,
+		  struct process *proc, struct arg_type_info *info,
 		  struct value *valuep)
 {
 	if (proc->e_machine == EM_386)
diff --git a/sysdeps/linux-gnu/x86/plt.c b/sysdeps/linux-gnu/x86/plt.c
index dc6f183..c2a4151 100644
--- a/sysdeps/linux-gnu/x86/plt.c
+++ b/sysdeps/linux-gnu/x86/plt.c
@@ -24,11 +24,13 @@
 #include "library.h"
 
 GElf_Addr
-arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
+arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+{
 	return lte->plt_addr + (ndx + 1) * 16;
 }
 
 void *
-sym2addr(Process *proc, struct library_symbol *sym) {
+sym2addr(struct process *proc, struct library_symbol *sym)
+{
 	return sym->enter_addr;
 }
diff --git a/sysdeps/linux-gnu/x86/regs.c b/sysdeps/linux-gnu/x86/regs.c
index ca6470b..3886e84 100644
--- a/sysdeps/linux-gnu/x86/regs.c
+++ b/sysdeps/linux-gnu/x86/regs.c
@@ -56,7 +56,7 @@ conv_32(arch_addr_t val)
 }
 
 void *
-get_instruction_pointer(struct Process *proc)
+get_instruction_pointer(struct process *proc)
 {
 	long int ret = ptrace(PTRACE_PEEKUSER, proc->pid, XIP, 0);
 	if (proc->e_machine == EM_386)
@@ -65,7 +65,7 @@ get_instruction_pointer(struct Process *proc)
 }
 
 void
-set_instruction_pointer(struct Process *proc, arch_addr_t addr)
+set_instruction_pointer(struct process *proc, arch_addr_t addr)
 {
 	if (proc->e_machine == EM_386)
 		addr = conv_32(addr);
@@ -73,7 +73,7 @@ set_instruction_pointer(struct Process *proc, arch_addr_t addr)
 }
 
 void *
-get_stack_pointer(struct Process *proc)
+get_stack_pointer(struct process *proc)
 {
 	long sp = ptrace(PTRACE_PEEKUSER, proc->pid, XSP, 0);
 	if (sp == -1 && errno) {
@@ -91,7 +91,7 @@ get_stack_pointer(struct Process *proc)
 }
 
 void *
-get_return_addr(struct Process *proc, void *sp)
+get_return_addr(struct process *proc, void *sp)
 {
 	long a = ptrace(PTRACE_PEEKTEXT, proc->pid, sp, 0);
 	if (a == -1 && errno) {
@@ -109,7 +109,8 @@ get_return_addr(struct Process *proc, void *sp)
 }
 
 void
-set_return_addr(Process *proc, void *addr) {
+set_return_addr(struct process *proc, void *addr)
+{
 	if (proc->e_machine == EM_386)
 		addr = (void *)((long int)addr & 0xffffffff);
 	ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr);
diff --git a/sysdeps/linux-gnu/x86/trace.c b/sysdeps/linux-gnu/x86/trace.c
index ed8bdb4..6a1a6a5 100644
--- a/sysdeps/linux-gnu/x86/trace.c
+++ b/sysdeps/linux-gnu/x86/trace.c
@@ -55,7 +55,7 @@ static const int x86_64 = 0;
 #endif
 
 void
-get_arch_dep(struct Process *proc)
+get_arch_dep(struct process *proc)
 {
 	/* Unfortunately there are still remnants of mask_32bit uses
 	 * around.  */
@@ -75,7 +75,7 @@ get_arch_dep(struct Process *proc)
 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
  */
 int
-syscall_p(struct Process *proc, int status, int *sysnum)
+syscall_p(struct process *proc, int status, int *sysnum)
 {
 	if (WIFSTOPPED(status)
 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
@@ -109,7 +109,7 @@ syscall_p(struct Process *proc, int status, int *sysnum)
 }
 
 size_t
-arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
+arch_type_sizeof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
@@ -151,7 +151,7 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info *info)
 }
 
 size_t
-arch_type_alignof(struct Process *proc, struct arg_type_info *info)
+arch_type_alignof(struct process *proc, struct arg_type_info *info)
 {
 	if (proc == NULL)
 		return (size_t)-2;
diff --git a/type.c b/type.c
index 3ce8563..d80550b 100644
--- a/type.c
+++ b/type.c
@@ -123,7 +123,7 @@ type_struct_destroy(struct arg_type_info *info)
 }
 
 static int
-layout_struct(struct Process *proc, struct arg_type_info *info,
+layout_struct(struct process *proc, struct arg_type_info *info,
 	      size_t *sizep, size_t *alignmentp, size_t *offsetofp)
 {
 	size_t sz = 0;
@@ -254,10 +254,10 @@ type_destroy(struct arg_type_info *info)
 }
 
 #ifdef ARCH_HAVE_SIZEOF
-size_t arch_type_sizeof(struct Process *proc, struct arg_type_info * arg);
+size_t arch_type_sizeof(struct process *proc, struct arg_type_info *arg);
 #else
 size_t
-arch_type_sizeof(struct Process *proc, struct arg_type_info * arg)
+arch_type_sizeof(struct process *proc, struct arg_type_info *arg)
 {
 	/* Use default value.  */
 	return (size_t)-2;
@@ -265,10 +265,10 @@ arch_type_sizeof(struct Process *proc, struct arg_type_info * arg)
 #endif
 
 #ifdef ARCH_HAVE_ALIGNOF
-size_t arch_type_alignof(struct Process *proc, struct arg_type_info * arg);
+size_t arch_type_alignof(struct process *proc, struct arg_type_info *arg);
 #else
 size_t
-arch_type_alignof(struct Process *proc, struct arg_type_info * arg)
+arch_type_alignof(struct process *proc, struct arg_type_info *arg)
 {
 	/* Use default value.  */
 	return (size_t)-2;
@@ -289,7 +289,7 @@ align(size_t sz, size_t alignment)
 }
 
 size_t
-type_sizeof(struct Process *proc, struct arg_type_info *type)
+type_sizeof(struct process *proc, struct arg_type_info *type)
 {
 	size_t arch_size = arch_type_sizeof(proc, type);
 	if (arch_size != (size_t)-2)
@@ -359,7 +359,7 @@ type_sizeof(struct Process *proc, struct arg_type_info *type)
 #define alignof(field,st) ((size_t) ((char*) &st.field - (char*) &st))
 
 size_t
-type_alignof(struct Process *proc, struct arg_type_info *type)
+type_alignof(struct process *proc, struct arg_type_info *type)
 {
 	size_t arch_alignment = arch_type_alignof(proc, type);
 	if (arch_alignment != (size_t)-2)
@@ -412,7 +412,7 @@ type_alignof(struct Process *proc, struct arg_type_info *type)
 }
 
 size_t
-type_offsetof(struct Process *proc, struct arg_type_info *type, size_t emt)
+type_offsetof(struct process *proc, struct arg_type_info *type, size_t emt)
 {
 	assert(type->type == ARGTYPE_STRUCT
 	       || type->type == ARGTYPE_ARRAY);
diff --git a/type.h b/type.h
index e8dec71..b92c1af 100644
--- a/type.h
+++ b/type.h
@@ -111,11 +111,11 @@ void type_init_pointer(struct arg_type_info *info,
 void type_destroy(struct arg_type_info *info);
 
 /* Compute a size of given type.  Return (size_t)-1 for error.  */
-size_t type_sizeof(struct Process *proc, struct arg_type_info *type);
+size_t type_sizeof(struct process *proc, struct arg_type_info *type);
 
 /* Compute an alignment necessary for elements of this type.  Return
  * (size_t)-1 for error.  */
-size_t type_alignof(struct Process *proc, struct arg_type_info *type);
+size_t type_alignof(struct process *proc, struct arg_type_info *type);
 
 /* Align value SZ to ALIGNMENT and return the result.  */
 size_t align(size_t sz, size_t alignment);
@@ -126,7 +126,7 @@ struct arg_type_info *type_element(struct arg_type_info *type, size_t elt);
 
 /* Compute an offset of EMT-th element of type TYPE.  This works for
  * arrays and structures.  Return (size_t)-1 for error.  */
-size_t type_offsetof(struct Process *proc,
+size_t type_offsetof(struct process *proc,
 		     struct arg_type_info *type, size_t elt);
 
 /* Whether TYPE is an integral type as defined by the C standard.  */
diff --git a/value.c b/value.c
index f7950da..d18db17 100644
--- a/value.c
+++ b/value.c
@@ -29,7 +29,7 @@
 #include "backend.h"
 
 static void
-value_common_init(struct value *valp, struct Process *inferior,
+value_common_init(struct value *valp, struct process *inferior,
 		  struct value *parent, struct arg_type_info *type,
 		  int own_type)
 {
@@ -43,7 +43,7 @@ value_common_init(struct value *valp, struct Process *inferior,
 }
 
 void
-value_init(struct value *valp, struct Process *inferior, struct value *parent,
+value_init(struct value *valp, struct process *inferior, struct value *parent,
 	   struct arg_type_info *type, int own_type)
 {
 	assert(inferior != NULL);
diff --git a/value.h b/value.h
index 795573c..f501254 100644
--- a/value.h
+++ b/value.h
@@ -46,7 +46,7 @@ enum value_location_t {
 
 struct value {
 	struct arg_type_info *type;
-	struct Process *inferior;
+	struct process *inferior;
 	struct value *parent;
 	size_t size;
 	union {
@@ -63,7 +63,7 @@ struct value {
  * value, in case of compound types.  It may be NULL.  TYPE is a type
  * of the value.  It may be NULL if the type is not yet known.  If
  * OWN_TYPE, the passed-in type is owned and released by value.  */
-void value_init(struct value *value, struct Process *inferior,
+void value_init(struct value *value, struct process *inferior,
 		struct value *parent, struct arg_type_info *type,
 		int own_type);
 
diff --git a/zero.c b/zero.c
index bc119ee..5757943 100644
--- a/zero.c
+++ b/zero.c
@@ -18,7 +18,6 @@
  * 02110-1301 USA
  */
 
-#include <error.h>
 #include <errno.h>
 
 #include "zero.h"
@@ -93,13 +92,12 @@ build_zero_w_arg(struct expr_node *expr, int own)
 struct expr_node *
 expr_node_zero(void)
 {
-	static struct expr_node *node = NULL;
-	if (node == NULL) {
-		node = malloc(sizeof(*node));
-		if (node == NULL)
-			error(1, errno, "malloc expr_node_zero");
-		expr_init_cb1(node, &zero1_callback,
+	static struct expr_node *nodep = NULL;
+	if (nodep == NULL) {
+		static struct expr_node node;
+		expr_init_cb1(&node, &zero1_callback,
 			      expr_self(), 0, (void *)-1);
+		nodep = &node;
 	}
-	return node;
+	return nodep;
 }