summaryrefslogtreecommitdiff
path: root/usr/src/cmd/sgs/elfedit/common/_elfedit.h
blob: 57f7dc1c9eae003031cea1a9ee884aa57c5a10e8 (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
253
254
255
256
257
258
259
260
261
262
263
/*
 * 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 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	__ELFEDIT_H
#define	__ELFEDIT_H

#include	<setjmp.h>
#include	<libtecla.h>
#include	<elfedit.h>

/*
 * Local include file for elfedit.
 */
#ifdef	__cplusplus
extern "C" {
#endif


/*
 * Maximum command line, and history
 */
#define	ELFEDIT_MAXCMD	1024
#define	ELFEDIT_MAXHIST	1024

/* Maximum number of command completion arguments */
#define	ELFEDIT_MAXCPLARGS	128

/* Maximum length of a module name */
#define	ELFEDIT_MAXMODNAM	64


/*
 * In elfedit.h, you will find elfedit32_cmd_t and elfedit64_cmd_t
 * typedefs. These types are identical, except for the definition
 * of the cmd_func and cmd_cplfunc function pointers. These function
 * pointers have different argument definitions that reflect the
 * different object state definition blocks for the 32 and 64-bit cases.
 * Yet, From a strictly machine based view, these two types are identical
 * in size and layout:
 *
 *	- At the machine level, all function pointers are simply
 *		machine sized words containing an address.
 *
 *	- Other than the function pointers, the remaining fields
 *		are exactly the same in both cases.
 *
 * The vast majority of elfedit's internals that examine elfedit_cmd_t
 * are looking at the non-function pointer fields. It simplfiies
 * a great deal of code if we can treat elfedit32_cmd_t and elfedit64_cmd_t
 * as equivalent types for this purpose. In C++, we would do this with
 * a superclass. In C, we do it by defining another variant named
 * elfeditGC_cmd_t (GC stands for "Generic Class"). The function pointers
 * are replaced with (void *) pointers. This variant has the same size
 * and layout as the others. We use it internally to represent either type.
 * In the cases where we need to use the function pointers, we first cast
 * them to the proper type for the ELFCLASS being processed.
 *
 * The existance of elfeditGC_cmd_t implies the need for elfeditGC_module_t,
 * for the same reasons.
 *
 * It is extremely important that these definitions exactly mirror the
 * definitions in elfedit.h.
 */
typedef struct {
	void			*cmd_func;
	void			*cmd_cplfunc;
	const char		**cmd_name;
	elfedit_i18nhdl_t	cmd_desc;
	elfedit_i18nhdl_t	cmd_help;
	elfedit_cmd_optarg_t	*cmd_opt;
	elfedit_cmd_optarg_t	*cmd_args;
} elfeditGC_cmd_t;


typedef struct {
	elfedit_module_version_t mod_version;
	const char		*mod_name;
	elfedit_i18nhdl_t	mod_desc;
	elfeditGC_cmd_t		*mod_cmds;
	elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str;
} elfeditGC_module_t;


/*
 * The result of parsing a user command is one of these blocks entered
 * at the end of state.user_cmd. They encapsulate the arguments and
 * the command function to call. In combination with an elfedit_obj_state_t,
 * they contain everything needed to execute a specified operation. A single
 * call to free() suffices to release the ELFEDIT_USER_CMD and any memory
 * it references.
 */
typedef struct user_cmd_t {
	struct user_cmd_t *ucmd_next;	/* Commands are kept in linked list */
	int		ucmd_argc;	/* # of arguments to command */
	const char	**ucmd_argv;	/* Argument strings */
	char		*ucmd_orig_str;	/* Command string as entered by user */
	elfeditGC_module_t *ucmd_mod;	/* Module defining command */
	elfeditGC_cmd_t	*ucmd_cmd;	/* Command to call */
	int		ucmd_ostyle_set;	/* True if there is a per-cmd */
						/* 	output style active */
	elfedit_outstyle_t ucmd_ostyle; /* Per-cmd output style, if active */
} USER_CMD_T;

/*
 * MODLIST_T is used to manage module definitions. Note that a simple linked
 * list is used to maintain the set of active modules. This can be easily
 * changed if the number of modules grows to a point where the lookup
 * time is noticible.
 */
typedef struct moddef_t {
	struct moddef_t		*ml_next;	/* Used for list of open mods */
	elfeditGC_module_t	*ml_mod;	/* The module definition */
	void			*ml_dl_hdl;	/* dlopen() handle for lib */
	const char		*ml_path;	/* Path used to open lib */
} MODLIST_T;


/*
 * Type of the global variable used to maintain elfedit state.
 */
typedef struct {
	MODLIST_T *modlist;		/* List of loaded commands */
	elfedit_flag_t	flags;		/* ELFEDIT_F_ command line options */
	elfedit_outstyle_t outstyle;	/* Output style */
	struct {
		int present;		/* True if there is a source file. */
					/*	 False otherwise */
		/*
		 * The remaining file fields are not to be accessed
		 * unless present is True.
		 */
		const char *infile;	/* Name of source file */
		const char *outfile;	/* Name of file being edited */
		int unlink_on_exit;	/* TRUE to unlink outfile on exit  */
		int dirty;		/* TRUE if outfile needs to be saved */
	} file;
	struct {		/* Jump buffer used for ELFEDIT_MSG_ERR */
		int active;	/*	True if MSG_ERR jumps to outer loop */
		sigjmp_buf env;	/*	jump environment buffer */
	} msg_jbuf;
	struct {			/* Search path used to find modules */
		size_t n;		/*	# of path segments */
		const char **seg;	/*	path segments */
	} modpath;
	struct {		/* Linked list of user commands to execute */
		size_t n;		/* # of commands */
		USER_CMD_T *list;	/* head of list */
		USER_CMD_T *tail;	/* points at last element of list */
	} ucmd;
	struct {			/* Pager related state */
		FILE *fptr;		/* Output file */
	} pager;
	struct {
		int	is_tty;		/* True in stdin is a tty */
		int	full_tty;	/* True if stdin and stdout are tty */
		int	in_tecla;	/* gl_get_line() is active */
		GetLine	*gl;		/* getline object */
	} input;
	struct {		/* ELF file state */
		int elfclass;		/* ELFCLASS of file being edited */
		int elfconst_ehdr_change;	/* ELF header has changed. */
						/*	Recheck elfconst strs */
		/*
		 * Information for the ELF object being edited.
		 * The value of elfclass determines which of these
		 * fields is valid in the current session. This is
		 * only usable if file.present is True. Otherwise, there
		 * is no object state, and these pointers will be NULL.
		 */
		union {
			elfedit32_obj_state_t *s32;	/* ELFCLASS32 */
			elfedit64_obj_state_t *s64;	/* ELFCLASS64 */
		} obj_state;
	} elf;
	USER_CMD_T *cur_cmd;	 /* NULL, or currently executing command */
} STATE_T;



/*
 * Type of item argument to elfedit_next_optarg(), used to pull together
 * the information for a single command option or argument, handling
 * the ELFEDIT_CMDOA_F_VALUE and ELFEDIT_CMDOA_F_INHERIT cases.
 */
typedef struct {
	const char		*oai_name;	/* Name of option */
	const char		*oai_vname;	/* Name of value field if */
						/* ELFEDIT_CMDOA_F_VALUE */
	elfedit_i18nhdl_t	oai_help;	/* Help text for option */
	elfedit_cmd_oa_flag_t	oai_flags;	/* Additional attributes */
	elfedit_cmd_oa_mask_t	oai_idmask;	/* Returned by elfedit_getopt */
	elfedit_cmd_oa_mask_t	oai_excmask;	/* mutual exclusion mask */
} elfedit_optarg_item_t;



/* Global state is accessible between elfedit files */
extern STATE_T state;

/* Exported by sys.c, used in elfedit.c to initialize builtin sys module */
extern MODLIST_T *elfedit_sys_init(elfedit_module_version_t version);

/* Exported by util.c, used by elfedit.c and sys.c to process output style */
extern int elfedit_atooutstyle(const char *str, elfedit_outstyle_t *outstyle);

/*
 * getopt related routines that are not public
 */
extern void elfedit_set_cmd_outstyle(const char *str);

/* elfedit internal functions used by sys module */
extern void elfedit_exit(int status);
extern elfeditGC_cmd_t *elfedit_find_command(const char *name, int must_exist,
    elfeditGC_module_t **mod_ret);
extern const char *elfedit_format_command_usage(elfeditGC_module_t *mod,
    elfeditGC_cmd_t *cmd, const char *wrap_str, size_t cur_col);
extern elfeditGC_module_t *elfedit_load_module(const char *name, int must_exist,
    int allow_abs_path);
extern void elfedit_load_moddir(const char *dirpath, int must_exist,
    int abs_path);
extern void elfedit_load_modpath(void);
extern void elfedit_unload_module(const char *name);
extern void elfedit_next_optarg(elfedit_cmd_optarg_t **optarg,
    elfedit_optarg_item_t *item);
extern const char *elfedit_optarg_helpstr(elfeditGC_module_t *mod,
    elfedit_optarg_item_t *item);


/* Used by elfedit_getopt_init() to access options array for command */
elfeditGC_cmd_t *elfedit_curcmd(void);

/* elfedit_machelf functions used by elfedit */
extern	void elfedit32_init_obj_state(const char *file, int fd, Elf *elf);
extern	void elfedit64_init_obj_state(const char *file, int fd, Elf *elf);

#ifdef	__cplusplus
}
#endif

#endif	/* __ELFEDIT_H */