blob: 753d3dc758778643a7c0a8e200eca03d492bd317 [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;
Petr Machata211f0882010-11-03 18:42:18 +0100152 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200153};
154
155#define MAX_CALLDEPTH 64
156
157typedef enum Process_State Process_State;
158enum Process_State {
159 STATE_ATTACHED = 0,
160 STATE_BEING_CREATED,
161 STATE_IGNORED /* ignore this process (it's a fork and no -f was used) */
162};
163
Juan Cespedes3df476b2009-05-28 19:17:17 +0200164struct Process {
165 Process_State state;
Juan Cespedes2a61d192009-07-04 11:29:27 +0200166 Process * parent; /* needed by STATE_BEING_CREATED */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200167 char * filename;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200168 pid_t pid;
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200169 Dict * breakpoints;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200170 int breakpoints_enabled; /* -1:not enabled yet, 0:disabled, 1:enabled */
171 int mask_32bit; /* 1 if 64-bit ltrace is tracing 32-bit process */
172 unsigned int personality;
173 int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
174
175 int callstack_depth;
176 struct callstack_element callstack[MAX_CALLDEPTH];
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200177 struct library_symbol * list_of_symbols;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200178
179 /* Arch-dependent: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200180 void * instruction_pointer;
181 void * stack_pointer; /* To get return addr, args... */
182 void * return_addr;
183 Breakpoint * breakpoint_being_enabled;
184 void * arch_ptr;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200185 short e_machine;
186 short need_to_reinitialize_breakpoints;
187#ifdef __arm__
188 int thumb_mode; /* ARM execution mode: 0: ARM, 1: Thumb */
189#endif
190
191 /* output: */
192 enum tof type_being_displayed;
193
Joe Damatoab3b72c2010-10-31 00:21:53 -0700194#if defined(HAVE_LIBUNWIND)
195 /* libunwind address space */
196 unw_addr_space_t unwind_as;
197 void *unwind_priv;
198#endif /* defined(HAVE_LIBUNWIND) */
199
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200200 Process * next;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200201};
202
Juan Cespedes3df476b2009-05-28 19:17:17 +0200203struct opt_c_struct {
204 int count;
205 struct timeval tv;
206};
Juan Cespedes3df476b2009-05-28 19:17:17 +0200207
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200208#include "options.h"
209#include "output.h"
210#ifdef USE_DEMANGLE
211#include "demangle.h"
212#endif
Juan Cespedes3df476b2009-05-28 19:17:17 +0200213
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200214extern Dict * dict_opt_c;
Juan Cespedes3df476b2009-05-28 19:17:17 +0200215
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200216extern Process * list_of_processes;
217
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200218extern Event * next_event(void);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200219extern Process * pid2proc(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200220extern void handle_event(Event * event);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200221extern void execute_program(Process *, char **);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200222extern int display_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
223extern Breakpoint * address2bpstruct(Process * proc, void * addr);
224extern void breakpoints_init(Process * proc);
225extern void insert_breakpoint(Process * proc, void * addr, struct library_symbol * libsym);
226extern void delete_breakpoint(Process * proc, void * addr);
227extern void enable_all_breakpoints(Process * proc);
228extern void disable_all_breakpoints(Process * proc);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200229extern void reinitialize_breakpoints(Process *);
230
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200231extern Process * open_program(char * filename, pid_t pid);
232extern void open_pid(pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200233extern void show_summary(void);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200234extern arg_type_info * lookup_prototype(enum arg_type at);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200235
236/* Arch-dependent stuff: */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200237extern char * pid2name(pid_t pid);
238extern void trace_set_options(Process * proc, pid_t pid);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200239extern void trace_me(void);
240extern int trace_pid(pid_t pid);
241extern void untrace_pid(pid_t pid);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200242extern void get_arch_dep(Process * proc);
243extern void * get_instruction_pointer(Process * proc);
244extern void set_instruction_pointer(Process * proc, void * addr);
245extern void * get_stack_pointer(Process * proc);
246extern void * get_return_addr(Process * proc, void * stack_pointer);
Juan Cespedes2a61d192009-07-04 11:29:27 +0200247extern void set_return_addr(Process * proc, void * addr);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200248extern void enable_breakpoint(pid_t pid, Breakpoint * sbp);
249extern void disable_breakpoint(pid_t pid, const Breakpoint * sbp);
250extern int syscall_p(Process * proc, int status, int * sysnum);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200251extern void continue_process(pid_t pid);
252extern void continue_after_signal(pid_t pid, int signum);
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200253extern void continue_after_breakpoint(Process * proc, Breakpoint * sbp);
254extern void continue_enabling_breakpoint(pid_t pid, Breakpoint * sbp);
255extern long gimme_arg(enum tof type, Process * proc, int arg_num, arg_type_info * info);
256extern void save_register_args(enum tof type, Process * proc);
257extern int umovestr(Process * proc, void * addr, int len, void * laddr);
258extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
259extern int ffcheck(void * maddr);
260extern void * sym2addr(Process *, struct library_symbol *);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200261
262#if 0 /* not yet */
Juan Cespedes8d1b92b2009-07-03 10:39:34 +0200263extern int umoven(Process * proc, void * addr, int len, void * laddr);
Juan Cespedes3df476b2009-05-28 19:17:17 +0200264#endif