xref: /onnv-gate/usr/src/cmd/sgs/elfedit/modules/common/shdr.c (revision 5892:b863dde33f1b)
15088Sab196087 /*
25088Sab196087  * CDDL HEADER START
35088Sab196087  *
45088Sab196087  * The contents of this file are subject to the terms of the
55088Sab196087  * Common Development and Distribution License (the "License").
65088Sab196087  * You may not use this file except in compliance with the License.
75088Sab196087  *
85088Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95088Sab196087  * or http://www.opensolaris.org/os/licensing.
105088Sab196087  * See the License for the specific language governing permissions
115088Sab196087  * and limitations under the License.
125088Sab196087  *
135088Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
145088Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155088Sab196087  * If applicable, add the following below this CDDL HEADER, with the
165088Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
175088Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
185088Sab196087  *
195088Sab196087  * CDDL HEADER END
205088Sab196087  */
215088Sab196087 
225088Sab196087 /*
23*5892Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
245088Sab196087  * Use is subject to license terms.
255088Sab196087  */
265088Sab196087 #pragma ident	"%Z%%M%	%I%	%E% SMI"
275088Sab196087 
285088Sab196087 #include	<stdio.h>
295088Sab196087 #include	<unistd.h>
305088Sab196087 #include	<machdep.h>
315088Sab196087 #include	<elfedit.h>
325088Sab196087 #include	<sys/elf_SPARC.h>
335088Sab196087 #include	<sys/elf_amd64.h>
345088Sab196087 #include	<strings.h>
355088Sab196087 #include	<debug.h>
365088Sab196087 #include	<conv.h>
375088Sab196087 #include	<shdr_msg.h>
385088Sab196087 
395088Sab196087 
405088Sab196087 
415088Sab196087 
425088Sab196087 /*
435088Sab196087  * This module uses shared code for several of the commands.
445088Sab196087  * It is sometimes necessary to know which specific command
455088Sab196087  * is active.
465088Sab196087  */
475088Sab196087 typedef enum {
485088Sab196087 	SHDR_CMD_T_DUMP =		0,	/* shdr:dump */
495088Sab196087 
505088Sab196087 	SHDR_CMD_T_SH_ADDR =		1,	/* shdr:sh_addr */
515088Sab196087 	SHDR_CMD_T_SH_ADDRALIGN =	2,	/* shdr:sh_addralign */
525088Sab196087 	SHDR_CMD_T_SH_ENTSIZE =		3,	/* shdr:sh_entsize */
535088Sab196087 	SHDR_CMD_T_SH_FLAGS =		4,	/* shdr:sh_flags */
545088Sab196087 	SHDR_CMD_T_SH_INFO =		5,	/* shdr:sh_info */
555088Sab196087 	SHDR_CMD_T_SH_LINK =		6,	/* shdr:sh_link */
565088Sab196087 	SHDR_CMD_T_SH_NAME =		7,	/* shdr:sh_name */
575088Sab196087 	SHDR_CMD_T_SH_OFFSET =		8,	/* shdr:sh_offset */
585088Sab196087 	SHDR_CMD_T_SH_SIZE =		9,	/* shdr:sh_size */
595088Sab196087 	SHDR_CMD_T_SH_TYPE =		10	/* shdr:sh_type */
605088Sab196087 } SHDR_CMD_T;
615088Sab196087 
625088Sab196087 
635088Sab196087 
645088Sab196087 #ifndef _ELF64
655088Sab196087 /*
665088Sab196087  * We supply this function for the msg module. Only one copy is needed.
675088Sab196087  */
685088Sab196087 const char *
695088Sab196087 _shdr_msg(Msg mid)
705088Sab196087 {
715088Sab196087 	return (gettext(MSG_ORIG(mid)));
725088Sab196087 }
735088Sab196087 
745088Sab196087 #endif
755088Sab196087 
765088Sab196087 
775088Sab196087 
785088Sab196087 /*
795088Sab196087  * This function is supplied to elfedit through our elfedit_module_t
805088Sab196087  * definition. It translates the opaque elfedit_i18nhdl_t handles
815088Sab196087  * in our module interface into the actual strings for elfedit to
825088Sab196087  * use.
835088Sab196087  *
845088Sab196087  * note:
855088Sab196087  *	This module uses Msg codes for its i18n handle type.
865088Sab196087  *	So the translation is simply to use MSG_INTL() to turn
875088Sab196087  *	it into a string and return it.
885088Sab196087  */
895088Sab196087 static const char *
905088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
915088Sab196087 {
925088Sab196087 	Msg msg = (Msg)hdl;
935088Sab196087 
945088Sab196087 	return (MSG_INTL(msg));
955088Sab196087 }
965088Sab196087 
975088Sab196087 
985088Sab196087 
995088Sab196087 /*
1005088Sab196087  * The shdr_opt_t enum specifies a bit value for every optional
1015088Sab196087  * argument allowed by a command in this module.
1025088Sab196087  */
1035088Sab196087 typedef enum {
1045088Sab196087 	SHDR_OPT_F_AND =	1,	/* -and: AND (&) values to dest */
1055088Sab196087 	SHDR_OPT_F_CMP =	2,	/* -cmp: Complement (~) values */
1065088Sab196087 	SHDR_OPT_F_NAMOFFSET =	4,	/* -name_offset: Name arg is numeric */
1075088Sab196087 					/*	 ofset rather than string */
1085088Sab196087 	SHDR_OPT_F_OR =		8,	/* -or: OR (|) values to dest */
1095088Sab196087 	SHDR_OPT_F_SHNDX =	16,	/* -shndx: Section by index, not name */
110*5892Sab196087 	SHDR_OPT_F_SHTYP =	32,	/* -shtyp: Section by type, not name */
111*5892Sab196087 	SHDR_OPT_F_VALUE_SHNAM = 64,	/* -value_shnam: Value of sh_info or */
112*5892Sab196087 					/*	sh_link given as section name */
113*5892Sab196087 	SHDR_OPT_F_VALUE_SHTYP = 128	/* -value_shtyp: Value of sh_info or */
114*5892Sab196087 					/*	sh_link given as section type */
1155088Sab196087 } shdr_opt_t;
1165088Sab196087 
1175088Sab196087 
1185088Sab196087 /*
1195088Sab196087  * A variable of type ARGSTATE is used by each command to maintain
1205088Sab196087  * information about the section headers and related things. It is
1215088Sab196087  * initialized by process_args(), and used by the other routines.
1225088Sab196087  */
1235088Sab196087 typedef struct {
1245088Sab196087 	elfedit_obj_state_t	*obj_state;
1255088Sab196087 	shdr_opt_t		optmask;   	/* Mask of options used */
1265088Sab196087 	int			argc;		/* # of plain arguments */
1275088Sab196087 	const char		**argv;		/* Plain arguments */
1285088Sab196087 } ARGSTATE;
1295088Sab196087 
1305088Sab196087 
1315088Sab196087 
1325088Sab196087 
1335088Sab196087 /*
1345088Sab196087  * Standard argument processing for shdr module
1355088Sab196087  *
1365088Sab196087  * entry
1375088Sab196087  *	obj_state, argc, argv - Standard command arguments
1385088Sab196087  *	optmask - Mask of allowed optional arguments.
1395088Sab196087  *	cmd - SHDR_CMD_T_* value giving identify of caller
1405088Sab196087  *	argstate - Address of ARGSTATE block to be initialized
1415088Sab196087  *
1425088Sab196087  * exit:
1435088Sab196087  *	On success, *argstate is initialized. On error,
1445088Sab196087  *	an error is issued and this routine does not return.
1455088Sab196087  */
1465088Sab196087 static void
1475088Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
1485088Sab196087     SHDR_CMD_T cmd, ARGSTATE *argstate)
1495088Sab196087 {
1505088Sab196087 	elfedit_getopt_state_t	getopt_state;
1515088Sab196087 	elfedit_getopt_ret_t	*getopt_ret;
1525088Sab196087 
1535088Sab196087 	bzero(argstate, sizeof (*argstate));
1545088Sab196087 	argstate->obj_state = obj_state;
1555088Sab196087 
1565088Sab196087 	elfedit_getopt_init(&getopt_state, &argc, &argv);
1575088Sab196087 
1585088Sab196087 	/* Add each new option to the options mask */
1595088Sab196087 	while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL)
1605088Sab196087 		argstate->optmask |= getopt_ret->gor_idmask;
1615088Sab196087 
1625088Sab196087 	/* Are the right number of plain arguments present? */
1635088Sab196087 	switch (cmd) {
1645088Sab196087 	case SHDR_CMD_T_DUMP:
1655088Sab196087 		if (argc > 1)
1665088Sab196087 			elfedit_command_usage();
1675088Sab196087 		break;
1685088Sab196087 	case SHDR_CMD_T_SH_FLAGS:
1695088Sab196087 		/* shdr:sh_flags allows an arbitrary number of arguments */
1705088Sab196087 		break;
1715088Sab196087 	default:
1725088Sab196087 		/* The remaining commands accept 2 plain arguments */
1735088Sab196087 		if (argc > 2)
1745088Sab196087 			elfedit_command_usage();
1755088Sab196087 		break;
1765088Sab196087 	}
1775088Sab196087 
1785088Sab196087 	/* If there may be an arbitrary amount of output, use a pager */
1795088Sab196087 	if (argc == 0)
1805088Sab196087 		elfedit_pager_init();
1815088Sab196087 
1825088Sab196087 	/* Return the updated values of argc/argv */
1835088Sab196087 	argstate->argc = argc;
1845088Sab196087 	argstate->argv = argv;
1855088Sab196087 }
1865088Sab196087 
1875088Sab196087 
1885088Sab196087 
1895088Sab196087 /*
1905088Sab196087  * Print section header values, taking the calling command, and output style
1915088Sab196087  * into account.
1925088Sab196087  *
1935088Sab196087  * entry:
1945088Sab196087  *	autoprint - If True, output is only produced if the elfedit
1955088Sab196087  *		autoprint flag is set. If False, output is always produced.
1965088Sab196087  *	cmd - SHDR_CMD_T_* value giving identify of caller
1975088Sab196087  *	argstate - State block for section header array
1985088Sab196087  *	ndx - Index of first section to display
1995088Sab196087  *	cnt - Number of sections to display
2005088Sab196087  */
2015088Sab196087 static void
2025088Sab196087 print_shdr(SHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate,
2035088Sab196087     Word ndx, Word cnt)
2045088Sab196087 {
2055088Sab196087 	elfedit_outstyle_t	outstyle;
2065088Sab196087 
2075088Sab196087 	if ((autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) ||
2085088Sab196087 	    (cnt == 0))
2095088Sab196087 		return;
2105088Sab196087 
2115088Sab196087 	/*
2125088Sab196087 	 * Pick an output style. shdr:dump is required to use the default
2135088Sab196087 	 * style. The other commands use the current output style.
2145088Sab196087 	 */
2155088Sab196087 	outstyle = (cmd == SHDR_CMD_T_DUMP) ?
2165088Sab196087 	    ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
2175088Sab196087 
2185088Sab196087 	/*
2195088Sab196087 	 * If doing default output, use elfdump style where we
2205088Sab196087 	 * show all section header attributes. In this case, the
2215088Sab196087 	 * command that called us doesn't matter
2225088Sab196087 	 */
2235088Sab196087 	if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
2245088Sab196087 		Half mach = argstate->obj_state->os_ehdr->e_machine;
2255088Sab196087 
2265088Sab196087 		for (; cnt--; ndx++) {
2275088Sab196087 			elfedit_section_t *sec =
2285088Sab196087 			    &argstate->obj_state->os_secarr[ndx];
2295088Sab196087 
2305088Sab196087 			elfedit_printf(MSG_ORIG(MSG_STR_NL));
2315088Sab196087 			elfedit_printf(MSG_INTL(MSG_ELF_SHDR), ndx,
2325088Sab196087 			    sec->sec_name);
2335088Sab196087 			Elf_shdr(NULL, mach, sec->sec_shdr);
2345088Sab196087 		}
2355088Sab196087 		return;
2365088Sab196087 	}
2375088Sab196087 
2385088Sab196087 
2395088Sab196087 	switch (cmd) {
2405088Sab196087 	case SHDR_CMD_T_SH_ADDR:
2415088Sab196087 		for (; cnt--; ndx++) {
2425088Sab196087 			Shdr *shdr =
2435088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
2445088Sab196087 
2455088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
2465088Sab196087 			    EC_XWORD(shdr->sh_addr));
2475088Sab196087 		}
2485088Sab196087 		return;
2495088Sab196087 
2505088Sab196087 	case SHDR_CMD_T_SH_ADDRALIGN:
2515088Sab196087 		for (; cnt--; ndx++) {
2525088Sab196087 			Shdr *shdr =
2535088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
2545088Sab196087 
2555088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
2565088Sab196087 			    EC_XWORD(shdr->sh_addralign));
2575088Sab196087 		}
2585088Sab196087 		return;
2595088Sab196087 
2605088Sab196087 	case SHDR_CMD_T_SH_ENTSIZE:
2615088Sab196087 		for (; cnt--; ndx++) {
2625088Sab196087 			Shdr *shdr =
2635088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
2645088Sab196087 
2655088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
2665088Sab196087 			    EC_XWORD(shdr->sh_entsize));
2675088Sab196087 		}
2685088Sab196087 		return;
2695088Sab196087 
2705088Sab196087 	case SHDR_CMD_T_SH_FLAGS:
2715088Sab196087 		for (; cnt--; ndx++) {
2725088Sab196087 			Shdr *shdr =
2735088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
2745088Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
2755088Sab196087 				Conv_sec_flags_buf_t sec_flags_buf;
2765088Sab196087 
2775088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
2785088Sab196087 				    conv_sec_flags(shdr->sh_flags,
2795088Sab196087 				    CONV_FMT_NOBKT, &sec_flags_buf));
2805088Sab196087 			} else {
2815088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
2825088Sab196087 				    EC_XWORD(shdr->sh_flags));
2835088Sab196087 			}
2845088Sab196087 		}
2855088Sab196087 		return;
2865088Sab196087 
2875088Sab196087 	case SHDR_CMD_T_SH_INFO:
2885088Sab196087 		for (; cnt--; ndx++) {
2895088Sab196087 			Shdr *shdr =
2905088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
2915088Sab196087 
2925088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
2935088Sab196087 			    EC_WORD(shdr->sh_info));
2945088Sab196087 		}
2955088Sab196087 		return;
2965088Sab196087 
2975088Sab196087 	case SHDR_CMD_T_SH_LINK:
2985088Sab196087 		for (; cnt--; ndx++) {
2995088Sab196087 			Shdr *shdr =
3005088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
3015088Sab196087 
3025088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
3035088Sab196087 			    EC_WORD(shdr->sh_link));
3045088Sab196087 		}
3055088Sab196087 		return;
3065088Sab196087 
3075088Sab196087 	case SHDR_CMD_T_SH_NAME:
3085088Sab196087 		/*
3095088Sab196087 		 * In simple output mode, we show the string. In numeric
3105088Sab196087 		 * mode, we show the string table offset.
3115088Sab196087 		 */
3125088Sab196087 		for (; cnt--; ndx++) {
3135088Sab196087 			elfedit_section_t *shdr_sec =
3145088Sab196087 			    &argstate->obj_state->os_secarr[ndx];
3155088Sab196087 
3165088Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
3175088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
3185088Sab196087 				    shdr_sec->sec_name);
3195088Sab196087 			} else {
3205088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
3215088Sab196087 				    EC_WORD(shdr_sec->sec_shdr->sh_name));
3225088Sab196087 			}
3235088Sab196087 		}
3245088Sab196087 		return;
3255088Sab196087 
3265088Sab196087 	case SHDR_CMD_T_SH_OFFSET:
3275088Sab196087 		for (; cnt--; ndx++) {
3285088Sab196087 			Shdr *shdr =
3295088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
3305088Sab196087 
3315088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
3325088Sab196087 			    EC_XWORD(shdr->sh_offset));
3335088Sab196087 		}
3345088Sab196087 		return;
3355088Sab196087 
3365088Sab196087 	case SHDR_CMD_T_SH_SIZE:
3375088Sab196087 		for (; cnt--; ndx++) {
3385088Sab196087 			Shdr *shdr =
3395088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
3405088Sab196087 
3415088Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
3425088Sab196087 			    EC_XWORD(shdr->sh_size));
3435088Sab196087 		}
3445088Sab196087 		return;
3455088Sab196087 
3465088Sab196087 	case SHDR_CMD_T_SH_TYPE:
3475088Sab196087 		for (; cnt--; ndx++) {
3485088Sab196087 			Shdr *shdr =
3495088Sab196087 			    argstate->obj_state->os_secarr[ndx].sec_shdr;
3505088Sab196087 			Conv_inv_buf_t inv_buf;
3515088Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
3525088Sab196087 				Half mach =
3535088Sab196087 				    argstate->obj_state->os_ehdr->e_machine;
3545088Sab196087 
3555088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
3565088Sab196087 				    conv_sec_type(mach, shdr->sh_type, 0,
3575088Sab196087 				    &inv_buf));
3585088Sab196087 			} else {
3595088Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_WORDHEXNL),
3605088Sab196087 				    EC_WORD(shdr->sh_type));
3615088Sab196087 			}
3625088Sab196087 		}
3635088Sab196087 		return;
3645088Sab196087 	}
3655088Sab196087 }
3665088Sab196087 
3675088Sab196087 
3685088Sab196087 /*
3695088Sab196087  * Common body for the shdr: module commands. These commands
3705088Sab196087  * share a large amount of common behavior, so it is convenient
3715088Sab196087  * to centralize things and use the cmd argument to handle the
3725088Sab196087  * small differences.
3735088Sab196087  *
3745088Sab196087  * entry:
3755088Sab196087  *	cmd - One of the SHDR_CMD_T_* constants listed above, specifying
3765088Sab196087  *		which command to implement.
3775088Sab196087  *	obj_state, argc, argv - Standard command arguments
3785088Sab196087  */
3795088Sab196087 static elfedit_cmdret_t
3805088Sab196087 cmd_body(SHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,
3815088Sab196087     int argc, const char *argv[])
3825088Sab196087 {
3835088Sab196087 	ARGSTATE		argstate;
3845088Sab196087 	Word			ndx;
3855088Sab196087 	elfedit_section_t	*shdr_sec;
3865088Sab196087 	Shdr			*shdr;
3875088Sab196087 	elfedit_cmdret_t	ret = ELFEDIT_CMDRET_NONE;
3885088Sab196087 
3895088Sab196087 	process_args(obj_state, argc, argv, cmd, &argstate);
3905088Sab196087 
3915088Sab196087 	/* If there are no arguments, dump the whole table and return */
3925088Sab196087 	if (argstate.argc == 0) {
3935088Sab196087 		print_shdr(cmd, 0, &argstate, 0, obj_state->os_shnum);
3945088Sab196087 		return (ELFEDIT_CMDRET_NONE);
3955088Sab196087 	}
3965088Sab196087 
3975088Sab196087 	/*
3985088Sab196087 	 * The first argument gives the section to use. This can be a
3995088Sab196087 	 * name (default), section index, or section type, depending on
4005088Sab196087 	 * the options used.
4015088Sab196087 	 */
4025088Sab196087 	if (argstate.optmask & SHDR_OPT_F_SHNDX)
4035088Sab196087 		ndx = elfedit_atoshndx(argstate.argv[0], obj_state->os_shnum);
4045088Sab196087 	else if (argstate.optmask & SHDR_OPT_F_SHTYP)
4055088Sab196087 		ndx = elfedit_type_to_shndx(obj_state,
4065088Sab196087 		    elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_SHT));
4075088Sab196087 	else
4085088Sab196087 		ndx = elfedit_name_to_shndx(obj_state, argstate.argv[0]);
4095088Sab196087 
4105088Sab196087 	/* If there is a single argument, display that item and return */
4115088Sab196087 	if (argstate.argc == 1) {
4125088Sab196087 		print_shdr(cmd, 0, &argstate, ndx, 1);
4135088Sab196087 		return (ELFEDIT_CMDRET_NONE);
4145088Sab196087 	}
4155088Sab196087 
4165088Sab196087 	/*
4175088Sab196087 	 * Section [0] is supposed to be all zero unless extended sections
4185088Sab196087 	 * are in force. Rather than setting extended values directly,
4195088Sab196087 	 * it is expected to be handled by the ELF header module. So, a
4205088Sab196087 	 * direct change here is probably not what was intended.
4215088Sab196087 	 */
4225088Sab196087 	if (ndx == 0)
4235088Sab196087 		elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CHGSHDR0));
4245088Sab196087 
4255088Sab196087 	/* The second value is an integer giving a new value */
4265088Sab196087 	shdr_sec = &obj_state->os_secarr[ndx];
4275088Sab196087 	shdr = shdr_sec->sec_shdr;
4285088Sab196087 	switch (cmd) {
4295088Sab196087 		/*
4305088Sab196087 		 * SHDR_CMD_T_DUMP can't get here: It never has more than
4315088Sab196087 		 * one argument, and is handled above.
4325088Sab196087 		 */
4335088Sab196087 
4345088Sab196087 	case SHDR_CMD_T_SH_ADDR:
4355088Sab196087 		{
4365088Sab196087 			Addr sh_addr = elfedit_atoui(argstate.argv[1], NULL);
4375088Sab196087 
4385088Sab196087 			if (shdr->sh_addr == sh_addr) {
4395088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4405088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
4415088Sab196087 				    ndx, shdr_sec->sec_name,
4425088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDR),
4435088Sab196087 				    EC_ADDR(shdr->sh_addr));
4445088Sab196087 			} else {
4455088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4465088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
4475088Sab196087 				    ndx, shdr_sec->sec_name,
4485088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDR),
4495088Sab196087 				    EC_ADDR(shdr->sh_addr), EC_ADDR(sh_addr));
4505088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
4515088Sab196087 				shdr->sh_addr = sh_addr;
4525088Sab196087 			}
4535088Sab196087 		}
4545088Sab196087 		break;
4555088Sab196087 
4565088Sab196087 	case SHDR_CMD_T_SH_ADDRALIGN:
4575088Sab196087 		{
4585088Sab196087 			Xword	sh_addralign;
4595088Sab196087 
4605088Sab196087 			sh_addralign = elfedit_atoui(argstate.argv[1], NULL);
4615088Sab196087 			if (elfedit_bits_set(sh_addralign,
4625088Sab196087 			    sizeof (sh_addralign)) > 1)
4635088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4645088Sab196087 				    MSG_INTL(MSG_DEBUG_ADDRALIGN),
4655088Sab196087 				    argstate.argv[1]);
4665088Sab196087 			if (shdr->sh_addralign == sh_addralign) {
4675088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4685088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
4695088Sab196087 				    ndx, shdr_sec->sec_name,
4705088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDRALIGN),
4715088Sab196087 				    EC_XWORD(shdr->sh_addralign));
4725088Sab196087 			} else {
4735088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4745088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
4755088Sab196087 				    ndx, shdr_sec->sec_name,
4765088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDRALIGN),
4775088Sab196087 				    EC_XWORD(shdr->sh_addralign),
4785088Sab196087 				    EC_XWORD(sh_addralign));
4795088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
4805088Sab196087 				shdr->sh_addralign = sh_addralign;
4815088Sab196087 			}
4825088Sab196087 		}
4835088Sab196087 		break;
4845088Sab196087 
4855088Sab196087 	case SHDR_CMD_T_SH_ENTSIZE:
4865088Sab196087 		{
4875088Sab196087 			Xword sh_entsize;
4885088Sab196087 
4895088Sab196087 			sh_entsize = elfedit_atoui(argstate.argv[1], NULL);
4905088Sab196087 			if (shdr->sh_entsize == sh_entsize) {
4915088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4925088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
4935088Sab196087 				    ndx, shdr_sec->sec_name,
4945088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ENTSIZE),
4955088Sab196087 				    EC_XWORD(shdr->sh_entsize));
4965088Sab196087 			} else {
4975088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
4985088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
4995088Sab196087 				    ndx, shdr_sec->sec_name,
5005088Sab196087 				    MSG_ORIG(MSG_CMD_SH_ENTSIZE),
5015088Sab196087 				    EC_XWORD(shdr->sh_entsize),
5025088Sab196087 				    EC_XWORD(sh_entsize));
5035088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
5045088Sab196087 				shdr->sh_entsize = sh_entsize;
5055088Sab196087 			}
5065088Sab196087 		}
5075088Sab196087 		break;
5085088Sab196087 
5095088Sab196087 	case SHDR_CMD_T_SH_FLAGS:
5105088Sab196087 		{
5115088Sab196087 			Conv_sec_flags_buf_t buf1, buf2;
5125088Sab196087 			Word	sh_flags = 0;
5135088Sab196087 			int	i;
5145088Sab196087 
5155088Sab196087 						/* Collect the flag arguments */
5165088Sab196087 			for (i = 1; i < argstate.argc; i++)
5175088Sab196087 				sh_flags |=
5185088Sab196087 				    (Word) elfedit_atoconst(argstate.argv[i],
5195088Sab196087 				    ELFEDIT_CONST_SHF);
5205088Sab196087 
5215088Sab196087 			/* Complement the value? */
5225088Sab196087 			if (argstate.optmask & SHDR_OPT_F_CMP)
5235088Sab196087 				sh_flags = ~sh_flags;
5245088Sab196087 
5255088Sab196087 			/* Perform any requested bit operations */
5265088Sab196087 			if (argstate.optmask & SHDR_OPT_F_AND)
5275088Sab196087 				sh_flags &= shdr->sh_flags;
5285088Sab196087 			else if (argstate.optmask & SHDR_OPT_F_OR)
5295088Sab196087 				sh_flags |= shdr->sh_flags;
5305088Sab196087 
5315088Sab196087 			/* Set the value */
5325088Sab196087 			if (shdr->sh_flags == sh_flags) {
5335088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
5345088Sab196087 				    MSG_INTL(MSG_DEBUG_S_OK),
5355088Sab196087 				    ndx, shdr_sec->sec_name,
5365088Sab196087 				    MSG_ORIG(MSG_CMD_SH_FLAGS),
5375088Sab196087 				    conv_sec_flags(shdr->sh_flags, 0, &buf1));
5385088Sab196087 			} else {
5395088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
5405088Sab196087 				    MSG_INTL(MSG_DEBUG_S_CHG),
5415088Sab196087 				    ndx, shdr_sec->sec_name,
5425088Sab196087 				    MSG_ORIG(MSG_CMD_SH_FLAGS),
5435088Sab196087 				    conv_sec_flags(shdr->sh_flags, 0, &buf1),
5445088Sab196087 				    conv_sec_flags(sh_flags, 0, &buf2));
5455088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
5465088Sab196087 				shdr->sh_flags = sh_flags;
5475088Sab196087 			}
5485088Sab196087 		}
5495088Sab196087 		break;
5505088Sab196087 
5515088Sab196087 	case SHDR_CMD_T_SH_INFO:
5525088Sab196087 		{
553*5892Sab196087 			Word sh_info;
554*5892Sab196087 
555*5892Sab196087 			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM)
556*5892Sab196087 				sh_info = elfedit_name_to_shndx(obj_state,
557*5892Sab196087 				    argstate.argv[1]);
558*5892Sab196087 			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP)
559*5892Sab196087 				sh_info = elfedit_type_to_shndx(obj_state,
560*5892Sab196087 				    elfedit_atoconst(argstate.argv[1],
561*5892Sab196087 				    ELFEDIT_CONST_SHT));
562*5892Sab196087 			else
563*5892Sab196087 				sh_info = elfedit_atoui(argstate.argv[1], NULL);
5645088Sab196087 
5655088Sab196087 			if (shdr->sh_info == sh_info) {
5665088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
5675088Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
5685088Sab196087 				    ndx, shdr_sec->sec_name,
5695088Sab196087 				    MSG_ORIG(MSG_CMD_SH_INFO),
5705088Sab196087 				    EC_WORD(shdr->sh_info));
5715088Sab196087 			} else {
5725088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
5735088Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
5745088Sab196087 				    ndx, shdr_sec->sec_name,
5755088Sab196087 				    MSG_ORIG(MSG_CMD_SH_INFO),
5765088Sab196087 				    EC_WORD(shdr->sh_info), EC_WORD(sh_info));
5775088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
5785088Sab196087 				shdr->sh_info = sh_info;
5795088Sab196087 			}
5805088Sab196087 		}
5815088Sab196087 		break;
5825088Sab196087 
5835088Sab196087 	case SHDR_CMD_T_SH_LINK:
5845088Sab196087 		{
585*5892Sab196087 			Word sh_link;
586*5892Sab196087 
587*5892Sab196087 			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM)
588*5892Sab196087 				sh_link = elfedit_name_to_shndx(obj_state,
589*5892Sab196087 				    argstate.argv[1]);
590*5892Sab196087 			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP)
591*5892Sab196087 				sh_link = elfedit_type_to_shndx(obj_state,
592*5892Sab196087 				    elfedit_atoconst(argstate.argv[1],
593*5892Sab196087 				    ELFEDIT_CONST_SHT));
594*5892Sab196087 			else
595*5892Sab196087 				sh_link = elfedit_atoui(argstate.argv[1], NULL);
5965088Sab196087 
5975088Sab196087 			if (shdr->sh_link == sh_link) {
5985088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
5995088Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
6005088Sab196087 				    ndx, shdr_sec->sec_name,
6015088Sab196087 				    MSG_ORIG(MSG_CMD_SH_LINK),
6025088Sab196087 				    EC_WORD(shdr->sh_link));
6035088Sab196087 			} else {
6045088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6055088Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
6065088Sab196087 				    ndx, shdr_sec->sec_name,
6075088Sab196087 				    MSG_ORIG(MSG_CMD_SH_LINK),
6085088Sab196087 				    EC_WORD(shdr->sh_link), EC_WORD(sh_link));
6095088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
6105088Sab196087 				shdr->sh_link = sh_link;
6115088Sab196087 			}
6125088Sab196087 		}
6135088Sab196087 		break;
6145088Sab196087 
6155088Sab196087 	case SHDR_CMD_T_SH_NAME:
6165088Sab196087 		{
6175088Sab196087 			elfedit_section_t *shstr_sec =
6185088Sab196087 			    &obj_state->os_secarr[obj_state->os_shstrndx];
6195088Sab196087 			Word sh_name;
6205088Sab196087 
6215088Sab196087 			/*
6225088Sab196087 			 * If -name_offset was specified, this is an offset
6235088Sab196087 			 * into the string table. Otherwise it is a string
6245088Sab196087 			 * we need to turn into an offset.
6255088Sab196087 			 */
6265088Sab196087 			sh_name = (argstate.optmask & SHDR_OPT_F_NAMOFFSET) ?
6275088Sab196087 			    elfedit_atoui(argstate.argv[1], NULL) :
6285088Sab196087 			    elfedit_strtab_insert(obj_state,
6295088Sab196087 			    shstr_sec, NULL, argstate.argv[1]);
6305088Sab196087 			if (shdr->sh_name == sh_name) {
6315088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6325088Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
6335088Sab196087 				    ndx, shdr_sec->sec_name,
6345088Sab196087 				    MSG_ORIG(MSG_CMD_SH_NAME),
6355088Sab196087 				    EC_WORD(shdr->sh_name));
6365088Sab196087 			} else {
6375088Sab196087 				/*
6385088Sab196087 				 * The section name is cached, so we must
6395088Sab196087 				 * also update that value. This call will
6405088Sab196087 				 * warn if the offset is out of range, and
6415088Sab196087 				 * will supply a safe string in that case.
6425088Sab196087 				 */
6435088Sab196087 				shdr_sec->sec_name =
6445088Sab196087 				    elfedit_offset_to_str(shstr_sec,
6455088Sab196087 				    sh_name, ELFEDIT_MSG_DEBUG, 1);
6465088Sab196087 
6475088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6485088Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
6495088Sab196087 				    ndx, shdr_sec->sec_name,
6505088Sab196087 				    MSG_ORIG(MSG_CMD_SH_NAME),
6515088Sab196087 				    EC_WORD(shdr->sh_name), EC_WORD(sh_name));
6525088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
6535088Sab196087 				shdr->sh_name = sh_name;
6545088Sab196087 			}
6555088Sab196087 		}
6565088Sab196087 		break;
6575088Sab196087 
6585088Sab196087 	case SHDR_CMD_T_SH_OFFSET:
6595088Sab196087 		{
6605088Sab196087 			Off sh_offset;
6615088Sab196087 
6625088Sab196087 			sh_offset = elfedit_atoui(argstate.argv[1], NULL);
6635088Sab196087 			if (shdr->sh_offset == sh_offset) {
6645088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6655088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
6665088Sab196087 				    ndx, shdr_sec->sec_name,
6675088Sab196087 				    MSG_ORIG(MSG_CMD_SH_OFFSET),
6685088Sab196087 				    EC_XWORD(shdr->sh_offset));
6695088Sab196087 			} else {
6705088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6715088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
6725088Sab196087 				    ndx, shdr_sec->sec_name,
6735088Sab196087 				    MSG_ORIG(MSG_CMD_SH_OFFSET),
6745088Sab196087 				    EC_XWORD(shdr->sh_offset),
6755088Sab196087 				    EC_XWORD(sh_offset));
6765088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
6775088Sab196087 				shdr->sh_offset = sh_offset;
6785088Sab196087 			}
6795088Sab196087 		}
6805088Sab196087 		break;
6815088Sab196087 
6825088Sab196087 	case SHDR_CMD_T_SH_SIZE:
6835088Sab196087 		{
6845088Sab196087 			Xword sh_size;
6855088Sab196087 
6865088Sab196087 			sh_size = elfedit_atoui(argstate.argv[1], NULL);
6875088Sab196087 			if (shdr->sh_size == sh_size) {
6885088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6895088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
6905088Sab196087 				    ndx, shdr_sec->sec_name,
6915088Sab196087 				    MSG_ORIG(MSG_CMD_SH_SIZE),
6925088Sab196087 				    EC_XWORD(shdr->sh_size));
6935088Sab196087 			} else {
6945088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
6955088Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
6965088Sab196087 				    ndx, shdr_sec->sec_name,
6975088Sab196087 				    MSG_ORIG(MSG_CMD_SH_SIZE),
6985088Sab196087 				    EC_XWORD(shdr->sh_size),
6995088Sab196087 				    EC_XWORD(sh_size));
7005088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
7015088Sab196087 				shdr->sh_size = sh_size;
7025088Sab196087 			}
7035088Sab196087 		}
7045088Sab196087 		break;
7055088Sab196087 
7065088Sab196087 	case SHDR_CMD_T_SH_TYPE:
7075088Sab196087 		{
7085088Sab196087 			Half mach = obj_state->os_ehdr->e_machine;
7095088Sab196087 			Word sh_type = elfedit_atoconst(argstate.argv[1],
7105088Sab196087 			    ELFEDIT_CONST_SHT);
7115088Sab196087 			Conv_inv_buf_t inv_buf1, inv_buf2;
7125088Sab196087 
7135088Sab196087 			if (shdr->sh_type == sh_type) {
7145088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
7155088Sab196087 				    MSG_INTL(MSG_DEBUG_S_OK),
7165088Sab196087 				    ndx, shdr_sec->sec_name,
7175088Sab196087 				    MSG_ORIG(MSG_CMD_SH_TYPE),
7185088Sab196087 				    conv_sec_type(mach, shdr->sh_type,
7195088Sab196087 				    0, &inv_buf1));
7205088Sab196087 			} else {
7215088Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
7225088Sab196087 				    MSG_INTL(MSG_DEBUG_S_CHG),
7235088Sab196087 				    ndx, shdr_sec->sec_name,
7245088Sab196087 				    MSG_ORIG(MSG_CMD_SH_TYPE),
7255088Sab196087 				    conv_sec_type(mach, shdr->sh_type, 0,
7265088Sab196087 				    &inv_buf1),
7275088Sab196087 				    conv_sec_type(mach, sh_type, 0, &inv_buf2));
7285088Sab196087 				ret = ELFEDIT_CMDRET_MOD;
7295088Sab196087 				shdr->sh_type = sh_type;
7305088Sab196087 			}
7315088Sab196087 		}
7325088Sab196087 		break;
7335088Sab196087 	}
7345088Sab196087 
7355088Sab196087 	/*
7365088Sab196087 	 * If we modified the section header array, tell libelf.
7375088Sab196087 	 */
7385088Sab196087 	if (ret == ELFEDIT_CMDRET_MOD)
7395088Sab196087 		elfedit_modified_shdr(shdr_sec);
7405088Sab196087 
7415088Sab196087 	/* Do autoprint */
7425088Sab196087 	print_shdr(cmd, 1, &argstate, ndx, 1);
7435088Sab196087 
7445088Sab196087 	return (ret);
7455088Sab196087 }
7465088Sab196087 
7475088Sab196087 
7485088Sab196087 
7495088Sab196087 
7505088Sab196087 /*
7515088Sab196087  * Command completion functions for the various commands
7525088Sab196087  */
7535088Sab196087 
7545088Sab196087 /*
7555088Sab196087  * All of the commands accept the same first argument (sec) that
7565088Sab196087  * specifies the section. This argument can be a section name
7575088Sab196087  * (default), section index, or section type, depending on the
7585088Sab196087  * options used. This routine determines which case is current,
7595088Sab196087  * and then supplies completion for the first argument.
7605088Sab196087  */
7615088Sab196087 static void
7625088Sab196087 cpl_1starg_sec(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
7635088Sab196087     const char *argv[], int num_opt)
7645088Sab196087 {
7655088Sab196087 	elfedit_section_t *sec;
7665088Sab196087 	enum { NAME, INDEX, TYPE } op;
7675088Sab196087 	Word ndx;
7685088Sab196087 
7695088Sab196087 	if (argc != (num_opt + 1))
7705088Sab196087 		return;
7715088Sab196087 
7725088Sab196087 	op = NAME;
7735088Sab196087 	for (ndx = 0; ndx < num_opt; ndx++) {
7745088Sab196087 		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0)
7755088Sab196087 			op = INDEX;
7765088Sab196087 		else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0)
7775088Sab196087 			op = TYPE;
7785088Sab196087 	}
7795088Sab196087 
7805088Sab196087 	switch (op) {
7815088Sab196087 	case NAME:
7825088Sab196087 		if (obj_state == NULL)
7835088Sab196087 			break;
7845088Sab196087 		sec = obj_state->os_secarr;
7855088Sab196087 		for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++)
7865088Sab196087 			elfedit_cpl_match(cpldata, sec->sec_name, 0);
7875088Sab196087 		break;
7885088Sab196087 
7895088Sab196087 	case INDEX:
7905088Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHN);
7915088Sab196087 		break;
7925088Sab196087 
7935088Sab196087 	case TYPE:
7945088Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
7955088Sab196087 		break;
7965088Sab196087 	}
7975088Sab196087 }
7985088Sab196087 
7995088Sab196087 
8005088Sab196087 /*ARGSUSED*/
8015088Sab196087 static void
8025088Sab196087 cpl_sh_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
8035088Sab196087     const char *argv[], int num_opt)
8045088Sab196087 {
8055088Sab196087 	/* Handle -shXXX options */
8065088Sab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
8075088Sab196087 
8085088Sab196087 	/* The second and following arguments can be an SHF_ value */
8095088Sab196087 	if (argc >= (num_opt + 2))
8105088Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHF);
8115088Sab196087 }
8125088Sab196087 
813*5892Sab196087 /*
814*5892Sab196087  * For shdr:sh_info and shdr:sh_link: The value argument can be an
815*5892Sab196087  * integer, section name, or section type.
816*5892Sab196087  */
817*5892Sab196087 /*ARGSUSED*/
818*5892Sab196087 static void
819*5892Sab196087 cpl_sh_infolink(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
820*5892Sab196087     const char *argv[], int num_opt)
821*5892Sab196087 {
822*5892Sab196087 	elfedit_section_t *sec;
823*5892Sab196087 	enum { NAME, INTVAL, TYPE } op;
824*5892Sab196087 	Word ndx;
825*5892Sab196087 
826*5892Sab196087 	/* Handle -shXXX options */
827*5892Sab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
828*5892Sab196087 
829*5892Sab196087 	if (argc != (num_opt + 2))
830*5892Sab196087 		return;
831*5892Sab196087 
832*5892Sab196087 	op = INTVAL;
833*5892Sab196087 	for (ndx = 0; ndx < num_opt; ndx++) {
834*5892Sab196087 		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM)) == 0)
835*5892Sab196087 			op = NAME;
836*5892Sab196087 		else if (strcmp(argv[ndx],
837*5892Sab196087 		    MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP)) == 0)
838*5892Sab196087 			op = TYPE;
839*5892Sab196087 	}
840*5892Sab196087 
841*5892Sab196087 	switch (op) {
842*5892Sab196087 	case NAME:
843*5892Sab196087 		if (obj_state == NULL)
844*5892Sab196087 			break;
845*5892Sab196087 		sec = obj_state->os_secarr;
846*5892Sab196087 		for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++)
847*5892Sab196087 			elfedit_cpl_match(cpldata, sec->sec_name, 0);
848*5892Sab196087 		break;
849*5892Sab196087 
850*5892Sab196087 	case TYPE:
851*5892Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
852*5892Sab196087 		break;
853*5892Sab196087 	}
854*5892Sab196087 }
855*5892Sab196087 
8565088Sab196087 /*ARGSUSED*/
8575088Sab196087 static void
8585088Sab196087 cpl_sh_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
8595088Sab196087     const char *argv[], int num_opt)
8605088Sab196087 {
8615088Sab196087 	/* Handle -shXXX options */
8625088Sab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
8635088Sab196087 
8645088Sab196087 	/* The second argument can be an SHT_ value */
8655088Sab196087 	if (argc == (num_opt + 2))
8665088Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
8675088Sab196087 }
8685088Sab196087 
8695088Sab196087 
8705088Sab196087 
8715088Sab196087 /*
8725088Sab196087  * Implementation functions for the commands
8735088Sab196087  */
8745088Sab196087 static elfedit_cmdret_t
8755088Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
8765088Sab196087 {
8775088Sab196087 	return (cmd_body(SHDR_CMD_T_DUMP, obj_state, argc, argv));
8785088Sab196087 }
8795088Sab196087 
8805088Sab196087 
8815088Sab196087 static elfedit_cmdret_t
8825088Sab196087 cmd_sh_addr(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
8835088Sab196087 {
8845088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ADDR, obj_state, argc, argv));
8855088Sab196087 }
8865088Sab196087 
8875088Sab196087 
8885088Sab196087 static elfedit_cmdret_t
8895088Sab196087 cmd_sh_addralign(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
8905088Sab196087 {
8915088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ADDRALIGN, obj_state, argc, argv));
8925088Sab196087 }
8935088Sab196087 
8945088Sab196087 
8955088Sab196087 static elfedit_cmdret_t
8965088Sab196087 cmd_sh_entsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
8975088Sab196087 {
8985088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ENTSIZE, obj_state, argc, argv));
8995088Sab196087 }
9005088Sab196087 
9015088Sab196087 static elfedit_cmdret_t
9025088Sab196087 cmd_sh_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9035088Sab196087 {
9045088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_FLAGS, obj_state, argc, argv));
9055088Sab196087 }
9065088Sab196087 
9075088Sab196087 static elfedit_cmdret_t
9085088Sab196087 cmd_sh_info(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9095088Sab196087 {
9105088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_INFO, obj_state, argc, argv));
9115088Sab196087 }
9125088Sab196087 
9135088Sab196087 static elfedit_cmdret_t
9145088Sab196087 cmd_sh_link(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9155088Sab196087 {
9165088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_LINK, obj_state, argc, argv));
9175088Sab196087 }
9185088Sab196087 
9195088Sab196087 static elfedit_cmdret_t
9205088Sab196087 cmd_sh_name(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9215088Sab196087 {
9225088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_NAME, obj_state, argc, argv));
9235088Sab196087 }
9245088Sab196087 
9255088Sab196087 static elfedit_cmdret_t
9265088Sab196087 cmd_sh_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9275088Sab196087 {
9285088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_OFFSET, obj_state, argc, argv));
9295088Sab196087 }
9305088Sab196087 
9315088Sab196087 static elfedit_cmdret_t
9325088Sab196087 cmd_sh_size(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9335088Sab196087 {
9345088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_SIZE, obj_state, argc, argv));
9355088Sab196087 }
9365088Sab196087 
9375088Sab196087 static elfedit_cmdret_t
9385088Sab196087 cmd_sh_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
9395088Sab196087 {
9405088Sab196087 	return (cmd_body(SHDR_CMD_T_SH_TYPE, obj_state, argc, argv));
9415088Sab196087 }
9425088Sab196087 
9435088Sab196087 
9445088Sab196087 
9455088Sab196087 /*ARGSUSED*/
9465088Sab196087 elfedit_module_t *
9475088Sab196087 elfedit_init(elfedit_module_version_t version)
9485088Sab196087 {
9495088Sab196087 	/* Multiple commands accept only the standard set of options */
9505088Sab196087 	static elfedit_cmd_optarg_t opt_std[] = {
9515088Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
9525088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
9535088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
9545088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
9555088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
9565088Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
9575088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
9585088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
9595088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
9605088Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
9615088Sab196087 		{ NULL }
9625088Sab196087 	};
9635088Sab196087 
964*5892Sab196087 	/*
965*5892Sab196087 	 * sh_info and sh_link accept the standard options above,
966*5892Sab196087 	 * plus -value_shnam and -value_shtyp.
967*5892Sab196087 	 */
968*5892Sab196087 	static elfedit_cmd_optarg_t opt_infolink[] = {
969*5892Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
970*5892Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
971*5892Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
972*5892Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
973*5892Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
974*5892Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
975*5892Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
976*5892Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
977*5892Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
978*5892Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
979*5892Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM),
980*5892Sab196087 		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHNAM) */
981*5892Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHNAM), 0,
982*5892Sab196087 		    SHDR_OPT_F_VALUE_SHNAM, SHDR_OPT_F_VALUE_SHNAM },
983*5892Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP),
984*5892Sab196087 		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHTYP) */
985*5892Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHTYP), 0,
986*5892Sab196087 		    SHDR_OPT_F_VALUE_SHTYP, SHDR_OPT_F_VALUE_SHTYP },
987*5892Sab196087 		{ NULL }
988*5892Sab196087 	};
989*5892Sab196087 
9905088Sab196087 	/* shdr:sh_addr */
9915088Sab196087 	static const char *name_sh_addr[] = {
9925088Sab196087 	    MSG_ORIG(MSG_CMD_SH_ADDR), NULL };
9935088Sab196087 	static elfedit_cmd_optarg_t arg_sh_addr[] = {
9945088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
9955088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
9965088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
9975088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
9985088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
9995088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ADDR) */
10005088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDR),
10015088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10025088Sab196087 		{ NULL }
10035088Sab196087 	};
10045088Sab196087 
10055088Sab196087 	/* shdr:dump */
10065088Sab196087 	static const char *name_dump[] = {
10075088Sab196087 	    MSG_ORIG(MSG_CMD_DUMP),
10085088Sab196087 	    MSG_ORIG(MSG_STR_EMPTY),	/* "" makes this the default command */
10095088Sab196087 	    NULL
10105088Sab196087 	};
10115088Sab196087 	static elfedit_cmd_optarg_t opt_dump[] = {
10125088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
10135088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
10145088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
10155088Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
10165088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
10175088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
10185088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
10195088Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
10205088Sab196087 		{ NULL }
10215088Sab196087 	};
10225088Sab196087 	static elfedit_cmd_optarg_t arg_dump[] = {
10235088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
10245088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
10255088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
10265088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10275088Sab196087 		{ NULL }
10285088Sab196087 	};
10295088Sab196087 
10305088Sab196087 	/* shdr:sh_addralign */
10315088Sab196087 	static const char *name_sh_addralign[] = {
10325088Sab196087 	    MSG_ORIG(MSG_CMD_SH_ADDRALIGN), NULL };
10335088Sab196087 	static elfedit_cmd_optarg_t arg_sh_addralign[] = {
10345088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
10355088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
10365088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
10375088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10385088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
10395088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ADDRALIGN) */
10405088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDRALIGN),
10415088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10425088Sab196087 		{ NULL }
10435088Sab196087 	};
10445088Sab196087 
10455088Sab196087 	/* shdr:sh_entsize */
10465088Sab196087 	static const char *name_sh_entsize[] = {
10475088Sab196087 	    MSG_ORIG(MSG_CMD_SH_ENTSIZE), NULL };
10485088Sab196087 	static elfedit_cmd_optarg_t arg_sh_entsize[] = {
10495088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
10505088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
10515088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
10525088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10535088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
10545088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ENTSIZE) */
10555088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ENTSIZE),
10565088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10575088Sab196087 		{ NULL }
10585088Sab196087 	};
10595088Sab196087 
10605088Sab196087 	/* shdr:sh_flags */
10615088Sab196087 	static const char *name_sh_flags[] = {
10625088Sab196087 	    MSG_ORIG(MSG_CMD_SH_FLAGS), NULL };
10635088Sab196087 	static elfedit_cmd_optarg_t opt_sh_flags[] = {
10645088Sab196087 		{ ELFEDIT_STDOA_OPT_AND, NULL,
10655088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_AND, SHDR_OPT_F_OR },
10665088Sab196087 		{ ELFEDIT_STDOA_OPT_CMP, NULL,
10675088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_CMP, 0 },
10685088Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
10695088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
10705088Sab196087 		{ ELFEDIT_STDOA_OPT_OR, NULL,
10715088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_OR, SHDR_OPT_F_AND },
10725088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
10735088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
10745088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
10755088Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
10765088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
10775088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
10785088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
10795088Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
10805088Sab196087 		{ NULL }
10815088Sab196087 	};
10825088Sab196087 	static elfedit_cmd_optarg_t arg_sh_flags[] = {
10835088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
10845088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
10855088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
10865088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
10875088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
10885088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_FLAGS) */
10895088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_FLAGS),
10905088Sab196087 		    ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
10915088Sab196087 		{ NULL }
10925088Sab196087 	};
10935088Sab196087 
10945088Sab196087 	/* shdr:sh_info */
10955088Sab196087 	static const char *name_sh_info[] = {
10965088Sab196087 	    MSG_ORIG(MSG_CMD_SH_INFO), NULL };
10975088Sab196087 	static elfedit_cmd_optarg_t arg_sh_info[] = {
10985088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
10995088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11005088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11015088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11025088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
11035088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_INFO) */
11045088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_INFO),
11055088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11065088Sab196087 		{ NULL }
11075088Sab196087 	};
11085088Sab196087 
11095088Sab196087 	/* shdr:sh_link */
11105088Sab196087 	static const char *name_sh_link[] = {
11115088Sab196087 	    MSG_ORIG(MSG_CMD_SH_LINK), NULL };
11125088Sab196087 	static elfedit_cmd_optarg_t arg_sh_link[] = {
11135088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
11145088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11155088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11165088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11175088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
11185088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_LINK) */
11195088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_LINK),
11205088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11215088Sab196087 		{ NULL }
11225088Sab196087 	};
11235088Sab196087 
11245088Sab196087 	/* shdr:sh_name */
11255088Sab196087 	static const char *name_sh_name[] = {
11265088Sab196087 	    MSG_ORIG(MSG_CMD_SH_NAME), NULL };
11275088Sab196087 	static elfedit_cmd_optarg_t opt_sh_name[] = {
11285088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_NAME_OFFSET),
11295088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */
11305088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_NAME_OFFSET), 0,
11315088Sab196087 		    SHDR_OPT_F_NAMOFFSET, 0 },
11325088Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
11335088Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
11345088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
11355088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
11365088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
11375088Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
11385088Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
11395088Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
11405088Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
11415088Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
11425088Sab196087 		{ NULL }
11435088Sab196087 	};
11445088Sab196087 	static elfedit_cmd_optarg_t arg_sh_name[] = {
11455088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
11465088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11475088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11485088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11495088Sab196087 		{ MSG_ORIG(MSG_STR_NAME),
11505088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_NAME) */
11515088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_NAME),
11525088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11535088Sab196087 		{ NULL }
11545088Sab196087 	};
11555088Sab196087 
11565088Sab196087 	/* shdr:sh_offset */
11575088Sab196087 	static const char *name_sh_offset[] = {
11585088Sab196087 	    MSG_ORIG(MSG_CMD_SH_OFFSET), NULL };
11595088Sab196087 	static elfedit_cmd_optarg_t arg_sh_offset[] = {
11605088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
11615088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11625088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11635088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11645088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
11655088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_OFFSET) */
11665088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_OFFSET),
11675088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11685088Sab196087 		{ NULL }
11695088Sab196087 	};
11705088Sab196087 
11715088Sab196087 	/* shdr:sh_size */
11725088Sab196087 	static const char *name_sh_size[] = {
11735088Sab196087 	    MSG_ORIG(MSG_CMD_SH_SIZE), NULL };
11745088Sab196087 	static elfedit_cmd_optarg_t arg_sh_size[] = {
11755088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
11765088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11775088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11785088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11795088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
11805088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_SIZE) */
11815088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_SIZE),
11825088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11835088Sab196087 		{ NULL }
11845088Sab196087 	};
11855088Sab196087 
11865088Sab196087 	/* shdr:sh_type */
11875088Sab196087 	static const char *name_sh_type[] = {
11885088Sab196087 	    MSG_ORIG(MSG_CMD_SH_TYPE), NULL };
11895088Sab196087 	static elfedit_cmd_optarg_t arg_sh_type[] = {
11905088Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
11915088Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
11925088Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
11935088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11945088Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
11955088Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_TYPE) */
11965088Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_TYPE),
11975088Sab196087 		    ELFEDIT_CMDOA_F_OPT },
11985088Sab196087 		{ NULL }
11995088Sab196087 	};
12005088Sab196087 
12015088Sab196087 	static elfedit_cmd_t cmds[] = {
12025088Sab196087 		/* shdr:dump */
12035088Sab196087 		{ cmd_dump, cpl_1starg_sec, name_dump,
12045088Sab196087 		    /* MSG_INTL(MSG_DESC_DUMP) */
12055088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_DUMP),
12065088Sab196087 		    /* MSG_INTL(MSG_HELP_DUMP) */
12075088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_DUMP),
12085088Sab196087 		    opt_dump, arg_dump },
12095088Sab196087 
12105088Sab196087 		/* shdr:sh_addr */
12115088Sab196087 		{ cmd_sh_addr, cpl_1starg_sec, name_sh_addr,
12125088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ADDR) */
12135088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ADDR),
12145088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ADDR) */
12155088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ADDR),
12165088Sab196087 		    opt_std, arg_sh_addr },
12175088Sab196087 
12185088Sab196087 		/* shdr:sh_addralign */
12195088Sab196087 		{ cmd_sh_addralign, cpl_1starg_sec, name_sh_addralign,
12205088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ADDRALIGN) */
12215088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ADDRALIGN),
12225088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ADDRALIGN) */
12235088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ADDRALIGN),
12245088Sab196087 		    opt_std, arg_sh_addralign },
12255088Sab196087 
12265088Sab196087 		/* shdr:sh_entsize */
12275088Sab196087 		{ cmd_sh_entsize, cpl_1starg_sec, name_sh_entsize,
12285088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ENTSIZE) */
12295088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ENTSIZE),
12305088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ENTSIZE) */
12315088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ENTSIZE),
12325088Sab196087 		    opt_std, arg_sh_entsize },
12335088Sab196087 
12345088Sab196087 		/* shdr:sh_flags */
12355088Sab196087 		{ cmd_sh_flags, cpl_sh_flags, name_sh_flags,
12365088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_FLAGS) */
12375088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_FLAGS),
12385088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_FLAGS) */
12395088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_FLAGS),
12405088Sab196087 		    opt_sh_flags, arg_sh_flags },
12415088Sab196087 
12425088Sab196087 		/* shdr:sh_info */
1243*5892Sab196087 		{ cmd_sh_info, cpl_sh_infolink, name_sh_info,
12445088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_INFO) */
12455088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_INFO),
12465088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_INFO) */
12475088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_INFO),
1248*5892Sab196087 		    opt_infolink, arg_sh_info },
12495088Sab196087 
12505088Sab196087 		/* shdr:sh_link */
1251*5892Sab196087 		{ cmd_sh_link, cpl_sh_infolink, name_sh_link,
12525088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_LINK) */
12535088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_LINK),
12545088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_LINK) */
12555088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_LINK),
1256*5892Sab196087 		    opt_infolink, arg_sh_link },
12575088Sab196087 
12585088Sab196087 		/* shdr:sh_name */
12595088Sab196087 		{ cmd_sh_name, cpl_1starg_sec, name_sh_name,
12605088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_NAME) */
12615088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_NAME),
12625088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_NAME) */
12635088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_NAME),
12645088Sab196087 		    opt_sh_name, arg_sh_name },
12655088Sab196087 
12665088Sab196087 		/* shdr:sh_offset */
12675088Sab196087 		{ cmd_sh_offset, cpl_1starg_sec, name_sh_offset,
12685088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_OFFSET) */
12695088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_OFFSET),
12705088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_OFFSET) */
12715088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_OFFSET),
12725088Sab196087 		    opt_std, arg_sh_offset },
12735088Sab196087 
12745088Sab196087 		/* shdr:sh_size */
12755088Sab196087 		{ cmd_sh_size, cpl_1starg_sec, name_sh_size,
12765088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_SIZE) */
12775088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_SIZE),
12785088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_SIZE) */
12795088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_SIZE),
12805088Sab196087 		    opt_std, arg_sh_size },
12815088Sab196087 
12825088Sab196087 		/* shdr:sh_type */
12835088Sab196087 		{ cmd_sh_type, cpl_sh_type, name_sh_type,
12845088Sab196087 		    /* MSG_INTL(MSG_DESC_SH_TYPE) */
12855088Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_TYPE),
12865088Sab196087 		    /* MSG_INTL(MSG_HELP_SH_TYPE) */
12875088Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_TYPE),
12885088Sab196087 		    opt_std, arg_sh_type },
12895088Sab196087 
12905088Sab196087 		{ NULL }
12915088Sab196087 	};
12925088Sab196087 
12935088Sab196087 	static elfedit_module_t module = {
12945088Sab196087 	    ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
12955088Sab196087 	    /* MSG_INTL(MSG_MOD_DESC) */
12965088Sab196087 	    ELFEDIT_I18NHDL(MSG_MOD_DESC),
12975088Sab196087 	    cmds, mod_i18nhdl_to_str };
12985088Sab196087 
12995088Sab196087 	return (&module);
13005088Sab196087 }
1301