xref: /illumos-gate/usr/src/cmd/sgs/demo_rdb/common/rdb.h (revision 1a90c98d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 #ifndef _RDB_H
26 #define	_RDB_H
27 
28 #include <rtld_db.h>
29 #include <sys/types.h>
30 #include <procfs.h>
31 #include <proc_service.h>
32 #include <libelf.h>
33 #include <gelf.h>
34 
35 #include <rdb_mach.h>
36 
37 #ifdef	__cplusplus
38 extern "C" {
39 #endif
40 
41 /*
42  * Definitions from 2.7 sys/procfs_isa.h.
43  */
44 #ifndef	PR_MODEL_LP64
45 #define	PR_MODEL_UNKNOWN 0
46 #define	PR_MODEL_ILP32	1	/* process data model is ILP32 */
47 #define	PR_MODEL_LP64	2	/* process data model is LP64 */
48 #endif
49 
50 #define	INTERPSECT	".interp"
51 #define	PLTSECT		".plt"
52 
53 /*
54  * Flags for step_n routine
55  */
56 typedef enum {
57 	FLG_SN_NONE = 0,
58 	FLG_SN_VERBOSE = (1 << 0),	/* disassemble instructions */
59 	FLG_SN_PLTSKIP = (1 << 1)	/* step *over* PLTS */
60 } sn_flags_e;
61 
62 
63 typedef	enum {
64 	RET_FAILED = -1,
65 	RET_OK = 0
66 } retc_t;
67 
68 /*
69  * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which
70  * we wish to treat as a single logical symbol table. In this logical table,
71  * the data from the auxiliary table precedes that from the primary. Symbol
72  * indices start at [0], which is the first item in the auxiliary table
73  * if there is one. The sole purpose for this is so that we can treat the
74  * combination of .SUNW_ldynsym and .dynsym sections as a logically single
75  * entity without having to violate the public interface to libelf.
76  *
77  * Both tables must share the same string table section.
78  *
79  * The symtab_getsym() function serves as a gelf_getsym() replacement
80  * that is aware of the two tables and makes them look like a single table
81  * to the caller.
82  *
83  */
84 typedef struct sym_tbl {
85 	Elf_Data	*st_syms_pri;	/* start of primary table */
86 	Elf_Data	*st_syms_aux;	/* start of auxiliary table */
87 	char		*st_strs;	/* ptr to strings */
88 	size_t		st_symn;	/* Total # of entries in both tables */
89 	size_t		st_symn_aux;	/* # of entries in auxiliary table */
90 } sym_tbl_t;
91 
92 typedef struct	map_info {
93 	char			*mi_name;	/* file info */
94 	char			*mi_refname;	/* filter reference name */
95 	ulong_t			mi_addr;	/* start address */
96 	ulong_t			mi_end;		/* end address */
97 	int			mi_mapfd;	/* file desc. for mapping */
98 	size_t			mi_pltentsz;	/* size of PLT entries */
99 	Elf			*mi_elf;	/* elf handle so we can close */
100 	GElf_Ehdr		mi_ehdr;
101 	sym_tbl_t		mi_symtab;	/* symbol table */
102 	sym_tbl_t		mi_dynsym;	/* dynamic symbol table */
103 	Lmid_t			mi_lmident;	/* Link Map Ident */
104 	ulong_t			mi_pltbase;	/* PLT base address */
105 	ulong_t			mi_pltsize;	/* size of PLT table */
106 	struct map_info		*mi_next;
107 	ulong_t			mi_flags;	/* misc flags */
108 	rd_loadobj_t		mi_loadobj;	/* keep the old loadobj for */
109 						/*	good luck */
110 } map_info_t;
111 
112 #define	FLG_MI_EXEC		0x0001		/* is object an EXEC */
113 
114 #define	FLG_PAP_SONAME		0x0001		/* embed SONAME in sym name */
115 #define	FLG_PAP_NOHEXNAME	0x0002		/* if no symbol return */
116 						/* null string */
117 #define	FLG_PAP_PLTDECOM	0x0004		/* decompe PLT name if */
118 						/* possible */
119 typedef struct map_list {
120 	map_info_t		*ml_head;
121 	map_info_t		*ml_tail;
122 } map_list_t;
123 
124 /*
125  * Break point information
126  */
127 typedef struct bpt_struct {
128 	ulong_t			bl_addr;	/* address of breakpoint */
129 	bptinstr_t		bl_instr;	/* original instruction */
130 	unsigned		bl_flags;	/* break point flags */
131 	struct bpt_struct	*bl_next;
132 } bptlist_t;
133 
134 #define	FLG_BP_USERDEF		0x0001		/* user defined BP */
135 #define	FLG_BP_RDPREINIT	0x0002		/* PREINIT BreakPoint */
136 #define	FLG_BP_RDPOSTINIT	0x0004		/* POSTINIT BreakPoint */
137 #define	FLG_BP_RDDLACT		0x0008		/* DLACT BreakPoint */
138 #define	FLG_BP_PLTRES		0x0010		/* PLT Resolve BP */
139 
140 #define	MASK_BP_SPECIAL \
141 		(FLG_BP_RDPREINIT | FLG_BP_RDPOSTINIT | FLG_BP_RDDLACT)
142 #define	MASK_BP_STOP \
143 		(FLG_BP_USERDEF | FLG_BP_PLTRES)
144 #define	MASK_BP_ALL \
145 		(MASK_BP_SPECIAL | FLG_BP_USERDEF)
146 
147 /*
148  * Proc Services Structure
149  */
150 struct ps_prochandle {
151 	pid_t		pp_pid;		/* debug process pid */
152 	rd_agent_t	*pp_rap;	/* rtld_db handle */
153 	int		pp_ctlfd;	/* open ctl proc fd */
154 	int		pp_statusfd;	/* open status proc fd */
155 	int		pp_asfd;	/* open as proc fd */
156 	int		pp_mapfd;	/* open map proc fd */
157 	uintptr_t	pp_ldsobase;	/* ld.so.1 base address */
158 	uintptr_t	pp_execphdr;	/* a.out phdr address */
159 	map_info_t	pp_ldsomap;	/* ld.so.1 map info */
160 	map_info_t	pp_execmap;	/* exec map info */
161 	map_list_t	pp_lmaplist;	/* list of link map infos */
162 	bptlist_t	*pp_breakpoints; /* break point list */
163 	void		*pp_auxvp;	/* pointer to AUX vectors */
164 	int		pp_flags;	/* misc flags */
165 	int		pp_dmodel;	/* data model */
166 };
167 
168 #define	FLG_PP_PROMPT	0x0001		/* display debugger prompt */
169 #define	FLG_PP_LMAPS	0x0002		/* link maps available */
170 #define	FLG_PP_PACT	0x0004		/* active process being traced */
171 #define	FLG_PP_PLTSKIP	0x0008		/* PLT skipping is active */
172 
173 /*
174  * Debugging Structure
175  */
176 typedef struct rtld_debug {
177 	int		rd_vers;
178 	caddr_t		rd_preinit;
179 	caddr_t		rd_postinit;
180 } rtld_debug_t;
181 
182 #define	TRAPBREAK	0x91d02001	/* ta	ST_BREAKPOINT */
183 
184 /*
185  * values for rdb_flags
186  */
187 #define	RDB_FL_EVENTS	0x0001		/* enable printing event information */
188 
189 /*
190  * Globals
191  */
192 
193 extern struct ps_prochandle	proch;
194 extern unsigned long		rdb_flags;
195 
196 /*
197  * Functions
198  */
199 extern map_info_t	*addr_to_map(struct ps_prochandle *, ulong_t);
200 extern retc_t		addr_to_sym(struct ps_prochandle *, ulong_t,
201 				GElf_Sym *, char **);
202 extern void		CallStack(struct ps_prochandle *ph);
203 extern unsigned		continue_to_break(struct ps_prochandle *);
204 extern retc_t		delete_all_breakpoints(struct ps_prochandle *);
205 extern retc_t		delete_breakpoint(struct ps_prochandle *, ulong_t,
206 				unsigned);
207 extern void		disasm(struct ps_prochandle *, int);
208 extern retc_t		disasm_addr(struct ps_prochandle *, ulong_t, int);
209 extern retc_t		display_all_regs(struct ps_prochandle *);
210 extern retc_t		display_maps(struct ps_prochandle *);
211 extern retc_t		display_linkmaps(struct ps_prochandle *);
212 extern void		free_linkmaps(struct ps_prochandle *);
213 extern retc_t		get_linkmaps(struct ps_prochandle *);
214 extern ulong_t		hexstr_to_num(const char *);
215 extern ulong_t		is_plt(struct ps_prochandle *, ulong_t);
216 extern void		list_breakpoints(struct ps_prochandle *);
217 extern retc_t		load_map(struct ps_prochandle *, caddr_t,
218 				map_info_t *mp);
219 extern char		*print_address(unsigned long);
220 extern char		*print_address_ps(struct ps_prochandle *,
221 				unsigned long, unsigned);
222 extern void		print_mem(struct ps_prochandle *, ulong_t, int,
223 				char *);
224 extern void		print_varstring(struct ps_prochandle *, const char *);
225 extern void		print_mach_varstring(struct ps_prochandle *,
226 				const char *);
227 extern void		rdb_help(const char *);
228 extern void		rdb_prompt();
229 extern void		perr(char *);
230 extern retc_t		proc_string_read(struct ps_prochandle *,
231 				ulong_t, char *, int);
232 extern retc_t		ps_close(struct ps_prochandle *);
233 extern retc_t		ps_init(int, int, pid_t, struct ps_prochandle *);
234 extern retc_t		set_breakpoint(struct ps_prochandle *, ulong_t,
235 				unsigned);
236 extern retc_t		set_objpad(struct ps_prochandle *, size_t);
237 extern retc_t		step_n(struct ps_prochandle *, size_t, sn_flags_e);
238 extern void		step_to_addr(struct ps_prochandle *, ulong_t);
239 extern retc_t		str_map_sym(const char *, map_info_t *, GElf_Sym *,
240 				char **);
241 extern map_info_t	*str_to_map(struct ps_prochandle *, const char *);
242 extern retc_t		str_to_sym(struct ps_prochandle *, const char *,
243 				GElf_Sym *);
244 extern int		yyparse(void);
245 extern int		yyerror(const char *);
246 extern int		yylex(void);
247 
248 #ifdef	__cplusplus
249 }
250 #endif
251 
252 #endif /* _RDB_H */
253