blob: 091bd1d420902bca907d116597627ac37bace9a3 [file] [log] [blame]
Juan Cespedes3df476b2009-05-28 19:17:17 +02001#include <sys/types.h>
2#include <sys/time.h>
3#include <stdio.h>
4
Juan Cespedes8d1b92b2009-07-03 10:39:34 +02005#include "ltrace.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +02006#include "defs.h"
7#include "dict.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +02008#include "sysdep.h"
Juan Cespedes8d1b92b2009-07-03 10:39:34 +02009#include "debug.h"
10#include "elf.h"
11#include "read_config_file.h"
Juan Cespedes3df476b2009-05-28 19:17:17 +020012
13#if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
14# define USE_DEMANGLE
15#endif
16
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020017extern char * command;
Juan Cespedes3df476b2009-05-28 19:17:17 +020018
19extern int exiting; /* =1 if we have to exit ASAP */
20
21typedef struct Breakpoint Breakpoint;
22struct Breakpoint {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020023 void * addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +020024 unsigned char orig_value[BREAKPOINT_LENGTH];
25 int enabled;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020026 struct library_symbol * libsym;
Juan Cespedes3df476b2009-05-28 19:17:17 +020027#ifdef __arm__
28 int thumb_mode;
29#endif
30};
31
32enum arg_type {
33 ARGTYPE_UNKNOWN = -1,
34 ARGTYPE_VOID,
35 ARGTYPE_INT,
36 ARGTYPE_UINT,
37 ARGTYPE_LONG,
38 ARGTYPE_ULONG,
39 ARGTYPE_OCTAL,
40 ARGTYPE_CHAR,
41 ARGTYPE_SHORT,
42 ARGTYPE_USHORT,
43 ARGTYPE_FLOAT, /* float value, may require index */
44 ARGTYPE_DOUBLE, /* double value, may require index */
45 ARGTYPE_ADDR,
46 ARGTYPE_FILE,
47 ARGTYPE_FORMAT, /* printf-like format */
48 ARGTYPE_STRING, /* NUL-terminated string */
49 ARGTYPE_STRING_N, /* String of known maxlen */
50 ARGTYPE_ARRAY, /* Series of values in memory */
51 ARGTYPE_ENUM, /* Enumeration */
52 ARGTYPE_STRUCT, /* Structure of values */
53 ARGTYPE_POINTER, /* Pointer to some other type */
54 ARGTYPE_COUNT /* number of ARGTYPE_* values */
55};
56
57typedef struct arg_type_info_t {
58 enum arg_type type;
59 union {
60 /* ARGTYPE_ENUM */
61 struct {
62 size_t entries;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020063 char ** keys;
64 int * values;
Juan Cespedes3df476b2009-05-28 19:17:17 +020065 } enum_info;
66
67 /* ARGTYPE_ARRAY */
68 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020069 struct arg_type_info_t * elt_type;
Juan Cespedes3df476b2009-05-28 19:17:17 +020070 size_t elt_size;
71 int len_spec;
72 } array_info;
73
74 /* ARGTYPE_STRING_N */
75 struct {
76 int size_spec;
77 } string_n_info;
78
79 /* ARGTYPE_STRUCT */
80 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020081 struct arg_type_info_t ** fields; /* NULL-terminated */
82 size_t * offset;
Juan Cespedes3df476b2009-05-28 19:17:17 +020083 size_t size;
84 } struct_info;
85
86 /* ARGTYPE_POINTER */
87 struct {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +020088 struct arg_type_info_t * info;
Juan Cespedes3df476b2009-05-28 19:17:17 +020089 } ptr_info;
90
91 /* ARGTYPE_FLOAT */
92 struct {
93 size_t float_index;
94 } float_info;
95
96 /* ARGTYPE_DOUBLE */
97 struct {
98 size_t float_index;
99 } double_info;
100 } u;
101} arg_type_info;
102
103enum tof {
104 LT_TOF_NONE = 0,
105 LT_TOF_FUNCTION, /* A real library function */
106 LT_TOF_FUNCTIONR, /* Return from a real library function */
107 LT_TOF_SYSCALL, /* A syscall */
108 LT_TOF_SYSCALLR, /* Return from a syscall */
109 LT_TOF_STRUCT /* Not a function; read args from struct */
110};
111
112typedef struct Function Function;
113struct Function {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200114 const char * name;
115 arg_type_info * return_info;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200116 int num_params;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200117 arg_type_info * arg_info[MAX_ARGS];
Juan Cespedes3df476b2009-05-28 19:17:17 +0200118 int params_right;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200119 Function * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200120};
121
122enum toplt {
123 LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */
124 LS_TOPLT_EXEC, /* PLT for this symbol is executable. */
125 LS_TOPLT_POINT /* PLT for this symbol is a non-executable. */
126};
127
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200128extern Function * list_of_functions;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200129extern char *PLTs_initialized_by_here;
130
131struct library_symbol {
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200132 char * name;
133 void * enter_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200134 char needs_init;
135 enum toplt plt_type;
136 char is_weak;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200137 struct library_symbol * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200138};
139
140struct callstack_element {
141 union {
142 int syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200143 struct library_symbol * libfunc;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200144 } c_un;
145 int is_syscall;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200146 void * return_addr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200147 struct timeval time_spent;
148};
149
150#define MAX_CALLDEPTH 64
151
152typedef enum Process_State Process_State;
153enum Process_State {
154 STATE_ATTACHED = 0,
155 STATE_BEING_CREATED,
156 STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */
157};
158
Juan Cespedes3df476b2009-05-28 19:17:17 +0200159struct Process {
160 Process_State state;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200161 Process * parent; /* needed by STATE_BEING_CREATED */
162 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200163 pid_t pid;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200164 Dict * breakpoints;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200165 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
166 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
167 unsigned int personality;
168 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
169
170 int callstack_depth;
171 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200172 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200173
174 /* Arch-dependent: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200175 void * instruction_pointer;
176 void * stack_pointer; /* To get return addr, args... */
177 void * return_addr;
178 Breakpoint * breakpoint_being_enabled;
179 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200180 short e_machine;
181 short need_to_reinitialize_breakpoints;
182#ifdef __arm__
183 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
184#endif
185
186 /* output: */
187 enum tof type_being_displayed;
188
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200189 Process * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200190};
191
Juan Cespedes3df476b2009-05-28 19:17:17 +0200192struct opt_c_struct {
193 int count;
194 struct timeval tv;
195};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200196
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200197#include "options.h"
198#include "output.h"
199#ifdef USE_DEMANGLE
200#include "demangle.h"
201#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200202
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200203extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200204
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200205extern Process * list_of_processes;
206
207extern void * instruction_pointer;
208
209extern Event * next_event(void);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200210extern Process * pid2proc(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200211extern void handle_event(Event * event);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200212extern void execute_program(Process *, char **);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200213extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
214extern Breakpoint * address2bpstruct(Process * proc, void * addr);
215extern void breakpoints_init(Process * proc);
216extern void insert_breakpoint(Process * proc, void * addr, struct library_symbol * libsym);
217extern void delete_breakpoint(Process * proc, void * addr);
218extern void enable_all_breakpoints(Process * proc);
219extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200220extern void reinitialize_breakpoints(Process *);
221
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200222extern Process * open_program(char * filename, pid_t pid);
223extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200224extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200225extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200226
227/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200228extern char * pid2name(pid_t pid);
229extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200230extern void trace_me(void);
231extern int trace_pid(pid_t pid);
232extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200233extern void get_arch_dep(Process * proc);
234extern void * get_instruction_pointer(Process * proc);
235extern void set_instruction_pointer(Process * proc, void * addr);
236extern void * get_stack_pointer(Process * proc);
237extern void * get_return_addr(Process * proc, void * stack_pointer);
238extern void enable_breakpoint(pid_t pid, Breakpoint * sbp);
239extern void disable_breakpoint(pid_t pid, const Breakpoint * sbp);
240extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200241extern void continue_process(pid_t pid);
242extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200243extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
244extern void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp);
245extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
246extern void save_register_args(enum tof type, Process * proc);
247extern int umovestr(Process * proc, void * addr, int len, void * laddr);
248extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
249extern int ffcheck(void * maddr);
250extern void * sym2addr(Process *, struct library_symbol *);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200251
252#if 0 /* not yet */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200253extern int umoven(Process * proc, void * addr, int len, void * laddr);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200254#endif