blob: a53bc8338f6e4c6a88b77dff2d67e6238ca69baf [file] [log] [blame]
Michael K. Edwardsef4428a2011-03-06 20:39:18 +00001#ifndef COMMON_H
2#define COMMON_H
3
Petr Machataa06eb812011-07-08 19:23:25 +02004#include <config.h>
Joe Damatoab3b72c2010-10-31 00:21:53 -07005#if defined(HAVE_LIBUNWIND)
6#include <libunwind.h>
7#endif /* defined(HAVE_LIBUNWIND) */
8
Juan Cespedes3df476b2009-05-28 19:17:17 +02009#include <sys/types.h>
10#include <sys/time.h>
11#include <stdio.h>
12
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020013#include "ltrace.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020014#include "defs.h"
15#include "dict.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020016#include "sysdep.h"
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020017#include "debug.h"
Marc Kleine-Budde747c73d2010-02-03 20:23:20 +010018#include "ltrace-elf.h"
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020019#include "read_config_file.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020020
21#if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
22# define USE_DEMANGLE
23#endif
24
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020025extern char * command;
Juan Cespedes3df476b2009-05-28 19:17:17 +020026
27extern int exiting; /* =1 if we have to exit ASAP */
28
29typedef struct Breakpoint Breakpoint;
30struct Breakpoint {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020031 void * addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +020032 unsigned char orig_value[BREAKPOINT_LENGTH];
33 int enabled;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020034 struct library_symbol * libsym;
Juan Cespedes3df476b2009-05-28 19:17:17 +020035#ifdef __arm__
36 int thumb_mode;
37#endif
38};
39
40enum arg_type {
41 ARGTYPE_UNKNOWN = -1,
42 ARGTYPE_VOID,
43 ARGTYPE_INT,
44 ARGTYPE_UINT,
45 ARGTYPE_LONG,
46 ARGTYPE_ULONG,
47 ARGTYPE_OCTAL,
48 ARGTYPE_CHAR,
49 ARGTYPE_SHORT,
50 ARGTYPE_USHORT,
51 ARGTYPE_FLOAT, /* float value, may require index */
52 ARGTYPE_DOUBLE, /* double value, may require index */
53 ARGTYPE_ADDR,
54 ARGTYPE_FILE,
55 ARGTYPE_FORMAT, /* printf-like format */
56 ARGTYPE_STRING, /* NUL-terminated string */
57 ARGTYPE_STRING_N, /* String of known maxlen */
58 ARGTYPE_ARRAY, /* Series of values in memory */
59 ARGTYPE_ENUM, /* Enumeration */
60 ARGTYPE_STRUCT, /* Structure of values */
61 ARGTYPE_POINTER, /* Pointer to some other type */
62 ARGTYPE_COUNT /* number of ARGTYPE_* values */
63};
64
65typedef struct arg_type_info_t {
66 enum arg_type type;
67 union {
68 /* ARGTYPE_ENUM */
69 struct {
70 size_t entries;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020071 char ** keys;
72 int * values;
Juan Cespedes3df476b2009-05-28 19:17:17 +020073 } enum_info;
74
75 /* ARGTYPE_ARRAY */
76 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020077 struct arg_type_info_t * elt_type;
Juan Cespedes3df476b2009-05-28 19:17:17 +020078 size_t elt_size;
79 int len_spec;
80 } array_info;
81
82 /* ARGTYPE_STRING_N */
83 struct {
84 int size_spec;
85 } string_n_info;
86
87 /* ARGTYPE_STRUCT */
88 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020089 struct arg_type_info_t ** fields; /* NULL-terminated */
90 size_t * offset;
Juan Cespedes3df476b2009-05-28 19:17:17 +020091 size_t size;
92 } struct_info;
93
94 /* ARGTYPE_POINTER */
95 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020096 struct arg_type_info_t * info;
Juan Cespedes3df476b2009-05-28 19:17:17 +020097 } ptr_info;
98
99 /* ARGTYPE_FLOAT */
100 struct {
101 size_t float_index;
102 } float_info;
103
104 /* ARGTYPE_DOUBLE */
105 struct {
106 size_t float_index;
107 } double_info;
108 } u;
109} arg_type_info;
110
111enum tof {
112 LT_TOF_NONE = 0,
113 LT_TOF_FUNCTION, /* A real library function */
114 LT_TOF_FUNCTIONR, /* Return from a real library function */
115 LT_TOF_SYSCALL, /* A syscall */
116 LT_TOF_SYSCALLR, /* Return from a syscall */
117 LT_TOF_STRUCT /* Not a function; read args from struct */
118};
119
120typedef struct Function Function;
121struct Function {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200122 const char * name;
123 arg_type_info * return_info;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200124 int num_params;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200125 arg_type_info * arg_info[MAX_ARGS];
Juan Cespedes3df476b2009-05-28 19:17:17 +0200126 int params_right;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200127 Function * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200128};
129
130enum toplt {
131 LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */
132 LS_TOPLT_EXEC, /* PLT for this symbol is executable. */
133 LS_TOPLT_POINT /* PLT for this symbol is a non-executable. */
134};
135
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200136extern Function * list_of_functions;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200137extern char *PLTs_initialized_by_here;
138
139struct library_symbol {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200140 char * name;
141 void * enter_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200142 char needs_init;
143 enum toplt plt_type;
144 char is_weak;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200145 struct library_symbol * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200146};
147
148struct callstack_element {
149 union {
150 int syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200151 struct library_symbol * libfunc;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200152 } c_un;
153 int is_syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200154 void * return_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200155 struct timeval time_spent;
Petr Machata211f0882010-11-03 18:42:18 +0100156 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200157};
158
159#define MAX_CALLDEPTH 64
160
161typedef enum Process_State Process_State;
162enum Process_State {
163 STATE_ATTACHED = 0,
164 STATE_BEING_CREATED,
165 STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */
166};
167
Petr Machata9a5420c2011-07-09 11:21:23 +0200168/* XXX We would rather have this all organized a little differently,
169 * have Process for the whole group and Task for what's there for
170 * per-thread stuff. But for now this is the less invasive way of
171 * structuring it. */
Juan Cespedes3df476b2009-05-28 19:17:17 +0200172struct Process {
173 Process_State state;
Juan Cespedes2a61d192009-07-04 11:29:27 +0200174 Process * parent; /* needed by STATE_BEING_CREATED */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200175 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200176 pid_t pid;
Petr Machata9a5420c2011-07-09 11:21:23 +0200177
178 /* Dictionary of breakpoints (which is a mapping
179 * address->Breakpoint). This is NULL for non-leader
180 * processes. */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200181 Dict * breakpoints;
Petr Machata9a5420c2011-07-09 11:21:23 +0200182
Juan Cespedes3df476b2009-05-28 19:17:17 +0200183 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
184 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
185 unsigned int personality;
186 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
187
188 int callstack_depth;
189 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200190 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200191
Joe Damatof0bd98b2010-11-08 15:47:42 -0800192 int libdl_hooked;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200193 /* Arch-dependent: */
Joe Damatof0bd98b2010-11-08 15:47:42 -0800194 void * debug; /* arch-dep process debug struct */
195 long debug_state; /* arch-dep debug state */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200196 void * instruction_pointer;
197 void * stack_pointer; /* To get return addr, args... */
198 void * return_addr;
199 Breakpoint * breakpoint_being_enabled;
200 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200201 short e_machine;
202 short need_to_reinitialize_breakpoints;
203#ifdef __arm__
204 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
205#endif
206
Joe Damatoab3b72c2010-10-31 00:21:53 -0700207#if defined(HAVE_LIBUNWIND)
208 /* libunwind address space */
209 unw_addr_space_t unwind_as;
210 void *unwind_priv;
211#endif /* defined(HAVE_LIBUNWIND) */
212
Petr Machata9a5420c2011-07-09 11:21:23 +0200213 /**
214 * Process chaining.
215 **/
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200216 Process * next;
Petr Machata9a5420c2011-07-09 11:21:23 +0200217
218 /* LEADER points to the leader thread of the POSIX.1 process.
219 If X->LEADER == X, then X is the leader thread and the
220 Process structures chained by NEXT represent other threads,
221 up until, but not including, the next leader thread.
222 LEADER may be NULL after the leader has already exited. In
223 that case this process is waiting to be collected. */
224 Process * leader;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200225};
226
Juan Cespedes3df476b2009-05-28 19:17:17 +0200227struct opt_c_struct {
228 int count;
229 struct timeval tv;
230};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200231
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200232#include "options.h"
233#include "output.h"
234#ifdef USE_DEMANGLE
235#include "demangle.h"
236#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200237
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200238extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200239
Petr Machatacebb8842011-07-09 11:14:11 +0200240enum pcb_status {
241 pcb_stop, /* The iteration should stop. */
242 pcb_cont, /* The iteration should continue. */
243};
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200244
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200245extern Event * next_event(void);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200246extern Process * pid2proc(pid_t pid);
Petr Machatacebb8842011-07-09 11:14:11 +0200247extern void add_process(Process * proc);
248extern void remove_process(Process * proc);
249extern Process *each_process(Process * start,
250 enum pcb_status (* cb)(Process * proc, void * data),
251 void * data);
Petr Machata9a5420c2011-07-09 11:21:23 +0200252extern Process *each_task(Process * start,
253 enum pcb_status (* cb)(Process * proc, void * data),
254 void * data);
255
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200256extern void handle_event(Event * event);
Petr Machata1b17dbf2011-07-08 19:22:52 +0200257extern pid_t execute_program(const char * command, char ** argv);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200258extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
259extern Breakpoint * address2bpstruct(Process * proc, void * addr);
Petr Machatac7585b62011-07-08 22:58:12 +0200260extern void breakpoints_init(Process * proc, int enable);
261extern void insert_breakpoint(Process * proc, void * addr,
262 struct library_symbol * libsym, int enable);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200263extern void delete_breakpoint(Process * proc, void * addr);
264extern void enable_all_breakpoints(Process * proc);
265extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200266extern void reinitialize_breakpoints(Process *);
267
Petr Machatac7585b62011-07-08 22:58:12 +0200268extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200269extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200270extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200271extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200272
Joe Damato7a2bdf82010-11-08 15:47:41 -0800273extern void do_init_elf(struct ltelf *lte, const char *filename);
274extern void do_close_elf(struct ltelf *lte);
275extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
276extern struct library_symbol *library_symbols;
277extern void add_library_symbol(GElf_Addr addr, const char *name,
278 struct library_symbol **library_symbolspp,
279 enum toplt type_of_plt, int is_weak);
280
Juan Cespedes3df476b2009-05-28 19:17:17 +0200281/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200282extern char * pid2name(pid_t pid);
Petr Machata9a5420c2011-07-09 11:21:23 +0200283extern pid_t process_leader(pid_t pid);
284extern int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
285extern int process_stopped(pid_t pid);
286extern char process_status(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200287extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200288extern void trace_me(void);
289extern int trace_pid(pid_t pid);
290extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200291extern void get_arch_dep(Process * proc);
292extern void * get_instruction_pointer(Process * proc);
293extern void set_instruction_pointer(Process * proc, void * addr);
294extern void * get_stack_pointer(Process * proc);
295extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200296extern void set_return_addr(Process * proc, void * addr);
Petr Machataf789c9c2011-07-09 10:54:27 +0200297extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
298extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200299extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200300extern void continue_process(pid_t pid);
301extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200302extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
Petr Machataf789c9c2011-07-09 10:54:27 +0200303extern void continue_enabling_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200304extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
305extern void save_register_args(enum tof type, Process * proc);
306extern int umovestr(Process * proc, void * addr, int len, void * laddr);
307extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
Joe Damatodfa3fa32010-11-08 15:47:35 -0800308extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200309extern int ffcheck(void * maddr);
310extern void * sym2addr(Process *, struct library_symbol *);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800311extern int linkmap_init(Process *, struct ltelf *);
312extern void arch_check_dbg(Process *proc);
Petr Machata9a5420c2011-07-09 11:21:23 +0200313extern int task_kill (pid_t pid, int sig);
314
Juan Cespedes3df476b2009-05-28 19:17:17 +0200315
Joe Damatof0bd98b2010-11-08 15:47:42 -0800316extern struct ltelf main_lte;
Michael K. Edwardsef4428a2011-03-06 20:39:18 +0000317
318#endif