blob: a83e49777f3ebd5d75166be76f79ded44493e12e [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 Machatacebb8842011-07-09 11:14:11 +0200254enum pcb_status {
255 pcb_stop, /* The iteration should stop. */
256 pcb_cont, /* The iteration should continue. */
257};
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200258
Petr Machata4007d742011-07-09 11:29:42 +0200259/* Process list */
Juan Cespedes3df476b2009-05-28 19:17:17 +0200260extern Process * pid2proc(pid_t pid);
Petr Machatacebb8842011-07-09 11:14:11 +0200261extern void add_process(Process * proc);
262extern void remove_process(Process * proc);
263extern Process *each_process(Process * start,
264 enum pcb_status (* cb)(Process * proc, void * data),
265 void * data);
Petr Machata9a5420c2011-07-09 11:21:23 +0200266extern Process *each_task(Process * start,
267 enum pcb_status (* cb)(Process * proc, void * data),
268 void * data);
269
Petr Machata69a03e62011-07-09 11:29:12 +0200270/* Events */
271enum ecb_status {
272 ecb_cont, /* The iteration should continue. */
273 ecb_yield, /* The iteration should stop, yielding this
274 * event. */
275 ecb_deque, /* Like ecb_stop, but the event should be removed
276 * from the queue. */
277};
278extern Event * next_event(void);
279extern Event * each_qd_event(enum ecb_status (* cb)(Event * event, void * data),
280 void * data);
281extern void enque_event(Event * event);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200282extern void handle_event(Event * event);
Petr Machata4007d742011-07-09 11:29:42 +0200283
284extern void install_event_handler(Process * proc, Event_Handler * handler);
285extern void destroy_event_handler(Process * proc);
286
Petr Machata1b17dbf2011-07-08 19:22:52 +0200287extern pid_t execute_program(const char * command, char ** argv);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200288extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
289extern Breakpoint * address2bpstruct(Process * proc, void * addr);
Petr Machatac7585b62011-07-08 22:58:12 +0200290extern void breakpoints_init(Process * proc, int enable);
291extern void insert_breakpoint(Process * proc, void * addr,
292 struct library_symbol * libsym, int enable);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200293extern void delete_breakpoint(Process * proc, void * addr);
294extern void enable_all_breakpoints(Process * proc);
295extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200296extern void reinitialize_breakpoints(Process *);
297
Petr Machatac7585b62011-07-08 22:58:12 +0200298extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200299extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200300extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200301extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200302
Joe Damato7a2bdf82010-11-08 15:47:41 -0800303extern void do_init_elf(struct ltelf *lte, const char *filename);
304extern void do_close_elf(struct ltelf *lte);
305extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
306extern struct library_symbol *library_symbols;
307extern void add_library_symbol(GElf_Addr addr, const char *name,
308 struct library_symbol **library_symbolspp,
309 enum toplt type_of_plt, int is_weak);
310
Juan Cespedes3df476b2009-05-28 19:17:17 +0200311/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200312extern char * pid2name(pid_t pid);
Petr Machata9a5420c2011-07-09 11:21:23 +0200313extern pid_t process_leader(pid_t pid);
314extern int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
315extern int process_stopped(pid_t pid);
316extern char process_status(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200317extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200318extern void trace_me(void);
319extern int trace_pid(pid_t pid);
320extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200321extern void get_arch_dep(Process * proc);
322extern void * get_instruction_pointer(Process * proc);
323extern void set_instruction_pointer(Process * proc, void * addr);
324extern void * get_stack_pointer(Process * proc);
325extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200326extern void set_return_addr(Process * proc, void * addr);
Petr Machataf789c9c2011-07-09 10:54:27 +0200327extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
328extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200329extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200330extern void continue_process(pid_t pid);
331extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200332extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
Petr Machata602330f2011-07-09 11:15:34 +0200333extern void ltrace_exiting(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200334extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
335extern void save_register_args(enum tof type, Process * proc);
336extern int umovestr(Process * proc, void * addr, int len, void * laddr);
337extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
Joe Damatodfa3fa32010-11-08 15:47:35 -0800338extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200339extern int ffcheck(void * maddr);
340extern void * sym2addr(Process *, struct library_symbol *);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800341extern int linkmap_init(Process *, struct ltelf *);
342extern void arch_check_dbg(Process *proc);
Petr Machata9a5420c2011-07-09 11:21:23 +0200343extern int task_kill (pid_t pid, int sig);
344
Juan Cespedes3df476b2009-05-28 19:17:17 +0200345
Joe Damatof0bd98b2010-11-08 15:47:42 -0800346extern struct ltelf main_lte;
Michael K. Edwardsef4428a2011-03-06 20:39:18 +0000347
348#endif