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 */ 21d29b2c44Sab 22d29b2c44Sab /* 23*4f680cc6SAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24d29b2c44Sab * Use is subject to license terms. 25d29b2c44Sab */ 26d29b2c44Sab 27d29b2c44Sab #ifndef __ELFEDIT_H 28d29b2c44Sab #define __ELFEDIT_H 29d29b2c44Sab 30d29b2c44Sab #include <setjmp.h> 31d29b2c44Sab #include <libtecla.h> 32d29b2c44Sab #include <elfedit.h> 33d29b2c44Sab 34d29b2c44Sab /* 35d29b2c44Sab * Local include file for elfedit. 36d29b2c44Sab */ 37d29b2c44Sab #ifdef __cplusplus 38d29b2c44Sab extern "C" { 39d29b2c44Sab #endif 40d29b2c44Sab 41d29b2c44Sab 42d29b2c44Sab /* 43d29b2c44Sab * Maximum command line, and history 44d29b2c44Sab */ 45d29b2c44Sab #define ELFEDIT_MAXCMD 1024 46d29b2c44Sab #define ELFEDIT_MAXHIST 1024 47d29b2c44Sab 48d29b2c44Sab /* Maximum number of command completion arguments */ 49d29b2c44Sab #define ELFEDIT_MAXCPLARGS 128 50d29b2c44Sab 51d29b2c44Sab /* Maximum length of a module name */ 52d29b2c44Sab #define ELFEDIT_MAXMODNAM 64 53d29b2c44Sab 54d29b2c44Sab 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; 96d29b2c44Sab 97d29b2c44Sab 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; 105d29b2c44Sab 106d29b2c44Sab 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; 126d29b2c44Sab 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; 139d29b2c44Sab 140d29b2c44Sab 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; 200d29b2c44Sab 201d29b2c44Sab 202d29b2c44Sab 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; 217d29b2c44Sab 218d29b2c44Sab 219d29b2c44Sab 220d29b2c44Sab /* Global state is accessible between elfedit files */ 221d29b2c44Sab extern STATE_T state; 222d29b2c44Sab 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); 225d29b2c44Sab 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); 228d29b2c44Sab 229d29b2c44Sab /* 230d29b2c44Sab * getopt related routines that are not public 231d29b2c44Sab */ 232d29b2c44Sab extern void elfedit_set_cmd_outstyle(const char *str); 233d29b2c44Sab 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); 250d29b2c44Sab 251d29b2c44Sab 252d29b2c44Sab /* Used by elfedit_getopt_init() to access options array for command */ 253d29b2c44Sab elfeditGC_cmd_t *elfedit_curcmd(void); 254d29b2c44Sab 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); 258d29b2c44Sab 259d29b2c44Sab #ifdef __cplusplus 260d29b2c44Sab } 261d29b2c44Sab #endif 262d29b2c44Sab 263d29b2c44Sab #endif /* __ELFEDIT_H */ 264