summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs/demo_rdb/common/rdb.h
blob: 28bda1bdd12b3989a6bedef45645d197376165f1 (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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
 */
#ifndef _RDB_H
#define	_RDB_H

#include <rtld_db.h>
#include <sys/types.h>
#include <procfs.h>
#include <proc_service.h>
#include <libelf.h>
#include <gelf.h>

#include <rdb_mach.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Definitions from 2.7 sys/procfs_isa.h.
 */
#ifndef	PR_MODEL_LP64
#define	PR_MODEL_UNKNOWN 0
#define	PR_MODEL_ILP32	1	/* process data model is ILP32 */
#define	PR_MODEL_LP64	2	/* process data model is LP64 */
#endif

#define	INTERPSECT	".interp"
#define	PLTSECT		".plt"

/*
 * Flags for step_n routine
 */
typedef enum {
	FLG_SN_NONE = 0,
	FLG_SN_VERBOSE = (1 << 0),	/* disassemble instructions */
	FLG_SN_PLTSKIP = (1 << 1)	/* step *over* PLTS */
} sn_flags_e;


typedef	enum {
	RET_FAILED = -1,
	RET_OK = 0
} retc_t;

/*
 * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which
 * we wish to treat as a single logical symbol table. In this logical table,
 * the data from the auxiliary table precedes that from the primary. Symbol
 * indices start at [0], which is the first item in the auxiliary table
 * if there is one. The sole purpose for this is so that we can treat the
 * combination of .SUNW_ldynsym and .dynsym sections as a logically single
 * entity without having to violate the public interface to libelf.
 *
 * Both tables must share the same string table section.
 *
 * The symtab_getsym() function serves as a gelf_getsym() replacement
 * that is aware of the two tables and makes them look like a single table
 * to the caller.
 *
 */
typedef struct sym_tbl {
	Elf_Data	*st_syms_pri;	/* start of primary table */
	Elf_Data	*st_syms_aux;	/* start of auxiliary table */
	char		*st_strs;	/* ptr to strings */
	size_t		st_symn;	/* Total # of entries in both tables */
	size_t		st_symn_aux;	/* # of entries in auxiliary table */
} sym_tbl_t;

typedef struct	map_info {
	char			*mi_name;	/* file info */
	char			*mi_refname;	/* filter reference name */
	ulong_t			mi_addr;	/* start address */
	ulong_t			mi_end;		/* end address */
	int			mi_mapfd;	/* file desc. for mapping */
	size_t			mi_pltentsz;	/* size of PLT entries */
	Elf			*mi_elf;	/* elf handle so we can close */
	GElf_Ehdr		mi_ehdr;
	sym_tbl_t		mi_symtab;	/* symbol table */
	sym_tbl_t		mi_dynsym;	/* dynamic symbol table */
	Lmid_t			mi_lmident;	/* Link Map Ident */
	ulong_t			mi_pltbase;	/* PLT base address */
	ulong_t			mi_pltsize;	/* size of PLT table */
	struct map_info		*mi_next;
	ulong_t			mi_flags;	/* misc flags */
	rd_loadobj_t		mi_loadobj;	/* keep the old loadobj for */
						/* 	good luck */
} map_info_t;

#define	FLG_MI_EXEC		0x0001		/* is object an EXEC */

#define	FLG_PAP_SONAME		0x0001		/* embed SONAME in sym name */
#define	FLG_PAP_NOHEXNAME	0x0002		/* if no symbol return */
						/* null string */
#define	FLG_PAP_PLTDECOM	0x0004		/* decompe PLT name if */
						/* possible */
typedef struct map_list {
	map_info_t		*ml_head;
	map_info_t		*ml_tail;
} map_list_t;

/*
 * Break point information
 */
typedef struct bpt_struct {
	ulong_t			bl_addr;	/* address of breakpoint */
	bptinstr_t 		bl_instr;	/* original instruction */
	unsigned		bl_flags;	/* break point flags */
	struct bpt_struct	*bl_next;
} bptlist_t;

#define	FLG_BP_USERDEF		0x0001		/* user defined BP */
#define	FLG_BP_RDPREINIT	0x0002		/* PREINIT BreakPoint */
#define	FLG_BP_RDPOSTINIT	0x0004		/* POSTINIT BreakPoint */
#define	FLG_BP_RDDLACT		0x0008		/* DLACT BreakPoint */
#define	FLG_BP_PLTRES		0x0010		/* PLT Resolve BP */

#define	MASK_BP_SPECIAL \
		(FLG_BP_RDPREINIT | FLG_BP_RDPOSTINIT | FLG_BP_RDDLACT)
#define	MASK_BP_STOP \
		(FLG_BP_USERDEF | FLG_BP_PLTRES)
#define	MASK_BP_ALL \
		(MASK_BP_SPECIAL | FLG_BP_USERDEF)

/*
 * Proc Services Structure
 */
struct ps_prochandle {
	pid_t		pp_pid;		/* debug process pid */
	rd_agent_t	*pp_rap;	/* rtld_db handle */
	int		pp_ctlfd;	/* open ctl proc fd */
	int		pp_statusfd;	/* open status proc fd */
	int		pp_asfd;	/* open as proc fd */
	int		pp_mapfd;	/* open map proc fd */
	uintptr_t	pp_ldsobase;	/* ld.so.1 base address */
	uintptr_t	pp_execphdr;	/* a.out phdr address */
	map_info_t	pp_ldsomap;	/* ld.so.1 map info */
	map_info_t	pp_execmap;	/* exec map info */
	map_list_t	pp_lmaplist;	/* list of link map infos */
	bptlist_t	*pp_breakpoints; /* break point list */
	void		*pp_auxvp;	/* pointer to AUX vectors */
	int		pp_flags;	/* misc flags */
	int		pp_dmodel;	/* data model */
};

#define	FLG_PP_PROMPT	0x0001		/* display debugger prompt */
#define	FLG_PP_LMAPS	0x0002		/* link maps available */
#define	FLG_PP_PACT	0x0004		/* active process being traced */
#define	FLG_PP_PLTSKIP	0x0008		/* PLT skipping is active */

/*
 * Debugging Structure
 */
typedef struct rtld_debug {
	int		rd_vers;
	caddr_t		rd_preinit;
	caddr_t		rd_postinit;
} rtld_debug_t;

#define	TRAPBREAK	0x91d02001	/* ta	ST_BREAKPOINT */

/*
 * values for rdb_flags
 */
#define	RDB_FL_EVENTS	0x0001		/* enable printing event information */

/*
 * Globals
 */

extern struct ps_prochandle	proch;
extern unsigned long		rdb_flags;

/*
 * Functions
 */
extern map_info_t	*addr_to_map(struct ps_prochandle *, ulong_t);
extern retc_t		addr_to_sym(struct ps_prochandle *, ulong_t,
				GElf_Sym *, char **);
extern void		CallStack(struct ps_prochandle *ph);
extern unsigned		continue_to_break(struct ps_prochandle *);
extern retc_t		delete_all_breakpoints(struct ps_prochandle *);
extern retc_t		delete_breakpoint(struct ps_prochandle *, ulong_t,
				unsigned);
extern void		disasm(struct ps_prochandle *, int);
extern retc_t		disasm_addr(struct ps_prochandle *, ulong_t, int);
extern retc_t		display_all_regs(struct ps_prochandle *);
extern retc_t		display_maps(struct ps_prochandle *);
extern retc_t		display_linkmaps(struct ps_prochandle *);
extern void		free_linkmaps(struct ps_prochandle *);
extern retc_t		get_linkmaps(struct ps_prochandle *);
extern ulong_t		hexstr_to_num(const char *);
extern ulong_t		is_plt(struct ps_prochandle *, ulong_t);
extern void		list_breakpoints(struct ps_prochandle *);
extern retc_t		load_map(struct ps_prochandle *, caddr_t,
				map_info_t *mp);
extern char		*print_address(unsigned long);
extern char		*print_address_ps(struct ps_prochandle *,
				unsigned long, unsigned);
extern void		print_mem(struct ps_prochandle *, ulong_t, int,
				char *);
extern void		print_varstring(struct ps_prochandle *, const char *);
extern void		print_mach_varstring(struct ps_prochandle *,
				const char *);
extern void		rdb_help(const char *);
extern void		rdb_prompt();
extern void		perr(char *);
extern retc_t		proc_string_read(struct ps_prochandle *,
				ulong_t, char *, int);
extern retc_t		ps_close(struct ps_prochandle *);
extern retc_t		ps_init(int, int, pid_t, struct ps_prochandle *);
extern retc_t		set_breakpoint(struct ps_prochandle *, ulong_t,
				unsigned);
extern retc_t		set_objpad(struct ps_prochandle *, size_t);
extern retc_t		step_n(struct ps_prochandle *, size_t, sn_flags_e);
extern void		step_to_addr(struct ps_prochandle *, ulong_t);
extern retc_t		str_map_sym(const char *, map_info_t *, GElf_Sym *,
				char **);
extern map_info_t	*str_to_map(struct ps_prochandle *, const char *);
extern retc_t		str_to_sym(struct ps_prochandle *, const char *,
				GElf_Sym *);
extern int		yyparse(void);
extern int		yyerror(char *);
extern int		yylex(void);

#ifdef	__cplusplus
}
#endif

#endif /* _RDB_H */