aboutsummaryrefslogtreecommitdiff
path: root/ltrace.h
blob: 3b40cb3c3d5d2802484fb0b1714e6ad3c78d6d10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#ifndef _HCK_LTRACE_H
#define _HCK_LTRACE_H

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>

#include "defs.h"
#include "dict.h"

/* BREAKPOINT_LENGTH is defined in "sysdep.h" */
#include "sysdep.h"

#define MAX_LIBRARY	30

#if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
# define USE_DEMANGLE
#endif

extern char *command;

extern int exiting;		/* =1 if we have to exit ASAP */

struct breakpoint {
	void *addr;
	unsigned char orig_value[BREAKPOINT_LENGTH];
	int enabled;
	struct library_symbol *libsym;
};

enum arg_type {
	ARGTYPE_UNKNOWN = -1,
	ARGTYPE_VOID,
	ARGTYPE_INT,
	ARGTYPE_UINT,
	ARGTYPE_LONG,
	ARGTYPE_ULONG,
	ARGTYPE_OCTAL,
	ARGTYPE_CHAR,
	ARGTYPE_ADDR,
	ARGTYPE_FILE,
	ARGTYPE_FORMAT,		/* printf-like format */
	ARGTYPE_STRING,		/* NUL-terminated string */
	ARGTYPE_STRING_N,	/* String of known maxlen */
        ARGTYPE_ENUM,		/* Enumeration */
        ARGTYPE_IGNORE,		/* Leave parameter blank */
        ARGTYPE_POINTER,	/* Pointer to some other type */
        ARGTYPE_COUNT		/* number of ARGTYPE_* values */
};

typedef struct arg_type_info_t {
    enum arg_type type;
    union {
	// ARGTYPE_ENUM
	struct {
	    size_t entries;
	    char **keys;
	    int *values;
	} enum_info;

	// ARGTYPE_STRING_N
	struct {
	    int size_spec;
	} string_n_info;

	// ARGTYPE_POINTER
	struct {
	    struct arg_type_info_t *info;
	} ptr_info;
    } u;
} arg_type_info;

enum tof {
	LT_TOF_NONE = 0,
	LT_TOF_FUNCTION,	/* A real library function */
	LT_TOF_FUNCTIONR,	/* Return from a real library function */
	LT_TOF_SYSCALL,		/* A syscall */
	LT_TOF_SYSCALLR		/* Return from a syscall */
};

struct function {
	const char *name;
	arg_type_info *return_info;
	int num_params;
	arg_type_info *arg_info[MAX_ARGS];
	int params_right;
	struct function *next;
};

enum toplt {
	LS_TOPLT_NONE = 0,	/* PLT not used for this symbol. */
	LS_TOPLT_EXEC,		/* PLT for this symbol is executable. */
	LS_TOPLT_POINT		/* PLT for this symbol is a non-executable. */
};


extern struct function *list_of_functions;
extern char *PLTs_initialized_by_here;

struct library_symbol {
	char *name;
	void *enter_addr;
	struct breakpoint *brkpnt;
	char needs_init;
	enum toplt plt_type;
	char is_weak;
	struct library_symbol *next;
};

struct callstack_element {
	union {
		int syscall;
		struct library_symbol *libfunc;
	} c_un;
	int is_syscall;
	void *return_addr;
	struct timeval time_spent;
};

#define MAX_CALLDEPTH 64

struct process {
	char *filename;
	pid_t pid;
	struct dict *breakpoints;
	int breakpoints_enabled;	/* -1:not enabled yet, 0:disabled, 1:enabled */
	int mask_32bit;		/* 1 if 64-bit ltrace is tracing 32-bit process.  */
	unsigned int personality;
	int tracesysgood;	/* signal indicating a PTRACE_SYSCALL trap */

	int callstack_depth;
	struct callstack_element callstack[MAX_CALLDEPTH];
	struct library_symbol *list_of_symbols;

	/* Arch-dependent: */
	void *instruction_pointer;
	void *stack_pointer;	/* To get return addr, args... */
	void *return_addr;
	struct breakpoint *breakpoint_being_enabled;
	void *arch_ptr;
	short e_machine;
	short need_to_reinitialize_breakpoints;

	/* output: */
	enum tof type_being_displayed;

	struct process *next;
};

struct event {
	struct process *proc;
	enum {
		LT_EV_UNKNOWN,
		LT_EV_NONE,
		LT_EV_SIGNAL,
		LT_EV_EXIT,
		LT_EV_EXIT_SIGNAL,
		LT_EV_SYSCALL,
		LT_EV_SYSRET,
		LT_EV_BREAKPOINT
	} thing;
	union {
		int ret_val;	/* _EV_EXIT */
		int signum;	/* _EV_SIGNAL, _EV_EXIT_SIGNAL */
		int sysnum;	/* _EV_SYSCALL, _EV_SYSRET */
		void *brk_addr;	/* _EV_BREAKPOINT */
	} e_un;
};

struct opt_c_struct {
	int count;
	struct timeval tv;
};
extern struct dict *dict_opt_c;

extern struct process *list_of_processes;

extern void *instruction_pointer;

extern struct event *wait_for_something(void);
extern void process_event(struct event *event);
extern void execute_program(struct process *, char **);
extern int display_arg(enum tof type, struct process *proc, int arg_num,
		       arg_type_info *info);
extern struct breakpoint *address2bpstruct(struct process *proc, void *addr);
extern void breakpoints_init(struct process *proc);
extern void insert_breakpoint(struct process *proc, void *addr,
			      struct library_symbol *libsym);
extern void delete_breakpoint(struct process *proc, void *addr);
extern void enable_all_breakpoints(struct process *proc);
extern void disable_all_breakpoints(struct process *proc);
extern void reinitialize_breakpoints(struct process *);

extern struct process *open_program(char *filename, pid_t pid);
extern void open_pid(pid_t pid, int verbose);
extern void show_summary(void);
extern arg_type_info *lookup_singleton(enum arg_type at);

/* Arch-dependent stuff: */
extern char *pid2name(pid_t pid);
extern void trace_set_options(struct process *proc, pid_t pid);
extern void trace_me(void);
extern int trace_pid(pid_t pid);
extern void untrace_pid(pid_t pid);
extern void get_arch_dep(struct process *proc);
extern void *get_instruction_pointer(struct process *proc);
extern void set_instruction_pointer(struct process *proc, void *addr);
extern void *get_stack_pointer(struct process *proc);
extern void *get_return_addr(struct process *proc, void *stack_pointer);
extern void enable_breakpoint(pid_t pid, struct breakpoint *sbp);
extern void disable_breakpoint(pid_t pid, const struct breakpoint *sbp);
extern int fork_p(struct process *proc, int sysnum);
extern int exec_p(struct process *proc, int sysnum);
extern int syscall_p(struct process *proc, int status, int *sysnum);
extern void continue_process(pid_t pid);
extern void continue_after_signal(pid_t pid, int signum);
extern void continue_after_breakpoint(struct process *proc,
				      struct breakpoint *sbp);
extern void continue_enabling_breakpoint(pid_t pid, struct breakpoint *sbp);
extern long gimme_arg(enum tof type, struct process *proc, int arg_num);
extern void save_register_args(enum tof type, struct process *proc);
extern int umovestr(struct process *proc, void *addr, int len, void *laddr);
extern int umovelong(struct process *proc, void *addr, long *result);
extern int ffcheck(void *maddr);
extern void *sym2addr(struct process *, struct library_symbol *);

#if 0				/* not yet */
extern int umoven(struct process *proc, void *addr, int len, void *laddr);
#endif

#endif