blob: 20f1a96e07be740e77d556f6a9dfea7fce864ecb [file] [log] [blame]
Joe Damatoab3b72c2010-10-31 00:21:53 -07001#if defined(HAVE_LIBUNWIND)
2#include <libunwind.h>
3#endif /* defined(HAVE_LIBUNWIND) */
4
Juan Cespedes3df476b2009-05-28 19:17:17 +02005#include <sys/types.h>
6#include <sys/time.h>
7#include <stdio.h>
8
Juan Cespedes8d1b92b2009-07-03 10:39:34 +02009#include "ltrace.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020010#include "defs.h"
11#include "dict.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020012#include "sysdep.h"
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020013#include "debug.h"
Marc Kleine-Budde747c73d2010-02-03 20:23:20 +010014#include "ltrace-elf.h"
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020015#include "read_config_file.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020016
17#if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
18# define USE_DEMANGLE
19#endif
20
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020021extern char * command;
Juan Cespedes3df476b2009-05-28 19:17:17 +020022
23extern int exiting; /* =1 if we have to exit ASAP */
24
25typedef struct Breakpoint Breakpoint;
26struct Breakpoint {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020027 void * addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +020028 unsigned char orig_value[BREAKPOINT_LENGTH];
29 int enabled;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020030 struct library_symbol * libsym;
Juan Cespedes3df476b2009-05-28 19:17:17 +020031#ifdef __arm__
32 int thumb_mode;
33#endif
34};
35
36enum arg_type {
37 ARGTYPE_UNKNOWN = -1,
38 ARGTYPE_VOID,
39 ARGTYPE_INT,
40 ARGTYPE_UINT,
41 ARGTYPE_LONG,
42 ARGTYPE_ULONG,
43 ARGTYPE_OCTAL,
44 ARGTYPE_CHAR,
45 ARGTYPE_SHORT,
46 ARGTYPE_USHORT,
47 ARGTYPE_FLOAT, /* float value, may require index */
48 ARGTYPE_DOUBLE, /* double value, may require index */
49 ARGTYPE_ADDR,
50 ARGTYPE_FILE,
51 ARGTYPE_FORMAT, /* printf-like format */
52 ARGTYPE_STRING, /* NUL-terminated string */
53 ARGTYPE_STRING_N, /* String of known maxlen */
54 ARGTYPE_ARRAY, /* Series of values in memory */
55 ARGTYPE_ENUM, /* Enumeration */
56 ARGTYPE_STRUCT, /* Structure of values */
57 ARGTYPE_POINTER, /* Pointer to some other type */
58 ARGTYPE_COUNT /* number of ARGTYPE_* values */
59};
60
61typedef struct arg_type_info_t {
62 enum arg_type type;
63 union {
64 /* ARGTYPE_ENUM */
65 struct {
66 size_t entries;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020067 char ** keys;
68 int * values;
Juan Cespedes3df476b2009-05-28 19:17:17 +020069 } enum_info;
70
71 /* ARGTYPE_ARRAY */
72 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020073 struct arg_type_info_t * elt_type;
Juan Cespedes3df476b2009-05-28 19:17:17 +020074 size_t elt_size;
75 int len_spec;
76 } array_info;
77
78 /* ARGTYPE_STRING_N */
79 struct {
80 int size_spec;
81 } string_n_info;
82
83 /* ARGTYPE_STRUCT */
84 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020085 struct arg_type_info_t ** fields; /* NULL-terminated */
86 size_t * offset;
Juan Cespedes3df476b2009-05-28 19:17:17 +020087 size_t size;
88 } struct_info;
89
90 /* ARGTYPE_POINTER */
91 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020092 struct arg_type_info_t * info;
Juan Cespedes3df476b2009-05-28 19:17:17 +020093 } ptr_info;
94
95 /* ARGTYPE_FLOAT */
96 struct {
97 size_t float_index;
98 } float_info;
99
100 /* ARGTYPE_DOUBLE */
101 struct {
102 size_t float_index;
103 } double_info;
104 } u;
105} arg_type_info;
106
107enum tof {
108 LT_TOF_NONE = 0,
109 LT_TOF_FUNCTION, /* A real library function */
110 LT_TOF_FUNCTIONR, /* Return from a real library function */
111 LT_TOF_SYSCALL, /* A syscall */
112 LT_TOF_SYSCALLR, /* Return from a syscall */
113 LT_TOF_STRUCT /* Not a function; read args from struct */
114};
115
116typedef struct Function Function;
117struct Function {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200118 const char * name;
119 arg_type_info * return_info;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200120 int num_params;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200121 arg_type_info * arg_info[MAX_ARGS];
Juan Cespedes3df476b2009-05-28 19:17:17 +0200122 int params_right;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200123 Function * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200124};
125
126enum toplt {
127 LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */
128 LS_TOPLT_EXEC, /* PLT for this symbol is executable. */
129 LS_TOPLT_POINT /* PLT for this symbol is a non-executable. */
130};
131
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200132extern Function * list_of_functions;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200133extern char *PLTs_initialized_by_here;
134
135struct library_symbol {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200136 char * name;
137 void * enter_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200138 char needs_init;
139 enum toplt plt_type;
140 char is_weak;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200141 struct library_symbol * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200142};
143
144struct callstack_element {
145 union {
146 int syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200147 struct library_symbol * libfunc;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200148 } c_un;
149 int is_syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200150 void * return_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200151 struct timeval time_spent;
152};
153
154#define MAX_CALLDEPTH 64
155
156typedef enum Process_State Process_State;
157enum Process_State {
158 STATE_ATTACHED = 0,
159 STATE_BEING_CREATED,
160 STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */
161};
162
Juan Cespedes3df476b2009-05-28 19:17:17 +0200163struct Process {
164 Process_State state;
Juan Cespedes2a61d192009-07-04 11:29:27 +0200165 Process * parent; /* needed by STATE_BEING_CREATED */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200166 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200167 pid_t pid;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200168 Dict * breakpoints;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200169 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
170 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
171 unsigned int personality;
172 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
173
174 int callstack_depth;
175 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200176 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200177
178 /* Arch-dependent: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200179 void * instruction_pointer;
180 void * stack_pointer; /* To get return addr, args... */
181 void * return_addr;
182 Breakpoint * breakpoint_being_enabled;
183 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200184 short e_machine;
185 short need_to_reinitialize_breakpoints;
186#ifdef __arm__
187 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
188#endif
189
190 /* output: */
191 enum tof type_being_displayed;
192
Joe Damatoab3b72c2010-10-31 00:21:53 -0700193#if defined(HAVE_LIBUNWIND)
194 /* libunwind address space */
195 unw_addr_space_t unwind_as;
196 void *unwind_priv;
197#endif /* defined(HAVE_LIBUNWIND) */
198
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200199 Process * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200200};
201
Juan Cespedes3df476b2009-05-28 19:17:17 +0200202struct opt_c_struct {
203 int count;
204 struct timeval tv;
205};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200206
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200207#include "options.h"
208#include "output.h"
209#ifdef USE_DEMANGLE
210#include "demangle.h"
211#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200212
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200213extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200214
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200215extern Process * list_of_processes;
216
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200217extern Event * next_event(void);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200218extern Process * pid2proc(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200219extern void handle_event(Event * event);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200220extern void execute_program(Process *, char **);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200221extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
222extern Breakpoint * address2bpstruct(Process * proc, void * addr);
223extern void breakpoints_init(Process * proc);
224extern void insert_breakpoint(Process * proc, void * addr, struct library_symbol * libsym);
225extern void delete_breakpoint(Process * proc, void * addr);
226extern void enable_all_breakpoints(Process * proc);
227extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200228extern void reinitialize_breakpoints(Process *);
229
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200230extern Process * open_program(char * filename, pid_t pid);
231extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200232extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200233extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200234
235/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200236extern char * pid2name(pid_t pid);
237extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200238extern void trace_me(void);
239extern int trace_pid(pid_t pid);
240extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200241extern void get_arch_dep(Process * proc);
242extern void * get_instruction_pointer(Process * proc);
243extern void set_instruction_pointer(Process * proc, void * addr);
244extern void * get_stack_pointer(Process * proc);
245extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200246extern void set_return_addr(Process * proc, void * addr);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200247extern void enable_breakpoint(pid_t pid, Breakpoint * sbp);
248extern void disable_breakpoint(pid_t pid, const Breakpoint * sbp);
249extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200250extern void continue_process(pid_t pid);
251extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200252extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
253extern void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp);
254extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
255extern void save_register_args(enum tof type, Process * proc);
256extern int umovestr(Process * proc, void * addr, int len, void * laddr);
257extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
258extern int ffcheck(void * maddr);
259extern void * sym2addr(Process *, struct library_symbol *);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200260
261#if 0 /* not yet */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200262extern int umoven(Process * proc, void * addr, int len, void * laddr);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200263#endif