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