Blame proc.h

Packit 0021fb
/*
Packit 0021fb
 * This file is part of ltrace.
Packit 0021fb
 * Copyright (C) 2010,2011,2012,2013 Petr Machata, Red Hat Inc.
Packit 0021fb
 * Copyright (C) 2010 Joe Damato
Packit 0021fb
 * Copyright (C) 1998,2001,2008,2009 Juan Cespedes
Packit 0021fb
 *
Packit 0021fb
 * This program is free software; you can redistribute it and/or
Packit 0021fb
 * modify it under the terms of the GNU General Public License as
Packit 0021fb
 * published by the Free Software Foundation; either version 2 of the
Packit 0021fb
 * License, or (at your option) any later version.
Packit 0021fb
 *
Packit 0021fb
 * This program is distributed in the hope that it will be useful, but
Packit 0021fb
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 0021fb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 0021fb
 * General Public License for more details.
Packit 0021fb
 *
Packit 0021fb
 * You should have received a copy of the GNU General Public License
Packit 0021fb
 * along with this program; if not, write to the Free Software
Packit 0021fb
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
Packit 0021fb
 * 02110-1301 USA
Packit 0021fb
 */
Packit 0021fb
Packit 0021fb
#ifndef _PROC_H_
Packit 0021fb
#define _PROC_H_
Packit 0021fb
Packit 0021fb
#include "config.h"
Packit 0021fb
Packit 0021fb
#include <sys/time.h>
Packit 0021fb
#include <stdint.h>
Packit 0021fb
Packit 0021fb
#if defined(HAVE_LIBUNWIND)
Packit 0021fb
# include <libunwind.h>
Packit 0021fb
#endif /* defined(HAVE_LIBUNWIND) */
Packit 0021fb
Packit 0021fb
#include "ltrace.h"
Packit 0021fb
#include "dict.h"
Packit 0021fb
#include "sysdep.h"
Packit 0021fb
#include "callback.h"
Packit 0021fb
#include "forward.h"
Packit 0021fb
Packit 0021fb
struct event_handler {
Packit 0021fb
	/* Event handler that overrides the default one.  Should
Packit 0021fb
	 * return NULL if the event was handled, otherwise the
Packit 0021fb
	 * returned event is passed to the default handler.  */
Packit 0021fb
	Event *(*on_event)(struct event_handler *self, Event *event);
Packit 0021fb
Packit 0021fb
	/* Called when the event handler removal is requested.  */
Packit 0021fb
	void (*destroy)(struct event_handler *self);
Packit 0021fb
};
Packit 0021fb
Packit 0021fb
enum process_state {
Packit 0021fb
	STATE_ATTACHED = 0,
Packit 0021fb
	STATE_BEING_CREATED,
Packit 0021fb
	STATE_IGNORED  /* ignore this process (it's a fork and no -f was used) */
Packit 0021fb
};
Packit 0021fb
Packit 0021fb
struct output_state {
Packit 0021fb
	size_t params_left;
Packit 0021fb
	int need_delim;
Packit 0021fb
};
Packit 0021fb
Packit 0021fb
struct callstack_element {
Packit 0021fb
	union {
Packit 0021fb
		int syscall;
Packit 0021fb
		struct library_symbol * libfunc;
Packit 0021fb
	} c_un;
Packit 0021fb
	int is_syscall;
Packit 0021fb
	arch_addr_t return_addr;
Packit 0021fb
	struct timeval time_spent;
Packit 0021fb
	struct fetch_context *fetch_context;
Packit 0021fb
	struct value_dict *arguments;
Packit 0021fb
	struct output_state out;
Packit 0021fb
};
Packit 0021fb
Packit 0021fb
/* XXX We should get rid of this.  */
Packit 0021fb
#define MAX_CALLDEPTH 64
Packit 0021fb
Packit 0021fb
/* XXX We would rather have this all organized a little differently,
Packit 0021fb
 * have struct process for the whole group and struct task (or struct
Packit 0021fb
 * lwp, struct thread) for what's there for per-thread stuff.  But for
Packit 0021fb
 * now this is the less invasive way of structuring it.  */
Packit 0021fb
struct process {
Packit 0021fb
	enum process_state state;
Packit 0021fb
	struct process *parent;         /* needed by STATE_BEING_CREATED */
Packit 0021fb
	char * filename;
Packit 0021fb
	pid_t pid;
Packit 0021fb
Packit 0021fb
	/* Dictionary of breakpoints (which is a mapping
Packit 0021fb
	 * address->breakpoint).  This is NULL for non-leader
Packit 0021fb
	 * processes.  */
Packit 0021fb
	struct dict *breakpoints;
Packit 0021fb
Packit 0021fb
	int mask_32bit;           /* 1 if 64-bit ltrace is tracing 32-bit process */
Packit 0021fb
	unsigned int personality;
Packit 0021fb
	int tracesysgood;         /* signal indicating a PTRACE_SYSCALL trap */
Packit 0021fb
Packit 0021fb
	size_t callstack_depth;
Packit 0021fb
	struct callstack_element callstack[MAX_CALLDEPTH];
Packit 0021fb
Packit 0021fb
	/* Linked list of libraries in backwards order of mapping.
Packit 0021fb
	 * The last element is the executed binary itself.  */
Packit 0021fb
	struct library *libraries;
Packit 0021fb
Packit 0021fb
	/* Arch-dependent: */
Packit 0021fb
	void * instruction_pointer;
Packit 0021fb
	void * stack_pointer;      /* To get return addr, args... */
Packit 0021fb
	void * arch_ptr;
Packit 0021fb
Packit 0021fb
	/* XXX We would like to replace this with a pointer to ABI
Packit 0021fb
	 * object that would provide the relevant services, instead of
Packit 0021fb
	 * checking the necessary flags in the back end ad
Packit 0021fb
	 * nauseam.  */
Packit 0021fb
	short e_machine;
Packit 0021fb
	char e_class;
Packit 0021fb
Packit 0021fb
#if defined(HAVE_LIBUNWIND)
Packit 0021fb
	/* libunwind address space */
Packit 0021fb
	unw_addr_space_t unwind_as;
Packit 0021fb
	void *unwind_priv;
Packit 0021fb
#endif /* defined(HAVE_LIBUNWIND) */
Packit 0021fb
Packit 0021fb
	/* Set in leader.  */
Packit 0021fb
	struct event_handler *event_handler;
Packit 0021fb
Packit 0021fb
	/**
Packit 0021fb
	 * Process chaining.
Packit 0021fb
	 **/
Packit 0021fb
	struct process *next;
Packit 0021fb
Packit 0021fb
	/* LEADER points to the leader thread of the POSIX.1 process.
Packit 0021fb
	   If X->LEADER == X, then X is the leader thread and the
Packit 0021fb
	   process structures chained by NEXT represent other threads,
Packit 0021fb
	   up until, but not including, the next leader thread.
Packit 0021fb
	   LEADER may be NULL after the leader has already exited.  In
Packit 0021fb
	   that case this process is waiting to be collected.  */
Packit 0021fb
	struct process *leader;
Packit 0021fb
Packit 0021fb
	struct os_process_data os;
Packit 0021fb
	struct arch_process_data arch;
Packit 0021fb
};
Packit 0021fb
Packit 0021fb
/* Initialize a process given a path to binary FILENAME, with a PID,
Packit 0021fb
 * and add the process to an internal chain of traced processes.  */
Packit 0021fb
int process_init(struct process *proc, const char *filename, pid_t pid);
Packit 0021fb
Packit 0021fb
/* PROC underwent an exec.  This is a bit like process_destroy
Packit 0021fb
 * followed by process_init, except that some state is kept and the
Packit 0021fb
 * process doesn't lose it's place in the list of processes.  */
Packit 0021fb
int process_exec(struct process *proc);
Packit 0021fb
Packit 0021fb
/* Release any memory allocated for PROC (but not PROC itself).  Does
Packit 0021fb
 * NOT remove PROC from internal chain.
Packit 0021fb
 *
Packit 0021fb
 * XXX clearly this init/destroy pair is different than others and
Packit 0021fb
 * should be fixed.  process_init should presumably be separate from
Packit 0021fb
 * process_add.  */
Packit 0021fb
void process_destroy(struct process *proc);
Packit 0021fb
Packit 0021fb
struct process *open_program(const char *filename, pid_t pid);
Packit 0021fb
void open_pid(pid_t pid);
Packit 0021fb
struct process *pid2proc(pid_t pid);
Packit 0021fb
Packit 0021fb
/* Clone the contents of PROC into the memory referenced by RETP.
Packit 0021fb
 * Returns 0 on success or a negative value on failure.  */
Packit 0021fb
int process_clone(struct process *retp, struct process *proc, pid_t pid);
Packit 0021fb
Packit 0021fb
/* Iterate through the processes that ltrace currently traces.  Tasks
Packit 0021fb
 * are considered to be processes for the purpose of this iterator.
Packit 0021fb
 * See callback.h for notes on iteration interfaces.  */
Packit 0021fb
struct process *each_process(struct process *start_after,
Packit 0021fb
			     enum callback_status (*cb)(struct process *proc,
Packit 0021fb
							void *data),
Packit 0021fb
			     void *data);
Packit 0021fb
Packit 0021fb
/* Iterate through list of tasks of given process PROC.  See
Packit 0021fb
 * callback.h for notes on iteration interfaces.  */
Packit 0021fb
struct process *each_task(struct process *proc, struct process *start_after,
Packit 0021fb
			  enum callback_status (*cb)(struct process *proc,
Packit 0021fb
						     void *data),
Packit 0021fb
			  void *data);
Packit 0021fb
Packit 0021fb
void change_process_leader(struct process *proc, struct process *leader);
Packit 0021fb
Packit 0021fb
/* Prepare those parts of process initialization that need to be done
Packit 0021fb
 * after _start is hit (i.e. after dynamic linking was done).  */
Packit 0021fb
void process_hit_start(struct process *proc);
Packit 0021fb
Packit 0021fb
/* Remove process from the list of traced processes, drop any events
Packit 0021fb
 * in the event queue, destroy it and free memory.  */
Packit 0021fb
void remove_process(struct process *proc);
Packit 0021fb
Packit 0021fb
void install_event_handler(struct process *proc, struct event_handler *handler);
Packit 0021fb
void destroy_event_handler(struct process *proc);
Packit 0021fb
Packit 0021fb
/* Add a library LIB to the list of PROC's libraries.  */
Packit 0021fb
void proc_add_library(struct process *proc, struct library *lib);
Packit 0021fb
Packit 0021fb
/* Remove LIB from list of PROC's libraries.  Returns 0 if the library
Packit 0021fb
 * was found and unlinked, otherwise returns a negative value.  */
Packit 0021fb
int proc_remove_library(struct process *proc, struct library *lib);
Packit 0021fb
Packit 0021fb
/* Clear a delayed flag.  If a symbol is neither latent, nor delayed,
Packit 0021fb
 * a breakpoint is inserted for it.  Returns 0 if the activation was
Packit 0021fb
 * successful or a negative value if it failed.  Note that if a symbol
Packit 0021fb
 * is both latent and delayed, this will not enable the corresponding
Packit 0021fb
 * breakpoint.  */
Packit 0021fb
int proc_activate_delayed_symbol(struct process *proc,
Packit 0021fb
				 struct library_symbol *libsym);
Packit 0021fb
Packit 0021fb
/* Iterate through the libraries of PROC.  See callback.h for notes on
Packit 0021fb
 * iteration interfaces.  */
Packit 0021fb
struct library *proc_each_library(struct process *proc,
Packit 0021fb
				  struct library *start_after,
Packit 0021fb
				  enum callback_status (*cb)(struct process *p,
Packit 0021fb
							     struct library *l,
Packit 0021fb
							     void *data),
Packit 0021fb
				  void *data);
Packit 0021fb
Packit 0021fb
/* Insert BP into PROC.  */
Packit 0021fb
int proc_add_breakpoint(struct process *proc, struct breakpoint *bp);
Packit 0021fb
Packit 0021fb
/* Remove BP from PROC.  This has no reason to fail in runtime.  If it
Packit 0021fb
 * does not find BP in PROC, it's hard error guarded by assertion.  */
Packit 0021fb
void proc_remove_breakpoint(struct process *proc, struct breakpoint *bp);
Packit 0021fb
Packit 0021fb
/* Iterate through the breakpoints of PROC.  See callback.h for notes
Packit 0021fb
 * on iteration interfaces.  */
Packit 0021fb
void *proc_each_breakpoint(struct process *proc, void *start,
Packit 0021fb
			   enum callback_status (*cb)(struct process *proc,
Packit 0021fb
						      struct breakpoint *bp,
Packit 0021fb
						      void *data),
Packit 0021fb
			   void *data);
Packit 0021fb
Packit 0021fb
/* Iterate through the dynamic section at src_addr looking for D_TAG.
Packit 0021fb
 * If tag is found, fill it's value in RET and return 0.
Packit 0021fb
 * If tag is not found, return a negative value.  */
Packit 0021fb
int proc_find_dynamic_entry_addr(struct process *proc, arch_addr_t src_addr,
Packit 0021fb
				 int d_tag, arch_addr_t *ret);
Packit 0021fb
Packit 0021fb
/* Finds a symbol corresponding to LIBSYM in a process PROC.  Returns
Packit 0021fb
 * 0 and sets *RETLIB and *RETSYM if the corresponding pointer is
Packit 0021fb
 * non-NULL.  Returns a negative value when the symbols couldn't be
Packit 0021fb
 * found.  */
Packit 0021fb
int proc_find_symbol(struct process *proc, struct library_symbol *sym,
Packit 0021fb
		     struct library **retlib, struct library_symbol **retsym);
Packit 0021fb
Packit 0021fb
/* Iterate through all symbols in all libraries of PROC.  See
Packit 0021fb
 * callback.h for notes on this interface.  */
Packit 0021fb
struct library_symbol *proc_each_symbol
Packit 0021fb
	(struct process *proc, struct library_symbol *start_after,
Packit 0021fb
	 enum callback_status (*cb)(struct library_symbol *, void *),
Packit 0021fb
	 void *data);
Packit 0021fb
Packit 0021fb
/* Read 8, 16, 32 or 64-bit quantity located at ADDR in PROC.  The
Packit 0021fb
 * resulting value is stored in *LP.  0 is returned on success or a
Packit 0021fb
 * negative value on failure.  This uses umovebytes under the hood
Packit 0021fb
 * (see backend.h).  */
Packit 0021fb
int proc_read_8(struct process *proc, arch_addr_t addr, uint8_t *lp);
Packit 0021fb
int proc_read_16(struct process *proc, arch_addr_t addr, uint16_t *lp);
Packit 0021fb
int proc_read_32(struct process *proc, arch_addr_t addr, uint32_t *lp);
Packit 0021fb
int proc_read_64(struct process *proc, arch_addr_t addr, uint64_t *lp);
Packit 0021fb
Packit 0021fb
#endif /* _PROC_H_ */