blob: ab2465e8d23b8753fbbb0006b99b7eaccdaf9e52 [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 Cespedes3df476b2009-05-28 19:17:17 +0200245extern Process * pid2proc(pid_t pid);
Petr Machatacebb8842011-07-09 11:14:11 +0200246extern void add_process(Process * proc);
247extern void remove_process(Process * proc);
248extern Process *each_process(Process * start,
249 enum pcb_status (* cb)(Process * proc, void * data),
250 void * data);
Petr Machata9a5420c2011-07-09 11:21:23 +0200251extern Process *each_task(Process * start,
252 enum pcb_status (* cb)(Process * proc, void * data),
253 void * data);
254
Petr Machata69a03e62011-07-09 11:29:12 +0200255/* Events */
256enum ecb_status {
257 ecb_cont, /* The iteration should continue. */
258 ecb_yield, /* The iteration should stop, yielding this
259 * event. */
260 ecb_deque, /* Like ecb_stop, but the event should be removed
261 * from the queue. */
262};
263extern Event * next_event(void);
264extern Event * each_qd_event(enum ecb_status (* cb)(Event * event, void * data),
265 void * data);
266extern void enque_event(Event * event);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200267extern void handle_event(Event * event);
Petr Machata1b17dbf2011-07-08 19:22:52 +0200268extern pid_t execute_program(const char * command, char ** argv);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200269extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
270extern Breakpoint * address2bpstruct(Process * proc, void * addr);
Petr Machatac7585b62011-07-08 22:58:12 +0200271extern void breakpoints_init(Process * proc, int enable);
272extern void insert_breakpoint(Process * proc, void * addr,
273 struct library_symbol * libsym, int enable);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200274extern void delete_breakpoint(Process * proc, void * addr);
275extern void enable_all_breakpoints(Process * proc);
276extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200277extern void reinitialize_breakpoints(Process *);
278
Petr Machatac7585b62011-07-08 22:58:12 +0200279extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200280extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200281extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200282extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200283
Joe Damato7a2bdf82010-11-08 15:47:41 -0800284extern void do_init_elf(struct ltelf *lte, const char *filename);
285extern void do_close_elf(struct ltelf *lte);
286extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
287extern struct library_symbol *library_symbols;
288extern void add_library_symbol(GElf_Addr addr, const char *name,
289 struct library_symbol **library_symbolspp,
290 enum toplt type_of_plt, int is_weak);
291
Juan Cespedes3df476b2009-05-28 19:17:17 +0200292/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200293extern char * pid2name(pid_t pid);
Petr Machata9a5420c2011-07-09 11:21:23 +0200294extern pid_t process_leader(pid_t pid);
295extern int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
296extern int process_stopped(pid_t pid);
297extern char process_status(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200298extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200299extern void trace_me(void);
300extern int trace_pid(pid_t pid);
301extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200302extern void get_arch_dep(Process * proc);
303extern void * get_instruction_pointer(Process * proc);
304extern void set_instruction_pointer(Process * proc, void * addr);
305extern void * get_stack_pointer(Process * proc);
306extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200307extern void set_return_addr(Process * proc, void * addr);
Petr Machataf789c9c2011-07-09 10:54:27 +0200308extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
309extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200310extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200311extern void continue_process(pid_t pid);
312extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200313extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
Petr Machataf789c9c2011-07-09 10:54:27 +0200314extern void continue_enabling_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200315extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
316extern void save_register_args(enum tof type, Process * proc);
317extern int umovestr(Process * proc, void * addr, int len, void * laddr);
318extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
Joe Damatodfa3fa32010-11-08 15:47:35 -0800319extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200320extern int ffcheck(void * maddr);
321extern void * sym2addr(Process *, struct library_symbol *);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800322extern int linkmap_init(Process *, struct ltelf *);
323extern void arch_check_dbg(Process *proc);
Petr Machata9a5420c2011-07-09 11:21:23 +0200324extern int task_kill (pid_t pid, int sig);
325
Juan Cespedes3df476b2009-05-28 19:17:17 +0200326
Joe Damatof0bd98b2010-11-08 15:47:42 -0800327extern struct ltelf main_lte;
Michael K. Edwardsef4428a2011-03-06 20:39:18 +0000328
329#endif