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