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 2007 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 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <setjmp.h> 33 #include <libtecla.h> 34 #include <elfedit.h> 35 36 /* 37 * Local include file for elfedit. 38 */ 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 44 /* 45 * Maximum command line, and history 46 */ 47 #define ELFEDIT_MAXCMD 1024 48 #define ELFEDIT_MAXHIST 1024 49 50 /* Maximum number of command completion arguments */ 51 #define ELFEDIT_MAXCPLARGS 128 52 53 /* Maximum length of a module name */ 54 #define ELFEDIT_MAXMODNAM 64 55 56 57 /* 58 * In elfedit.h, you will find elfedit32_cmd_t and elfedit64_cmd_t 59 * typedefs. These types are identical, except for the definition 60 * of the cmd_func and cmd_cplfunc function pointers. These function 61 * pointers have different argument definitions that reflect the 62 * different object state definition blocks for the 32 and 64-bit cases. 63 * Yet, From a strictly machine based view, these two types are identical 64 * in size and layout: 65 * 66 * - At the machine level, all function pointers are simply 67 * machine sized words containing an address. 68 * 69 * - Other than the function pointers, the remaining fields 70 * are exactly the same in both cases. 71 * 72 * The vast majority of elfedit's internals that examine elfedit_cmd_t 73 * are looking at the non-function pointer fields. It simplfiies 74 * a great deal of code if we can treat elfedit32_cmd_t and elfedit64_cmd_t 75 * as equivalent types for this purpose. In C++, we would do this with 76 * a superclass. In C, we do it by defining another variant named 77 * elfeditGC_cmd_t (GC stands for "Generic Class"). The function pointers 78 * are replaced with (void *) pointers. This variant has the same size 79 * and layout as the others. We use it internally to represent either type. 80 * In the cases where we need to use the function pointers, we first cast 81 * them to the proper type for the ELFCLASS being processed. 82 * 83 * The existance of elfeditGC_cmd_t implies the need for elfeditGC_module_t, 84 * for the same reasons. 85 * 86 * It is extremely important that these definitions exactly mirror the 87 * definitions in elfedit.h. 88 */ 89 typedef struct { 90 void *cmd_func; 91 void *cmd_cplfunc; 92 const char **cmd_name; 93 elfedit_i18nhdl_t cmd_desc; 94 elfedit_i18nhdl_t cmd_help; 95 elfedit_cmd_optarg_t *cmd_opt; 96 elfedit_cmd_optarg_t *cmd_args; 97 } elfeditGC_cmd_t; 98 99 100 typedef struct { 101 elfedit_module_version_t mod_version; 102 const char *mod_name; 103 elfedit_i18nhdl_t mod_desc; 104 elfeditGC_cmd_t *mod_cmds; 105 elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str; 106 } elfeditGC_module_t; 107 108 109 /* 110 * The result of parsing a user command is one of these blocks entered 111 * at the end of state.user_cmd. They encapsulate the arguments and 112 * the command function to call. In combination with an elfedit_obj_state_t, 113 * they contain everything needed to execute a specified operation. A single 114 * call to free() suffices to release the ELFEDIT_USER_CMD and any memory 115 * it references. 116 */ 117 typedef struct user_cmd_t { 118 struct user_cmd_t *ucmd_next; /* Commands are kept in linked list */ 119 int ucmd_argc; /* # of arguments to command */ 120 const char **ucmd_argv; /* Argument strings */ 121 char *ucmd_orig_str; /* Command string as entered by user */ 122 elfeditGC_module_t *ucmd_mod; /* Module defining command */ 123 elfeditGC_cmd_t *ucmd_cmd; /* Command to call */ 124 int ucmd_ostyle_set; /* True if there is a per-cmd */ 125 /* output style active */ 126 elfedit_outstyle_t ucmd_ostyle; /* Per-cmd output style, if active */ 127 } USER_CMD_T; 128 129 /* 130 * MODLIST_T is used to manage module definitions. Note that a simple linked 131 * list is used to maintain the set of active modules. This can be easily 132 * changed if the number of modules grows to a point where the lookup 133 * time is noticible. 134 */ 135 typedef struct moddef_t { 136 struct moddef_t *ml_next; /* Used for list of open mods */ 137 elfeditGC_module_t *ml_mod; /* The module definition */ 138 void *ml_dl_hdl; /* dlopen() handle for lib */ 139 const char *ml_path; /* Path used to open lib */ 140 } MODLIST_T; 141 142 143 /* 144 * Type of the global variable used to maintain elfedit state. 145 */ 146 typedef struct { 147 MODLIST_T *modlist; /* List of loaded commands */ 148 elfedit_flag_t flags; /* ELFEDIT_F_ command line options */ 149 elfedit_outstyle_t outstyle; /* Output style */ 150 struct { 151 int present; /* True if there is a source file. */ 152 /* False otherwise */ 153 /* 154 * The remaining file fields are not to be accessed 155 * unless present is True. 156 */ 157 const char *infile; /* Name of source file */ 158 const char *outfile; /* Name of file being edited */ 159 int unlink_on_exit; /* TRUE to unlink outfile on exit */ 160 int dirty; /* TRUE if outfile needs to be saved */ 161 } file; 162 struct { /* Jump buffer used for ELFEDIT_MSG_ERR */ 163 int active; /* True if MSG_ERR jumps to outer loop */ 164 sigjmp_buf env; /* jump environment buffer */ 165 } msg_jbuf; 166 struct { /* Search path used to find modules */ 167 size_t n; /* # of path segments */ 168 const char **seg; /* path segments */ 169 } modpath; 170 struct { /* Linked list of user commands to execute */ 171 size_t n; /* # of commands */ 172 USER_CMD_T *list; /* head of list */ 173 USER_CMD_T *tail; /* points at last element of list */ 174 } ucmd; 175 struct { /* Pager related state */ 176 FILE *fptr; /* Output file */ 177 } pager; 178 struct { 179 int is_tty; /* True in stdin is a tty */ 180 int full_tty; /* True if stdin and stdout are tty */ 181 int in_tecla; /* gl_get_line() is active */ 182 GetLine *gl; /* getline object */ 183 } input; 184 struct { /* ELF file state */ 185 int elfclass; /* ELFCLASS of file being edited */ 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