1d29b2c44Sab /*
2d29b2c44Sab  * CDDL HEADER START
3d29b2c44Sab  *
4d29b2c44Sab  * The contents of this file are subject to the terms of the
5d29b2c44Sab  * Common Development and Distribution License (the "License").
6d29b2c44Sab  * You may not use this file except in compliance with the License.
7d29b2c44Sab  *
8d29b2c44Sab  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d29b2c44Sab  * or http://www.opensolaris.org/os/licensing.
10d29b2c44Sab  * See the License for the specific language governing permissions
11d29b2c44Sab  * and limitations under the License.
12d29b2c44Sab  *
13d29b2c44Sab  * When distributing Covered Code, include this CDDL HEADER in each
14d29b2c44Sab  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d29b2c44Sab  * If applicable, add the following below this CDDL HEADER, with the
16d29b2c44Sab  * fields enclosed by brackets "[]" replaced with your own identifying
17d29b2c44Sab  * information: Portions Copyright [yyyy] [name of copyright owner]
18d29b2c44Sab  *
19d29b2c44Sab  * CDDL HEADER END
20d29b2c44Sab  */
22d29b2c44Sab /*
23*4f680cc6SAli Bahrami  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24d29b2c44Sab  * Use is subject to license terms.
25d29b2c44Sab  */
27d29b2c44Sab #ifndef	__ELFEDIT_H
28d29b2c44Sab #define	__ELFEDIT_H
30d29b2c44Sab #include	<setjmp.h>
31d29b2c44Sab #include	<libtecla.h>
32d29b2c44Sab #include	<elfedit.h>
34d29b2c44Sab /*
35d29b2c44Sab  * Local include file for elfedit.
36d29b2c44Sab  */
37d29b2c44Sab #ifdef	__cplusplus
38d29b2c44Sab extern "C" {
39d29b2c44Sab #endif
42d29b2c44Sab /*
43d29b2c44Sab  * Maximum command line, and history
44d29b2c44Sab  */
45d29b2c44Sab #define	ELFEDIT_MAXCMD	1024
46d29b2c44Sab #define	ELFEDIT_MAXHIST	1024
48d29b2c44Sab /* Maximum number of command completion arguments */
49d29b2c44Sab #define	ELFEDIT_MAXCPLARGS	128
51d29b2c44Sab /* Maximum length of a module name */
52d29b2c44Sab #define	ELFEDIT_MAXMODNAM	64
55d29b2c44Sab /*
56d29b2c44Sab  * In elfedit.h, you will find elfedit32_cmd_t and elfedit64_cmd_t
57d29b2c44Sab  * typedefs. These types are identical, except for the definition
58d29b2c44Sab  * of the cmd_func and cmd_cplfunc function pointers. These function
59d29b2c44Sab  * pointers have different argument definitions that reflect the
60d29b2c44Sab  * different object state definition blocks for the 32 and 64-bit cases.
61d29b2c44Sab  * Yet, From a strictly machine based view, these two types are identical
62d29b2c44Sab  * in size and layout:
63d29b2c44Sab  *
64d29b2c44Sab  *	- At the machine level, all function pointers are simply
65d29b2c44Sab  *		machine sized words containing an address.
66d29b2c44Sab  *
67d29b2c44Sab  *	- Other than the function pointers, the remaining fields
68d29b2c44Sab  *		are exactly the same in both cases.
69d29b2c44Sab  *
70d29b2c44Sab  * The vast majority of elfedit's internals that examine elfedit_cmd_t
71d29b2c44Sab  * are looking at the non-function pointer fields. It simplfiies
72d29b2c44Sab  * a great deal of code if we can treat elfedit32_cmd_t and elfedit64_cmd_t
73d29b2c44Sab  * as equivalent types for this purpose. In C++, we would do this with
74d29b2c44Sab  * a superclass. In C, we do it by defining another variant named
75d29b2c44Sab  * elfeditGC_cmd_t (GC stands for "Generic Class"). The function pointers
76d29b2c44Sab  * are replaced with (void *) pointers. This variant has the same size
77d29b2c44Sab  * and layout as the others. We use it internally to represent either type.
78d29b2c44Sab  * In the cases where we need to use the function pointers, we first cast
79d29b2c44Sab  * them to the proper type for the ELFCLASS being processed.
80d29b2c44Sab  *
81d29b2c44Sab  * The existance of elfeditGC_cmd_t implies the need for elfeditGC_module_t,
82d29b2c44Sab  * for the same reasons.
83d29b2c44Sab  *
84d29b2c44Sab  * It is extremely important that these definitions exactly mirror the
85d29b2c44Sab  * definitions in elfedit.h.
86d29b2c44Sab  */
87d29b2c44Sab typedef struct {
88d29b2c44Sab 	void			*cmd_func;
89d29b2c44Sab 	void			*cmd_cplfunc;
90d29b2c44Sab 	const char		**cmd_name;
91d29b2c44Sab 	elfedit_i18nhdl_t	cmd_desc;
92d29b2c44Sab 	elfedit_i18nhdl_t	cmd_help;
93d29b2c44Sab 	elfedit_cmd_optarg_t	*cmd_opt;
94d29b2c44Sab 	elfedit_cmd_optarg_t	*cmd_args;
95d29b2c44Sab } elfeditGC_cmd_t;
98d29b2c44Sab typedef struct {
99d29b2c44Sab 	elfedit_module_version_t mod_version;
100d29b2c44Sab 	const char		*mod_name;
101d29b2c44Sab 	elfedit_i18nhdl_t	mod_desc;
102d29b2c44Sab 	elfeditGC_cmd_t		*mod_cmds;
103d29b2c44Sab 	elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str;
104d29b2c44Sab } elfeditGC_module_t;
107d29b2c44Sab /*
108d29b2c44Sab  * The result of parsing a user command is one of these blocks entered
109d29b2c44Sab  * at the end of state.user_cmd. They encapsulate the arguments and
110d29b2c44Sab  * the command function to call. In combination with an elfedit_obj_state_t,
111d29b2c44Sab  * they contain everything needed to execute a specified operation. A single
112d29b2c44Sab  * call to free() suffices to release the ELFEDIT_USER_CMD and any memory
113d29b2c44Sab  * it references.
114d29b2c44Sab  */
115d29b2c44Sab typedef struct user_cmd_t {
116d29b2c44Sab 	struct user_cmd_t *ucmd_next;	/* Commands are kept in linked list */
117d29b2c44Sab 	int		ucmd_argc;	/* # of arguments to command */
118d29b2c44Sab 	const char	**ucmd_argv;	/* Argument strings */
119d29b2c44Sab 	char		*ucmd_orig_str;	/* Command string as entered by user */
120d29b2c44Sab 	elfeditGC_module_t *ucmd_mod;	/* Module defining command */
121d29b2c44Sab 	elfeditGC_cmd_t	*ucmd_cmd;	/* Command to call */
122d29b2c44Sab 	int		ucmd_ostyle_set;	/* True if there is a per-cmd */
123d29b2c44Sab 						/* 	output style active */
124d29b2c44Sab 	elfedit_outstyle_t ucmd_ostyle; /* Per-cmd output style, if active */
125d29b2c44Sab } USER_CMD_T;
127d29b2c44Sab /*
128d29b2c44Sab  * MODLIST_T is used to manage module definitions. Note that a simple linked
129d29b2c44Sab  * list is used to maintain the set of active modules. This can be easily
130d29b2c44Sab  * changed if the number of modules grows to a point where the lookup
131d29b2c44Sab  * time is noticible.
132d29b2c44Sab  */
133d29b2c44Sab typedef struct moddef_t {
134d29b2c44Sab 	struct moddef_t		*ml_next;	/* Used for list of open mods */
135d29b2c44Sab 	elfeditGC_module_t	*ml_mod;	/* The module definition */
136d29b2c44Sab 	void			*ml_dl_hdl;	/* dlopen() handle for lib */
137d29b2c44Sab 	const char		*ml_path;	/* Path used to open lib */
138d29b2c44Sab } MODLIST_T;
141d29b2c44Sab /*
142d29b2c44Sab  * Type of the global variable used to maintain elfedit state.
143d29b2c44Sab  */
144d29b2c44Sab typedef struct {
145d29b2c44Sab 	MODLIST_T *modlist;		/* List of loaded commands */
146d29b2c44Sab 	elfedit_flag_t	flags;		/* ELFEDIT_F_ command line options */
147d29b2c44Sab 	elfedit_outstyle_t outstyle;	/* Output style */
148d29b2c44Sab 	struct {
149d29b2c44Sab 		int present;		/* True if there is a source file. */
150d29b2c44Sab 					/*	 False otherwise */
151d29b2c44Sab 		/*
152d29b2c44Sab 		 * The remaining file fields are not to be accessed
153d29b2c44Sab 		 * unless present is True.
154d29b2c44Sab 		 */
155d29b2c44Sab 		const char *infile;	/* Name of source file */
156d29b2c44Sab 		const char *outfile;	/* Name of file being edited */
157d29b2c44Sab 		int unlink_on_exit;	/* TRUE to unlink outfile on exit  */
158d29b2c44Sab 		int dirty;		/* TRUE if outfile needs to be saved */
159d29b2c44Sab 	} file;
160d29b2c44Sab 	struct {		/* Jump buffer used for ELFEDIT_MSG_ERR */
161d29b2c44Sab 		int active;	/*	True if MSG_ERR jumps to outer loop */
162d29b2c44Sab 		sigjmp_buf env;	/*	jump environment buffer */
163d29b2c44Sab 	} msg_jbuf;
164d29b2c44Sab 	struct {			/* Search path used to find modules */
165d29b2c44Sab 		size_t n;		/*	# of path segments */
166d29b2c44Sab 		const char **seg;	/*	path segments */
167d29b2c44Sab 	} modpath;
168d29b2c44Sab 	struct {		/* Linked list of user commands to execute */
169d29b2c44Sab 		size_t n;		/* # of commands */
170d29b2c44Sab 		USER_CMD_T *list;	/* head of list */
171d29b2c44Sab 		USER_CMD_T *tail;	/* points at last element of list */
172d29b2c44Sab 	} ucmd;
173d29b2c44Sab 	struct {			/* Pager related state */
174d29b2c44Sab 		FILE *fptr;		/* Output file */
175d29b2c44Sab 	} pager;
176d29b2c44Sab 	struct {
177d29b2c44Sab 		int	is_tty;		/* True in stdin is a tty */
178d29b2c44Sab 		int	full_tty;	/* True if stdin and stdout are tty */
179d29b2c44Sab 		int	in_tecla;	/* gl_get_line() is active */
180d29b2c44Sab 		GetLine	*gl;		/* getline object */
181d29b2c44Sab 	} input;
182d29b2c44Sab 	struct {		/* ELF file state */
183d29b2c44Sab 		int elfclass;		/* ELFCLASS of file being edited */
184*4f680cc6SAli Bahrami 		int elfconst_ehdr_change;	/* ELF header has changed. */
185*4f680cc6SAli Bahrami 						/*	Recheck elfconst strs */
186d29b2c44Sab 		/*
187d29b2c44Sab 		 * Information for the ELF object being edited.
188d29b2c44Sab 		 * The value of elfclass determines which of these
189d29b2c44Sab 		 * fields is valid in the current session. This is
190d29b2c44Sab 		 * only usable if file.present is True. Otherwise, there
191d29b2c44Sab 		 * is no object state, and these pointers will be NULL.
192d29b2c44Sab 		 */
193d29b2c44Sab 		union {
194d29b2c44Sab 			elfedit32_obj_state_t *s32;	/* ELFCLASS32 */
195d29b2c44Sab 			elfedit64_obj_state_t *s64;	/* ELFCLASS64 */
196d29b2c44Sab 		} obj_state;
197d29b2c44Sab 	} elf;
198d29b2c44Sab 	USER_CMD_T *cur_cmd;	 /* NULL, or currently executing command */
199d29b2c44Sab } STATE_T;
203d29b2c44Sab /*
204d29b2c44Sab  * Type of item argument to elfedit_next_optarg(), used to pull together
205d29b2c44Sab  * the information for a single command option or argument, handling
206d29b2c44Sab  * the ELFEDIT_CMDOA_F_VALUE and ELFEDIT_CMDOA_F_INHERIT cases.
207d29b2c44Sab  */
208d29b2c44Sab typedef struct {
209d29b2c44Sab 	const char		*oai_name;	/* Name of option */
210d29b2c44Sab 	const char		*oai_vname;	/* Name of value field if */
211d29b2c44Sab 						/* ELFEDIT_CMDOA_F_VALUE */
212d29b2c44Sab 	elfedit_i18nhdl_t	oai_help;	/* Help text for option */
213d29b2c44Sab 	elfedit_cmd_oa_flag_t	oai_flags;	/* Additional attributes */
214d29b2c44Sab 	elfedit_cmd_oa_mask_t	oai_idmask;	/* Returned by elfedit_getopt */
215d29b2c44Sab 	elfedit_cmd_oa_mask_t	oai_excmask;	/* mutual exclusion mask */
216d29b2c44Sab } elfedit_optarg_item_t;
220d29b2c44Sab /* Global state is accessible between elfedit files */
221d29b2c44Sab extern STATE_T state;
223d29b2c44Sab /* Exported by sys.c, used in elfedit.c to initialize builtin sys module */
224d29b2c44Sab extern MODLIST_T *elfedit_sys_init(elfedit_module_version_t version);
226d29b2c44Sab /* Exported by util.c, used by elfedit.c and sys.c to process output style */
227d29b2c44Sab extern int elfedit_atooutstyle(const char *str, elfedit_outstyle_t *outstyle);
229d29b2c44Sab /*
230d29b2c44Sab  * getopt related routines that are not public
231d29b2c44Sab  */
232d29b2c44Sab extern void elfedit_set_cmd_outstyle(const char *str);
234d29b2c44Sab /* elfedit internal functions used by sys module */
235d29b2c44Sab extern void elfedit_exit(int status);
236d29b2c44Sab extern elfeditGC_cmd_t *elfedit_find_command(const char *name, int must_exist,
237d29b2c44Sab     elfeditGC_module_t **mod_ret);
238d29b2c44Sab extern const char *elfedit_format_command_usage(elfeditGC_module_t *mod,
239d29b2c44Sab     elfeditGC_cmd_t *cmd, const char *wrap_str, size_t cur_col);
240d29b2c44Sab extern elfeditGC_module_t *elfedit_load_module(const char *name, int must_exist,
241d29b2c44Sab     int allow_abs_path);
242d29b2c44Sab extern void elfedit_load_moddir(const char *dirpath, int must_exist,
243d29b2c44Sab     int abs_path);
244d29b2c44Sab extern void elfedit_load_modpath(void);
245d29b2c44Sab extern void elfedit_unload_module(const char *name);
246d29b2c44Sab extern void elfedit_next_optarg(elfedit_cmd_optarg_t **optarg,
247d29b2c44Sab     elfedit_optarg_item_t *item);
248d29b2c44Sab extern const char *elfedit_optarg_helpstr(elfeditGC_module_t *mod,
249d29b2c44Sab     elfedit_optarg_item_t *item);
252d29b2c44Sab /* Used by elfedit_getopt_init() to access options array for command */
253d29b2c44Sab elfeditGC_cmd_t *elfedit_curcmd(void);
255d29b2c44Sab /* elfedit_machelf functions used by elfedit */
256d29b2c44Sab extern	void elfedit32_init_obj_state(const char *file, int fd, Elf *elf);
257d29b2c44Sab extern	void elfedit64_init_obj_state(const char *file, int fd, Elf *elf);
259d29b2c44Sab #ifdef	__cplusplus
260d29b2c44Sab }
261d29b2c44Sab #endif
263d29b2c44Sab #endif	/* __ELFEDIT_H */