xref: /onnv-gate/usr/src/cmd/sgs/elfedit/common/_elfedit.h (revision 9273:9a0603d78ad3)
15088Sab196087 /*
25088Sab196087  * CDDL HEADER START
35088Sab196087  *
45088Sab196087  * The contents of this file are subject to the terms of the
55088Sab196087  * Common Development and Distribution License (the "License").
65088Sab196087  * You may not use this file except in compliance with the License.
75088Sab196087  *
85088Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95088Sab196087  * or http://www.opensolaris.org/os/licensing.
105088Sab196087  * See the License for the specific language governing permissions
115088Sab196087  * and limitations under the License.
125088Sab196087  *
135088Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
145088Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155088Sab196087  * If applicable, add the following below this CDDL HEADER, with the
165088Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
175088Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
185088Sab196087  *
195088Sab196087  * CDDL HEADER END
205088Sab196087  */
215088Sab196087 
225088Sab196087 /*
23*9273SAli.Bahrami@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245088Sab196087  * Use is subject to license terms.
255088Sab196087  */
265088Sab196087 
275088Sab196087 #ifndef	__ELFEDIT_H
285088Sab196087 #define	__ELFEDIT_H
295088Sab196087 
305088Sab196087 #include	<setjmp.h>
315088Sab196087 #include	<libtecla.h>
325088Sab196087 #include	<elfedit.h>
335088Sab196087 
345088Sab196087 /*
355088Sab196087  * Local include file for elfedit.
365088Sab196087  */
375088Sab196087 #ifdef	__cplusplus
385088Sab196087 extern "C" {
395088Sab196087 #endif
405088Sab196087 
415088Sab196087 
425088Sab196087 /*
435088Sab196087  * Maximum command line, and history
445088Sab196087  */
455088Sab196087 #define	ELFEDIT_MAXCMD	1024
465088Sab196087 #define	ELFEDIT_MAXHIST	1024
475088Sab196087 
485088Sab196087 /* Maximum number of command completion arguments */
495088Sab196087 #define	ELFEDIT_MAXCPLARGS	128
505088Sab196087 
515088Sab196087 /* Maximum length of a module name */
525088Sab196087 #define	ELFEDIT_MAXMODNAM	64
535088Sab196087 
545088Sab196087 
555088Sab196087 /*
565088Sab196087  * In elfedit.h, you will find elfedit32_cmd_t and elfedit64_cmd_t
575088Sab196087  * typedefs. These types are identical, except for the definition
585088Sab196087  * of the cmd_func and cmd_cplfunc function pointers. These function
595088Sab196087  * pointers have different argument definitions that reflect the
605088Sab196087  * different object state definition blocks for the 32 and 64-bit cases.
615088Sab196087  * Yet, From a strictly machine based view, these two types are identical
625088Sab196087  * in size and layout:
635088Sab196087  *
645088Sab196087  *	- At the machine level, all function pointers are simply
655088Sab196087  *		machine sized words containing an address.
665088Sab196087  *
675088Sab196087  *	- Other than the function pointers, the remaining fields
685088Sab196087  *		are exactly the same in both cases.
695088Sab196087  *
705088Sab196087  * The vast majority of elfedit's internals that examine elfedit_cmd_t
715088Sab196087  * are looking at the non-function pointer fields. It simplfiies
725088Sab196087  * a great deal of code if we can treat elfedit32_cmd_t and elfedit64_cmd_t
735088Sab196087  * as equivalent types for this purpose. In C++, we would do this with
745088Sab196087  * a superclass. In C, we do it by defining another variant named
755088Sab196087  * elfeditGC_cmd_t (GC stands for "Generic Class"). The function pointers
765088Sab196087  * are replaced with (void *) pointers. This variant has the same size
775088Sab196087  * and layout as the others. We use it internally to represent either type.
785088Sab196087  * In the cases where we need to use the function pointers, we first cast
795088Sab196087  * them to the proper type for the ELFCLASS being processed.
805088Sab196087  *
815088Sab196087  * The existance of elfeditGC_cmd_t implies the need for elfeditGC_module_t,
825088Sab196087  * for the same reasons.
835088Sab196087  *
845088Sab196087  * It is extremely important that these definitions exactly mirror the
855088Sab196087  * definitions in elfedit.h.
865088Sab196087  */
875088Sab196087 typedef struct {
885088Sab196087 	void			*cmd_func;
895088Sab196087 	void			*cmd_cplfunc;
905088Sab196087 	const char		**cmd_name;
915088Sab196087 	elfedit_i18nhdl_t	cmd_desc;
925088Sab196087 	elfedit_i18nhdl_t	cmd_help;
935088Sab196087 	elfedit_cmd_optarg_t	*cmd_opt;
945088Sab196087 	elfedit_cmd_optarg_t	*cmd_args;
955088Sab196087 } elfeditGC_cmd_t;
965088Sab196087 
975088Sab196087 
985088Sab196087 typedef struct {
995088Sab196087 	elfedit_module_version_t mod_version;
1005088Sab196087 	const char		*mod_name;
1015088Sab196087 	elfedit_i18nhdl_t	mod_desc;
1025088Sab196087 	elfeditGC_cmd_t		*mod_cmds;
1035088Sab196087 	elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str;
1045088Sab196087 } elfeditGC_module_t;
1055088Sab196087 
1065088Sab196087 
1075088Sab196087 /*
1085088Sab196087  * The result of parsing a user command is one of these blocks entered
1095088Sab196087  * at the end of state.user_cmd. They encapsulate the arguments and
1105088Sab196087  * the command function to call. In combination with an elfedit_obj_state_t,
1115088Sab196087  * they contain everything needed to execute a specified operation. A single
1125088Sab196087  * call to free() suffices to release the ELFEDIT_USER_CMD and any memory
1135088Sab196087  * it references.
1145088Sab196087  */
1155088Sab196087 typedef struct user_cmd_t {
1165088Sab196087 	struct user_cmd_t *ucmd_next;	/* Commands are kept in linked list */
1175088Sab196087 	int		ucmd_argc;	/* # of arguments to command */
1185088Sab196087 	const char	**ucmd_argv;	/* Argument strings */
1195088Sab196087 	char		*ucmd_orig_str;	/* Command string as entered by user */
1205088Sab196087 	elfeditGC_module_t *ucmd_mod;	/* Module defining command */
1215088Sab196087 	elfeditGC_cmd_t	*ucmd_cmd;	/* Command to call */
1225088Sab196087 	int		ucmd_ostyle_set;	/* True if there is a per-cmd */
1235088Sab196087 						/* 	output style active */
1245088Sab196087 	elfedit_outstyle_t ucmd_ostyle; /* Per-cmd output style, if active */
1255088Sab196087 } USER_CMD_T;
1265088Sab196087 
1275088Sab196087 /*
1285088Sab196087  * MODLIST_T is used to manage module definitions. Note that a simple linked
1295088Sab196087  * list is used to maintain the set of active modules. This can be easily
1305088Sab196087  * changed if the number of modules grows to a point where the lookup
1315088Sab196087  * time is noticible.
1325088Sab196087  */
1335088Sab196087 typedef struct moddef_t {
1345088Sab196087 	struct moddef_t		*ml_next;	/* Used for list of open mods */
1355088Sab196087 	elfeditGC_module_t	*ml_mod;	/* The module definition */
1365088Sab196087 	void			*ml_dl_hdl;	/* dlopen() handle for lib */
1375088Sab196087 	const char		*ml_path;	/* Path used to open lib */
1385088Sab196087 } MODLIST_T;
1395088Sab196087 
1405088Sab196087 
1415088Sab196087 /*
1425088Sab196087  * Type of the global variable used to maintain elfedit state.
1435088Sab196087  */
1445088Sab196087 typedef struct {
1455088Sab196087 	MODLIST_T *modlist;		/* List of loaded commands */
1465088Sab196087 	elfedit_flag_t	flags;		/* ELFEDIT_F_ command line options */
1475088Sab196087 	elfedit_outstyle_t outstyle;	/* Output style */
1485088Sab196087 	struct {
1495088Sab196087 		int present;		/* True if there is a source file. */
1505088Sab196087 					/*	 False otherwise */
1515088Sab196087 		/*
1525088Sab196087 		 * The remaining file fields are not to be accessed
1535088Sab196087 		 * unless present is True.
1545088Sab196087 		 */
1555088Sab196087 		const char *infile;	/* Name of source file */
1565088Sab196087 		const char *outfile;	/* Name of file being edited */
1575088Sab196087 		int unlink_on_exit;	/* TRUE to unlink outfile on exit  */
1585088Sab196087 		int dirty;		/* TRUE if outfile needs to be saved */
1595088Sab196087 	} file;
1605088Sab196087 	struct {		/* Jump buffer used for ELFEDIT_MSG_ERR */
1615088Sab196087 		int active;	/*	True if MSG_ERR jumps to outer loop */
1625088Sab196087 		sigjmp_buf env;	/*	jump environment buffer */
1635088Sab196087 	} msg_jbuf;
1645088Sab196087 	struct {			/* Search path used to find modules */
1655088Sab196087 		size_t n;		/*	# of path segments */
1665088Sab196087 		const char **seg;	/*	path segments */
1675088Sab196087 	} modpath;
1685088Sab196087 	struct {		/* Linked list of user commands to execute */
1695088Sab196087 		size_t n;		/* # of commands */
1705088Sab196087 		USER_CMD_T *list;	/* head of list */
1715088Sab196087 		USER_CMD_T *tail;	/* points at last element of list */
1725088Sab196087 	} ucmd;
1735088Sab196087 	struct {			/* Pager related state */
1745088Sab196087 		FILE *fptr;		/* Output file */
1755088Sab196087 	} pager;
1765088Sab196087 	struct {
1775088Sab196087 		int	is_tty;		/* True in stdin is a tty */
1785088Sab196087 		int	full_tty;	/* True if stdin and stdout are tty */
1795088Sab196087 		int	in_tecla;	/* gl_get_line() is active */
1805088Sab196087 		GetLine	*gl;		/* getline object */
1815088Sab196087 	} input;
1825088Sab196087 	struct {		/* ELF file state */
1835088Sab196087 		int elfclass;		/* ELFCLASS of file being edited */
184*9273SAli.Bahrami@Sun.COM 		int elfconst_ehdr_change;	/* ELF header has changed. */
185*9273SAli.Bahrami@Sun.COM 						/*	Recheck elfconst strs */
1865088Sab196087 		/*
1875088Sab196087 		 * Information for the ELF object being edited.
1885088Sab196087 		 * The value of elfclass determines which of these
1895088Sab196087 		 * fields is valid in the current session. This is
1905088Sab196087 		 * only usable if file.present is True. Otherwise, there
1915088Sab196087 		 * is no object state, and these pointers will be NULL.
1925088Sab196087 		 */
1935088Sab196087 		union {
1945088Sab196087 			elfedit32_obj_state_t *s32;	/* ELFCLASS32 */
1955088Sab196087 			elfedit64_obj_state_t *s64;	/* ELFCLASS64 */
1965088Sab196087 		} obj_state;
1975088Sab196087 	} elf;
1985088Sab196087 	USER_CMD_T *cur_cmd;	 /* NULL, or currently executing command */
1995088Sab196087 } STATE_T;
2005088Sab196087 
2015088Sab196087 
2025088Sab196087 
2035088Sab196087 /*
2045088Sab196087  * Type of item argument to elfedit_next_optarg(), used to pull together
2055088Sab196087  * the information for a single command option or argument, handling
2065088Sab196087  * the ELFEDIT_CMDOA_F_VALUE and ELFEDIT_CMDOA_F_INHERIT cases.
2075088Sab196087  */
2085088Sab196087 typedef struct {
2095088Sab196087 	const char		*oai_name;	/* Name of option */
2105088Sab196087 	const char		*oai_vname;	/* Name of value field if */
2115088Sab196087 						/* ELFEDIT_CMDOA_F_VALUE */
2125088Sab196087 	elfedit_i18nhdl_t	oai_help;	/* Help text for option */
2135088Sab196087 	elfedit_cmd_oa_flag_t	oai_flags;	/* Additional attributes */
2145088Sab196087 	elfedit_cmd_oa_mask_t	oai_idmask;	/* Returned by elfedit_getopt */
2155088Sab196087 	elfedit_cmd_oa_mask_t	oai_excmask;	/* mutual exclusion mask */
2165088Sab196087 } elfedit_optarg_item_t;
2175088Sab196087 
2185088Sab196087 
2195088Sab196087 
2205088Sab196087 /* Global state is accessible between elfedit files */
2215088Sab196087 extern STATE_T state;
2225088Sab196087 
2235088Sab196087 /* Exported by sys.c, used in elfedit.c to initialize builtin sys module */
2245088Sab196087 extern MODLIST_T *elfedit_sys_init(elfedit_module_version_t version);
2255088Sab196087 
2265088Sab196087 /* Exported by util.c, used by elfedit.c and sys.c to process output style */
2275088Sab196087 extern int elfedit_atooutstyle(const char *str, elfedit_outstyle_t *outstyle);
2285088Sab196087 
2295088Sab196087 /*
2305088Sab196087  * getopt related routines that are not public
2315088Sab196087  */
2325088Sab196087 extern void elfedit_set_cmd_outstyle(const char *str);
2335088Sab196087 
2345088Sab196087 /* elfedit internal functions used by sys module */
2355088Sab196087 extern void elfedit_exit(int status);
2365088Sab196087 extern elfeditGC_cmd_t *elfedit_find_command(const char *name, int must_exist,
2375088Sab196087     elfeditGC_module_t **mod_ret);
2385088Sab196087 extern const char *elfedit_format_command_usage(elfeditGC_module_t *mod,
2395088Sab196087     elfeditGC_cmd_t *cmd, const char *wrap_str, size_t cur_col);
2405088Sab196087 extern elfeditGC_module_t *elfedit_load_module(const char *name, int must_exist,
2415088Sab196087     int allow_abs_path);
2425088Sab196087 extern void elfedit_load_moddir(const char *dirpath, int must_exist,
2435088Sab196087     int abs_path);
2445088Sab196087 extern void elfedit_load_modpath(void);
2455088Sab196087 extern void elfedit_unload_module(const char *name);
2465088Sab196087 extern void elfedit_next_optarg(elfedit_cmd_optarg_t **optarg,
2475088Sab196087     elfedit_optarg_item_t *item);
2485088Sab196087 extern const char *elfedit_optarg_helpstr(elfeditGC_module_t *mod,
2495088Sab196087     elfedit_optarg_item_t *item);
2505088Sab196087 
2515088Sab196087 
2525088Sab196087 /* Used by elfedit_getopt_init() to access options array for command */
2535088Sab196087 elfeditGC_cmd_t *elfedit_curcmd(void);
2545088Sab196087 
2555088Sab196087 /* elfedit_machelf functions used by elfedit */
2565088Sab196087 extern	void elfedit32_init_obj_state(const char *file, int fd, Elf *elf);
2575088Sab196087 extern	void elfedit64_init_obj_state(const char *file, int fd, Elf *elf);
2585088Sab196087 
2595088Sab196087 #ifdef	__cplusplus
2605088Sab196087 }
2615088Sab196087 #endif
2625088Sab196087 
2635088Sab196087 #endif	/* __ELFEDIT_H */
264