blob: 715898d6bb97a195b3825ae03994da7c1bdcceeb [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 Machata4007d742011-07-09 11:29:42 +0200168typedef struct Event_Handler Event_Handler;
169struct Event_Handler {
170 /* Event handler that overrides the default one. Should
171 * return NULL if the event was handled, otherwise the
172 * returned event is passed to the default handler. */
173 Event * (* on_event)(Event_Handler * self, Event * event);
174
175 /* Called when the event handler removal is requested. */
176 void (* destroy)(Event_Handler * self);
177};
178
Petr Machata9a5420c2011-07-09 11:21:23 +0200179/* XXX We would rather have this all organized a little differently,
180 * have Process for the whole group and Task for what's there for
181 * per-thread stuff. But for now this is the less invasive way of
182 * structuring it. */
Juan Cespedes3df476b2009-05-28 19:17:17 +0200183struct Process {
184 Process_State state;
Juan Cespedes2a61d192009-07-04 11:29:27 +0200185 Process * parent; /* needed by STATE_BEING_CREATED */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200186 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200187 pid_t pid;
Petr Machata9a5420c2011-07-09 11:21:23 +0200188
189 /* Dictionary of breakpoints (which is a mapping
190 * address->Breakpoint). This is NULL for non-leader
191 * processes. */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200192 Dict * breakpoints;
Petr Machata9a5420c2011-07-09 11:21:23 +0200193
Juan Cespedes3df476b2009-05-28 19:17:17 +0200194 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
195 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
196 unsigned int personality;
197 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
198
199 int callstack_depth;
200 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200201 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200202
Joe Damatof0bd98b2010-11-08 15:47:42 -0800203 int libdl_hooked;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200204 /* Arch-dependent: */
Joe Damatof0bd98b2010-11-08 15:47:42 -0800205 void * debug; /* arch-dep process debug struct */
206 long debug_state; /* arch-dep debug state */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200207 void * instruction_pointer;
208 void * stack_pointer; /* To get return addr, args... */
209 void * return_addr;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200210 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200211 short e_machine;
212 short need_to_reinitialize_breakpoints;
213#ifdef __arm__
214 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
215#endif
216
Joe Damatoab3b72c2010-10-31 00:21:53 -0700217#if defined(HAVE_LIBUNWIND)
218 /* libunwind address space */
219 unw_addr_space_t unwind_as;
220 void *unwind_priv;
221#endif /* defined(HAVE_LIBUNWIND) */
222
Petr Machata4007d742011-07-09 11:29:42 +0200223 /* Set in leader. */
224 Event_Handler * event_handler;
225
226
Petr Machata9a5420c2011-07-09 11:21:23 +0200227 /**
228 * Process chaining.
229 **/
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200230 Process * next;
Petr Machata9a5420c2011-07-09 11:21:23 +0200231
232 /* LEADER points to the leader thread of the POSIX.1 process.
233 If X->LEADER == X, then X is the leader thread and the
234 Process structures chained by NEXT represent other threads,
235 up until, but not including, the next leader thread.
236 LEADER may be NULL after the leader has already exited. In
237 that case this process is waiting to be collected. */
238 Process * leader;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200239};
240
Juan Cespedes3df476b2009-05-28 19:17:17 +0200241struct opt_c_struct {
242 int count;
243 struct timeval tv;
244};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200245
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200246#include "options.h"
247#include "output.h"
248#ifdef USE_DEMANGLE
249#include "demangle.h"
250#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200251
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200252extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200253
Petr Machata617ff0b2011-10-06 14:23:24 +0200254enum process_status {
255 ps_invalid, /* Failure. */
256 ps_stop, /* Job-control stop. */
257 ps_tracing_stop,
Petr Machatacbe29c62011-09-27 02:27:58 +0200258 ps_sleeping,
Petr Machata617ff0b2011-10-06 14:23:24 +0200259 ps_zombie,
260 ps_other, /* Necessary other states can be added as needed. */
261};
262
Petr Machatacebb8842011-07-09 11:14:11 +0200263enum pcb_status {
264 pcb_stop, /* The iteration should stop. */
265 pcb_cont, /* The iteration should continue. */
266};
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200267
Petr Machata4007d742011-07-09 11:29:42 +0200268/* Process list */
Juan Cespedes3df476b2009-05-28 19:17:17 +0200269extern Process * pid2proc(pid_t pid);
Petr Machatacebb8842011-07-09 11:14:11 +0200270extern void add_process(Process * proc);
271extern void remove_process(Process * proc);
Petr Machatacbe29c62011-09-27 02:27:58 +0200272extern void change_process_leader(Process * proc, Process * leader);
Petr Machatacebb8842011-07-09 11:14:11 +0200273extern Process *each_process(Process * start,
274 enum pcb_status (* cb)(Process * proc, void * data),
275 void * data);
Petr Machata9a5420c2011-07-09 11:21:23 +0200276extern Process *each_task(Process * start,
277 enum pcb_status (* cb)(Process * proc, void * data),
278 void * data);
279
Petr Machata69a03e62011-07-09 11:29:12 +0200280/* Events */
281enum ecb_status {
282 ecb_cont, /* The iteration should continue. */
283 ecb_yield, /* The iteration should stop, yielding this
284 * event. */
285 ecb_deque, /* Like ecb_stop, but the event should be removed
286 * from the queue. */
287};
288extern Event * next_event(void);
289extern Event * each_qd_event(enum ecb_status (* cb)(Event * event, void * data),
290 void * data);
291extern void enque_event(Event * event);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200292extern void handle_event(Event * event);
Petr Machata4007d742011-07-09 11:29:42 +0200293
294extern void install_event_handler(Process * proc, Event_Handler * handler);
295extern void destroy_event_handler(Process * proc);
296
Petr Machata1b17dbf2011-07-08 19:22:52 +0200297extern pid_t execute_program(const char * command, char ** argv);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200298extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
299extern Breakpoint * address2bpstruct(Process * proc, void * addr);
Petr Machata1974dbc2011-08-19 18:58:01 +0200300extern int breakpoints_init(Process * proc, int enable);
Petr Machatac7585b62011-07-08 22:58:12 +0200301extern void insert_breakpoint(Process * proc, void * addr,
302 struct library_symbol * libsym, int enable);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200303extern void delete_breakpoint(Process * proc, void * addr);
304extern void enable_all_breakpoints(Process * proc);
305extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200306extern void reinitialize_breakpoints(Process *);
307
Petr Machatac7585b62011-07-08 22:58:12 +0200308extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200309extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200310extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200311extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200312
Petr Machata1974dbc2011-08-19 18:58:01 +0200313extern int do_init_elf(struct ltelf *lte, const char *filename);
Joe Damato7a2bdf82010-11-08 15:47:41 -0800314extern void do_close_elf(struct ltelf *lte);
315extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
316extern struct library_symbol *library_symbols;
317extern void add_library_symbol(GElf_Addr addr, const char *name,
318 struct library_symbol **library_symbolspp,
319 enum toplt type_of_plt, int is_weak);
320
Petr Machata534e00f2011-09-27 17:58:38 +0200321extern struct library_symbol * clone_library_symbol(struct library_symbol * s);
322extern void destroy_library_symbol(struct library_symbol * s);
323extern void destroy_library_symbol_chain(struct library_symbol * chain);
324
Juan Cespedes3df476b2009-05-28 19:17:17 +0200325/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200326extern char * pid2name(pid_t pid);
Petr Machata9a5420c2011-07-09 11:21:23 +0200327extern pid_t process_leader(pid_t pid);
328extern int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
329extern int process_stopped(pid_t pid);
Petr Machata617ff0b2011-10-06 14:23:24 +0200330extern enum process_status process_status(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200331extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200332extern void trace_me(void);
333extern int trace_pid(pid_t pid);
334extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200335extern void get_arch_dep(Process * proc);
336extern void * get_instruction_pointer(Process * proc);
337extern void set_instruction_pointer(Process * proc, void * addr);
338extern void * get_stack_pointer(Process * proc);
339extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200340extern void set_return_addr(Process * proc, void * addr);
Petr Machataf789c9c2011-07-09 10:54:27 +0200341extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
342extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200343extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200344extern void continue_process(pid_t pid);
345extern void continue_after_signal(pid_t pid, int signum);
Petr Machata43d2fe52011-11-02 13:25:49 +0100346extern void continue_after_syscall(Process *proc, int sysnum, int ret_p);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200347extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
Petr Machatacbe29c62011-09-27 02:27:58 +0200348extern void continue_after_vfork(Process * proc);
Petr Machata602330f2011-07-09 11:15:34 +0200349extern void ltrace_exiting(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200350extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
351extern void save_register_args(enum tof type, Process * proc);
352extern int umovestr(Process * proc, void * addr, int len, void * laddr);
353extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
Joe Damatodfa3fa32010-11-08 15:47:35 -0800354extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200355extern int ffcheck(void * maddr);
356extern void * sym2addr(Process *, struct library_symbol *);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800357extern int linkmap_init(Process *, struct ltelf *);
358extern void arch_check_dbg(Process *proc);
Petr Machata9a5420c2011-07-09 11:21:23 +0200359extern int task_kill (pid_t pid, int sig);
360
Juan Cespedes3df476b2009-05-28 19:17:17 +0200361
Joe Damatof0bd98b2010-11-08 15:47:42 -0800362extern struct ltelf main_lte;
Michael K. Edwardsef4428a2011-03-06 20:39:18 +0000363
364#endif