Home | History | Annotate | Download | only in include
      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	<stdio.h>
     31 #include	<stdlib.h>
     32 #include	<sys/types.h>
     33 #include	<libelf.h>
     34 #include	<stdarg.h>
     35 
     36 /* The following are here to support use of elfedit_msg() */
     37 #include	<sys/machelf.h>		/* EC_ macros */
     38 #include	<libintl.h>
     39 
     40 #ifdef	__cplusplus
     41 extern "C" {
     42 #endif
     43 
     44 
     45 /*
     46  * elfedit uses elfedit_printf() to produce generic output to stdout.
     47  * elfedit_msg() is used to produce error message, or specific types
     48  * of terse informational messages:
     49  *
     50  *	ELFEDIT_MSG_ERR:
     51  *		Issues an error to stderr. elfedit_msg() does not return
     52  *		to the caller. Control returns to the outer loop in
     53  *		interactive use. elfedit exits in non-interactive use.
     54  *
     55  *	ELFEDIT_MSG_FATAL:
     56  *		Issues an error to stderr. elfedit_msg() exits the process,
     57  *		and does not return to the caller.
     58  *
     59  *	ELFEDIT_MSG_USAGE:
     60  *		Issues an elfedit usage message to stderr, and
     61  *		returns to the caller.
     62  *
     63  *	ELFEDIT_MSG_CMDUSAGE
     64  *		Issues an elfedit usage message to stderr, and
     65  *		does not return to the caller.
     66  *
     67  *	ELFEDIT_MSG_DEBUG
     68  *		If the ELFEDIT_F_DEBUG flag is set, the message
     69  *		is printed to stdout, otherwise no output is produced.
     70  *		elfedit_msg() returns to the caller.
     71  *
     72  *	ELFEDIT_MSG_QUIET
     73  *		This is a very special case, intended to handle the
     74  *		case where the pager subprocess exits before we are
     75  *		done producing output (the user presses 'q'). It acts
     76  *		just like ELFEDIT_MSG_ERR, except that no message is
     77  *		actually printed.
     78  *
     79  * In the cases where elfedit_msg() does not return to the caller, the
     80  * behavior depends on the mode of execution. If running in interactive
     81  * mode (reading from a tty), control is returned directly to the outer
     82  * elfedit control loop to read another command. If not running in interactive
     83  * mode, elfedit exits with a non-zero status.
     84  */
     85 typedef enum {
     86 	ELFEDIT_MSG_ERR = 0,
     87 	ELFEDIT_MSG_FATAL = 1,
     88 	ELFEDIT_MSG_USAGE = 2,
     89 	ELFEDIT_MSG_CMDUSAGE = 3,
     90 	ELFEDIT_MSG_DEBUG = 4,
     91 	ELFEDIT_MSG_QUIET = 5
     92 } elfedit_msg_t;
     93 
     94 
     95 /*
     96  * Information for a single ELF section.
     97  *
     98  * NOTE: sec_xshndx
     99  *	A symbol table can have an associated SHT_SYMTAB_SHNDX section. This
    100  *	happens when the number of sections is too large to fit in the
    101  *	ELF symbol st_shndx field, which is a 16-bit value. The sec_xshndx
    102  *	field will be SHN_UNDEF if there is no such section, and will be
    103  *	the section index of the extended section index section assocated
    104  *	with the symbol table otherwise.
    105  *
    106  * NOTE: sec_versym
    107  *	Symbol table sections can have an SHT_SUNW_VERSYM section that
    108  *	contains its version indices. Other types of section will have
    109  *	this field set to SHN_UNDEF.
    110  */
    111 typedef struct {
    112 	Elf32_Word	sec_shndx;	/* Section index */
    113 	Elf_Scn		*sec_scn;	/* Section descriptor */
    114 	Elf32_Shdr	*sec_shdr;	/* Section header */
    115 	Elf_Data	*sec_data;	/* Data region of section */
    116 	const char	*sec_name;	/* Name of section */
    117 } elfedit32_section_t;
    118 
    119 typedef struct {
    120 	Elf64_Word	sec_shndx;
    121 	Elf_Scn		*sec_scn;
    122 	Elf64_Shdr	*sec_shdr;
    123 	Elf_Data	*sec_data;
    124 	const char	*sec_name;
    125 } elfedit64_section_t;
    126 
    127 #ifdef _ELF64
    128 #define	elfedit_section_t	elfedit64_section_t
    129 #else
    130 #define	elfedit_section_t	elfedit32_section_t
    131 #endif
    132 
    133 
    134 /*
    135  * We maintain extra information for symbol tables. We look them
    136  * up frequently, so we want to eliminate expensive linear searches
    137  * of the entire section header array. Also, symbol tables usually
    138  * have associated parallal sections (syminfo, versym, extended indexes, etc)
    139  * and we want to eliminate repeated linear lookups for them, as well as
    140  * the basic error checking that is necessary to ensure they match the
    141  * symbol table they're given.
    142  *
    143  * This extra information is kept in elfedit_symtab_t structs. Each field
    144  * is a section index, with SHN_UNDEF used for those that do not apply.
    145  */
    146 typedef struct {
    147 	Elf32_Word	symt_shndx;	/* Symbol table section index */
    148 	Elf32_Word	symt_xshndx;	/* Index of extended index section */
    149 	Elf32_Word	symt_syminfo;	/* Index of versym section */
    150 	Elf32_Word	symt_versym;	/* Index of versym section */
    151 } elfedit32_symtab_t;
    152 
    153 typedef struct {
    154 	Elf64_Word	symt_shndx;
    155 	Elf64_Word	symt_xshndx;
    156 	Elf64_Word	symt_versym;
    157 	Elf64_Word	symt_syminfo;
    158 } elfedit64_symtab_t;
    159 
    160 #ifdef _ELF64
    161 #define	elfedit_symtab_t	elfedit64_symtab_t
    162 #else
    163 #define	elfedit_symtab_t	elfedit32_symtab_t
    164 #endif
    165 
    166 
    167 /*
    168  * Information for a single ELF object.
    169  *
    170  * note:
    171  *	elfedit is intended to be an expert's tool, capable of modifying
    172  *	nearly everything in the file, whether or not such modifications
    173  *	are a good idea. At the same time, elfedit, via libelf, relies
    174  *	on the contents of the object to properly locate information in
    175  *	the file. As this is the same information that elfedit allows the
    176  *	user to modify, it should be obvious that the potential exists
    177  *	for users to corrupt the file to the degree that elfedit itself
    178  *	may fail, or produce spurious results. We allow such changes for
    179  *	several reasons:
    180  *
    181  *	1) Such corruption does not happen in the most obvious and
    182  *		useful operations elfedit supports, but comes as a result
    183  *		of modifying fields that contain size and offset information
    184  *		used to navigate the file. Non-ELF developers have
    185  *		little practical reason to change such things.
    186  *
    187  *	2) Producing a corrupt ELF file can be very useful
    188  *		for R&D and/or testing purposes.
    189  *
    190  *	3) ELF is sufficiently complex that no absolute guarantees can
    191  *		be made about "safe" operations, beyond the basic
    192  *		and obvious things that are of practical use.
    193  *
    194  *	One way we protect ourselves is via the information cached in
    195  *	the elfedit_obj_state_t structure at startup. By using this
    196  *	information, rather than constantly fetching it via libelf,
    197  *	we protect ourselves against many user changes, such as changing the
    198  *	program or section header offsets, or similar size/position fields.
    199  *
    200  *	Of course, we make no assurances that that we will be able to
    201  *	read the resulting file in a subsequent session.
    202  */
    203 typedef struct {
    204 	const char		*os_file;	/* Path to ELF file */
    205 	int			os_fd;		/* Open file descriptor */
    206 	Elf			*os_elf;	/* ELF descriptor */
    207 	Elf32_Ehdr		*os_ehdr;	/* ELF header */
    208 	Elf32_Word		os_dynndx;	/* Index of dynamic section */
    209 	size_t			os_shstrndx;	/* Index of section header */
    210 						/*	string table section */
    211 	size_t			os_shnum;	/* # of sections in file */
    212 	elfedit32_section_t	*os_secarr;	/* Section data */
    213 	size_t			os_phnum;	/* # of program headers */
    214 	Elf32_Phdr		*os_phdr;	/* Program header array */
    215 	size_t			os_symtabnum;	/* # items in os_symtab[] */
    216 	elfedit32_symtab_t	*os_symtab;	/* Array of symbol tbl info  */
    217 } elfedit32_obj_state_t;
    218 
    219 typedef struct {
    220 	const char		*os_file;
    221 	int			os_fd;
    222 	Elf			*os_elf;
    223 	Elf64_Ehdr		*os_ehdr;
    224 	Elf64_Word		os_dynndx;
    225 	size_t			os_shstrndx;
    226 	size_t			os_shnum;
    227 	elfedit64_section_t	*os_secarr;
    228 	size_t			os_phnum;
    229 	Elf64_Phdr		*os_phdr;
    230 	size_t			os_symtabnum;
    231 	elfedit64_symtab_t	*os_symtab;
    232 } elfedit64_obj_state_t;
    233 
    234 #ifdef _ELF64
    235 #define	elfedit_obj_state_t	elfedit64_obj_state_t
    236 #else
    237 #define	elfedit_obj_state_t	elfedit32_obj_state_t
    238 #endif
    239 
    240 
    241 /*
    242  * Bit values for editor state.
    243  */
    244 typedef enum {
    245 	ELFEDIT_F_AUTOPRINT = 1, /* Print informational text about edits */
    246 	ELFEDIT_F_DEBUG = 2,	/* Print informational text about operations */
    247 	ELFEDIT_F_READONLY = 4,	/* File is processed readonly */
    248 } elfedit_flag_t;
    249 
    250 /*
    251  * Type used to represent the output style for printing ELF values.
    252  *
    253  * DEFAULT - Output is in 'elfdump' style, designed for human eyes.
    254  *	Headers, and additional information are shown.
    255  * SIMPLE - Output is simple, consisting only of the target item.
    256  *	Integer values are shown as symbolic constants when possible,
    257  *	and integers otherwise.
    258  * NUM - Like SIMPLE, except integer values are always shown as
    259  *	integer constants, and strings are shown as the integer
    260  *	offset into the string table.
    261  */
    262 typedef enum {
    263 	ELFEDIT_OUTSTYLE_DEFAULT = 0,
    264 	ELFEDIT_OUTSTYLE_SIMPLE = 1,
    265 	ELFEDIT_OUTSTYLE_NUM = 2
    266 } elfedit_outstyle_t;
    267 
    268 
    269 /*
    270  * The elfedit_module_t, and the types it references, are defined
    271  * by loadable elfedit modules, and used by elfedit. These structures
    272  * need to communicate internationalized strings for elfedit to print.
    273  *
    274  * We want to leave the choice of internationalization APIs, as well as
    275  * the decision about whether or not to even to it to the individual
    276  * modules. Hence, we do not use a simple (const char *) pointer to
    277  * communicate potentially internationalized strings. Instead, we define
    278  * elfedit_i18nhdl_t, an opaque type guaranteed to be large enough
    279  * to hold a pointer. Each module casts the handle needed to access the
    280  * string to this type. Each module also supplies a function
    281  * (mod_i18nhdl_to_str field of elfedit_module_t) that given one
    282  * of these opaque keys, will return a (const char *) pointer to the
    283  * actual string, for elfedit to print.
    284  *
    285  * If the underlying module doesn't want to implement i18n support,
    286  * all it has to do is cast the strings to elfedit_i18nhdl_t and
    287  * back.
    288  */
    289 typedef uintptr_t elfedit_i18nhdl_t;
    290 
    291 
    292 
    293 /*
    294  * Macro to handle casting international string "handles" to the
    295  * elfedit_i18nhdl_t opaque type.
    296  */
    297 #define	ELFEDIT_I18NHDL(_i18n_str_ref) ((elfedit_i18nhdl_t)_i18n_str_ref)
    298 
    299 
    300 /*
    301  * Return values from command functions
    302  */
    303 typedef enum {
    304 	ELFEDIT_CMDRET_NONE = 0,	/* Nothing to report */
    305 	ELFEDIT_CMDRET_MOD = 1,		/* Command modified output ELF file */
    306 	ELFEDIT_CMDRET_MOD_OS_MACH = 2, /* As per _MOD, include ELF header */
    307 					/*	osabi or machine change */
    308 	ELFEDIT_CMDRET_FLUSH = 3	/* Output file flushed: elf_update() */
    309 } elfedit_cmdret_t;
    310 
    311 /*
    312  * Prototype of an implementation function for an edit command. Note that
    313  * commands do not return a status:
    314  *	- Success is indicated by a normal return.
    315  *	- The command indicates a fatal error by calling elfedit_msg() with the
    316  *		ELFEDIT_MSG_ERR type, in which case execution does not return
    317  *		to the command, and the elfedit command loop knows that an
    318  *		error occurred.
    319  *	- The command is responsible for using the standard libelf
    320  *		mechanisms to indicate when changes have been made to
    321  *		the ELF file.
    322  */
    323 typedef elfedit_cmdret_t elfedit32_cmd_func_t(elfedit32_obj_state_t *state,
    324     int argc, const char *argv[]);
    325 typedef elfedit_cmdret_t elfedit64_cmd_func_t(elfedit64_obj_state_t *state,
    326     int argc, const char *argv[]);
    327 #ifdef _ELF64
    328 #define	elfedit_cmd_func_t	elfedit64_cmd_func_t
    329 #else
    330 #define	elfedit_cmd_func_t	elfedit32_cmd_func_t
    331 #endif
    332 
    333 
    334 /*
    335  * An elfedit command (elfedit_cmd_t) has a cmd_cpl field that
    336  * can be set to a command completion function. If such a function
    337  * is present (non-NULL), and the user presses the tab key at the
    338  * command line while the cursor is at a plain (non option) argument,
    339  * elfedit calls the function, passing it all the tokens up through
    340  * the one needing completion.  The function can use elfedit_cpl_match()
    341  * to enter possible alternatives.  Additionally, there are helper
    342  * functions built on top of elfedit_cpl_match() that simplify common cases.
    343  *
    344  *	elfedit_cpl_ato[iu]() - enter matches from elfedit_ato[iu]_sym_t
    345  *		mappings.
    346  *	elfedit_cpl_atoconst() - Enter matches for well known constants
    347  *	elfedit_cpl_command() - enter matches for all known commands
    348  *	elfedit_cpl_mod() - enter matches for all known modules.
    349  *	elfedit_cpl_ndx() - enter numeric index as a match
    350  *
    351  * The completion function is passed the following arguments:
    352  *
    353  *	obj_state - Object state. Will be NULL if elfedit session does not
    354  *		have an active object. The completion function must test
    355  *		the pointer before using it.
    356  *	cpldata - Completion data, to be passed to elfedit_cpl_match()
    357  *		or the helper functions built on it to register alternative
    358  *		strings.
    359  *	argc, argv - The tokens from the start of the line throught
    360  *		the one needing completion, which will always
    361  *		be cmdcpl_argv[cmdcpl_argc - 1].
    362  *	num_opt - A count of the optional arguments (those starting with
    363  *		'-' at the beginning of argv. This means that argv[num_opt]
    364  *		is the first plain argument, and the 1-based positional
    365  *		number of the plain argument for which command completion
    366  *		is needed is (argc - num_opt).
    367  */
    368 typedef void elfedit32_cmdcpl_func_t(elfedit32_obj_state_t *state,
    369     void *cpldata, int argc, const char *argv[], int num_opt);
    370 typedef void elfedit64_cmdcpl_func_t(elfedit64_obj_state_t *state,
    371     void *cpldata, int argc, const char *argv[], int num_opt);
    372 #ifdef _ELF64
    373 #define	elfedit_cmdcpl_func_t	elfedit64_cmdcpl_func_t
    374 #else
    375 #define	elfedit_cmdcpl_func_t	elfedit32_cmdcpl_func_t
    376 #endif
    377 
    378 
    379 
    380 
    381 /*
    382  * Command option/argument descriptor. These structures
    383  * are used to represent each option and plain argument accepted
    384  * by a command, via the cmd_opt and cmd_args fields in the
    385  * command definition (elfedit_cmd_t). Each descriptor consists
    386  * of a name, a help string (formatted for display via sys:help),
    387  * and a flags field that conveys extra information about the
    388  * item:
    389  *
    390  *	ELFEDIT_CMDOA_F_OPT
    391  *	The item is optional. This flag is implicit for options
    392  *	and need only be set for plain arguments.
    393  *
    394  *	ELFEDIT_CMDOA_F_VALUE
    395  *	The item has a value, which is found in the following
    396  *	item. This flag only has meaning for options, and should
    397  *	not be set for plain arguments. The descriptor for the
    398  *	value is found in the next array element, and only the
    399  *	oa_name field is used (the other should be set t 0).
    400  *
    401  *	ELFEDIT_CMDOA_F_MULT
    402  *	More than one of the specified items may be specified
    403  *
    404  *	ELFEDIT_CMDOA_F_INHERIT
    405  *	This is an item for which a common definition exists.
    406  *	Elfedit will substitute the standard values for the
    407  *	name, help text, and flags. This enforces consistency
    408  *	in documentation, plus it is easier for the module author.
    409  *	When ELFEDIT_CMDOA_F_INHERIT is set:
    410  *		- oa_name should be set to one of the ELFEDIT_STDOA_
    411  *			values to specifiy which standard item is being
    412  *			inherited.
    413  *		- oa_help must be set to NULL.
    414  *		- It is an error to set any other flags with
    415  *			ELFEDIT_CMDOA_F_INHERIT.
    416  *		- oa_idmask and oa_excmask are used in the normal way.
    417  *
    418  * The oa_idmask and oa_excmask fields are used to identify options,
    419  * and to support mutual exclusion (when two or more options cannot be
    420  * used together). They are ignored for arguments, and should be set to 0.
    421  * oa_idmask is used to uniquely identify each item. When elfedit_getopt()
    422  * matches an option, it returns the value of oa_idmask to the caller to
    423  * indicate which option was matched. elfedit enforces the following rules
    424  * for oa_idmask, and will refuse to load a module that does not follow them:
    425  *	- The value of oa_idmask must be 0, or have a value that
    426  *		is a power of 2 (i.e. only has one bit set).
    427  *	- Each item that sets a non-0 value for oa_idmask must have
    428  *		a unique value.
    429  *	- If oa_idmask is 0, oa_excmask must be 0 also.
    430  *	- oa_excmask is set to 0 if an item is not mutually exclusive
    431  *		to any other item. Otherwise, it should set the bit
    432  *		values representing the items it is mutually exclusive to.
    433  *	- An oa_idmask value of 0 can be used for any item that
    434  *		the module does not need to identify, and which
    435  *		is not mutually exclusive to any other item.
    436  * As elfedit_getopt() processes items, it maintains a bitmask combining the
    437  * oa_idmask fields of all the options already seen. For each option, it uses
    438  * oa_excmask to check for conflicts.
    439  *
    440  * note: elfedit enforces the rule that options consist of a '-'
    441  *	character followed by at least one character when a module
    442  *	is loaded.
    443  */
    444 typedef enum {
    445 	ELFEDIT_CMDOA_F_OPT =	1,	/* Item is optional */
    446 	ELFEDIT_CMDOA_F_VALUE =	2,	/* Item has a value arg following */
    447 	ELFEDIT_CMDOA_F_MULT =	4,	/* More than one are allowed */
    448 	ELFEDIT_CMDOA_F_INHERIT = 8,	/* Inherit definition: See above */
    449 } elfedit_cmd_oa_flag_t;
    450 
    451 typedef u_longlong_t elfedit_cmd_oa_mask_t;
    452 
    453 typedef struct {
    454 	const char		*oa_name;	/* Name of option */
    455 	elfedit_i18nhdl_t	oa_help;	/* Help text for option */
    456 	elfedit_cmd_oa_flag_t	oa_flags;	/* Additional attributes */
    457 	elfedit_cmd_oa_mask_t	oa_idmask;	/* Unique id, returned by */
    458 						/* 	elfedit_getopt */
    459 						/*	for use by caller */
    460 	elfedit_cmd_oa_mask_t	oa_excmask;	/* Mutual exclusion mask */
    461 } elfedit_cmd_optarg_t;
    462 
    463 
    464 
    465 /*
    466  * These values define the standard options and arguments that a module
    467  * can inherit using the ELFEDIT_CMDOA_F_INHERIT flag (described above).
    468  * New items must be added at the end --- reordering the list will
    469  * require all modules to be rebuilt.
    470  *
    471  * Note: 0 cannot be used as a ELFEDIT_STDOA_ value, because a NULL
    472  *	value of oa_name is used to terminate argument and options lists.
    473  *	Therefore, these values start at 1.
    474  */
    475 #define	ELFEDIT_STDOA_OPT_O		((const char *) 1)	/* -o ostyle */
    476 #define	ELFEDIT_STDOA_OPT_AND		((const char *) 2)	/* -and */
    477 #define	ELFEDIT_STDOA_OPT_CMP		((const char *) 3)	/* -cmp */
    478 #define	ELFEDIT_STDOA_OPT_OR		((const char *) 4)	/* -or */
    479 
    480 #define	ELFEDIT_NUM_STDOA	4	/* # of ELFEDIT_STDOA_ definitions */
    481 
    482 
    483 
    484 /*
    485  * Definition of a command
    486  *
    487  * This structure includes an elfedit_cmd_func_t pointer, which has
    488  * different definitions for different ELFCLASS. Rather than needlessly
    489  * complicate the code with three versions of this type, and any
    490  * type that uses it, we simply use the GenericClass type. elfedit
    491  * will always cast this to the correct type before calling a module.
    492  *
    493  * cmd_name is an array of pointers to the names for the command.
    494  * The "primary" name should always be first, followed by any alias
    495  * names. The final element of the array must be a NULL pointer,
    496  * which terminates the list. Every command is required to have at
    497  * least one name, so code is allowed to assume that the first element
    498  * of cmd_name is non-NULL, and contains the primary name.
    499  *
    500  * Many modules provide a "default" command, which is a command
    501  * that is run if only the module name is specified, followed
    502  * by a colon (i.e. "sym:"). The way this is implemented is to
    503  * give the desired default command an empty string as an alias.
    504  * Note that the primary name cannot be an empty string, only the
    505  * alias name.
    506  *
    507  * cmd_opts and cmd_args are each an array of elfedit_cmd_argdesc_t
    508  * structures, that describe the options and plain arguments accepted
    509  * by the command. These arrays are used to general help text for
    510  * the commands. The cmd_opts array is also used to provide command
    511  * completion for options. Both of these arrays are terminated by
    512  * a final NULL element (all fields zero).
    513  */
    514 typedef struct {
    515 	elfedit32_cmd_func_t	*cmd_func;	/* Implementation */
    516 	elfedit32_cmdcpl_func_t	*cmd_cplfunc;	/* Completion function */
    517 	const char		**cmd_name;	/* Cmd names (null term.) */
    518 	elfedit_i18nhdl_t	cmd_desc;	/* Short desc. of cmd purpose */
    519 	elfedit_i18nhdl_t	cmd_help;	/* Help text for the command */
    520 	elfedit_cmd_optarg_t	*cmd_opt;	/* Options */
    521 	elfedit_cmd_optarg_t	*cmd_args;	/* Plain arguments */
    522 } elfedit32_cmd_t;
    523 
    524 typedef struct {
    525 	elfedit64_cmd_func_t	*cmd_func;
    526 	elfedit64_cmdcpl_func_t	*cmd_cplfunc;
    527 	const char		**cmd_name;
    528 	elfedit_i18nhdl_t	cmd_desc;
    529 	elfedit_i18nhdl_t	cmd_help;
    530 	elfedit_cmd_optarg_t	*cmd_opt;
    531 	elfedit_cmd_optarg_t	*cmd_args;
    532 } elfedit64_cmd_t;
    533 
    534 #ifdef _ELF64
    535 #define	elfedit_cmd_t		elfedit64_cmd_t
    536 #else
    537 #define	elfedit_cmd_t		elfedit32_cmd_t
    538 #endif
    539 
    540 
    541 
    542 /*
    543  * elfedit modules version themselves so that we can alter the definition
    544  * of elfedit_module_t in a backward compatible way.
    545  */
    546 typedef enum {
    547 	ELFEDIT_VER_NONE = 0,
    548 	ELFEDIT_VER_CURRENT = 1,
    549 	ELFEDIT_VER_NUM = 2
    550 } elfedit_module_version_t;
    551 
    552 
    553 /*
    554  * Each module returns a pointer to an elfedit_module_t, describing
    555  * what commands the module provides.
    556  *
    557  * Note: mod_cmds is a NULL terminated array of command defs. This
    558  * means that the final element in the array should have all of its
    559  * fields set to NULL.
    560  *
    561  * The mod_i18nhdl_to_str function pointer is explained above
    562  * with the definition of elfedit_i18nhdl_t.
    563  */
    564 typedef const char *(* elfedit_mod_i18nhdl_to_str_func_t)(elfedit_i18nhdl_t);
    565 
    566 typedef struct {
    567 	elfedit_module_version_t mod_version;	/* version */
    568 	const char		*mod_name;	/* Name of module */
    569 	elfedit_i18nhdl_t	mod_desc;	/* Short desc. of mod purpose */
    570 	elfedit32_cmd_t		*mod_cmds;	/* Array of command defs */
    571 						/* i18n -> (char *) fcn */
    572 	elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str;
    573 } elfedit32_module_t;
    574 
    575 typedef struct {
    576 	elfedit_module_version_t mod_version;
    577 	const char		*mod_name;
    578 	elfedit_i18nhdl_t	mod_desc;
    579 	elfedit64_cmd_t		*mod_cmds;
    580 	elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str;
    581 } elfedit64_module_t;
    582 
    583 #ifdef _ELF64
    584 #define	elfedit_module_t	elfedit64_module_t
    585 #else
    586 #define	elfedit_module_t	elfedit32_module_t
    587 #endif
    588 
    589 
    590 /*
    591  * Each module is a sharable library, expected to provide a single global
    592  * function, named elfedit_init(), with the following prototype.
    593  */
    594 typedef elfedit_module_t *elfedit_init_func_t(elfedit_module_version_t version);
    595 
    596 
    597 /*
    598  * Prototype for elfedit_write(), and for outfunc argument
    599  * to elfedit_str_to_c_literal().
    600  */
    601 typedef void elfedit_write_func_t(const void *ptr, size_t size);
    602 
    603 
    604 /*
    605  * Core elfedit functions exported for use by modules
    606  */
    607 extern void elfedit_command_usage(void);
    608 extern void elfedit_cpl_command(void *cpldata);
    609 extern void elfedit_cpl_match(void *cpldata, const char *str, int casefold);
    610 extern void elfedit_cpl_ndx(void *cpldata, uint_t ndx);
    611 extern void elfedit_elferr(const char *file, const char *libelf_rtn_name);
    612 extern elfedit_flag_t elfedit_flags(void);
    613 extern void *elfedit_malloc(const char *item_name, size_t size);
    614 extern void elfedit_msg(elfedit_msg_t type, const char *format, ...);
    615 extern elfedit_outstyle_t elfedit_outstyle(void);
    616 extern void elfedit_pager_init(void);
    617 extern void elfedit_printf(const char *format, ...);
    618 extern void *elfedit_realloc(const char *item_name, void *ptr, size_t size);
    619 extern void elfedit_str_to_c_literal(const char *str,
    620     elfedit_write_func_t *outfunc);
    621 extern elfedit_write_func_t elfedit_write;
    622 
    623 /*
    624  * Core elfedit functions exported for use by sys: module only
    625  */
    626 extern void elfedit_cpl_module(void *cpldata, int load_all_modules);
    627 
    628 
    629 /*
    630  * elfedit modules are expected to define two functions, one for
    631  * each ELFCLASS. Define a generic name for this function, based on
    632  * the class being supported by the including module.
    633  */
    634 #ifdef _ELF64
    635 #define	elfedit_init		elfedit64_init
    636 #else
    637 #define	elfedit_init		elfedit32_init
    638 #endif
    639 
    640 
    641 
    642 /*
    643  * It is common to search the dynamic section for specific elements.
    644  * Structures of this type are used to represent the contents of such
    645  * elements in a systematic way. The elfedit_dyn_elt_init() function
    646  * is used to prepare these strucutres for use.
    647  */
    648 typedef struct {
    649 	int		dn_seen;	/* True if this item has been seen */
    650 	Elf32_Word	dn_ndx;		/* Index of item in dynamic array */
    651 	Elf32_Dyn	dn_dyn;		/* Contents of dynamic item */
    652 } elfedit32_dyn_elt_t;
    653 
    654 typedef struct {
    655 	int		dn_seen;
    656 	Elf64_Word	dn_ndx;
    657 	Elf64_Dyn	dn_dyn;
    658 } elfedit64_dyn_elt_t;
    659 
    660 #ifdef _ELF64
    661 #define	elfedit_dyn_elt_t	elfedit64_dyn_elt_t
    662 #else
    663 #define	elfedit_dyn_elt_t	elfedit32_dyn_elt_t
    664 #endif
    665 
    666 /*
    667  * The elfedit_atoi() and elfedit_atoui() functions can optionally
    668  * accept an array of these structures, giving symbolic names that
    669  * will be accepted instead of numeric codes. If such an array is
    670  * present, the supplied string has it's leading and trailing whitespace
    671  * removed and is then compared to the list, and if there is a match,
    672  * the corresponding integer value is returned.
    673  *
    674  * The final array element must have its name field set to NULL.
    675  */
    676 typedef u_longlong_t elfedit_atoui_t;
    677 typedef struct {
    678 	const char	*sym_name;
    679 	elfedit_atoui_t	sym_value;
    680 } elfedit_atoui_sym_t;
    681 typedef longlong_t elfedit_atoi_t;
    682 typedef struct {
    683 	const char	*sym_name;
    684 	elfedit_atoi_t	sym_value;
    685 } elfedit_atoi_sym_t;
    686 
    687 
    688 /*
    689  * The elfedit_atoconst*() functions are built on top of the atoui routines.
    690  * These routines accept an elfedit_const_t code instead of a
    691  * pointer to an elfedit_atoui_sym_t array, and use internally
    692  * predefined tables of elfedit_atoui_sym_t in order to do the desired
    693  * mappings. elfedit modules are encouraged to use these standard
    694  * tables instead of defining their own elfedit_atoui_sym_t arrays.
    695  *
    696  * note:
    697  *	- The values assigned here must be in agreement with the
    698  *		sym_table[] array defined in elfconst.c.
    699  *	- Once defined, these values must not change. Reordering the
    700  *		list will require all modules to be rebuilt, and will
    701  *		break backward compatability. New items should be
    702  *		added to the end.
    703  */
    704 typedef enum {
    705 	ELFEDIT_CONST_OUTSTYLE =	0,	/* elfedit output styles  */
    706 	ELFEDIT_CONST_OUTSTYLE_MO =	1,	/* ostyles with -o prefix */
    707 	ELFEDIT_CONST_BOOL =		2,	/* boolean names */
    708 	ELFEDIT_CONST_SHT_STRTAB =	3,	/* ELF SHT_STRTAB */
    709 	ELFEDIT_CONST_SHT_SYMTAB =	4,	/* ELF SHT_SYMTAB */
    710 	ELFEDIT_CONST_SHT_DYNSYM =	5,	/* ELF SHT_DYNSYM */
    711 	ELFEDIT_CONST_SHT_LDYNSYM =	6,	/* ELF SHT_SUNW_LDYNSYM */
    712 	ELFEDIT_CONST_SHN =		7,	/* ELF SHN_ section indexes  */
    713 	ELFEDIT_CONST_SHT =		8,	/* ELF SHT_ section types  */
    714 	ELFEDIT_CONST_SHT_ALLSYMTAB =	9,	/* ELF SHT_ symbol table */
    715 						/*	section types */
    716 	ELFEDIT_CONST_DT =		10,	/* Dynamic tags: DT_ */
    717 	ELFEDIT_CONST_DF =		11,	/* DT_FLAGS bits */
    718 	ELFEDIT_CONST_DF_P1 =		12,	/* DF_POSFLAG_1 bits */
    719 	ELFEDIT_CONST_DF_1 =		13,	/* DT_FLAGS_1 bits */
    720 	ELFEDIT_CONST_DTF_1 =		14,	/* DT_FEATURE_1 bits */
    721 	ELFEDIT_CONST_EI =		15,	/* ELF header e_ident indexes */
    722 	ELFEDIT_CONST_ET =		16,	/* Ehdr obj type */
    723 	ELFEDIT_CONST_ELFCLASS =	17,	/* Ehdr wordsize (32,64) */
    724 	ELFEDIT_CONST_ELFDATA =		18,	/* Ehdr endian */
    725 	ELFEDIT_CONST_EF =		19,	/* Ehdr flags */
    726 	ELFEDIT_CONST_EV =		20,	/* Ehdr version */
    727 	ELFEDIT_CONST_EM =		21,	/* Ehdr machine */
    728 	ELFEDIT_CONST_ELFOSABI =	22,	/* Ehdr ABI */
    729 	ELFEDIT_CONST_EAV =		23,	/* Ehdr ABI version */
    730 	ELFEDIT_CONST_PT =		24,	/* Phdr type */
    731 	ELFEDIT_CONST_PF =		25,	/* Phdr flags */
    732 	ELFEDIT_CONST_SHF =		26,	/* Shdr flags */
    733 	ELFEDIT_CONST_STB =		27,	/* Sym binding */
    734 	ELFEDIT_CONST_STT =		28,	/* Sym type */
    735 	ELFEDIT_CONST_STV =		29,	/* Sym visibility */
    736 	ELFEDIT_CONST_SYMINFO_BT =	30,	/* Syminfo boundto */
    737 	ELFEDIT_CONST_SYMINFO_FLG =	31,	/* Syminfo flags */
    738 	ELFEDIT_CONST_CA =		32,	/* Capabilities tags */
    739 	ELFEDIT_CONST_AV =		33,	/* hardware capabilities */
    740 	ELFEDIT_CONST_SF1_SUNW =	34,	/* software capabilities */
    741 
    742 	ELFEDIT_CONST_NUM =		35,	/* # of constant types */
    743 } elfedit_const_t;
    744 
    745 /*
    746  * Given an elfedit_const_t, return the array of elfedit_atoui_sym_t
    747  * entries that it represents.
    748  */
    749 extern elfedit_atoui_sym_t *elfedit_const_to_atoui(elfedit_const_t const_type);
    750 
    751 /*
    752  * ato[u]i and const routines, used to turn strings into numeric values,
    753  * with support for mapping symbol names to numbers, and range checking.
    754  */
    755 extern elfedit_atoi_t elfedit_atoi(const char *str,
    756     const elfedit_atoi_sym_t *sym);
    757 extern elfedit_atoui_t elfedit_atoui(const char *str,
    758     const elfedit_atoui_sym_t *sym);
    759 extern elfedit_atoui_t elfedit_atoconst(const char *str,
    760     elfedit_const_t const_type);
    761 
    762 extern int elfedit_atoi2(const char *str, const elfedit_atoi_sym_t *sym,
    763     elfedit_atoi_t *v);
    764 extern int elfedit_atoui2(const char *str, const elfedit_atoui_sym_t *sym,
    765     elfedit_atoui_t *);
    766 extern int elfedit_atoconst2(const char *str, elfedit_const_t const_type,
    767     elfedit_atoui_t *);
    768 
    769 extern elfedit_atoi_t elfedit_atoi_range(const char *str,
    770     const char *item_name, elfedit_atoi_t min, elfedit_atoi_t max,
    771     const elfedit_atoi_sym_t *sym);
    772 extern elfedit_atoui_t elfedit_atoui_range(const char *str,
    773     const char *item_name, elfedit_atoui_t min, elfedit_atoui_t max,
    774     const elfedit_atoui_sym_t *sym);
    775 extern elfedit_atoui_t elfedit_atoconst_range(const char *str,
    776     const char *item_name, elfedit_atoui_t min, elfedit_atoui_t max,
    777     elfedit_const_t const_type);
    778 
    779 extern int elfedit_atoi_range2(const char *str, elfedit_atoi_t min,
    780     elfedit_atoi_t max, const elfedit_atoi_sym_t *sym, elfedit_atoi_t *v);
    781 extern int elfedit_atoui_range2(const char *str, elfedit_atoui_t min,
    782     elfedit_atoui_t max, const elfedit_atoui_sym_t *sym, elfedit_atoui_t *v);
    783 extern int elfedit_atoconst_range2(const char *str, elfedit_atoui_t min,
    784     elfedit_atoui_t max, elfedit_const_t const_type, elfedit_atoui_t *v);
    785 
    786 extern const char *elfedit_atoi_value_to_str(const elfedit_atoi_sym_t *sym,
    787     elfedit_atoi_t value, int required);
    788 extern const char *elfedit_atoui_value_to_str(const elfedit_atoui_sym_t *sym,
    789     elfedit_atoui_t value, int required);
    790 extern const char *elfedit_atoconst_value_to_str(elfedit_const_t const_type,
    791     elfedit_atoui_t value, int required);
    792 
    793 extern void elfedit_cpl_atoi(void *cpldata, const elfedit_atoi_sym_t *sym);
    794 extern void elfedit_cpl_atoui(void *cpldata, const elfedit_atoui_sym_t *sym);
    795 extern void elfedit_cpl_atoconst(void *cpldata, elfedit_const_t const_type);
    796 
    797 
    798 /*
    799  * Convenience functions built on top of the ato[u]i routines.
    800  */
    801 extern int elfedit_atobool(const char *str, const char *item_name);
    802 extern elfedit_atoui_t elfedit_atoshndx(const char *str, size_t shnum);
    803 
    804 
    805 /*
    806  * elfedit provides a getopt utility for use by the module commands.
    807  * elfedit_getopt_state_t is the state block used by elfedit_getopt().
    808  * elfedit_getopt_ret_t is the definition of the values returned to
    809  * the user by elfedit_getopt() when an option is matched. Elfedit
    810  * getopt processing is done as follows:
    811  *
    812  * 1) The caller initializes an elfedit_getopt_state_t struct via
    813  *	a call to elfedit_getopt_init(). The contents of this structure
    814  *	must not be accessed by the caller, as they are all private and
    815  *	subject to change.
    816  * 2) Repeated calls are made to elfedit_getopt(), as long as it returns
    817  *	a non-NULL pointer to an elfedit_getopt_ret_t structure. If the
    818  *	matched option has a value (ELFEDIT_CMDOA_F_VALUE), then the gor_value
    819  *	field contains the pointer to the string. Otherwise, gor_value is NULL.
    820  * 3) As elfedit_getopt() consumes optional arguments from the argc/argv
    821  *	passed to elfedit_getopt_init(), it adjusts argc/argc to skip over
    822  *	them. Once elfedit_getopt() returns NULL to indicate that there are no
    823  *	more options to match, argc/argv have been adjusted so that they
    824  *	reference the plain arguments.
    825  */
    826 typedef struct {
    827 	elfedit_cmd_oa_mask_t gor_idmask;	/* oa_idmask from matching */
    828 					/*	elfedit_cmd_optarg_t. Can be */
    829 					/*	used to quickly identify opt */
    830 	const char	*gor_value;	/* Opt value if ELFEDIT_CMDOA_F_VALUE */
    831 					/*	Otherwise, NULL */
    832 } elfedit_getopt_ret_t;
    833 typedef struct {
    834 	int			*go_argc;	/* Pointer to # of options */
    835 	const char		***go_argv;	/* Ptr to array of opt strs */
    836 	elfedit_cmd_optarg_t	*go_optarg;	/* Array of allowed options */
    837 	elfedit_cmd_oa_mask_t	go_idmask;	/* Combined id masks of all */
    838 						/*	seen options */
    839 	int			go_done;	/* True if last option seen */
    840 	const char		*go_sglgrp;	/* Group of 1-letter opts */
    841 	elfedit_getopt_ret_t	go_ret;		/* Data returned to user */
    842 } elfedit_getopt_state_t;
    843 
    844 
    845 
    846 /*
    847  * getopt related routines
    848  */
    849 extern void elfedit_getopt_init(elfedit_getopt_state_t *,
    850     int *, const char ***);
    851 extern elfedit_getopt_ret_t *elfedit_getopt(elfedit_getopt_state_t *);
    852 
    853 
    854 
    855 /*
    856  * Additional utility functions exported for use by modules
    857  */
    858 extern void elfedit_array_elts_delete(const char *name_str, void *data_start,
    859     size_t entsize, size_t num_ent, size_t start_ndx, size_t cnt);
    860 
    861 extern void elfedit_array_elts_move(const char *name_str, void *data_start,
    862     size_t entsize, size_t num_ent, size_t srcndx,
    863     size_t dstndx, size_t cnt, void *scr_item);
    864 
    865 extern int elfedit_bits_set(u_longlong_t v, int sizeof_orig_v);
    866 
    867 extern void elfedit32_dyn_elt_init(elfedit32_dyn_elt_t *dyn_elt);
    868 extern void elfedit64_dyn_elt_init(elfedit64_dyn_elt_t *dyn_elt);
    869 
    870 extern void elfedit32_dyn_elt_save(elfedit32_dyn_elt_t *elt, Elf32_Word ndx,
    871     Elf32_Dyn *dyn);
    872 extern void elfedit64_dyn_elt_save(elfedit64_dyn_elt_t *elt, Elf64_Word ndx,
    873     Elf64_Dyn *dyn);
    874 
    875 const char *elfedit32_dyn_offset_to_str(elfedit32_section_t *strsec,
    876     elfedit32_dyn_elt_t *dynelt);
    877 const char *elfedit64_dyn_offset_to_str(elfedit64_section_t *strsec,
    878     elfedit64_dyn_elt_t *dynelt);
    879 
    880 extern int elfedit32_dynstr_getpad(elfedit32_obj_state_t *obj_state,
    881     elfedit32_section_t *dynsec, elfedit32_dyn_elt_t *dyn_strpad);
    882 extern int elfedit64_dynstr_getpad(elfedit64_obj_state_t *obj_state,
    883     elfedit64_section_t *dynsec, elfedit64_dyn_elt_t *dyn_strpad);
    884 
    885 extern Elf32_Word elfedit32_dynstr_insert(elfedit32_section_t *dynsec,
    886     elfedit32_section_t *strsec, elfedit32_dyn_elt_t *dyn_strpad,
    887     const char *str);
    888 extern Elf64_Word elfedit64_dynstr_insert(elfedit64_section_t *dynsec,
    889     elfedit64_section_t *strsec, elfedit64_dyn_elt_t *dyn_strpad,
    890     const char *str);
    891 
    892 extern void elfedit32_modified_data(elfedit32_section_t *s);
    893 extern void elfedit64_modified_data(elfedit64_section_t *s);
    894 
    895 extern void elfedit32_modified_ehdr(elfedit32_obj_state_t *obj_state);
    896 extern void elfedit64_modified_ehdr(elfedit64_obj_state_t *obj_state);
    897 
    898 extern void elfedit32_modified_phdr(elfedit32_obj_state_t *obj_state);
    899 extern void elfedit64_modified_phdr(elfedit64_obj_state_t *obj_state);
    900 
    901 extern void elfedit32_modified_shdr(elfedit32_section_t *s);
    902 extern void elfedit64_modified_shdr(elfedit64_section_t *s);
    903 
    904 extern Elf32_Word elfedit32_name_to_shndx(elfedit32_obj_state_t *obj_state,
    905     const char *shnam);
    906 extern Elf64_Word elfedit64_name_to_shndx(elfedit64_obj_state_t *obj_state,
    907     const char *shnam);
    908 
    909 extern int elfedit32_name_to_symndx(elfedit32_section_t *symsec,
    910     elfedit32_section_t *strsec, const char *name, elfedit_msg_t msg_type,
    911     Elf32_Word *ret_symndx);
    912 extern int elfedit64_name_to_symndx(elfedit64_section_t *symsec,
    913     elfedit64_section_t *strsec, const char *name, elfedit_msg_t msg_type,
    914     Elf64_Word *ret_symndx);
    915 
    916 extern const char *elfedit32_offset_to_str(elfedit32_section_t *strsec,
    917     Elf32_Word offset, elfedit_msg_t msg_type, int debug_msg);
    918 extern const char *elfedit64_offset_to_str(elfedit64_section_t *strsec,
    919     Elf64_Word offset, elfedit_msg_t msg_type, int debug_msg);
    920 
    921 extern int elfedit32_sec_findstr(elfedit32_section_t *sec, Elf32_Word tail_ign,
    922     const char *str, Elf32_Word *ret_offset);
    923 extern int elfedit64_sec_findstr(elfedit64_section_t *sec, Elf64_Word tail_ign,
    924     const char *str, Elf64_Word *ret_offset);
    925 
    926 extern elfedit32_section_t *elfedit32_sec_get(
    927     elfedit32_obj_state_t *obj_state, Elf32_Word shndx);
    928 extern elfedit64_section_t *elfedit64_sec_get(
    929     elfedit64_obj_state_t *obj_state, Elf64_Word shndx);
    930 
    931 extern elfedit32_section_t *elfedit32_sec_getcap(
    932     elfedit32_obj_state_t *obj_state, Elf32_Cap **cap, Elf32_Word *num);
    933 extern elfedit64_section_t *elfedit64_sec_getcap(
    934     elfedit64_obj_state_t *obj_state, Elf64_Cap **cap, Elf64_Word *num);
    935 
    936 extern elfedit32_section_t *elfedit32_sec_getdyn(
    937     elfedit32_obj_state_t *obj_state, Elf32_Dyn **dyn, Elf32_Word *num);
    938 extern elfedit64_section_t *elfedit64_sec_getdyn(
    939     elfedit64_obj_state_t *obj_state, Elf64_Dyn **dyn, Elf64_Word *num);
    940 
    941 extern elfedit32_section_t *elfedit32_sec_getstr(
    942     elfedit32_obj_state_t *obj_state, Elf32_Word shndx, int);
    943 extern elfedit64_section_t *elfedit64_sec_getstr(
    944     elfedit64_obj_state_t *obj_state, Elf64_Word shndx, int);
    945 
    946 extern elfedit32_section_t *elfedit32_sec_getsyminfo(
    947     elfedit32_obj_state_t *obj_state, Elf32_Syminfo **syminfo, Elf32_Word *num);
    948 extern elfedit64_section_t *elfedit64_sec_getsyminfo(
    949     elfedit64_obj_state_t *obj_state, Elf64_Syminfo **syminfo, Elf64_Word *num);
    950 
    951 extern elfedit32_section_t *elfedit32_sec_getsymtab(
    952     elfedit32_obj_state_t *obj_state, int by_index, Elf32_Word index,
    953     const char *name, Elf32_Sym **sym, Elf32_Word *num,
    954     elfedit32_symtab_t **aux_info);
    955 extern elfedit64_section_t *elfedit64_sec_getsymtab(
    956     elfedit64_obj_state_t *obj_state, int by_index, Elf64_Word index,
    957     const char *name, Elf64_Sym **sym, Elf64_Word *num,
    958     elfedit64_symtab_t **aux_info);
    959 
    960 extern elfedit32_section_t *elfedit32_sec_getversym(
    961     elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec,
    962     Elf32_Versym **versym, Elf32_Word *num);
    963 extern elfedit64_section_t *elfedit64_sec_getversym(
    964     elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec,
    965     Elf64_Versym **versym, Elf64_Word *num);
    966 
    967 extern elfedit32_section_t *elfedit32_sec_getxshndx(
    968     elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec,
    969     Elf32_Word **xshndx, Elf32_Word *num);
    970 extern elfedit64_section_t *elfedit64_sec_getxshndx(
    971     elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec,
    972     Elf64_Word **xshndx, Elf64_Word *num);
    973 
    974 extern int elfedit32_sec_issymtab(elfedit32_obj_state_t *obj_state,
    975     elfedit32_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list);
    976 extern int elfedit64_sec_issymtab(elfedit64_obj_state_t *obj_state,
    977     elfedit64_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list);
    978 
    979 extern const char *elfedit32_sec_msgprefix(elfedit32_section_t *sec);
    980 extern const char *elfedit64_sec_msgprefix(elfedit64_section_t *sec);
    981 
    982 extern const char *elfedit32_shndx_to_name(elfedit32_obj_state_t *obj_state,
    983     Elf32_Word shndx);
    984 extern const char *elfedit64_shndx_to_name(elfedit64_obj_state_t *obj_state,
    985     Elf64_Word shndx);
    986 
    987 extern Elf32_Word elfedit32_strtab_insert(elfedit32_obj_state_t *obj_state,
    988     elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str);
    989 extern Elf64_Word elfedit64_strtab_insert(elfedit64_obj_state_t *obj_state,
    990     elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str);
    991 
    992 extern void elfedit32_strtab_insert_test(elfedit32_obj_state_t *obj_state,
    993     elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str);
    994 extern void elfedit64_strtab_insert_test(elfedit64_obj_state_t *obj_state,
    995     elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str);
    996 
    997 extern int elfedit32_test_osabi(elfedit32_obj_state_t *obj_state, uchar_t osabi,
    998     int issue_err);
    999 extern int elfedit64_test_osabi(elfedit64_obj_state_t *obj_state, uchar_t osabi,
   1000     int issue_err);
   1001 
   1002 extern Elf32_Word elfedit32_type_to_shndx(elfedit32_obj_state_t *obj_state,
   1003     Elf32_Word shtype);
   1004 extern Elf64_Word elfedit64_type_to_shndx(elfedit64_obj_state_t *obj_state,
   1005     Elf64_Word shtype);
   1006 
   1007 
   1008 
   1009 /*
   1010  * Map the generic names for each of the ELFCLASS specific routines
   1011  * above to reference the proper routine for the current compilation.
   1012  */
   1013 #ifdef _ELF64
   1014 #define	elfedit_dyn_elt_init		elfedit64_dyn_elt_init
   1015 #define	elfedit_dyn_elt_save		elfedit64_dyn_elt_save
   1016 #define	elfedit_dyn_offset_to_str	elfedit64_dyn_offset_to_str
   1017 #define	elfedit_dynstr_getpad		elfedit64_dynstr_getpad
   1018 #define	elfedit_dynstr_insert		elfedit64_dynstr_insert
   1019 #define	elfedit_modified_data		elfedit64_modified_data
   1020 #define	elfedit_modified_ehdr		elfedit64_modified_ehdr
   1021 #define	elfedit_modified_phdr		elfedit64_modified_phdr
   1022 #define	elfedit_modified_shdr		elfedit64_modified_shdr
   1023 #define	elfedit_name_to_shndx		elfedit64_name_to_shndx
   1024 #define	elfedit_name_to_symndx		elfedit64_name_to_symndx
   1025 #define	elfedit_offset_to_str		elfedit64_offset_to_str
   1026 #define	elfedit_sec_findstr		elfedit64_sec_findstr
   1027 #define	elfedit_sec_get			elfedit64_sec_get
   1028 #define	elfedit_sec_getcap		elfedit64_sec_getcap
   1029 #define	elfedit_sec_getdyn		elfedit64_sec_getdyn
   1030 #define	elfedit_sec_getstr		elfedit64_sec_getstr
   1031 #define	elfedit_sec_getsyminfo		elfedit64_sec_getsyminfo
   1032 #define	elfedit_sec_getsymtab		elfedit64_sec_getsymtab
   1033 #define	elfedit_sec_getversym		elfedit64_sec_getversym
   1034 #define	elfedit_sec_getxshndx		elfedit64_sec_getxshndx
   1035 #define	elfedit_sec_issymtab		elfedit64_sec_issymtab
   1036 #define	elfedit_shndx_to_name		elfedit64_shndx_to_name
   1037 #define	elfedit_sec_msgprefix		elfedit64_sec_msgprefix
   1038 #define	elfedit_strtab_insert		elfedit64_strtab_insert
   1039 #define	elfedit_strtab_insert_test	elfedit64_strtab_insert_test
   1040 #define	elfedit_test_osabi		elfedit64_test_osabi
   1041 #define	elfedit_type_to_shndx		elfedit64_type_to_shndx
   1042 #else
   1043 #define	elfedit_dyn_elt_init		elfedit32_dyn_elt_init
   1044 #define	elfedit_dyn_elt_save		elfedit32_dyn_elt_save
   1045 #define	elfedit_dyn_offset_to_str	elfedit32_dyn_offset_to_str
   1046 #define	elfedit_dynstr_getpad		elfedit32_dynstr_getpad
   1047 #define	elfedit_dynstr_insert		elfedit32_dynstr_insert
   1048 #define	elfedit_modified_data		elfedit32_modified_data
   1049 #define	elfedit_modified_ehdr		elfedit32_modified_ehdr
   1050 #define	elfedit_modified_phdr		elfedit32_modified_phdr
   1051 #define	elfedit_modified_shdr		elfedit32_modified_shdr
   1052 #define	elfedit_name_to_shndx		elfedit32_name_to_shndx
   1053 #define	elfedit_name_to_symndx		elfedit32_name_to_symndx
   1054 #define	elfedit_offset_to_str		elfedit32_offset_to_str
   1055 #define	elfedit_sec_findstr		elfedit32_sec_findstr
   1056 #define	elfedit_sec_get			elfedit32_sec_get
   1057 #define	elfedit_sec_getcap		elfedit32_sec_getcap
   1058 #define	elfedit_sec_getdyn		elfedit32_sec_getdyn
   1059 #define	elfedit_sec_getstr		elfedit32_sec_getstr
   1060 #define	elfedit_sec_getsyminfo		elfedit32_sec_getsyminfo
   1061 #define	elfedit_sec_getsymtab		elfedit32_sec_getsymtab
   1062 #define	elfedit_sec_getversym		elfedit32_sec_getversym
   1063 #define	elfedit_sec_getxshndx		elfedit32_sec_getxshndx
   1064 #define	elfedit_sec_issymtab		elfedit32_sec_issymtab
   1065 #define	elfedit_shndx_to_name		elfedit32_shndx_to_name
   1066 #define	elfedit_sec_msgprefix		elfedit32_sec_msgprefix
   1067 #define	elfedit_strtab_insert		elfedit32_strtab_insert
   1068 #define	elfedit_strtab_insert_test	elfedit32_strtab_insert_test
   1069 #define	elfedit_test_osabi		elfedit32_test_osabi
   1070 #define	elfedit_type_to_shndx		elfedit32_type_to_shndx
   1071 #endif
   1072 
   1073 
   1074 #ifdef	__cplusplus
   1075 }
   1076 #endif
   1077 
   1078 #endif	/* _ELFEDIT_H */
   1079