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 #include	<stdio.h>
     28 #include	<ctype.h>
     29 #include	<elfedit.h>
     30 #include	<sys/elf_SPARC.h>
     31 #include	<sys/elf_amd64.h>
     32 #include	<strings.h>
     33 #include	<conv.h>
     34 #include	<debug.h>
     35 #include	<ehdr_msg.h>
     36 
     37 
     38 
     39 
     40 /*
     41  * This module handles changes to the ELF header
     42  */
     43 
     44 
     45 
     46 /*
     47  * This module uses shared code for several of the commands.
     48  * It is sometimes necessary to know which specific command
     49  * is active.
     50  */
     51 typedef enum {
     52 	/* Dump command, used as module default to display ELF header */
     53 	EHDR_CMD_T_DUMP =		0,	/* ehdr:dump */
     54 
     55 	/* Commands that correspond directly to ELF header fields */
     56 	EHDR_CMD_T_E_IDENT =		1,	/* ehdr:e_ident */
     57 	EHDR_CMD_T_E_TYPE =		2,	/* ehdr:e_type */
     58 	EHDR_CMD_T_E_MACHINE =		3,	/* ehdr:e_machine */
     59 	EHDR_CMD_T_E_VERSION =		4,	/* ehdr:e_version */
     60 	EHDR_CMD_T_E_ENTRY =		5,	/* ehdr:e_entry */
     61 	EHDR_CMD_T_E_PHOFF =		6,	/* ehdr:e_phoff */
     62 	EHDR_CMD_T_E_SHOFF =		7,	/* ehdr:e_shoff */
     63 	EHDR_CMD_T_E_FLAGS =		8,	/* ehdr:e_flags */
     64 	EHDR_CMD_T_E_EHSIZE =		9,	/* ehdr:e_ehsize */
     65 	EHDR_CMD_T_E_PHENTSIZE =	10,	/* ehdr:e_phentsize */
     66 	EHDR_CMD_T_E_PHNUM =		11,	/* ehdr:e_phnum */
     67 	EHDR_CMD_T_E_SHENTSIZE =	12,	/* ehdr:e_shentsize */
     68 	EHDR_CMD_T_E_SHNUM =		13,	/* ehdr:e_shnum */
     69 	EHDR_CMD_T_E_SHSTRNDX =		14,	/* ehdr:e_shstrndx */
     70 
     71 	/* Commands that correspond to the e_ident[] array in ELF hdr */
     72 	EHDR_CMD_T_EI_MAG0 =		15,	/* ehdr:ei_mag0 */
     73 	EHDR_CMD_T_EI_MAG1 =		16,	/* ehdr:ei_mag1 */
     74 	EHDR_CMD_T_EI_MAG2 =		17,	/* ehdr:ei_mag2 */
     75 	EHDR_CMD_T_EI_MAG3 =		18,	/* ehdr:ei_mag3 */
     76 	EHDR_CMD_T_EI_CLASS =		19,	/* ehdr:ei_class */
     77 	EHDR_CMD_T_EI_DATA =		20,	/* ehdr:ei_data */
     78 	EHDR_CMD_T_EI_VERSION =		21,	/* ehdr:ei_version */
     79 	EHDR_CMD_T_EI_OSABI =		22,	/* ehdr:ei_osabi */
     80 	EHDR_CMD_T_EI_ABIVERSION =	23	/* ehdr:ei_abiversion */
     81 } EHDR_CMD_T;
     82 
     83 
     84 
     85 
     86 
     87 
     88 #ifndef _ELF64
     89 /*
     90  * We supply this function for the msg module
     91  */
     92 const char *
     93 _ehdr_msg(Msg mid)
     94 {
     95 	return (gettext(MSG_ORIG(mid)));
     96 }
     97 #endif
     98 
     99 
    100 /*
    101  * This function is supplied to elfedit through our elfedit_module_t
    102  * definition. It translates the opaque elfedit_i18nhdl_t handles
    103  * in our module interface into the actual strings for elfedit to
    104  * use.
    105  *
    106  * note:
    107  *	This module uses Msg codes for its i18n handle type.
    108  *	So the translation is simply to use MSG_INTL() to turn
    109  *	it into a string and return it.
    110  */
    111 static const char *
    112 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
    113 {
    114 	Msg msg = (Msg)hdl;
    115 
    116 	return (MSG_INTL(msg));
    117 }
    118 
    119 
    120 
    121 /*
    122  * The ehdr_opt_t enum specifies a bit value for every optional
    123  * argument allowed by a command in this module.
    124  */
    125 typedef enum {
    126 	EHDR_OPT_F_AND =	1,	/* -and: AND (&) values to dest */
    127 	EHDR_OPT_F_CMP =	2,	/* -cmp: Complement (~) values */
    128 	EHDR_OPT_F_OR =		4,	/* -or: OR (|) values to dest */
    129 	EHDR_OPT_F_SHNDX =	8,	/* -shndx: sec argument is index of */
    130 					/*	section, not name */
    131 	EHDR_OPT_F_SHTYP =	16	/* -shtyp: sec argument is type of */
    132 					/*	section, not name */
    133 } ehdr_opt_t;
    134 
    135 
    136 /*
    137  * A variable of type ARGSTATE is used by each command to maintain
    138  * information about the arguments and related things. It is
    139  * initialized by process_args(), and used by the other routines.
    140  */
    141 typedef struct {
    142 	elfedit_obj_state_t	*obj_state;
    143 	ehdr_opt_t		optmask;   	/* Mask of options used */
    144 	int			argc;		/* # of plain arguments */
    145 	const char		**argv;		/* Plain arguments */
    146 } ARGSTATE;
    147 
    148 
    149 
    150 /*
    151  * Standard argument processing for ehdr module
    152  *
    153  * entry
    154  *	obj_state, argc, argv - Standard command arguments
    155  *	argstate - Address of ARGSTATE block to be initialized
    156  *
    157  * exit:
    158  *	On success, *argstate is initialized. On error,
    159  *	an error is issued and this routine does not return.
    160  */
    161 static void
    162 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
    163     ARGSTATE *argstate)
    164 {
    165 	elfedit_getopt_state_t	getopt_state;
    166 	elfedit_getopt_ret_t	*getopt_ret;
    167 
    168 	bzero(argstate, sizeof (*argstate));
    169 	argstate->obj_state = obj_state;
    170 
    171 	elfedit_getopt_init(&getopt_state, &argc, &argv);
    172 	/* Add each new option to the options mask */
    173 	while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL)
    174 		argstate->optmask |= getopt_ret->gor_idmask;
    175 
    176 	/* If there may be an arbitrary amount of output, use a pager */
    177 	if (argc == 0)
    178 		elfedit_pager_init();
    179 
    180 	/* Return the updated values of argc/argv */
    181 	argstate->argc = argc;
    182 	argstate->argv = argv;
    183 }
    184 
    185 
    186 
    187 
    188 
    189 
    190 /*
    191  * Format the given magic number byte into a buffer
    192  *
    193  * entry:
    194  *	value - Value of the magic value byte given by
    195  *		ehdr->ei_ident[EI_MAG?]
    196  */
    197 static const char *
    198 conv_magic_value(int value)
    199 {
    200 	/*
    201 	 * This routine can be called twice within a single C statement,
    202 	 * so we use alternating buffers on each call to allow this
    203 	 * without requiring the caller to supply a buffer (the size of
    204 	 * which they don't know).
    205 	 */
    206 	static char buf1[20];
    207 	static char buf2[20];
    208 	static char *buf;
    209 
    210 	/* Switch buffers */
    211 	buf = (buf == buf1) ? buf2 : buf1;
    212 
    213 	if (isprint(value))
    214 		(void) snprintf(buf, sizeof (buf1),
    215 		    MSG_ORIG(MSG_FMT_HEXNUM_QCHR), value, value);
    216 	else
    217 		(void) snprintf(buf, sizeof (buf1),
    218 		    MSG_ORIG(MSG_FMT_HEXNUM), value);
    219 	return (buf);
    220 }
    221 
    222 
    223 
    224 /*
    225  * Print ELF header values, taking the calling command, and output style
    226  * into account.
    227  *
    228  * entry:
    229  *	cmd - EHDR_CMD_T_* value giving identify of caller
    230  *	e_ident_ndx - Ignored unless cmd is EHDR_CMD_T_E_IDENT. In IDENT
    231  *		case, index of item in e_ident[] array to display, or
    232  *		-1 to display the entire array.
    233  *	autoprint - If True, output is only produced if the elfedit
    234  *		autoprint flag is set. If False, output is always produced.
    235  *	argstate - Argument state block
    236  */
    237 static void
    238 print_ehdr(EHDR_CMD_T cmd, int e_ident_ndx, int autoprint,
    239     ARGSTATE *argstate)
    240 {
    241 	elfedit_outstyle_t	outstyle;
    242 	Conv_fmt_flags_t	flags_fmt_flags = 0;
    243 	Ehdr		*ehdr;
    244 	int		c;
    245 	Conv_inv_buf_t	inv_buf;
    246 
    247 	if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
    248 		return;
    249 
    250 	/*
    251 	 * Pick an output style. ehdr:dump is required to use the default
    252 	 * style. The other commands use the current output style.
    253 	 */
    254 	if (cmd == EHDR_CMD_T_DUMP) {
    255 		outstyle = ELFEDIT_OUTSTYLE_DEFAULT;
    256 	} else {
    257 		outstyle = elfedit_outstyle();
    258 
    259 		/*
    260 		 * When the caller specifies the simple output style,
    261 		 * omit the brackets from around the values.
    262 		 */
    263 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    264 			flags_fmt_flags = CONV_FMT_NOBKT;
    265 
    266 		/*
    267 		 * For things that show a single header item, switch
    268 		 * from default to simple mode.
    269 		 */
    270 		if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) &&
    271 		    ((cmd != EHDR_CMD_T_E_IDENT) || (e_ident_ndx != -1)))
    272 			outstyle = ELFEDIT_OUTSTYLE_SIMPLE;
    273 	}
    274 
    275 	ehdr = argstate->obj_state->os_ehdr;
    276 
    277 	/*
    278 	 * If doing default output, use elfdump style where we
    279 	 * show the full ELF header. In this case, the command
    280 	 * that called us doesn't matter. This can only happen
    281 	 * from ehdr:dump or ehdr:e_ident/
    282 	 */
    283 	if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
    284 		const char *ndx, *value;
    285 		char ndx_buf[64], value_buf[20];
    286 		int i;
    287 
    288 		if (cmd == EHDR_CMD_T_DUMP) {
    289 			Elf_ehdr(NULL, ehdr,
    290 			    argstate->obj_state->os_secarr[0].sec_shdr);
    291 			elfedit_printf(MSG_ORIG(MSG_STR_NL));
    292 		}
    293 
    294 		/*
    295 		 * Elf_ehdr() does not display all of e_ident[], so we
    296 		 * augment by displaying the entire array separately.
    297 		 */
    298 		elfedit_printf(MSG_ORIG(MSG_STR_EIDENT_HDR));
    299 
    300 		for (i = 0; i < EI_NIDENT; i++) {
    301 			ndx = value = NULL;
    302 
    303 			switch (i) {
    304 			case EI_MAG0:
    305 			case EI_MAG1:
    306 			case EI_MAG2:
    307 			case EI_MAG3:
    308 				ndx = elfedit_atoconst_value_to_str(
    309 				    ELFEDIT_CONST_EI, i, 1);
    310 				value = conv_magic_value(ehdr->e_ident[i]);
    311 				break;
    312 			case EI_CLASS:
    313 				ndx = elfedit_atoconst_value_to_str(
    314 				    ELFEDIT_CONST_EI, EI_CLASS, 1);
    315 				value = conv_ehdr_class(ehdr->e_ident[EI_CLASS],
    316 				    0, &inv_buf);
    317 				break;
    318 			case EI_DATA:
    319 				ndx = elfedit_atoconst_value_to_str(
    320 				    ELFEDIT_CONST_EI, EI_DATA, 1);
    321 				value = conv_ehdr_data(ehdr->e_ident[EI_DATA],
    322 				    0, &inv_buf);
    323 				break;
    324 			case EI_VERSION:
    325 				ndx = elfedit_atoconst_value_to_str(
    326 				    ELFEDIT_CONST_EI, EI_VERSION, 1);
    327 				value = conv_ehdr_vers(
    328 				    ehdr->e_ident[EI_VERSION], 0, &inv_buf);
    329 				break;
    330 			case EI_OSABI:
    331 				ndx = elfedit_atoconst_value_to_str(
    332 				    ELFEDIT_CONST_EI, EI_OSABI, 1);
    333 				value = conv_ehdr_osabi(ehdr->e_ident[EI_OSABI],
    334 				    0, &inv_buf);
    335 				break;
    336 			case EI_ABIVERSION:
    337 				ndx = elfedit_atoconst_value_to_str(
    338 				    ELFEDIT_CONST_EI, EI_ABIVERSION, 1);
    339 				value = conv_ehdr_abivers(
    340 				    ehdr->e_ident[EI_OSABI],
    341 				    ehdr->e_ident[EI_ABIVERSION],
    342 				    CONV_FMT_DECIMAL, &inv_buf);
    343 				break;
    344 			default:
    345 				value = value_buf;
    346 				(void) snprintf(value_buf, sizeof (value_buf),
    347 				    MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]);
    348 				break;
    349 			}
    350 
    351 			if (ndx == NULL)
    352 				(void) snprintf(ndx_buf, sizeof (ndx_buf),
    353 				    MSG_ORIG(MSG_FMT_BKTINT), i);
    354 			else
    355 				(void) snprintf(ndx_buf, sizeof (ndx_buf),
    356 				    MSG_ORIG(MSG_FMT_BKTSTR), ndx);
    357 			elfedit_printf(MSG_ORIG(MSG_FMT_EI_ELT),
    358 			    ndx_buf, value);
    359 		}
    360 		return;
    361 	}
    362 
    363 
    364 	switch (cmd) {
    365 	case EHDR_CMD_T_E_IDENT:
    366 		{
    367 			int		i, cnt;
    368 
    369 			/* Show one element, or the entire thing? */
    370 			if (e_ident_ndx == -1) {
    371 				i = 0;
    372 				cnt = EI_NIDENT;
    373 			} else {
    374 				i = e_ident_ndx;
    375 				cnt = 1;
    376 			}
    377 
    378 			for (; cnt-- > 0; i++) {
    379 				/*
    380 				 * If using numeric style, or there is
    381 				 * no conversion routine for this item,
    382 				 * print a simple hex value.
    383 				 */
    384 				if ((outstyle == ELFEDIT_OUTSTYLE_NUM) ||
    385 				    (i > EI_ABIVERSION)) {
    386 					elfedit_printf(
    387 					    MSG_ORIG(MSG_FMT_HEXNUMNL),
    388 					    ehdr->e_ident[i]);
    389 					continue;
    390 				}
    391 
    392 				/* Handle special cases in simple mode */
    393 				switch (i) {
    394 				case EI_MAG0:
    395 				case EI_MAG1:
    396 				case EI_MAG2:
    397 				case EI_MAG3:
    398 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    399 					    conv_magic_value(ehdr->e_ident[i]));
    400 					continue;
    401 				case EI_CLASS:
    402 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    403 					    conv_ehdr_class(
    404 					    ehdr->e_ident[EI_CLASS], 0,
    405 					    &inv_buf));
    406 					continue;
    407 				case EI_DATA:
    408 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    409 					    conv_ehdr_data(
    410 					    ehdr->e_ident[EI_DATA], 0,
    411 					    &inv_buf));
    412 					continue;
    413 				case EI_VERSION:
    414 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    415 					    conv_ehdr_vers(
    416 					    ehdr->e_ident[EI_VERSION], 0,
    417 					    &inv_buf));
    418 					continue;
    419 				case EI_OSABI:
    420 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    421 					    conv_ehdr_osabi(
    422 					    ehdr->e_ident[EI_OSABI], 0,
    423 					    &inv_buf));
    424 					continue;
    425 				case EI_ABIVERSION:
    426 					elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    427 					    conv_ehdr_abivers(
    428 					    ehdr->e_ident[EI_OSABI],
    429 					    ehdr->e_ident[EI_ABIVERSION],
    430 					    CONV_FMT_DECIMAL, &inv_buf));
    431 					continue;
    432 				}
    433 			}
    434 		}
    435 		return;
    436 
    437 	case EHDR_CMD_T_E_TYPE:
    438 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    439 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    440 			    conv_ehdr_type(ehdr->e_ident[EI_OSABI],
    441 			    ehdr->e_type, 0, &inv_buf));
    442 		else
    443 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    444 			    ehdr->e_type);
    445 		return;
    446 
    447 	case EHDR_CMD_T_E_MACHINE:
    448 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
    449 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    450 			    conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf));
    451 		} else {
    452 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    453 			    EC_WORD(ehdr->e_machine));
    454 		}
    455 		return;
    456 
    457 	case EHDR_CMD_T_E_VERSION:
    458 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    459 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    460 			    conv_ehdr_vers(ehdr->e_version, 0, &inv_buf));
    461 		else
    462 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    463 			    ehdr->e_version);
    464 		return;
    465 
    466 	case EHDR_CMD_T_E_ENTRY:
    467 		elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    468 		    EC_WORD(ehdr->e_entry));
    469 		return;
    470 
    471 	case EHDR_CMD_T_E_PHOFF:
    472 		elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    473 		    EC_WORD(ehdr->e_phoff));
    474 		return;
    475 
    476 	case EHDR_CMD_T_E_SHOFF:
    477 		elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    478 		    EC_WORD(ehdr->e_shoff));
    479 		return;
    480 
    481 	case EHDR_CMD_T_E_FLAGS:
    482 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
    483 			Conv_ehdr_flags_buf_t	flags_buf;
    484 
    485 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    486 			    conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags,
    487 			    flags_fmt_flags, &flags_buf));
    488 		} else {
    489 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    490 			    ehdr->e_flags);
    491 		}
    492 		return;
    493 
    494 	case EHDR_CMD_T_E_EHSIZE:
    495 		elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    496 		    EC_WORD(ehdr->e_ehsize));
    497 		return;
    498 
    499 	case EHDR_CMD_T_E_PHENTSIZE:
    500 		elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    501 		    EC_WORD(ehdr->e_phentsize));
    502 		return;
    503 
    504 	case EHDR_CMD_T_E_PHNUM:
    505 		{
    506 			Word num = ehdr->e_phnum;
    507 
    508 			/*
    509 			 * If using extended indexes, fetch the real
    510 			 * value from shdr[0].sh_info
    511 			 */
    512 			if (num == PN_XNUM)
    513 				num = argstate->obj_state->
    514 				    os_secarr[0].sec_shdr->sh_info;
    515 
    516 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    517 			    EC_WORD(num));
    518 		}
    519 		return;
    520 
    521 	case EHDR_CMD_T_E_SHENTSIZE:
    522 		elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    523 		    EC_WORD(ehdr->e_shentsize));
    524 		return;
    525 
    526 	case EHDR_CMD_T_E_SHNUM:
    527 		{
    528 			Word num = ehdr->e_shnum;
    529 
    530 			/*
    531 			 * If using extended indexes, fetch the real
    532 			 * value from shdr[0].sh_size
    533 			 */
    534 			if (num == 0)
    535 				num = argstate->obj_state->
    536 				    os_secarr[0].sec_shdr->sh_size;
    537 
    538 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    539 			    EC_WORD(num));
    540 		}
    541 		return;
    542 
    543 	case EHDR_CMD_T_E_SHSTRNDX:
    544 		{
    545 			Word num = ehdr->e_shstrndx;
    546 
    547 			/*
    548 			 * If using extended indexes, fetch the real
    549 			 * value from shdr[0].sh_link
    550 			 */
    551 			if (num == SHN_XINDEX)
    552 				num = argstate->obj_state->
    553 				    os_secarr[0].sec_shdr->sh_link;
    554 
    555 			elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
    556 			    EC_WORD(num));
    557 		}
    558 		return;
    559 
    560 	case EHDR_CMD_T_EI_MAG0:
    561 	case EHDR_CMD_T_EI_MAG1:
    562 	case EHDR_CMD_T_EI_MAG2:
    563 	case EHDR_CMD_T_EI_MAG3:
    564 		/* This depends on EHDR_CMD_T_EI_MAG[0-3] being contiguous */
    565 		c = ehdr->e_ident[cmd - EHDR_CMD_T_EI_MAG0];
    566 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    567 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    568 			    conv_magic_value(c));
    569 		else
    570 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
    571 		return;
    572 
    573 	case EHDR_CMD_T_EI_CLASS:
    574 		c = ehdr->e_ident[EI_CLASS];
    575 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    576 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    577 			    conv_ehdr_class(c, 0, &inv_buf));
    578 		else
    579 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
    580 		return;
    581 
    582 	case EHDR_CMD_T_EI_DATA:
    583 		c = ehdr->e_ident[EI_DATA];
    584 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    585 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    586 			    conv_ehdr_data(c, 0, &inv_buf));
    587 		else
    588 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
    589 		return;
    590 
    591 	case EHDR_CMD_T_EI_VERSION:
    592 		c = ehdr->e_ident[EI_VERSION];
    593 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
    594 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    595 			    conv_ehdr_vers(c, 0, &inv_buf));
    596 		else
    597 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
    598 		return;
    599 
    600 	case EHDR_CMD_T_EI_OSABI:
    601 		c = ehdr->e_ident[EI_OSABI];
    602 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
    603 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    604 			    conv_ehdr_osabi(c, 0, &inv_buf));
    605 		} else {
    606 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    607 			    EC_WORD(c));
    608 		}
    609 		return;
    610 
    611 	case EHDR_CMD_T_EI_ABIVERSION:
    612 		c = ehdr->e_ident[EI_ABIVERSION];
    613 		if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
    614 			elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
    615 			    conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
    616 			    c, CONV_FMT_DECIMAL, &inv_buf));
    617 		} else {
    618 			elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
    619 			    EC_WORD(c));
    620 		}
    621 		return;
    622 	}
    623 }
    624 
    625 
    626 /*
    627  * Common body for the ehdr: module commands. These commands
    628  * share a large amount of common behavior, so it is convenient
    629  * to centralize things and use the cmd argument to handle the
    630  * small differences.
    631  *
    632  * entry:
    633  *	cmd - One of the EHDR_CMD_T_* constants listed above, specifying
    634  *		which command to implement.
    635  *	obj_state, argc, argv - Standard command arguments
    636  */
    637 static elfedit_cmdret_t
    638 cmd_body(EHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,
    639     int argc, const char *argv[])
    640 {
    641 	/*
    642 	 * When a call comes in for ehdr:e_ident[ndx], and the
    643 	 * specified element is one that we have a special command
    644 	 * for, then we revector to that special command instead
    645 	 * of using the generic ehdr:e_ident processing. This array,
    646 	 * which is indexed by the e_ident[] index value is used
    647 	 * to decide if that is the case. If the resulting value
    648 	 * is EHDR_CMD_T_E_IDENT, then the generic processing is
    649 	 * used. Otherwise, we revector to the specified command.
    650 	 */
    651 	static const int e_ident_revector[16] = {
    652 		EHDR_CMD_T_EI_MAG0,		/* 0: EI_MAG0 */
    653 		EHDR_CMD_T_EI_MAG1,		/* 1: EI_MAG1 */
    654 		EHDR_CMD_T_EI_MAG2,		/* 2: EI_MAG2 */
    655 		EHDR_CMD_T_EI_MAG3,		/* 3: EI_MAG3 */
    656 		EHDR_CMD_T_EI_CLASS,		/* 4: EI_CLASS */
    657 		EHDR_CMD_T_EI_DATA,		/* 5: EI_DATA */
    658 		EHDR_CMD_T_EI_VERSION,		/* 6: EI_VERSION */
    659 		EHDR_CMD_T_EI_OSABI,		/* 7: EI_OSABI */
    660 		EHDR_CMD_T_EI_ABIVERSION,	/* 8: EI_ABIVERSION */
    661 		EHDR_CMD_T_E_IDENT,		/* 9: generic */
    662 		EHDR_CMD_T_E_IDENT,		/* 10: generic */
    663 		EHDR_CMD_T_E_IDENT,		/* 11: generic */
    664 		EHDR_CMD_T_E_IDENT,		/* 12: generic */
    665 		EHDR_CMD_T_E_IDENT,		/* 13: generic */
    666 		EHDR_CMD_T_E_IDENT,		/* 14: generic */
    667 		EHDR_CMD_T_E_IDENT,		/* 15: generic */
    668 	};
    669 
    670 
    671 	ARGSTATE		argstate;
    672 	Ehdr			*ehdr;
    673 	elfedit_cmdret_t	ret = ELFEDIT_CMDRET_NONE;
    674 	int			e_ident_ndx = -1;
    675 	Conv_inv_buf_t		inv_buf1, inv_buf2;
    676 
    677 	/* Process the optional arguments */
    678 	process_args(obj_state, argc, argv, &argstate);
    679 
    680 	/* Check number of arguments */
    681 	switch (cmd) {
    682 	case EHDR_CMD_T_DUMP:
    683 		/* ehdr:dump does not accept arguments */
    684 		if (argstate.argc > 0)
    685 			elfedit_command_usage();
    686 		break;
    687 	case EHDR_CMD_T_E_IDENT:
    688 		/*
    689 		 * ehdr:e_ident accepts 1 or 2 arguments, the first
    690 		 * being the index into the array, and the second being
    691 		 * the value. If there are arguments, then process the
    692 		 * index, and remove it from the argument list.
    693 		 */
    694 		if (argstate.argc > 0) {
    695 			if (argstate.argc > 2)
    696 				elfedit_command_usage();
    697 			e_ident_ndx = (int)
    698 			    elfedit_atoconst_range(argstate.argv[0],
    699 			    MSG_ORIG(MSG_STR_INDEX), 0, EI_NIDENT - 1,
    700 			    ELFEDIT_CONST_EI);
    701 			argstate.argc--;
    702 			argstate.argv++;
    703 
    704 			/*
    705 			 * If the index is for one of the e_ident elements
    706 			 * that we have a special command for, then switch
    707 			 * to that command. e_ident_revector[] returns
    708 			 * EHDR_CMD_T_E_IDENT in the cases where such a command
    709 			 * does not exist, in which case we'll continue with the
    710 			 * generic code.
    711 			 */
    712 			cmd = e_ident_revector[e_ident_ndx];
    713 		}
    714 		break;
    715 	case EHDR_CMD_T_E_FLAGS:
    716 		/* ehdr:e_flags accepts an arbitrary number of arguments */
    717 		break;
    718 	default:
    719 		/* The remaining commands accept a single optional argument */
    720 		if (argstate.argc > 1)
    721 			elfedit_command_usage();
    722 		break;
    723 	}
    724 
    725 	/* If there are no arguments, dump the ELF header and return */
    726 	if (argstate.argc == 0) {
    727 		print_ehdr(cmd, e_ident_ndx, 0, &argstate);
    728 		return (ELFEDIT_CMDRET_NONE);
    729 	}
    730 
    731 	ehdr = obj_state->os_ehdr;
    732 	switch (cmd) {
    733 		/*
    734 		 * EHDR_CMD_T_DUMP can't get here: It never has an
    735 		 * argument, and is handled above.
    736 		 */
    737 
    738 	case EHDR_CMD_T_E_IDENT:
    739 		{
    740 			/*
    741 			 * Only those e_ident[] elements for which we
    742 			 * don't have a specialized command come here.
    743 			 * The argument is a value to be set in
    744 			 * e_ident[e_ident_ndx].
    745 			 */
    746 			uchar_t value = (uchar_t)
    747 			    elfedit_atoui_range(argstate.argv[0],
    748 			    MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL);
    749 
    750 			if (ehdr->e_ident[e_ident_ndx] == value) {
    751 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    752 				    MSG_INTL(MSG_DEBUG_EI_D_X_OK),
    753 				    e_ident_ndx, EC_WORD(value));
    754 			} else {
    755 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    756 				    MSG_INTL(MSG_DEBUG_EI_D_X_CHG),
    757 				    e_ident_ndx, ehdr->e_ident[e_ident_ndx],
    758 				    value);
    759 				ret = ELFEDIT_CMDRET_MOD;
    760 				ehdr->e_ident[e_ident_ndx] = value;
    761 			}
    762 		}
    763 		break;
    764 
    765 	case EHDR_CMD_T_E_TYPE:
    766 		{
    767 			/* The argument gives the object type */
    768 			Half type = (Half) elfedit_atoconst(argstate.argv[0],
    769 			    ELFEDIT_CONST_ET);
    770 			const char *name = MSG_ORIG(MSG_CMD_E_TYPE);
    771 
    772 			if (ehdr->e_type == type) {
    773 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    774 				    MSG_INTL(MSG_DEBUG_E_S_OK), name,
    775 				    conv_ehdr_type(ehdr->e_ident[EI_OSABI],
    776 				    ehdr->e_type, 0, &inv_buf1));
    777 			} else {
    778 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    779 				    MSG_INTL(MSG_DEBUG_E_S_CHG), name,
    780 				    conv_ehdr_type(ehdr->e_ident[EI_OSABI],
    781 				    ehdr->e_type, 0, &inv_buf1),
    782 				    conv_ehdr_type(ehdr->e_ident[EI_OSABI],
    783 				    type, 0, &inv_buf2));
    784 				ret = ELFEDIT_CMDRET_MOD;
    785 				ehdr->e_type = type;
    786 			}
    787 		}
    788 		break;
    789 
    790 	case EHDR_CMD_T_E_MACHINE:
    791 		{
    792 			/* The argument gives the machine code */
    793 			Half mach = (Half) elfedit_atoconst(argstate.argv[0],
    794 			    ELFEDIT_CONST_EM);
    795 			const char *name = MSG_ORIG(MSG_CMD_E_MACHINE);
    796 
    797 			if (ehdr->e_machine == mach) {
    798 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    799 				    MSG_INTL(MSG_DEBUG_E_S_OK), name,
    800 				    conv_ehdr_mach(ehdr->e_machine, 0,
    801 				    &inv_buf1));
    802 			} else {
    803 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    804 				    MSG_INTL(MSG_DEBUG_E_S_CHG), name,
    805 				    conv_ehdr_mach(ehdr->e_machine, 0,
    806 				    &inv_buf1),
    807 				    conv_ehdr_mach(mach, 0, &inv_buf2));
    808 				ret = ELFEDIT_CMDRET_MOD_OS_MACH;
    809 				ehdr->e_machine = mach;
    810 
    811 			}
    812 		}
    813 		break;
    814 
    815 	case EHDR_CMD_T_E_VERSION:
    816 		{
    817 			/* The argument gives the version */
    818 			Word ver = (Word) elfedit_atoconst(argstate.argv[0],
    819 			    ELFEDIT_CONST_EV);
    820 			const char *name = MSG_ORIG(MSG_CMD_E_VERSION);
    821 
    822 			if (ehdr->e_version == ver) {
    823 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    824 				    MSG_INTL(MSG_DEBUG_E_S_OK), name,
    825 				    conv_ehdr_vers(ehdr->e_version, 0,
    826 				    &inv_buf1));
    827 			} else {
    828 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    829 				    MSG_INTL(MSG_DEBUG_E_S_CHG), name,
    830 				    conv_ehdr_vers(ehdr->e_version, 0,
    831 				    &inv_buf1),
    832 				    conv_ehdr_vers(ver, 0, &inv_buf2));
    833 				ret = ELFEDIT_CMDRET_MOD;
    834 				ehdr->e_version = ver;
    835 			}
    836 		}
    837 		break;
    838 
    839 	case EHDR_CMD_T_E_ENTRY:
    840 		{
    841 			/* The argument gives the entry address */
    842 			Addr entry = (Addr)
    843 			    elfedit_atoui(argstate.argv[0], NULL);
    844 			const char *name = MSG_ORIG(MSG_CMD_E_ENTRY);
    845 
    846 			if (ehdr->e_entry == entry) {
    847 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    848 				    MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
    849 				    EC_ADDR(ehdr->e_entry));
    850 			} else {
    851 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    852 				    MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
    853 				    EC_ADDR(ehdr->e_entry), EC_ADDR(entry));
    854 				ret = ELFEDIT_CMDRET_MOD;
    855 				ehdr->e_entry = entry;
    856 			}
    857 		}
    858 		break;
    859 
    860 	case EHDR_CMD_T_E_PHOFF:
    861 		{
    862 			/* The argument gives the program header offset */
    863 			Off off = (Off) elfedit_atoui(argstate.argv[0],
    864 			    NULL);
    865 			const char *name = MSG_ORIG(MSG_CMD_E_PHOFF);
    866 
    867 			if (ehdr->e_phoff == off) {
    868 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    869 				    MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
    870 				    EC_OFF(ehdr->e_phoff));
    871 			} else {
    872 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    873 				    MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
    874 				    EC_OFF(ehdr->e_phoff), EC_OFF(off));
    875 				ret = ELFEDIT_CMDRET_MOD;
    876 				ehdr->e_phoff = off;
    877 			}
    878 		}
    879 		break;
    880 
    881 	case EHDR_CMD_T_E_SHOFF:
    882 		{
    883 			/* The argument gives the section header offset */
    884 			Off off = (Off) elfedit_atoui(argstate.argv[0],
    885 			    NULL);
    886 			const char *name = MSG_ORIG(MSG_CMD_E_SHOFF);
    887 
    888 			if (ehdr->e_shoff == off) {
    889 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    890 				    MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
    891 				    EC_OFF(ehdr->e_shoff));
    892 			} else {
    893 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    894 				    MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
    895 				    EC_OFF(ehdr->e_shoff), EC_OFF(off));
    896 				ret = ELFEDIT_CMDRET_MOD;
    897 				ehdr->e_shoff = off;
    898 			}
    899 		}
    900 		break;
    901 
    902 	case EHDR_CMD_T_E_FLAGS:
    903 		{
    904 			Conv_ehdr_flags_buf_t flags_buf1, flags_buf2;
    905 			const char *name = MSG_ORIG(MSG_CMD_E_FLAGS);
    906 			Word flags = 0;
    907 			int i;
    908 
    909 			/* Collect the arguments */
    910 			for (i = 0; i < argstate.argc; i++)
    911 				flags |= (Word)
    912 				    elfedit_atoconst(argstate.argv[i],
    913 				    ELFEDIT_CONST_EF);
    914 
    915 			/* Complement the value? */
    916 			if (argstate.optmask & EHDR_OPT_F_CMP)
    917 				flags = ~flags;
    918 
    919 			/* Perform any requested bit operations */
    920 			if (argstate.optmask & EHDR_OPT_F_AND)
    921 				flags &= ehdr->e_flags;
    922 			else if (argstate.optmask & EHDR_OPT_F_OR)
    923 				flags |= ehdr->e_flags;
    924 
    925 			/* Set the value */
    926 			if (ehdr->e_flags == flags) {
    927 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    928 				    MSG_INTL(MSG_DEBUG_E_S_OK), name,
    929 				    conv_ehdr_flags(ehdr->e_machine,
    930 				    ehdr->e_flags, 0, &flags_buf1));
    931 			} else {
    932 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    933 				    MSG_INTL(MSG_DEBUG_E_S_CHG), name,
    934 				    conv_ehdr_flags(ehdr->e_machine,
    935 				    ehdr->e_flags, 0, &flags_buf1),
    936 				    conv_ehdr_flags(ehdr->e_machine,
    937 				    flags, 0, &flags_buf2));
    938 				ret = ELFEDIT_CMDRET_MOD;
    939 				ehdr->e_flags = flags;
    940 			}
    941 		}
    942 		break;
    943 
    944 	case EHDR_CMD_T_E_EHSIZE:
    945 		{
    946 			/* The argument gives the ELF header size */
    947 			Half ehsize = (Half) elfedit_atoui(argstate.argv[0],
    948 			    NULL);
    949 			const char *name = MSG_ORIG(MSG_CMD_E_EHSIZE);
    950 
    951 			if (ehdr->e_ehsize == ehsize) {
    952 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    953 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
    954 				    EC_WORD(ehdr->e_ehsize));
    955 			} else {
    956 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    957 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
    958 				    EC_WORD(ehdr->e_ehsize), EC_WORD(ehsize));
    959 				ret = ELFEDIT_CMDRET_MOD;
    960 				ehdr->e_ehsize = ehsize;
    961 			}
    962 		}
    963 		break;
    964 
    965 	case EHDR_CMD_T_E_PHENTSIZE:
    966 		{
    967 			/*
    968 			 * The argument gives the size of a program
    969 			 * header element.
    970 			 */
    971 			Half phentsize = (Half) elfedit_atoui(argstate.argv[0],
    972 			    NULL);
    973 			const char *name = MSG_ORIG(MSG_CMD_E_PHENTSIZE);
    974 
    975 			if (ehdr->e_phentsize == phentsize) {
    976 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    977 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
    978 				    EC_WORD(ehdr->e_phentsize));
    979 			} else {
    980 				elfedit_msg(ELFEDIT_MSG_DEBUG,
    981 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
    982 				    EC_WORD(ehdr->e_phentsize),
    983 				    EC_WORD(phentsize));
    984 				ret = ELFEDIT_CMDRET_MOD;
    985 				ehdr->e_phentsize = phentsize;
    986 			}
    987 		}
    988 		break;
    989 
    990 	case EHDR_CMD_T_E_PHNUM:
    991 		{
    992 			/* The argument gives the number of program headers */
    993 			Word phnum = (Word) elfedit_atoui(argstate.argv[0],
    994 			    NULL);
    995 			const char *name = MSG_ORIG(MSG_CMD_E_PHNUM);
    996 			elfedit_section_t *sec0 = &obj_state->os_secarr[0];
    997 			Shdr *shdr0 = sec0->sec_shdr;
    998 			Half e_phnum;
    999 			Word sh_info;
   1000 
   1001 			if (phnum >= PN_XNUM) {
   1002 				e_phnum = PN_XNUM;
   1003 				sh_info = phnum;
   1004 			} else {
   1005 				e_phnum = phnum;
   1006 				sh_info = 0;
   1007 			}
   1008 
   1009 			if (ehdr->e_phnum == e_phnum) {
   1010 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1011 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
   1012 				    EC_WORD(ehdr->e_phnum));
   1013 			} else {
   1014 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1015 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
   1016 				    EC_WORD(ehdr->e_phnum), e_phnum);
   1017 				ret = ELFEDIT_CMDRET_MOD;
   1018 				ehdr->e_phnum = e_phnum;
   1019 			}
   1020 			if (shdr0->sh_info == sh_info) {
   1021 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1022 				    MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
   1023 				    MSG_ORIG(MSG_STR_SH_INFO),
   1024 				    EC_WORD(shdr0->sh_info));
   1025 			} else {
   1026 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1027 				    MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
   1028 				    MSG_ORIG(MSG_STR_SH_INFO),
   1029 				    EC_WORD(shdr0->sh_info), sh_info);
   1030 				ret = ELFEDIT_CMDRET_MOD;
   1031 				shdr0->sh_info = sh_info;
   1032 				elfedit_modified_shdr(sec0);
   1033 			}
   1034 		}
   1035 		break;
   1036 
   1037 	case EHDR_CMD_T_E_SHENTSIZE:
   1038 		{
   1039 			/*
   1040 			 * The argument gives the size of a program
   1041 			 * header element.
   1042 			 */
   1043 			Half shentsize = (Half) elfedit_atoui(argstate.argv[0],
   1044 			    NULL);
   1045 			const char *name = MSG_ORIG(MSG_CMD_E_SHENTSIZE);
   1046 
   1047 			if (ehdr->e_shentsize == shentsize) {
   1048 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1049 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
   1050 				    EC_WORD(ehdr->e_shentsize));
   1051 			} else {
   1052 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1053 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
   1054 				    EC_WORD(ehdr->e_shentsize),
   1055 				    EC_WORD(shentsize));
   1056 				ret = ELFEDIT_CMDRET_MOD;
   1057 				ehdr->e_shentsize = shentsize;
   1058 			}
   1059 		}
   1060 		break;
   1061 
   1062 	case EHDR_CMD_T_E_SHNUM:
   1063 		{
   1064 			/* The argument gives the number of section headers */
   1065 			Word shnum = (Word) elfedit_atoui(argstate.argv[0],
   1066 			    NULL);
   1067 			const char *name = MSG_ORIG(MSG_CMD_E_SHNUM);
   1068 			elfedit_section_t *sec0 = &obj_state->os_secarr[0];
   1069 			Shdr *shdr0 = sec0->sec_shdr;
   1070 			Half e_shnum;
   1071 			Word sh_size;
   1072 
   1073 			if (shnum >= SHN_LORESERVE) {
   1074 				e_shnum = 0;
   1075 				sh_size = shnum;
   1076 			} else {
   1077 				e_shnum = shnum;
   1078 				sh_size = 0;
   1079 			}
   1080 
   1081 			if (ehdr->e_shnum == e_shnum) {
   1082 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1083 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
   1084 				    EC_WORD(ehdr->e_shnum));
   1085 			} else {
   1086 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1087 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
   1088 				    EC_WORD(ehdr->e_shnum), e_shnum);
   1089 				ret = ELFEDIT_CMDRET_MOD;
   1090 				ehdr->e_shnum = e_shnum;
   1091 			}
   1092 			if (shdr0->sh_size == sh_size) {
   1093 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1094 				    MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
   1095 				    MSG_ORIG(MSG_STR_SH_SIZE),
   1096 				    EC_WORD(shdr0->sh_size));
   1097 			} else {
   1098 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1099 				    MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
   1100 				    MSG_ORIG(MSG_STR_SH_SIZE),
   1101 				    EC_WORD(shdr0->sh_size), sh_size);
   1102 				ret = ELFEDIT_CMDRET_MOD;
   1103 				shdr0->sh_size = sh_size;
   1104 				elfedit_modified_shdr(sec0);
   1105 			}
   1106 		}
   1107 		break;
   1108 
   1109 	case EHDR_CMD_T_E_SHSTRNDX:
   1110 		{
   1111 			const char *name = MSG_ORIG(MSG_CMD_E_SHSTRNDX);
   1112 			Word shstrndx;
   1113 			elfedit_section_t *sec0 = &obj_state->os_secarr[0];
   1114 			Shdr *shdr0 = sec0->sec_shdr;
   1115 			Half e_shstrndx;
   1116 			Word sh_link;
   1117 
   1118 			/*
   1119 			 * By default, sec argument is name of section.
   1120 			 * If -shndx is used, it is a numeric index, and
   1121 			 * if -shtyp is used, it is a section type.
   1122 			 */
   1123 			if (argstate.optmask & EHDR_OPT_F_SHNDX)
   1124 				shstrndx = elfedit_atoshndx(argstate.argv[0],
   1125 				    obj_state->os_shnum);
   1126 			else if (argstate.optmask & EHDR_OPT_F_SHTYP)
   1127 				shstrndx = elfedit_type_to_shndx(obj_state,
   1128 				    elfedit_atoconst(argstate.argv[0],
   1129 				    ELFEDIT_CONST_SHT));
   1130 			else
   1131 				shstrndx = elfedit_name_to_shndx(obj_state,
   1132 				    argstate.argv[0]);
   1133 
   1134 			/* Warn if the section isn't a string table */
   1135 			if ((shstrndx >= obj_state->os_shnum) ||
   1136 			    ((shstrndx >= SHN_LORESERVE) &&
   1137 			    (shstrndx <= SHN_HIRESERVE)) ||
   1138 			    (obj_state->os_secarr[shstrndx].sec_shdr->sh_type !=
   1139 			    SHT_STRTAB))
   1140 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1141 				    MSG_INTL(MSG_DEBUG_NOTSTRTAB), name,
   1142 				    EC_WORD(shstrndx));
   1143 
   1144 			if (shstrndx >= SHN_LORESERVE) {
   1145 				e_shstrndx = SHN_XINDEX;
   1146 				sh_link = shstrndx;
   1147 			} else {
   1148 				e_shstrndx = shstrndx;
   1149 				sh_link = 0;
   1150 			}
   1151 
   1152 			if (ehdr->e_shstrndx == e_shstrndx) {
   1153 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1154 				    MSG_INTL(MSG_DEBUG_E_D_OK), name,
   1155 				    EC_WORD(ehdr->e_shstrndx));
   1156 			} else {
   1157 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1158 				    MSG_INTL(MSG_DEBUG_E_D_CHG), name,
   1159 				    EC_WORD(ehdr->e_shstrndx), e_shstrndx);
   1160 				ret = ELFEDIT_CMDRET_MOD;
   1161 				ehdr->e_shstrndx = e_shstrndx;
   1162 			}
   1163 			if (shdr0->sh_link == sh_link) {
   1164 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1165 				    MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
   1166 				    MSG_ORIG(MSG_STR_SH_LINK),
   1167 				    EC_WORD(shdr0->sh_link));
   1168 			} else {
   1169 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1170 				    MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
   1171 				    MSG_ORIG(MSG_STR_SH_LINK),
   1172 				    EC_WORD(shdr0->sh_link), sh_link);
   1173 				ret = ELFEDIT_CMDRET_MOD;
   1174 				shdr0->sh_link = sh_link;
   1175 				elfedit_modified_shdr(sec0);
   1176 			}
   1177 		}
   1178 		break;
   1179 
   1180 	case EHDR_CMD_T_EI_MAG0:
   1181 	case EHDR_CMD_T_EI_MAG1:
   1182 	case EHDR_CMD_T_EI_MAG2:
   1183 	case EHDR_CMD_T_EI_MAG3:
   1184 		{
   1185 			/*
   1186 			 * This depends on EHDR_CMD_T_EI_MAG[0-3]
   1187 			 * being contiguous
   1188 			 */
   1189 			int ei_ndx = (cmd - EHDR_CMD_T_EI_MAG0) + EI_MAG0;
   1190 
   1191 			/* The argument gives the magic number byte */
   1192 			int mag = (int)elfedit_atoui_range(argstate.argv[0],
   1193 			    MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL);
   1194 
   1195 			if (ehdr->e_ident[ei_ndx] == mag) {
   1196 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1197 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK),
   1198 				    elfedit_atoconst_value_to_str(
   1199 				    ELFEDIT_CONST_EI, ei_ndx, 1),
   1200 				    conv_magic_value(ehdr->e_ident[ei_ndx]));
   1201 			} else {
   1202 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1203 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG),
   1204 				    elfedit_atoconst_value_to_str(
   1205 				    ELFEDIT_CONST_EI, ei_ndx, 1),
   1206 				    conv_magic_value(ehdr->e_ident[ei_ndx]),
   1207 				    conv_magic_value(mag));
   1208 				ret = ELFEDIT_CMDRET_MOD;
   1209 				ehdr->e_ident[ei_ndx] = mag;
   1210 			}
   1211 		}
   1212 		break;
   1213 
   1214 	case EHDR_CMD_T_EI_CLASS:
   1215 		{
   1216 			/* The argument gives the ELFCLASS value */
   1217 			int class = (int)elfedit_atoconst_range(
   1218 			    argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
   1219 			    ELFEDIT_CONST_ELFCLASS);
   1220 			const char *name = elfedit_atoconst_value_to_str(
   1221 			    ELFEDIT_CONST_EI, EI_CLASS, 1);
   1222 
   1223 			if (ehdr->e_ident[EI_CLASS] == class) {
   1224 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1225 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
   1226 				    conv_ehdr_class(class, 0, &inv_buf1));
   1227 			} else {
   1228 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1229 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
   1230 				    conv_ehdr_class(ehdr->e_ident[EI_CLASS],
   1231 				    0, &inv_buf1),
   1232 				    conv_ehdr_class(class, 0, &inv_buf2));
   1233 				ret = ELFEDIT_CMDRET_MOD;
   1234 				ehdr->e_ident[EI_CLASS] = class;
   1235 			}
   1236 		}
   1237 		break;
   1238 
   1239 	case EHDR_CMD_T_EI_DATA:
   1240 		{
   1241 			/* The argument gives the ELFDATA value */
   1242 			int data = (int)elfedit_atoconst_range(argstate.argv[0],
   1243 			    MSG_ORIG(MSG_STR_VALUE), 0, 255,
   1244 			    ELFEDIT_CONST_ELFDATA);
   1245 			const char *name = elfedit_atoconst_value_to_str(
   1246 			    ELFEDIT_CONST_EI, EI_DATA, 1);
   1247 
   1248 			if (ehdr->e_ident[EI_DATA] == data) {
   1249 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1250 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
   1251 				    conv_ehdr_data(data, 0, &inv_buf1));
   1252 			} else {
   1253 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1254 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
   1255 				    conv_ehdr_data(ehdr->e_ident[EI_DATA],
   1256 				    0, &inv_buf1),
   1257 				    conv_ehdr_data(data, 0, &inv_buf2));
   1258 				ret = ELFEDIT_CMDRET_MOD;
   1259 				ehdr->e_ident[EI_DATA] = data;
   1260 			}
   1261 		}
   1262 		break;
   1263 
   1264 	case EHDR_CMD_T_EI_VERSION:
   1265 		{
   1266 			/* The argument gives the version */
   1267 			int ver = (int)elfedit_atoconst_range(argstate.argv[0],
   1268 			    MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_EV);
   1269 			const char *name = elfedit_atoconst_value_to_str(
   1270 			    ELFEDIT_CONST_EI, EI_VERSION, 1);
   1271 
   1272 			if (ehdr->e_ident[EI_VERSION] == ver) {
   1273 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1274 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
   1275 				    conv_ehdr_vers(ver, 0, &inv_buf1));
   1276 			} else {
   1277 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1278 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
   1279 				    conv_ehdr_vers(ehdr->e_ident[EI_VERSION],
   1280 				    0, &inv_buf1),
   1281 				    conv_ehdr_vers(ver, 0, &inv_buf2));
   1282 				ret = ELFEDIT_CMDRET_MOD;
   1283 				ehdr->e_ident[EI_VERSION] = ver;
   1284 			}
   1285 		}
   1286 		break;
   1287 
   1288 	case EHDR_CMD_T_EI_OSABI:
   1289 		{
   1290 			/* The argument gives the ABI code */
   1291 			int osabi = (int)elfedit_atoconst_range(
   1292 			    argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
   1293 			    ELFEDIT_CONST_ELFOSABI);
   1294 			const char *name = elfedit_atoconst_value_to_str(
   1295 			    ELFEDIT_CONST_EI, EI_OSABI, 1);
   1296 
   1297 			if (ehdr->e_ident[EI_OSABI] == osabi) {
   1298 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1299 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
   1300 				    conv_ehdr_osabi(osabi, 0, &inv_buf1));
   1301 			} else {
   1302 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1303 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
   1304 				    conv_ehdr_osabi(ehdr->e_ident[EI_OSABI],
   1305 				    0, &inv_buf1),
   1306 				    conv_ehdr_osabi(osabi, 0, &inv_buf2));
   1307 				ret = ELFEDIT_CMDRET_MOD_OS_MACH;
   1308 				ehdr->e_ident[EI_OSABI] = osabi;
   1309 			}
   1310 		}
   1311 		break;
   1312 
   1313 	case EHDR_CMD_T_EI_ABIVERSION:
   1314 		{
   1315 			/* The argument gives the ABI version  */
   1316 			int abiver = (int)elfedit_atoconst_range(
   1317 			    argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
   1318 			    ELFEDIT_CONST_EAV);
   1319 			const char *name = elfedit_atoconst_value_to_str(
   1320 			    ELFEDIT_CONST_EI, EI_ABIVERSION, 1);
   1321 
   1322 			if (ehdr->e_ident[EI_ABIVERSION] == abiver) {
   1323 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1324 				    MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
   1325 				    conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
   1326 				    abiver, CONV_FMT_DECIMAL, &inv_buf1));
   1327 			} else {
   1328 				elfedit_msg(ELFEDIT_MSG_DEBUG,
   1329 				    MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
   1330 				    conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
   1331 				    ehdr->e_ident[EI_ABIVERSION],
   1332 				    CONV_FMT_DECIMAL, &inv_buf1),
   1333 				    conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
   1334 				    abiver, CONV_FMT_DECIMAL, &inv_buf2));
   1335 				ret = ELFEDIT_CMDRET_MOD;
   1336 				ehdr->e_ident[EI_ABIVERSION] = abiver;
   1337 			}
   1338 		}
   1339 		break;
   1340 	}
   1341 
   1342 	/*
   1343 	 * If we modified the ELF header, tell libelf.
   1344 	 */
   1345 	if (ret == ELFEDIT_CMDRET_MOD)
   1346 		elfedit_modified_ehdr(obj_state);
   1347 
   1348 	/* Do autoprint */
   1349 	print_ehdr(cmd, e_ident_ndx, 1, &argstate);
   1350 
   1351 	return (ret);
   1352 }
   1353 
   1354 
   1355 
   1356 
   1357 /*
   1358  * Command completion functions for the various commands
   1359  */
   1360 
   1361 /*ARGSUSED*/
   1362 static void
   1363 cpl_e_ident(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1364     const char *argv[], int num_opt)
   1365 {
   1366 	elfedit_atoui_t	ndx;
   1367 
   1368 	/*
   1369 	 * This command doesn't accept options, so num_opt should be
   1370 	 * 0. This is a defensive measure, in case that should change.
   1371 	 */
   1372 	argc -= num_opt;
   1373 	argv += num_opt;
   1374 
   1375 	if (argc == 1) {
   1376 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EI);
   1377 		return;
   1378 	}
   1379 
   1380 	if (argc != 2)
   1381 		return;
   1382 
   1383 	/*
   1384 	 * In order to offer up the right completion strings for
   1385 	 * the value, we need to know what index was given for
   1386 	 * the first argument. If we don't recognize the index,
   1387 	 * we want to return quietly without issuing an error,
   1388 	 * so we use elfedit_atoui_range2(), which returns
   1389 	 * a success/failure result and does not throw any errors.
   1390 	 */
   1391 	if (elfedit_atoconst_range2(argv[0], 0, EI_NIDENT - 1,
   1392 	    ELFEDIT_CONST_EI, &ndx) == 0)
   1393 		return;
   1394 	switch (ndx) {
   1395 	case EI_CLASS:
   1396 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS);
   1397 		break;
   1398 	case EI_DATA:
   1399 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA);
   1400 		break;
   1401 	case EI_VERSION:
   1402 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV);
   1403 		break;
   1404 	case EI_OSABI:
   1405 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI);
   1406 		break;
   1407 	}
   1408 }
   1409 
   1410 /*ARGSUSED*/
   1411 static void
   1412 cpl_e_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1413     const char *argv[], int num_opt)
   1414 {
   1415 	/*
   1416 	 * This command doesn't accept options, so num_opt should be
   1417 	 * 0. This is a defensive measure, in case that should change.
   1418 	 */
   1419 	argc -= num_opt;
   1420 	argv += num_opt;
   1421 
   1422 	if (argc == 1)
   1423 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ET);
   1424 }
   1425 
   1426 /*ARGSUSED*/
   1427 static void
   1428 cpl_e_machine(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1429     const char *argv[], int num_opt)
   1430 {
   1431 	/*
   1432 	 * This command doesn't accept options, so num_opt should be
   1433 	 * 0. This is a defensive measure, in case that should change.
   1434 	 */
   1435 	argc -= num_opt;
   1436 	argv += num_opt;
   1437 
   1438 	if (argc == 1)
   1439 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM);
   1440 }
   1441 
   1442 /*ARGSUSED*/
   1443 static void
   1444 cpl_e_version(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1445     const char *argv[], int num_opt)
   1446 {
   1447 	/*
   1448 	 * This command doesn't accept options, so num_opt should be
   1449 	 * 0. This is a defensive measure, in case that should change.
   1450 	 */
   1451 	argc -= num_opt;
   1452 	argv += num_opt;
   1453 
   1454 	if (argc == 1)
   1455 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV);
   1456 }
   1457 
   1458 /*ARGSUSED*/
   1459 static void
   1460 cpl_e_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1461     const char *argv[], int num_opt)
   1462 {
   1463 	/* This routine allows multiple flags to be specified */
   1464 	elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EF);
   1465 }
   1466 
   1467 /*ARGSUSED*/
   1468 static void
   1469 cpl_e_shstrndx(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1470     const char *argv[], int num_opt)
   1471 {
   1472 	enum { NAME, INDEX, TYPE } op;
   1473 	Word ndx;
   1474 
   1475 	/*
   1476 	 * The plainargument can be a section name, index, or
   1477 	 * type, based on the options used. All have completions.
   1478 	 */
   1479 	if (argc != (num_opt + 1))
   1480 		return;
   1481 
   1482 	op = NAME;
   1483 	for (ndx = 0; ndx < num_opt; ndx++) {
   1484 		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0)
   1485 			op = INDEX;
   1486 		else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0)
   1487 			op = TYPE;
   1488 	}
   1489 
   1490 	if (obj_state == NULL) {	/* No object available */
   1491 		if (op == TYPE)
   1492 			elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
   1493 		return;
   1494 	}
   1495 
   1496 	/*
   1497 	 * Loop over the sections and supply command completion
   1498 	 * for the string tables in the file.
   1499 	 */
   1500 	for (ndx = 0; ndx < obj_state->os_shnum; ndx++) {
   1501 		elfedit_section_t *sec = &obj_state->os_secarr[ndx];
   1502 
   1503 		if (sec->sec_shdr->sh_type != SHT_STRTAB)
   1504 			continue;
   1505 
   1506 		switch (op) {
   1507 		case NAME:
   1508 			elfedit_cpl_match(cpldata, sec->sec_name, 0);
   1509 			break;
   1510 		case INDEX:
   1511 			elfedit_cpl_ndx(cpldata, ndx);
   1512 			break;
   1513 		case TYPE:
   1514 			elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT_STRTAB);
   1515 			break;
   1516 		}
   1517 	}
   1518 }
   1519 
   1520 /*ARGSUSED*/
   1521 static void
   1522 cpl_ei_class(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1523     const char *argv[], int num_opt)
   1524 {
   1525 	/*
   1526 	 * This command doesn't accept options, so num_opt should be
   1527 	 * 0. This is a defensive measure, in case that should change.
   1528 	 */
   1529 	argc -= num_opt;
   1530 	argv += num_opt;
   1531 
   1532 	if (argc == 1)
   1533 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS);
   1534 }
   1535 
   1536 /*ARGSUSED*/
   1537 static void
   1538 cpl_ei_data(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1539     const char *argv[], int num_opt)
   1540 {
   1541 	/*
   1542 	 * This command doesn't accept options, so num_opt should be
   1543 	 * 0. This is a defensive measure, in case that should change.
   1544 	 */
   1545 	argc -= num_opt;
   1546 	argv += num_opt;
   1547 
   1548 	if (argc == 1)
   1549 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA);
   1550 }
   1551 
   1552 /*ARGSUSED*/
   1553 static void
   1554 cpl_ei_osabi(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1555     const char *argv[], int num_opt)
   1556 {
   1557 	/*
   1558 	 * This command doesn't accept options, so num_opt should be
   1559 	 * 0. This is a defensive measure, in case that should change.
   1560 	 */
   1561 	argc -= num_opt;
   1562 	argv += num_opt;
   1563 
   1564 	if (argc == 1)
   1565 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI);
   1566 }
   1567 
   1568 /*ARGSUSED*/
   1569 static void
   1570 cpl_ei_abiversion(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
   1571     const char *argv[], int num_opt)
   1572 {
   1573 	/*
   1574 	 * This command doesn't accept options, so num_opt should be
   1575 	 * 0. This is a defensive measure, in case that should change.
   1576 	 */
   1577 	argc -= num_opt;
   1578 	argv += num_opt;
   1579 
   1580 	if (argc == 1)
   1581 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EAV);
   1582 }
   1583 
   1584 
   1585 
   1586 
   1587 /*
   1588  * Implementation functions for the commands
   1589  */
   1590 static elfedit_cmdret_t
   1591 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1592 {
   1593 	return (cmd_body(EHDR_CMD_T_DUMP, obj_state, argc, argv));
   1594 }
   1595 
   1596 
   1597 static elfedit_cmdret_t
   1598 cmd_e_ident(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1599 {
   1600 	return (cmd_body(EHDR_CMD_T_E_IDENT, obj_state, argc, argv));
   1601 }
   1602 
   1603 
   1604 static elfedit_cmdret_t
   1605 cmd_e_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1606 {
   1607 	return (cmd_body(EHDR_CMD_T_E_TYPE, obj_state, argc, argv));
   1608 }
   1609 
   1610 
   1611 static elfedit_cmdret_t
   1612 cmd_e_machine(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1613 {
   1614 	return (cmd_body(EHDR_CMD_T_E_MACHINE, obj_state, argc, argv));
   1615 }
   1616 
   1617 
   1618 static elfedit_cmdret_t
   1619 cmd_e_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1620 {
   1621 	return (cmd_body(EHDR_CMD_T_E_VERSION, obj_state, argc, argv));
   1622 }
   1623 
   1624 
   1625 static elfedit_cmdret_t
   1626 cmd_e_entry(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1627 {
   1628 	return (cmd_body(EHDR_CMD_T_E_ENTRY, obj_state, argc, argv));
   1629 }
   1630 
   1631 
   1632 static elfedit_cmdret_t
   1633 cmd_e_phoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1634 {
   1635 	return (cmd_body(EHDR_CMD_T_E_PHOFF, obj_state, argc, argv));
   1636 }
   1637 
   1638 
   1639 static elfedit_cmdret_t
   1640 cmd_e_shoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1641 {
   1642 	return (cmd_body(EHDR_CMD_T_E_SHOFF, obj_state, argc, argv));
   1643 }
   1644 
   1645 
   1646 static elfedit_cmdret_t
   1647 cmd_e_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1648 {
   1649 	return (cmd_body(EHDR_CMD_T_E_FLAGS, obj_state, argc, argv));
   1650 }
   1651 
   1652 
   1653 static elfedit_cmdret_t
   1654 cmd_e_ehsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1655 {
   1656 	return (cmd_body(EHDR_CMD_T_E_EHSIZE, obj_state, argc, argv));
   1657 }
   1658 
   1659 
   1660 static elfedit_cmdret_t
   1661 cmd_e_phentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1662 {
   1663 	return (cmd_body(EHDR_CMD_T_E_PHENTSIZE, obj_state, argc, argv));
   1664 }
   1665 
   1666 
   1667 static elfedit_cmdret_t
   1668 cmd_e_phnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1669 {
   1670 	return (cmd_body(EHDR_CMD_T_E_PHNUM, obj_state, argc, argv));
   1671 }
   1672 
   1673 
   1674 static elfedit_cmdret_t
   1675 cmd_e_shentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1676 {
   1677 	return (cmd_body(EHDR_CMD_T_E_SHENTSIZE, obj_state, argc, argv));
   1678 }
   1679 
   1680 
   1681 static elfedit_cmdret_t
   1682 cmd_e_shnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1683 {
   1684 	return (cmd_body(EHDR_CMD_T_E_SHNUM, obj_state, argc, argv));
   1685 }
   1686 
   1687 
   1688 static elfedit_cmdret_t
   1689 cmd_e_shstrndx(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1690 {
   1691 	return (cmd_body(EHDR_CMD_T_E_SHSTRNDX, obj_state, argc, argv));
   1692 }
   1693 
   1694 
   1695 static elfedit_cmdret_t
   1696 cmd_ei_mag0(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1697 {
   1698 	return (cmd_body(EHDR_CMD_T_EI_MAG0, obj_state, argc, argv));
   1699 }
   1700 
   1701 
   1702 static elfedit_cmdret_t
   1703 cmd_ei_mag1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1704 {
   1705 	return (cmd_body(EHDR_CMD_T_EI_MAG1, obj_state, argc, argv));
   1706 }
   1707 
   1708 
   1709 static elfedit_cmdret_t
   1710 cmd_ei_mag2(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1711 {
   1712 	return (cmd_body(EHDR_CMD_T_EI_MAG2, obj_state, argc, argv));
   1713 }
   1714 
   1715 
   1716 static elfedit_cmdret_t
   1717 cmd_ei_mag3(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1718 {
   1719 	return (cmd_body(EHDR_CMD_T_EI_MAG3, obj_state, argc, argv));
   1720 }
   1721 
   1722 
   1723 static elfedit_cmdret_t
   1724 cmd_ei_class(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1725 {
   1726 	return (cmd_body(EHDR_CMD_T_EI_CLASS, obj_state, argc, argv));
   1727 }
   1728 
   1729 
   1730 static elfedit_cmdret_t
   1731 cmd_ei_data(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1732 {
   1733 	return (cmd_body(EHDR_CMD_T_EI_DATA, obj_state, argc, argv));
   1734 }
   1735 
   1736 
   1737 static elfedit_cmdret_t
   1738 cmd_ei_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1739 {
   1740 	return (cmd_body(EHDR_CMD_T_EI_VERSION, obj_state, argc, argv));
   1741 }
   1742 
   1743 
   1744 static elfedit_cmdret_t
   1745 cmd_ei_osabi(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1746 {
   1747 	return (cmd_body(EHDR_CMD_T_EI_OSABI, obj_state, argc, argv));
   1748 }
   1749 
   1750 
   1751 static elfedit_cmdret_t
   1752 cmd_ei_abiversion(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
   1753 {
   1754 	return (cmd_body(EHDR_CMD_T_EI_ABIVERSION, obj_state, argc, argv));
   1755 }
   1756 
   1757 
   1758 
   1759 
   1760 /*ARGSUSED*/
   1761 elfedit_module_t *
   1762 elfedit_init(elfedit_module_version_t version)
   1763 {
   1764 	/* Many of the commands only accept -o */
   1765 	static elfedit_cmd_optarg_t opt_std[] = {
   1766 		{ ELFEDIT_STDOA_OPT_O, NULL,
   1767 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
   1768 		{ NULL }
   1769 	};
   1770 
   1771 
   1772 	/* ehdr:dump */
   1773 	static const char *name_dump[] = {
   1774 	    MSG_ORIG(MSG_CMD_DUMP),
   1775 	    MSG_ORIG(MSG_STR_EMPTY),	/* "" makes this the default command */
   1776 	    NULL
   1777 	};
   1778 
   1779 	/* ehdr:e_ident */
   1780 	static const char *name_e_ident[] = {
   1781 		MSG_ORIG(MSG_CMD_E_IDENT), NULL };
   1782 	static elfedit_cmd_optarg_t arg_e_ident[] = {
   1783 		{ MSG_ORIG(MSG_STR_INDEX),
   1784 		    /* MSG_INTL(MSG_ARGDESC_E_IDENT_NDX) */
   1785 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_NDX),
   1786 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1787 		{ MSG_ORIG(MSG_STR_VALUE),
   1788 		    /* MSG_INTL(MSG_ARGDESC_E_IDENT_VALUE) */
   1789 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_VALUE),
   1790 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1791 		{ NULL }
   1792 	};
   1793 
   1794 	/* ehdr:e_type */
   1795 	static const char *name_e_type[] = {
   1796 		MSG_ORIG(MSG_CMD_E_TYPE), NULL };
   1797 	static elfedit_cmd_optarg_t arg_e_type[] = {
   1798 		{ MSG_ORIG(MSG_STR_VALUE),
   1799 		    /* MSG_INTL(MSG_ARGDESC_E_TYPE_VALUE) */
   1800 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_TYPE_VALUE),
   1801 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1802 		{ NULL }
   1803 	};
   1804 
   1805 	/* ehdr:e_machine */
   1806 	static const char *name_e_machine[] = {
   1807 		MSG_ORIG(MSG_CMD_E_MACHINE), NULL };
   1808 	static elfedit_cmd_optarg_t arg_e_machine[] = {
   1809 		{ MSG_ORIG(MSG_STR_TYPE),
   1810 		    /* MSG_INTL(MSG_ARGDESC_E_MACHINE_VALUE) */
   1811 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_MACHINE_VALUE),
   1812 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1813 		{ NULL }
   1814 	};
   1815 
   1816 	/* ehdr:e_version */
   1817 	static const char *name_e_version[] = {
   1818 		MSG_ORIG(MSG_CMD_E_VERSION), NULL };
   1819 	static elfedit_cmd_optarg_t arg_e_version[] = {
   1820 		{ MSG_ORIG(MSG_STR_VERSION),
   1821 		    /* MSG_INTL(MSG_ARGDESC_E_VERSION_VALUE) */
   1822 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_VERSION_VALUE),
   1823 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1824 		{ NULL }
   1825 	};
   1826 
   1827 	/* ehdr:e_entry */
   1828 	static const char *name_e_entry[] = {
   1829 		MSG_ORIG(MSG_CMD_E_ENTRY), NULL };
   1830 	static elfedit_cmd_optarg_t arg_e_entry[] = {
   1831 		{ MSG_ORIG(MSG_STR_VALUE),
   1832 		    /* MSG_INTL(MSG_ARGDESC_E_ENTRY_VALUE) */
   1833 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_ENTRY_VALUE),
   1834 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1835 		{ NULL }
   1836 	};
   1837 
   1838 	/* ehdr:e_phoff */
   1839 	static const char *name_e_phoff[] = {
   1840 		MSG_ORIG(MSG_CMD_E_PHOFF), NULL };
   1841 	static elfedit_cmd_optarg_t arg_e_phoff[] = {
   1842 		{ MSG_ORIG(MSG_STR_OFFSET),
   1843 		    /* MSG_INTL(MSG_ARGDESC_E_PHOFF_VALUE) */
   1844 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHOFF_VALUE),
   1845 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1846 		{ NULL }
   1847 	};
   1848 
   1849 	/* ehdr:e_shoff */
   1850 	static const char *name_e_shoff[] = {
   1851 		MSG_ORIG(MSG_CMD_E_SHOFF), NULL };
   1852 	static elfedit_cmd_optarg_t arg_e_shoff[] = {
   1853 		{ MSG_ORIG(MSG_STR_OFFSET),
   1854 		    /* MSG_INTL(MSG_ARGDESC_E_SHOFF_VALUE) */
   1855 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHOFF_VALUE),
   1856 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1857 		{ NULL }
   1858 	};
   1859 
   1860 	/* ehdr:e_flags */
   1861 	static const char *name_e_flags[] = {
   1862 		MSG_ORIG(MSG_CMD_E_FLAGS), NULL };
   1863 	static elfedit_cmd_optarg_t opt_e_flags[] = {
   1864 		{ ELFEDIT_STDOA_OPT_AND, NULL,
   1865 		    ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_AND, EHDR_OPT_F_OR },
   1866 		{ ELFEDIT_STDOA_OPT_CMP, NULL,
   1867 		    ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_CMP, 0 },
   1868 		{ ELFEDIT_STDOA_OPT_O, NULL,
   1869 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
   1870 		{ ELFEDIT_STDOA_OPT_OR, NULL,
   1871 		    ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_OR, EHDR_OPT_F_AND },
   1872 		{ NULL }
   1873 	};
   1874 	static elfedit_cmd_optarg_t arg_e_flags[] = {
   1875 		{ MSG_ORIG(MSG_STR_FLAGVALUE),
   1876 		    /* MSG_INTL(MSG_ARGDESC_E_FLAGS_VALUE) */
   1877 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_FLAGS_VALUE),
   1878 		    ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT, 0 },
   1879 		{ NULL }
   1880 	};
   1881 
   1882 	/* ehdr:e_ehsize */
   1883 	static const char *name_e_ehsize[] = {
   1884 		MSG_ORIG(MSG_CMD_E_EHSIZE), NULL };
   1885 	static elfedit_cmd_optarg_t arg_e_ehsize[] = {
   1886 		{ MSG_ORIG(MSG_STR_VALUE),
   1887 		    /* MSG_INTL(MSG_ARGDESC_E_EHSIZE_VALUE) */
   1888 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_EHSIZE_VALUE),
   1889 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1890 		{ NULL }
   1891 	};
   1892 
   1893 	/* ehdr:e_phentsize */
   1894 	static const char *name_e_phentsize[] = {
   1895 		MSG_ORIG(MSG_CMD_E_PHENTSIZE), NULL };
   1896 	static elfedit_cmd_optarg_t arg_e_phentsize[] = {
   1897 		{ MSG_ORIG(MSG_STR_VALUE),
   1898 		    /* MSG_INTL(MSG_ARGDESC_E_PHENTSIZE_VALUE) */
   1899 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHENTSIZE_VALUE),
   1900 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1901 		{ NULL }
   1902 	};
   1903 
   1904 	/* ehdr:e_phnum */
   1905 	static const char *name_e_phnum[] = {
   1906 		MSG_ORIG(MSG_CMD_E_PHNUM), NULL };
   1907 	static elfedit_cmd_optarg_t arg_e_phnum[] = {
   1908 		{ MSG_ORIG(MSG_STR_VALUE),
   1909 		    /* MSG_INTL(MSG_ARGDESC_E_PHNUM_VALUE) */
   1910 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHNUM_VALUE),
   1911 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1912 		{ NULL }
   1913 	};
   1914 
   1915 	/* ehdr:e_shentsize */
   1916 	static const char *name_e_shentsize[] = {
   1917 		MSG_ORIG(MSG_CMD_E_SHENTSIZE), NULL };
   1918 	static elfedit_cmd_optarg_t arg_e_shentsize[] = {
   1919 		{ MSG_ORIG(MSG_STR_VALUE),
   1920 		    /* MSG_INTL(MSG_ARGDESC_E_SHENTSIZE_VALUE) */
   1921 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHENTSIZE_VALUE),
   1922 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1923 		{ NULL }
   1924 	};
   1925 
   1926 	/* ehdr:e_shnum */
   1927 	static const char *name_e_shnum[] = {
   1928 		MSG_ORIG(MSG_CMD_E_SHNUM), NULL };
   1929 	static elfedit_cmd_optarg_t arg_e_shnum[] = {
   1930 		{ MSG_ORIG(MSG_STR_VALUE),
   1931 		    /* MSG_INTL(MSG_ARGDESC_E_SHNUM_VALUE) */
   1932 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHNUM_VALUE),
   1933 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1934 		{ NULL }
   1935 	};
   1936 
   1937 	/* ehdr:e_shstrndx */
   1938 	static const char *name_e_shstrndx[] = {
   1939 		MSG_ORIG(MSG_CMD_E_SHSTRNDX), NULL };
   1940 	static elfedit_cmd_optarg_t opt_e_shstrndx[] = {
   1941 		{ ELFEDIT_STDOA_OPT_O, NULL,
   1942 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
   1943 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
   1944 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
   1945 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
   1946 		    EHDR_OPT_F_SHNDX, EHDR_OPT_F_SHTYP },
   1947 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
   1948 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
   1949 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
   1950 		    EHDR_OPT_F_SHTYP, EHDR_OPT_F_SHNDX,  },
   1951 		{ NULL }
   1952 	};
   1953 	static elfedit_cmd_optarg_t arg_e_shstrndx[] = {
   1954 		{ MSG_ORIG(MSG_STR_SEC),
   1955 		    /* MSG_INTL(MSG_ARGDESC_E_SHSTRNDX_SEC) */
   1956 		    ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHSTRNDX_SEC),
   1957 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1958 		{ NULL }
   1959 	};
   1960 
   1961 	/* ehdr:ei_mag0 */
   1962 	static const char *name_ei_mag0[] = {
   1963 		MSG_ORIG(MSG_CMD_EI_MAG0), NULL };
   1964 	static elfedit_cmd_optarg_t arg_ei_mag0[] = {
   1965 		{ MSG_ORIG(MSG_STR_VALUE),
   1966 		    /* MSG_INTL(MSG_ARGDESC_EI_MAG0_VALUE) */
   1967 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG0_VALUE),
   1968 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1969 		{ NULL }
   1970 	};
   1971 
   1972 	/* ehdr:ei_mag1 */
   1973 	static const char *name_ei_mag1[] = {
   1974 		MSG_ORIG(MSG_CMD_EI_MAG1), NULL };
   1975 	static elfedit_cmd_optarg_t arg_ei_mag1[] = {
   1976 		{ MSG_ORIG(MSG_STR_VALUE),
   1977 		    /* MSG_INTL(MSG_ARGDESC_EI_MAG1_VALUE) */
   1978 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG1_VALUE),
   1979 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1980 		{ NULL }
   1981 	};
   1982 
   1983 	/* ehdr:ei_mag2 */
   1984 	static const char *name_ei_mag2[] = {
   1985 		MSG_ORIG(MSG_CMD_EI_MAG2), NULL };
   1986 	static elfedit_cmd_optarg_t arg_ei_mag2[] = {
   1987 		{ MSG_ORIG(MSG_STR_VALUE),
   1988 		    /* MSG_INTL(MSG_ARGDESC_EI_MAG2_VALUE) */
   1989 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG2_VALUE),
   1990 		    ELFEDIT_CMDOA_F_OPT, 0 },
   1991 		{ NULL }
   1992 	};
   1993 
   1994 	/* ehdr:ei_mag3 */
   1995 	static const char *name_ei_mag3[] = {
   1996 		MSG_ORIG(MSG_CMD_EI_MAG3), NULL };
   1997 	static elfedit_cmd_optarg_t arg_ei_mag3[] = {
   1998 		{ MSG_ORIG(MSG_STR_VALUE),
   1999 		    /* MSG_INTL(MSG_ARGDESC_EI_MAG3_VALUE) */
   2000 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG3_VALUE),
   2001 		    ELFEDIT_CMDOA_F_OPT, 0 },
   2002 		{ NULL }
   2003 	};
   2004 
   2005 	/* ehdr:ei_class */
   2006 	static const char *name_ei_class[] = {
   2007 		MSG_ORIG(MSG_CMD_EI_CLASS), NULL };
   2008 	static elfedit_cmd_optarg_t arg_ei_class[] = {
   2009 		{ MSG_ORIG(MSG_STR_VALUE),
   2010 		    /* MSG_INTL(MSG_ARGDESC_EI_CLASS_VALUE) */
   2011 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_CLASS_VALUE),
   2012 		    ELFEDIT_CMDOA_F_OPT, 0 },
   2013 		{ NULL }
   2014 	};
   2015 
   2016 	/* ehdr:ei_data */
   2017 	static const char *name_ei_data[] = {
   2018 		MSG_ORIG(MSG_CMD_EI_DATA), NULL };
   2019 	static elfedit_cmd_optarg_t arg_ei_data[] = {
   2020 		{ MSG_ORIG(MSG_STR_VALUE),
   2021 		    /* MSG_INTL(MSG_ARGDESC_EI_DATA_VALUE) */
   2022 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_DATA_VALUE),
   2023 		    ELFEDIT_CMDOA_F_OPT, 0 },
   2024 		{ NULL }
   2025 	};
   2026 
   2027 	/* ehdr:ei_version */
   2028 	static const char *name_ei_version[] = {
   2029 		MSG_ORIG(MSG_CMD_EI_VERSION), NULL };
   2030 	/* Note: arg_e_version is also used for this command */
   2031 
   2032 	/* ehdr:ei_osabi */
   2033 	static const char *name_ei_osabi[] = {
   2034 		MSG_ORIG(MSG_CMD_EI_OSABI), NULL };
   2035 	static elfedit_cmd_optarg_t arg_ei_osabi[] = {
   2036 		{ MSG_ORIG(MSG_STR_VALUE),
   2037 		    /* MSG_INTL(MSG_ARGDESC_EI_OSABI_VALUE) */
   2038 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_OSABI_VALUE),
   2039 		    ELFEDIT_CMDOA_F_OPT, 0 },
   2040 		{ NULL }
   2041 	};
   2042 
   2043 	/* ehdr:ei_abiversion */
   2044 	static const char *name_ei_abiversion[] = {
   2045 		MSG_ORIG(MSG_CMD_EI_ABIVERSION), NULL };
   2046 	static elfedit_cmd_optarg_t arg_ei_abiversion[] = {
   2047 		{ MSG_ORIG(MSG_STR_VALUE),
   2048 		    /* MSG_INTL(MSG_ARGDESC_EI_ABIVERSION_VALUE) */
   2049 		    ELFEDIT_I18NHDL(MSG_ARGDESC_EI_ABIVERSION_VALUE),
   2050 		    ELFEDIT_CMDOA_F_OPT, 0 },
   2051 		{ NULL }
   2052 	};
   2053 
   2054 
   2055 
   2056 
   2057 	static elfedit_cmd_t cmds[] = {
   2058 		/* ehdr:dump */
   2059 		{ cmd_dump, NULL, name_dump,
   2060 		    /* MSG_INTL(MSG_DESC_DUMP) */
   2061 		    ELFEDIT_I18NHDL(MSG_DESC_DUMP),
   2062 		    /* MSG_INTL(MSG_HELP_DUMP) */
   2063 		    ELFEDIT_I18NHDL(MSG_HELP_DUMP),
   2064 		    NULL, NULL },
   2065 
   2066 		/* ehdr:e_ident */
   2067 		{ cmd_e_ident, cpl_e_ident, name_e_ident,
   2068 		    /* MSG_INTL(MSG_DESC_E_IDENT) */
   2069 		    ELFEDIT_I18NHDL(MSG_DESC_E_IDENT),
   2070 		    /* MSG_INTL(MSG_HELP_E_IDENT) */
   2071 		    ELFEDIT_I18NHDL(MSG_HELP_E_IDENT),
   2072 		    opt_std, arg_e_ident },
   2073 
   2074 		/* ehdr:e_type */
   2075 		{ cmd_e_type, cpl_e_type, name_e_type,
   2076 		    /* MSG_INTL(MSG_DESC_E_TYPE) */
   2077 		    ELFEDIT_I18NHDL(MSG_DESC_E_TYPE),
   2078 		    /* MSG_INTL(MSG_HELP_E_TYPE) */
   2079 		    ELFEDIT_I18NHDL(MSG_HELP_E_TYPE),
   2080 		    opt_std, arg_e_type },
   2081 
   2082 		/* ehdr:e_machine */
   2083 		{ cmd_e_machine, cpl_e_machine, name_e_machine,
   2084 		    /* MSG_INTL(MSG_DESC_E_MACHINE) */
   2085 		    ELFEDIT_I18NHDL(MSG_DESC_E_MACHINE),
   2086 		    /* MSG_INTL(MSG_HELP_E_MACHINE) */
   2087 		    ELFEDIT_I18NHDL(MSG_HELP_E_MACHINE),
   2088 		    opt_std, arg_e_machine },
   2089 
   2090 		/* ehdr:e_version */
   2091 		{ cmd_e_version, cpl_e_version, name_e_version,
   2092 		    /* MSG_INTL(MSG_DESC_E_VERSION) */
   2093 		    ELFEDIT_I18NHDL(MSG_DESC_E_VERSION),
   2094 		    /* MSG_INTL(MSG_HELP_E_VERSION) */
   2095 		    ELFEDIT_I18NHDL(MSG_HELP_E_VERSION),
   2096 		    opt_std, arg_e_version },
   2097 
   2098 		/* ehdr:e_entry */
   2099 		{ cmd_e_entry, NULL, name_e_entry,
   2100 		    /* MSG_INTL(MSG_DESC_E_ENTRY) */
   2101 		    ELFEDIT_I18NHDL(MSG_DESC_E_ENTRY),
   2102 		    /* MSG_INTL(MSG_HELP_E_ENTRY) */
   2103 		    ELFEDIT_I18NHDL(MSG_HELP_E_ENTRY),
   2104 		    opt_std, arg_e_entry },
   2105 
   2106 		/* ehdr:e_phoff */
   2107 		{ cmd_e_phoff, NULL, name_e_phoff,
   2108 		    /* MSG_INTL(MSG_DESC_E_PHOFF) */
   2109 		    ELFEDIT_I18NHDL(MSG_DESC_E_PHOFF),
   2110 		    /* MSG_INTL(MSG_HELP_E_PHOFF) */
   2111 		    ELFEDIT_I18NHDL(MSG_HELP_E_PHOFF),
   2112 		    opt_std, arg_e_phoff },
   2113 
   2114 		/* ehdr:e_shoff */
   2115 		{ cmd_e_shoff, NULL, name_e_shoff,
   2116 		    /* MSG_INTL(MSG_DESC_E_SHOFF) */
   2117 		    ELFEDIT_I18NHDL(MSG_DESC_E_SHOFF),
   2118 		    /* MSG_INTL(MSG_HELP_E_SHOFF) */
   2119 		    ELFEDIT_I18NHDL(MSG_HELP_E_SHOFF),
   2120 		    opt_std, arg_e_shoff },
   2121 
   2122 		/* ehdr:e_flags */
   2123 		{ cmd_e_flags, cpl_e_flags, name_e_flags,
   2124 		    /* MSG_INTL(MSG_DESC_E_FLAGS) */
   2125 		    ELFEDIT_I18NHDL(MSG_DESC_E_FLAGS),
   2126 		    /* MSG_INTL(MSG_HELP_E_FLAGS) */
   2127 		    ELFEDIT_I18NHDL(MSG_HELP_E_FLAGS),
   2128 		    opt_e_flags, arg_e_flags },
   2129 
   2130 		/* ehdr:e_ehsize */
   2131 		{ cmd_e_ehsize, NULL, name_e_ehsize,
   2132 		    /* MSG_INTL(MSG_DESC_E_EHSIZE) */
   2133 		    ELFEDIT_I18NHDL(MSG_DESC_E_EHSIZE),
   2134 		    /* MSG_INTL(MSG_HELP_E_EHSIZE) */
   2135 		    ELFEDIT_I18NHDL(MSG_HELP_E_EHSIZE),
   2136 		    opt_std, arg_e_ehsize },
   2137 
   2138 		/* ehdr:e_phentsize */
   2139 		{ cmd_e_phentsize, NULL, name_e_phentsize,
   2140 		    /* MSG_INTL(MSG_DESC_E_PHENTSIZE) */
   2141 		    ELFEDIT_I18NHDL(MSG_DESC_E_PHENTSIZE),
   2142 		    /* MSG_INTL(MSG_HELP_E_PHENTSIZE) */
   2143 		    ELFEDIT_I18NHDL(MSG_HELP_E_PHENTSIZE),
   2144 		    opt_std, arg_e_phentsize },
   2145 
   2146 		/* ehdr:e_phnum */
   2147 		{ cmd_e_phnum, NULL, name_e_phnum,
   2148 		    /* MSG_INTL(MSG_DESC_E_PHNUM) */
   2149 		    ELFEDIT_I18NHDL(MSG_DESC_E_PHNUM),
   2150 		    /* MSG_INTL(MSG_HELP_E_PHNUM) */
   2151 		    ELFEDIT_I18NHDL(MSG_HELP_E_PHNUM),
   2152 		    opt_std, arg_e_phnum },
   2153 
   2154 		/* ehdr:e_shentsize */
   2155 		{ cmd_e_shentsize, NULL, name_e_shentsize,
   2156 		    /* MSG_INTL(MSG_DESC_E_SHENTSIZE) */
   2157 		    ELFEDIT_I18NHDL(MSG_DESC_E_SHENTSIZE),
   2158 		    /* MSG_INTL(MSG_HELP_E_SHENTSIZE) */
   2159 		    ELFEDIT_I18NHDL(MSG_HELP_E_SHENTSIZE),
   2160 		    opt_std, arg_e_shentsize },
   2161 
   2162 		/* ehdr:e_shnum */
   2163 		{ cmd_e_shnum, NULL, name_e_shnum,
   2164 		    /* MSG_INTL(MSG_DESC_E_SHNUM) */
   2165 		    ELFEDIT_I18NHDL(MSG_DESC_E_SHNUM),
   2166 		    /* MSG_INTL(MSG_HELP_E_SHNUM) */
   2167 		    ELFEDIT_I18NHDL(MSG_HELP_E_SHNUM),
   2168 		    opt_std, arg_e_shnum },
   2169 
   2170 		/* ehdr:e_shstrndx */
   2171 		{ cmd_e_shstrndx, cpl_e_shstrndx, name_e_shstrndx,
   2172 		    /* MSG_INTL(MSG_DESC_E_SHSTRNDX) */
   2173 		    ELFEDIT_I18NHDL(MSG_DESC_E_SHSTRNDX),
   2174 		    /* MSG_INTL(MSG_HELP_E_SHSTRNDX) */
   2175 		    ELFEDIT_I18NHDL(MSG_HELP_E_SHSTRNDX),
   2176 		    opt_e_shstrndx, arg_e_shstrndx },
   2177 
   2178 		/* ehdr:ei_mag0 */
   2179 		{ cmd_ei_mag0, NULL, name_ei_mag0,
   2180 		    /* MSG_INTL(MSG_DESC_EI_MAG0) */
   2181 		    ELFEDIT_I18NHDL(MSG_DESC_EI_MAG0),
   2182 		    /* MSG_INTL(MSG_HELP_EI_MAG0) */
   2183 		    ELFEDIT_I18NHDL(MSG_HELP_EI_MAG0),
   2184 		    opt_std, arg_ei_mag0 },
   2185 
   2186 		/* ehdr:ei_mag1 */
   2187 		{ cmd_ei_mag1, NULL, name_ei_mag1,
   2188 		    /* MSG_INTL(MSG_DESC_EI_MAG1) */
   2189 		    ELFEDIT_I18NHDL(MSG_DESC_EI_MAG1),
   2190 		    /* MSG_INTL(MSG_HELP_EI_MAG1) */
   2191 		    ELFEDIT_I18NHDL(MSG_HELP_EI_MAG1),
   2192 		    opt_std, arg_ei_mag1 },
   2193 
   2194 		/* ehdr:ei_mag2 */
   2195 		{ cmd_ei_mag2, NULL, name_ei_mag2,
   2196 		    /* MSG_INTL(MSG_DESC_EI_MAG2) */
   2197 		    ELFEDIT_I18NHDL(MSG_DESC_EI_MAG2),
   2198 		    /* MSG_INTL(MSG_HELP_EI_MAG2) */
   2199 		    ELFEDIT_I18NHDL(MSG_HELP_EI_MAG2),
   2200 		    opt_std, arg_ei_mag2 },
   2201 
   2202 		/* ehdr:ei_mag3 */
   2203 		{ cmd_ei_mag3, NULL, name_ei_mag3,
   2204 		    /* MSG_INTL(MSG_DESC_EI_MAG3) */
   2205 		    ELFEDIT_I18NHDL(MSG_DESC_EI_MAG3),
   2206 		    /* MSG_INTL(MSG_HELP_EI_MAG3) */
   2207 		    ELFEDIT_I18NHDL(MSG_HELP_EI_MAG3),
   2208 		    opt_std, arg_ei_mag3 },
   2209 
   2210 		/* ehdr:ei_class */
   2211 		{ cmd_ei_class, cpl_ei_class, name_ei_class,
   2212 		    /* MSG_INTL(MSG_DESC_EI_CLASS) */
   2213 		    ELFEDIT_I18NHDL(MSG_DESC_EI_CLASS),
   2214 		    /* MSG_INTL(MSG_HELP_EI_CLASS) */
   2215 		    ELFEDIT_I18NHDL(MSG_HELP_EI_CLASS),
   2216 		    opt_std, arg_ei_class },
   2217 
   2218 		/* ehdr:ei_data */
   2219 		{ cmd_ei_data, cpl_ei_data, name_ei_data,
   2220 		    /* MSG_INTL(MSG_DESC_EI_DATA) */
   2221 		    ELFEDIT_I18NHDL(MSG_DESC_EI_DATA),
   2222 		    /* MSG_INTL(MSG_HELP_EI_DATA) */
   2223 		    ELFEDIT_I18NHDL(MSG_HELP_EI_DATA),
   2224 		    opt_std, arg_ei_data },
   2225 
   2226 		/* ehdr:ei_version */
   2227 		{ cmd_ei_version, cpl_e_version, name_ei_version,
   2228 		    /* MSG_INTL(MSG_DESC_EI_VERSION) */
   2229 		    ELFEDIT_I18NHDL(MSG_DESC_EI_VERSION),
   2230 		    /* MSG_INTL(MSG_HELP_EI_VERSION) */
   2231 		    ELFEDIT_I18NHDL(MSG_HELP_EI_VERSION),
   2232 		    opt_std, arg_e_version },
   2233 
   2234 		/* ehdr:ei_osabi */
   2235 		{ cmd_ei_osabi, cpl_ei_osabi, name_ei_osabi,
   2236 		    /* MSG_INTL(MSG_DESC_EI_OSABI) */
   2237 		    ELFEDIT_I18NHDL(MSG_DESC_EI_OSABI),
   2238 		    /* MSG_INTL(MSG_HELP_EI_OSABI) */
   2239 		    ELFEDIT_I18NHDL(MSG_HELP_EI_OSABI),
   2240 		    opt_std, arg_ei_osabi },
   2241 
   2242 		/* ehdr:ei_abiversion */
   2243 		{ cmd_ei_abiversion, cpl_ei_abiversion, name_ei_abiversion,
   2244 		    /* MSG_INTL(MSG_DESC_EI_ABIVERSION) */
   2245 		    ELFEDIT_I18NHDL(MSG_DESC_EI_ABIVERSION),
   2246 		    /* MSG_INTL(MSG_HELP_EI_ABIVERSION) */
   2247 		    ELFEDIT_I18NHDL(MSG_HELP_EI_ABIVERSION),
   2248 		    opt_std, arg_ei_abiversion },
   2249 
   2250 		{ NULL }
   2251 	};
   2252 
   2253 	static elfedit_module_t module = {
   2254 	    ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
   2255 	    /* MSG_INTL(MSG_MOD_DESC) */
   2256 	    ELFEDIT_I18NHDL(MSG_MOD_DESC),
   2257 	    cmds, mod_i18nhdl_to_str };
   2258 
   2259 	return (&module);
   2260 }
   2261