blob: 2677ebf9549b4c370e14ff38ed5610a37e0c1b75 [file] [log] [blame]
#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;
#ifdef __arm__
int thumb_mode;
#endif
};
enum arg_type {
ARGTYPE_UNKNOWN = -1,
ARGTYPE_VOID,
ARGTYPE_INT,
ARGTYPE_UINT,
ARGTYPE_LONG,
ARGTYPE_ULONG,
ARGTYPE_OCTAL,
ARGTYPE_CHAR,
ARGTYPE_SHORT,
ARGTYPE_USHORT,
ARGTYPE_FLOAT, /* float value, may require index */
ARGTYPE_DOUBLE, /* double value, may require index */
ARGTYPE_ADDR,
ARGTYPE_FILE,
ARGTYPE_FORMAT, /* printf-like format */
ARGTYPE_STRING, /* NUL-terminated string */
ARGTYPE_STRING_N, /* String of known maxlen */
ARGTYPE_ARRAY, /* Series of values in memory */
ARGTYPE_ENUM, /* Enumeration */
ARGTYPE_STRUCT, /* Structure of values */
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_ARRAY
struct {
struct arg_type_info_t *elt_type;
size_t elt_size;
int len_spec;
} array_info;
// ARGTYPE_STRING_N
struct {
int size_spec;
} string_n_info;
// ARGTYPE_STRUCT
struct {
struct arg_type_info_t **fields; // NULL-terminated
size_t *offset;
size_t size;
} struct_info;
// ARGTYPE_POINTER
struct {
struct arg_type_info_t *info;
} ptr_info;
// ARGTYPE_FLOAT
struct {
size_t float_index;
} float_info;
// ARGTYPE_DOUBLE
struct {
size_t float_index;
} double_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 */
LT_TOF_STRUCT /* Not a function; read args from struct */
};
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;
#ifdef __arm__
int thumb_mode; /* ARM execution mode: 0: ARM mode, 1: Thumb mode */
#endif
/* output: */
enum tof type_being_displayed;
struct process *next;
};
struct event {
struct process *proc;
enum {
EVENT_NONE,
EVENT_SIGNAL,
EVENT_EXIT,
EVENT_EXIT_SIGNAL,
EVENT_SYSCALL,
EVENT_SYSRET,
EVENT_ARCH_SYSCALL,
EVENT_ARCH_SYSRET,
EVENT_FORK,
EVENT_EXEC,
EVENT_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 */
int newpid; /* _EV_FORK */
} 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 *next_event(void);
extern struct process * pid2proc(pid_t pid);
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_prototype(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 was_exec(struct process *proc, int status);
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, arg_type_info *info);
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, arg_type_info *info);
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