blob: f34a99d1be0e027ccb3bc4d1b4e1964aaff3669c [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
Juan Cespedes3df476b2009-05-28 19:17:17 +0200168struct Process {
169 Process_State state;
Juan Cespedes2a61d192009-07-04 11:29:27 +0200170 Process * parent; /* needed by STATE_BEING_CREATED */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200171 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200172 pid_t pid;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200173 Dict * breakpoints;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200174 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
175 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
176 unsigned int personality;
177 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
178
179 int callstack_depth;
180 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200181 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200182
Joe Damatof0bd98b2010-11-08 15:47:42 -0800183 int libdl_hooked;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200184 /* Arch-dependent: */
Joe Damatof0bd98b2010-11-08 15:47:42 -0800185 void * debug; /* arch-dep process debug struct */
186 long debug_state; /* arch-dep debug state */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200187 void * instruction_pointer;
188 void * stack_pointer; /* To get return addr, args... */
189 void * return_addr;
190 Breakpoint * breakpoint_being_enabled;
191 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200192 short e_machine;
193 short need_to_reinitialize_breakpoints;
194#ifdef __arm__
195 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
196#endif
197
Joe Damatoab3b72c2010-10-31 00:21:53 -0700198#if defined(HAVE_LIBUNWIND)
199 /* libunwind address space */
200 unw_addr_space_t unwind_as;
201 void *unwind_priv;
202#endif /* defined(HAVE_LIBUNWIND) */
203
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200204 Process * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200205};
206
Juan Cespedes3df476b2009-05-28 19:17:17 +0200207struct opt_c_struct {
208 int count;
209 struct timeval tv;
210};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200211
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200212#include "options.h"
213#include "output.h"
214#ifdef USE_DEMANGLE
215#include "demangle.h"
216#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200217
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200218extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200219
Petr Machatacebb8842011-07-09 11:14:11 +0200220enum pcb_status {
221 pcb_stop, /* The iteration should stop. */
222 pcb_cont, /* The iteration should continue. */
223};
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200224
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200225extern Event * next_event(void);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200226extern Process * pid2proc(pid_t pid);
Petr Machatacebb8842011-07-09 11:14:11 +0200227extern void add_process(Process * proc);
228extern void remove_process(Process * proc);
229extern Process *each_process(Process * start,
230 enum pcb_status (* cb)(Process * proc, void * data),
231 void * data);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200232extern void handle_event(Event * event);
Petr Machata1b17dbf2011-07-08 19:22:52 +0200233extern pid_t execute_program(const char * command, char ** argv);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200234extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
235extern Breakpoint * address2bpstruct(Process * proc, void * addr);
Petr Machatac7585b62011-07-08 22:58:12 +0200236extern void breakpoints_init(Process * proc, int enable);
237extern void insert_breakpoint(Process * proc, void * addr,
238 struct library_symbol * libsym, int enable);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200239extern void delete_breakpoint(Process * proc, void * addr);
240extern void enable_all_breakpoints(Process * proc);
241extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200242extern void reinitialize_breakpoints(Process *);
243
Petr Machatac7585b62011-07-08 22:58:12 +0200244extern Process * open_program(char * filename, pid_t pid, int init_breakpoints);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200245extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200246extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200247extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200248
Joe Damato7a2bdf82010-11-08 15:47:41 -0800249extern void do_init_elf(struct ltelf *lte, const char *filename);
250extern void do_close_elf(struct ltelf *lte);
251extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
252extern struct library_symbol *library_symbols;
253extern void add_library_symbol(GElf_Addr addr, const char *name,
254 struct library_symbol **library_symbolspp,
255 enum toplt type_of_plt, int is_weak);
256
Juan Cespedes3df476b2009-05-28 19:17:17 +0200257/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200258extern char * pid2name(pid_t pid);
259extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200260extern void trace_me(void);
261extern int trace_pid(pid_t pid);
262extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200263extern void get_arch_dep(Process * proc);
264extern void * get_instruction_pointer(Process * proc);
265extern void set_instruction_pointer(Process * proc, void * addr);
266extern void * get_stack_pointer(Process * proc);
267extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200268extern void set_return_addr(Process * proc, void * addr);
Petr Machataf789c9c2011-07-09 10:54:27 +0200269extern void enable_breakpoint(Process * proc, Breakpoint * sbp);
270extern void disable_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200271extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200272extern void continue_process(pid_t pid);
273extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200274extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
Petr Machataf789c9c2011-07-09 10:54:27 +0200275extern void continue_enabling_breakpoint(Process * proc, Breakpoint * sbp);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200276extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
277extern void save_register_args(enum tof type, Process * proc);
278extern int umovestr(Process * proc, void * addr, int len, void * laddr);
279extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
Joe Damatodfa3fa32010-11-08 15:47:35 -0800280extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200281extern int ffcheck(void * maddr);
282extern void * sym2addr(Process *, struct library_symbol *);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800283extern int linkmap_init(Process *, struct ltelf *);
284extern void arch_check_dbg(Process *proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200285
Joe Damatof0bd98b2010-11-08 15:47:42 -0800286extern struct ltelf main_lte;
Michael K. Edwardsef4428a2011-03-06 20:39:18 +0000287
288#endif