/*
 * This file is part of ltrace.
 * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc.
 * Copyright (C) 2010 Joe Damato
 * Copyright (C) 1998,2009 Juan Cespedes
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include "config.h"

#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "backend.h"
#include "breakpoint.h"
#include "debug.h"
#include "fetch.h"
#include "options.h"
#include "proc.h"
#include "value_dict.h"

#ifndef OS_HAVE_PROCESS_DATA
int
os_process_init(struct process *proc)
{
	return 0;
}

void
os_process_destroy(struct process *proc)
{
}

int
os_process_clone(struct process *retp, struct process *proc)
{
	return 0;
}

int
os_process_exec(struct process *proc)
{
	return 0;
}
#endif

#ifndef ARCH_HAVE_PROCESS_DATA
int
arch_process_init(struct process *proc)
{
	return 0;
}

void
arch_process_destroy(struct process *proc)
{
}

int
arch_process_clone(struct process *retp, struct process *proc)
{
	return 0;
}

int
arch_process_exec(struct process *proc)
{
	return 0;
}
#endif

#ifndef ARCH_HAVE_DYNLINK_DONE
void
arch_dynlink_done(struct process *proc)
{
}
#endif

static int add_process(struct process *proc, int was_exec);
static void unlist_process(struct process *proc);

static void
destroy_unwind(struct process *proc)
{
#if defined(HAVE_LIBUNWIND)
	if (proc->unwind_priv != NULL)
		_UPT_destroy(proc->unwind_priv);
	if (proc->unwind_as != NULL)
		unw_destroy_addr_space(proc->unwind_as);
#endif /* defined(HAVE_LIBUNWIND) */

#if defined(HAVE_LIBDW)
	if (proc->dwfl != NULL)
		dwfl_end(proc->dwfl);
#endif /* defined(HAVE_LIBDW) */
}

static int
process_bare_init(struct process *proc, const char *filename,
		  pid_t pid, int was_exec)
{
	if (!was_exec) {
		memset(proc, 0, sizeof(*proc));

		proc->filename = strdup(filename);
		if (proc->filename == NULL) {
		fail:
			free(proc->filename);
			if (proc->breakpoints != NULL) {
				dict_destroy(proc->breakpoints,
					     NULL, NULL, NULL);
				free(proc->breakpoints);
				proc->breakpoints = NULL;
			}
			return -1;
		}
	}

	/* Add process so that we know who the leader is.  */
	proc->pid = pid;
	if (add_process(proc, was_exec) < 0)
		goto fail;
	if (proc->leader == NULL) {
	unlist_and_fail:
		if (!was_exec)
			unlist_process(proc);
		goto fail;
	}

	if (proc->leader == proc) {
		proc->breakpoints = malloc(sizeof(*proc->breakpoints));
		if (proc->breakpoints == NULL)
			goto unlist_and_fail;
		DICT_INIT(proc->breakpoints,
			  arch_addr_t, struct breakpoint *,
			  arch_addr_hash, arch_addr_eq, NULL);
	} else {
		proc->breakpoints = NULL;
	}

#if defined(HAVE_LIBUNWIND)
	if (options.bt_depth > 0) {
		proc->unwind_priv = _UPT_create(pid);
		proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0);

		if (proc->unwind_priv == NULL || proc->unwind_as == NULL) {
			fprintf(stderr,
				"Couldn't initialize unwinding "
				"for process %d\n", proc->pid);
			destroy_unwind(proc);
			proc->unwind_priv = NULL;
			proc->unwind_as = NULL;
		}
	}
#endif /* defined(HAVE_LIBUNWIND) */

#if defined(HAVE_LIBDW)
	proc->dwfl = NULL; /* Initialize for leader only on first library.  */
#endif /* defined(HAVE_LIBDW) */

	return 0;
}

static void
process_bare_destroy(struct process *proc, int was_exec)
{
	dict_destroy(proc->breakpoints, NULL, NULL, NULL);
	free(proc->breakpoints);
	if (!was_exec) {
		free(proc->filename);
		unlist_process(proc);
		destroy_unwind(proc);
	}
}

static int
process_init_main(struct process *proc)
{
	if (breakpoints_init(proc) < 0) {
		fprintf(stderr, "failed to init breakpoints %d\n",
			proc->pid);
		return -1;
	}

	return 0;
}

int
process_init(struct process *proc, const char *filename, pid_t pid)
{
	if (process_bare_init(proc, filename, pid, 0) < 0) {
	fail:
		fprintf(stderr, "failed to initialize process %d: %s\n",
			pid, strerror(errno));
		return -1;
	}

	if (os_process_init(proc) < 0) {
		process_bare_destroy(proc, 0);
		goto fail;
	}

	if (arch_process_init(proc) < 0) {
		os_process_destroy(proc);
		process_bare_destroy(proc, 0);
		goto fail;
	}

	if (proc->leader != proc) {
		proc->e_machine = proc->leader->e_machine;
		proc->e_class = proc->leader->e_class;
		get_arch_dep(proc);
	} else if (process_init_main(proc) < 0) {
		process_bare_destroy(proc, 0);
		goto fail;
	}
	return 0;
}

static enum callback_status
destroy_breakpoint_cb(struct process *proc, struct breakpoint *bp, void *data)
{
	breakpoint_destroy(bp);
	free(bp);
	return CBS_CONT;
}

// XXX see comment in handle_event.c
void callstack_pop(struct process *proc);

static void
private_process_destroy(struct process *proc, int was_exec)
{
	/* Pop remaining stack elements.  */
	while (proc->callstack_depth > 0) {
		/* When this is called just before a process is
		 * destroyed, the breakpoints should either have been
		 * retracted by now, or were killed by exec.  In any
		 * case, it's safe to pretend that there are no
		 * breakpoints associated with the stack elements, so
		 * that stack_pop doesn't attempt to destroy them.  */
		size_t i = proc->callstack_depth - 1;
		if (!proc->callstack[i].is_syscall)
			proc->callstack[i].return_addr = 0;

		callstack_pop(proc);
	}

	if (!was_exec)
		free(proc->filename);

	/* Libraries and symbols.  This is only relevant in
	 * leader.  */
	struct library *lib;
	for (lib = proc->libraries; lib != NULL; ) {
		struct library *next = lib->next;
		library_destroy(lib);
		free(lib);
		lib = next;
	}
	proc->libraries = NULL;

	/* Breakpoints.  */
	if (proc->breakpoints != NULL) {
		proc_each_breakpoint(proc, NULL, destroy_breakpoint_cb, NULL);
		dict_destroy(proc->breakpoints, NULL, NULL, NULL);
		free(proc->breakpoints);
		proc->breakpoints = NULL;
	}

	destroy_unwind(proc);
}

void
process_destroy(struct process *proc)
{
	arch_process_destroy(proc);
	os_process_destroy(proc);
	private_process_destroy(proc, 0);
}

int
process_exec(struct process *proc)
{
	/* Call exec handlers first, before we destroy the main
	 * state.  */
	if (arch_process_exec(proc) < 0
	    || os_process_exec(proc) < 0)
		return -1;

	private_process_destroy(proc, 1);

	if (process_bare_init(proc, NULL, proc->pid, 1) < 0)
		return -1;
	if (process_init_main(proc) < 0) {
		process_bare_destroy(proc, 1);
		return -1;
	}
	return 0;
}

struct process *
open_program(const char *filename, pid_t pid)
{
	assert(pid != 0);
	struct process *proc = malloc(sizeof(*proc));
	if (proc == NULL || process_init(proc, filename, pid) < 0) {
		free(proc);
		return NULL;
	}
	return proc;
}

struct clone_single_bp_data {
	struct process *old_proc;
	struct process *new_proc;
};

static enum callback_status
clone_single_bp(arch_addr_t *key, struct breakpoint **bpp, void *u)
{
	struct breakpoint *bp = *bpp;
	struct clone_single_bp_data *data = u;

	struct breakpoint *clone = malloc(sizeof(*clone));
	if (clone == NULL
	    || breakpoint_clone(clone, data->new_proc, bp) < 0) {
	fail:
		free(clone);
		return CBS_STOP;
	}
	if (proc_add_breakpoint(data->new_proc->leader, clone) < 0) {
		breakpoint_destroy(clone);
		goto fail;
	}
	return CBS_CONT;
}

int
process_clone(struct process *retp, struct process *proc, pid_t pid)
{
	if (process_bare_init(retp, proc->filename, pid, 0) < 0) {
	fail1:
		fprintf(stderr, "Failed to clone process %d to %d: %s\n",
			proc->pid, pid, strerror(errno));
		return -1;
	}

	retp->tracesysgood = proc->tracesysgood;
	retp->e_machine = proc->e_machine;
	retp->e_class = proc->e_class;

	/* For non-leader processes, that's all we need to do.  */
	if (retp->leader != retp)
		return 0;

	/* Clone symbols first so that we can clone and relink
	 * breakpoints.  */
	struct library *lib;
	struct library **nlibp = &retp->libraries;
	for (lib = proc->leader->libraries; lib != NULL; lib = lib->next) {
		*nlibp = malloc(sizeof(**nlibp));

		if (*nlibp == NULL
		    || library_clone(*nlibp, lib) < 0) {
			free(*nlibp);
			*nlibp = NULL;

		fail2:
			process_bare_destroy(retp, 0);

			/* Error when cloning.  Unroll what was done.  */
			for (lib = retp->libraries; lib != NULL; ) {
				struct library *next = lib->next;
				library_destroy(lib);
				free(lib);
				lib = next;
			}
			goto fail1;
		}

		nlibp = &(*nlibp)->next;
	}

	/* Now clone breakpoints.  Symbol relinking is done in
	 * clone_single_bp.  */
	struct clone_single_bp_data data = {
		.old_proc = proc,
		.new_proc = retp,
	};
	if (DICT_EACH(proc->leader->breakpoints,
		      arch_addr_t, struct breakpoint *, NULL,
		      clone_single_bp, &data) != NULL)
		goto fail2;

	/* And finally the call stack.  */
	/* XXX clearly the callstack handling should be moved to a
	 * separate module and this whole business extracted to
	 * callstack_clone, or callstack_element_clone.  */
	memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack));
	retp->callstack_depth = proc->callstack_depth;

	size_t i;
	for (i = 0; i < retp->callstack_depth; ++i) {
		struct callstack_element *elem = &retp->callstack[i];
		struct fetch_context *ctx = elem->fetch_context;
		if (ctx != NULL) {
			struct fetch_context *nctx = fetch_arg_clone(retp, ctx);
			if (nctx == NULL) {
				size_t j;
			fail3:
				for (j = 0; j < i; ++j) {
					nctx = retp->callstack[j].fetch_context;
					fetch_arg_done(nctx);
					elem->fetch_context = NULL;
				}
				goto fail2;
			}
			elem->fetch_context = nctx;
		}

		if (elem->arguments != NULL) {
			struct value_dict *nargs = malloc(sizeof(*nargs));
			if (nargs == NULL
			    || val_dict_clone(nargs, elem->arguments) < 0) {
				size_t j;
				for (j = 0; j < i; ++j) {
					nargs = retp->callstack[j].arguments;
					val_dict_destroy(nargs);
					free(nargs);
					elem->arguments = NULL;
				}

				/* Pretend that this round went well,
				 * so that fail3 frees I-th
				 * fetch_context.  */
				++i;
				goto fail3;
			}
			elem->arguments = nargs;
		}

		/* If it's not a syscall, we need to find the
		 * corresponding library symbol in the cloned
		 * library.  */
		if (!elem->is_syscall && elem->c_un.libfunc != NULL) {
			struct library_symbol *libfunc = elem->c_un.libfunc;
			int rc = proc_find_symbol(retp, libfunc,
						  NULL, &elem->c_un.libfunc);
			assert(rc == 0);
		}
	}

	/* At this point, retp is fully initialized, except for OS and
	 * arch parts, and we can call private_process_destroy.  */
	if (os_process_clone(retp, proc) < 0) {
		private_process_destroy(retp, 0);
		return -1;
	}
	if (arch_process_clone(retp, proc) < 0) {
		os_process_destroy(retp);
		private_process_destroy(retp, 0);
		return -1;
	}

	return 0;
}

static int
open_one_pid(pid_t pid)
{
	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.  */
	char *filename = pid2name(pid);
	if (filename == NULL || trace_pid(pid) < 0) {
	fail:
		free(filename);
		return -1;
	}

	struct process *proc = open_program(filename, pid);
	if (proc == NULL)
		goto fail;
	free(filename);
	trace_set_options(proc);

	return 0;
}

static enum callback_status
start_one_pid(struct process *proc, void *data)
{
	continue_process(proc->pid);
	return CBS_CONT;
}

static enum callback_status
is_main(struct process *proc, struct library *lib, void *data)
{
	return CBS_STOP_IF(lib->type == LT_LIBTYPE_MAIN);
}

void
process_hit_start(struct process *proc)
{
	struct process *leader = proc->leader;
	assert(leader != NULL);

	struct library *mainlib
		= proc_each_library(leader, NULL, is_main, NULL);
	assert(mainlib != NULL);
	linkmap_init(leader, mainlib->dyn_addr);
	arch_dynlink_done(leader);
}

void
open_pid(pid_t pid)
{
	debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid);
	/* If we are already tracing this guy, we should be seeing all
	 * his children via normal tracing route.  */
	if (pid2proc(pid) != NULL)
		return;

	/* First, see if we can attach the requested PID itself.  */
	if (open_one_pid(pid) < 0) {
		fprintf(stderr, "Cannot attach to pid %u: %s\n",
			pid, strerror(errno));
		trace_fail_warning(pid);
		return;
	}

	/* Now attach to all tasks that belong to that PID.  There's a
	 * race between process_tasks and open_one_pid.  So when we
	 * fail in open_one_pid below, we just do another round.
	 * Chances are that by then that PID will have gone away, and
	 * that's why we have seen the failure.  The processes that we
	 * manage to open_one_pid are stopped, so we should eventually
	 * reach a point where process_tasks doesn't give any new
	 * processes (because there's nobody left to produce
	 * them).  */
	size_t old_ntasks = 0;
	int have_all;
	while (1) {
		pid_t *tasks;
		size_t ntasks;
		size_t i;

		if (process_tasks(pid, &tasks, &ntasks) < 0) {
			fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n",
				pid, strerror(errno));
			break;
		}

		have_all = 1;
		for (i = 0; i < ntasks; ++i)
			if (pid2proc(tasks[i]) == NULL
			    && open_one_pid(tasks[i]) < 0)
				have_all = 0;

		free(tasks);

		if (have_all && old_ntasks == ntasks)
			break;
		old_ntasks = ntasks;
	}

	struct process *leader = pid2proc(pid)->leader;

	/* XXX Is there a way to figure out whether _start has
	 * actually already been hit?  */
	process_hit_start(leader);

	/* Done.  Continue everyone.  */
	each_task(leader, NULL, start_one_pid, NULL);
}

static enum callback_status
find_proc(struct process *proc, void *data)
{
	return CBS_STOP_IF(proc->pid == (pid_t)(uintptr_t)data);
}

struct process *
pid2proc(pid_t pid)
{
	return each_process(NULL, &find_proc, (void *)(uintptr_t)pid);
}

static struct process *list_of_processes = NULL;

static void
unlist_process(struct process *proc)
{
	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.  */
		assert(tmp->next != NULL);

		if (tmp->next == proc) {
			tmp->next = tmp->next->next;
			return;
		}
	}
}

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
		: start_after->next;

	while (it != NULL) {
		/* Callback might call remove_process.  */
		struct process *next = it->next;
		switch ((*cb)(it, data)) {
		case CBS_FAIL:
			/* XXX handle me */
		case CBS_STOP:
			return it;
		case CBS_CONT:
			break;
		}
		it = next;
	}
	return NULL;
}

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
		: start_after->next;

	if (it != NULL) {
		struct process *leader = it->leader;
		while (it != NULL && it->leader == leader) {
			/* Callback might call remove_process.  */
			struct process *next = it->next;
			switch ((*cb)(it, data)) {
			case CBS_FAIL:
				/* XXX handle me */
			case CBS_STOP:
				return it;
			case CBS_CONT:
				break;
			}
			it = next;
		}
	}
	return NULL;
}

static int
add_process(struct process *proc, int was_exec)
{
	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 -1;
		if (tgid == proc->pid) {
			proc->leader = proc;
		} else {
			struct process *leader = pid2proc(tgid);
			proc->leader = leader;
			if (leader != NULL)
				leaderp = &leader->next;
		}
	}

	if (!was_exec) {
		proc->next = *leaderp;
		*leaderp = proc;
	}
	return 0;
}

void
change_process_leader(struct process *proc, struct process *leader)
{
	struct process **leaderp = &list_of_processes;
	if (proc->leader == leader)
		return;

	assert(leader != NULL);
	unlist_process(proc);
	if (proc != leader)
		leaderp = &leader->next;

	proc->leader = leader;
	proc->next = *leaderp;
	*leaderp = proc;
}

static enum callback_status
clear_leader(struct process *proc, void *data)
{
	debug(DEBUG_FUNCTION, "detach_task %d from leader %d",
	      proc->pid, proc->leader->pid);
	proc->leader = NULL;
	return CBS_CONT;
}

void
remove_process(struct process *proc)
{
	debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid);

	if (proc->leader == proc)
		each_task(proc, NULL, &clear_leader, NULL);

	unlist_process(proc);
	process_removed(proc);
	process_destroy(proc);
	free(proc);
}

void
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);
	proc->event_handler = handler;
}

void
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);
	assert(handler != NULL);
	if (handler->destroy != NULL)
		handler->destroy(handler);
	free(handler);
	proc->event_handler = NULL;
}

static int
breakpoint_for_symbol(struct library_symbol *libsym, struct process *proc)
{
	arch_addr_t bp_addr;
	assert(proc->leader == proc);

	/* Don't enable latent or delayed symbols.  */
	if (libsym->latent || libsym->delayed) {
		debug(DEBUG_FUNCTION,
		      "delayed and/or latent breakpoint pid=%d, %s@%p",
		      proc->pid, libsym->name, libsym->enter_addr);
		return 0;
	}

	bp_addr = sym2addr(proc, libsym);

	/* If there is an artificial breakpoint on the same address,
	 * its libsym will be NULL, and we can smuggle our libsym
	 * there.  That artificial breakpoint is there presumably for
	 * the callbacks, which we don't touch.  If there is a real
	 * breakpoint, then this is a bug.  ltrace-elf.c should filter
	 * symbols and ignore extra symbol aliases.
	 *
	 * The other direction is more complicated and currently not
	 * supported.  If a breakpoint has custom callbacks, it might
	 * be also custom-allocated, and we would really need to swap
	 * the two: delete the one now in the dictionary, swap values
	 * around, and put the new breakpoint back in.  */
	struct breakpoint *bp;
	if (DICT_FIND_VAL(proc->breakpoints, &bp_addr, &bp) == 0) {
		/* MIPS backend makes duplicate requests.  This is
		 * likely a bug in the backend.  Currently there's no
		 * point assigning more than one symbol to a
		 * breakpoint, because when it hits, we won't know
		 * what to print out.  But it's easier to fix it here
		 * before someone who understands MIPS has the time to
		 * look into it.  So turn the sanity check off on
		 * MIPS.  References:
		 *
		 *   http://lists.alioth.debian.org/pipermail/ltrace-devel/2012-November/000764.html
		 *   http://lists.alioth.debian.org/pipermail/ltrace-devel/2012-November/000770.html
		 */
#ifndef __mips__
		assert(bp->libsym == NULL);
		bp->libsym = libsym;
#endif
		return 0;
	}

	bp = malloc(sizeof(*bp));
	if (bp == NULL
	    || breakpoint_init(bp, proc, bp_addr, libsym) < 0) {
	fail:
		free(bp);
		return -1;
	}
	if (proc_add_breakpoint(proc, bp) < 0) {
		breakpoint_destroy(bp);
		goto fail;
	}

	if (breakpoint_turn_on(bp, proc) < 0) {
		proc_remove_breakpoint(proc, bp);
		breakpoint_destroy(bp);
		goto fail;
	}

	return 0;
}

static enum callback_status
cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data)
{
	return CBS_STOP_IF(breakpoint_for_symbol(libsym, data) < 0);
}

static int
proc_activate_latent_symbol(struct process *proc,
			    struct library_symbol *libsym)
{
	assert(libsym->latent);
	libsym->latent = 0;
	debug(DEBUG_FUNCTION, "activated latent symbol");
	return breakpoint_for_symbol(libsym, proc);
}

int
proc_activate_delayed_symbol(struct process *proc,
			     struct library_symbol *libsym)
{
	assert(libsym->delayed);
	libsym->delayed = 0;
	debug(DEBUG_FUNCTION, "activated delayed symbol");
	return breakpoint_for_symbol(libsym, proc);
}

static enum callback_status
activate_latent_in(struct process *proc, struct library *lib, void *data)
{
	struct library_exported_name *exported;
	for (exported = data; exported != NULL; exported = exported->next) {
		struct library_symbol *libsym = NULL;
		while ((libsym = library_each_symbol(lib, libsym,
						     library_symbol_named_cb,
						     (void *)exported->name))
		       != NULL)
			if (libsym->latent
			    && proc_activate_latent_symbol(proc, libsym) < 0)
				return CBS_FAIL;
	}
	return CBS_CONT;
}

void
proc_add_library(struct process *proc, struct library *lib)
{
	assert(lib->next == NULL);
	lib->next = proc->libraries;
	proc->libraries = lib;
	debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d",
	      lib->soname, lib->base, lib->pathname, proc->pid);

#if defined(HAVE_LIBDW)
	if (options.bt_depth > 0) {
		/* Setup module tracking for libdwfl unwinding.  */
		struct process *leader = proc->leader;
		Dwfl *dwfl = leader->dwfl;
		if (dwfl == NULL) {
			static const Dwfl_Callbacks proc_callbacks = {
				.find_elf = dwfl_linux_proc_find_elf,
				.find_debuginfo = dwfl_standard_find_debuginfo
			};
			dwfl = dwfl_begin(&proc_callbacks);
			if (dwfl == NULL)
				fprintf(stderr,
					"Couldn't initialize libdwfl unwinding "
					"for process %d: %s\n", leader->pid,
					dwfl_errmsg (-1));
		}

		if (dwfl != NULL) {
			dwfl_report_begin_add(dwfl);
			if (dwfl_report_elf(dwfl, lib->soname,
					    lib->pathname, -1,
					    (GElf_Addr) lib->base,
					    false) == NULL)
				fprintf(stderr,
					"dwfl_report_elf %s@%p (%s) %d: %s\n",
					lib->soname, lib->base, lib->pathname,
					proc->pid, dwfl_errmsg (-1));
			dwfl_report_end(dwfl, NULL, NULL);

			if (leader->dwfl == NULL) {
				int r = dwfl_linux_proc_attach(dwfl,
							       leader->pid,
							       true);
				if (r == 0)
					leader->dwfl = dwfl;
				else {
					const char *msg;
					dwfl_end(dwfl);
					if (r < 0)
						msg = dwfl_errmsg(-1);
					else
						msg = strerror(r);
					fprintf(stderr, "Couldn't initialize "
						"libdwfl unwinding for "
						"process %d: %s\n",
						leader->pid, msg);
				}
			}
		}
	}
#endif /* defined(HAVE_LIBDW) */

	/* Insert breakpoints for all active (non-latent) symbols.  */
	struct library_symbol *libsym = NULL;
	while ((libsym = library_each_symbol(lib, libsym,
					     cb_breakpoint_for_symbol,
					     proc)) != NULL)
		fprintf(stderr,
			"Couldn't insert breakpoint for %s to %d: %s.\n",
			libsym->name, proc->pid, strerror(errno));

	/* Look through export list of the new library and compare it
	 * with latent symbols of all libraries (including this
	 * library itself).  */
	struct library *lib2 = NULL;
	while ((lib2 = proc_each_library(proc, lib2, activate_latent_in,
					 lib->exported_names)) != NULL)
		fprintf(stderr,
			"Couldn't activate latent symbols for %s in %d: %s.\n",
			lib2->soname, proc->pid, strerror(errno));
}

int
proc_remove_library(struct process *proc, struct library *lib)
{
	struct library **libp;
	for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next)
		if (*libp == lib) {
			*libp = lib->next;
			return 0;
		}
	return -1;
}

struct library *
proc_each_library(struct process *proc, struct library *it,
		  enum callback_status (*cb)(struct process *proc,
					     struct library *lib, void *data),
		  void *data)
{
	if (it == NULL)
		it = proc->libraries;
	else
		it = it->next;

	while (it != NULL) {
		struct library *next = it->next;

		switch (cb(proc, it, data)) {
		case CBS_FAIL:
			/* XXX handle me */
		case CBS_STOP:
			return it;
		case CBS_CONT:
			break;
		}

		it = next;
	}

	return NULL;
}

static void
check_leader(struct process *proc)
{
	/* Only the group leader should be getting the breakpoints and
	 * thus have ->breakpoint initialized.  */
	assert(proc->leader != NULL);
	assert(proc->leader == proc);
	assert(proc->breakpoints != NULL);
}

int
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);
	check_leader(proc);

	/* XXX We might merge bp->libsym instead of the following
	 * assert, but that's not necessary right now.  Read the
	 * comment in breakpoint_for_symbol.  */
	assert(dict_find(proc->breakpoints, &bp->addr) == NULL);

	if (DICT_INSERT(proc->breakpoints, &bp->addr, &bp) < 0) {
		fprintf(stderr,
			"couldn't enter breakpoint %s@%p to dictionary: %s\n",
			breakpoint_name(bp), bp->addr, strerror(errno));
		return -1;
	}

	return 0;
}

void
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);
	check_leader(proc);
	int rc = DICT_ERASE(proc->breakpoints, &bp->addr, struct breakpoint *,
			    NULL, NULL, NULL);
	assert(rc == 0);
}

struct each_breakpoint_data
{
	struct process *proc;
	enum callback_status (*cb)(struct process *proc,
				   struct breakpoint *bp,
				   void *data);
	void *cb_data;
};

static enum callback_status
each_breakpoint_cb(arch_addr_t *key, struct breakpoint **bpp, void *d)
{
	struct each_breakpoint_data *data = d;
	return data->cb(data->proc, *bpp, data->cb_data);
}

arch_addr_t *
proc_each_breakpoint(struct process *proc, arch_addr_t *start,
		     enum callback_status (*cb)(struct process *proc,
						struct breakpoint *bp,
						void *data), void *data)
{
	struct each_breakpoint_data dd = {
		.proc = proc,
		.cb = cb,
		.cb_data = data,
	};
	return DICT_EACH(proc->breakpoints,
			 arch_addr_t, struct breakpoint *, start,
			 &each_breakpoint_cb, &dd);
}

int
proc_find_symbol(struct process *proc, struct library_symbol *sym,
		 struct library **retlib, struct library_symbol **retsym)
{
	struct library *lib = sym->lib;
	assert(lib != NULL);

	struct library *flib
		= proc_each_library(proc, NULL, library_with_key_cb, &lib->key);
	if (flib == NULL)
		return -1;

	struct library_symbol *fsym
		= library_each_symbol(flib, NULL, library_symbol_named_cb,
				      (char *)sym->name);
	if (fsym == NULL)
		return -1;

	if (retlib != NULL)
		*retlib = flib;
	if (retsym != NULL)
		*retsym = fsym;

	return 0;
}

struct library_symbol *
proc_each_symbol(struct process *proc, struct library_symbol *start_after,
		 enum callback_status (*cb)(struct library_symbol *, void *),
		 void *data)
{
	struct library *lib;
	for (lib = start_after != NULL ? start_after->lib : proc->libraries;
	     lib != NULL; lib = lib->next) {
		start_after = library_each_symbol(lib, start_after, cb, data);
		if (start_after != NULL)
			return 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_8, 8)
DEF_READER(proc_read_16, 16)
DEF_READER(proc_read_32, 32)
DEF_READER(proc_read_64, 64)

#undef DEF_READER
