xref: /titanic_51/usr/src/cmd/sgs/elfedit/modules/common/shdr.c (revision 4f680cc668fa6cf678c531083400ade9a9c7934c)
1d29b2c44Sab196087 /*
2d29b2c44Sab196087  * CDDL HEADER START
3d29b2c44Sab196087  *
4d29b2c44Sab196087  * The contents of this file are subject to the terms of the
5d29b2c44Sab196087  * Common Development and Distribution License (the "License").
6d29b2c44Sab196087  * You may not use this file except in compliance with the License.
7d29b2c44Sab196087  *
8d29b2c44Sab196087  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d29b2c44Sab196087  * or http://www.opensolaris.org/os/licensing.
10d29b2c44Sab196087  * See the License for the specific language governing permissions
11d29b2c44Sab196087  * and limitations under the License.
12d29b2c44Sab196087  *
13d29b2c44Sab196087  * When distributing Covered Code, include this CDDL HEADER in each
14d29b2c44Sab196087  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d29b2c44Sab196087  * If applicable, add the following below this CDDL HEADER, with the
16d29b2c44Sab196087  * fields enclosed by brackets "[]" replaced with your own identifying
17d29b2c44Sab196087  * information: Portions Copyright [yyyy] [name of copyright owner]
18d29b2c44Sab196087  *
19d29b2c44Sab196087  * CDDL HEADER END
20d29b2c44Sab196087  */
21d29b2c44Sab196087 
22d29b2c44Sab196087 /*
23*4f680cc6SAli Bahrami  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24d29b2c44Sab196087  * Use is subject to license terms.
25d29b2c44Sab196087  */
26d29b2c44Sab196087 
27d29b2c44Sab196087 #include	<stdio.h>
28d29b2c44Sab196087 #include	<unistd.h>
29d29b2c44Sab196087 #include	<elfedit.h>
30d29b2c44Sab196087 #include	<sys/elf_SPARC.h>
31d29b2c44Sab196087 #include	<sys/elf_amd64.h>
32d29b2c44Sab196087 #include	<strings.h>
33d29b2c44Sab196087 #include	<debug.h>
34d29b2c44Sab196087 #include	<conv.h>
35d29b2c44Sab196087 #include	<shdr_msg.h>
36d29b2c44Sab196087 
37d29b2c44Sab196087 
38d29b2c44Sab196087 
39d29b2c44Sab196087 
40d29b2c44Sab196087 /*
41d29b2c44Sab196087  * This module uses shared code for several of the commands.
42d29b2c44Sab196087  * It is sometimes necessary to know which specific command
43d29b2c44Sab196087  * is active.
44d29b2c44Sab196087  */
45d29b2c44Sab196087 typedef enum {
46d29b2c44Sab196087 	SHDR_CMD_T_DUMP =		0,	/* shdr:dump */
47d29b2c44Sab196087 
48d29b2c44Sab196087 	SHDR_CMD_T_SH_ADDR =		1,	/* shdr:sh_addr */
49d29b2c44Sab196087 	SHDR_CMD_T_SH_ADDRALIGN =	2,	/* shdr:sh_addralign */
50d29b2c44Sab196087 	SHDR_CMD_T_SH_ENTSIZE =		3,	/* shdr:sh_entsize */
51d29b2c44Sab196087 	SHDR_CMD_T_SH_FLAGS =		4,	/* shdr:sh_flags */
52d29b2c44Sab196087 	SHDR_CMD_T_SH_INFO =		5,	/* shdr:sh_info */
53d29b2c44Sab196087 	SHDR_CMD_T_SH_LINK =		6,	/* shdr:sh_link */
54d29b2c44Sab196087 	SHDR_CMD_T_SH_NAME =		7,	/* shdr:sh_name */
55d29b2c44Sab196087 	SHDR_CMD_T_SH_OFFSET =		8,	/* shdr:sh_offset */
56d29b2c44Sab196087 	SHDR_CMD_T_SH_SIZE =		9,	/* shdr:sh_size */
57d29b2c44Sab196087 	SHDR_CMD_T_SH_TYPE =		10	/* shdr:sh_type */
58d29b2c44Sab196087 } SHDR_CMD_T;
59d29b2c44Sab196087 
60d29b2c44Sab196087 
61d29b2c44Sab196087 
62d29b2c44Sab196087 #ifndef _ELF64
63d29b2c44Sab196087 /*
64d29b2c44Sab196087  * We supply this function for the msg module. Only one copy is needed.
65d29b2c44Sab196087  */
66d29b2c44Sab196087 const char *
67d29b2c44Sab196087 _shdr_msg(Msg mid)
68d29b2c44Sab196087 {
69d29b2c44Sab196087 	return (gettext(MSG_ORIG(mid)));
70d29b2c44Sab196087 }
71d29b2c44Sab196087 
72d29b2c44Sab196087 #endif
73d29b2c44Sab196087 
74d29b2c44Sab196087 
75d29b2c44Sab196087 
76d29b2c44Sab196087 /*
77d29b2c44Sab196087  * This function is supplied to elfedit through our elfedit_module_t
78d29b2c44Sab196087  * definition. It translates the opaque elfedit_i18nhdl_t handles
79d29b2c44Sab196087  * in our module interface into the actual strings for elfedit to
80d29b2c44Sab196087  * use.
81d29b2c44Sab196087  *
82d29b2c44Sab196087  * note:
83d29b2c44Sab196087  *	This module uses Msg codes for its i18n handle type.
84d29b2c44Sab196087  *	So the translation is simply to use MSG_INTL() to turn
85d29b2c44Sab196087  *	it into a string and return it.
86d29b2c44Sab196087  */
87d29b2c44Sab196087 static const char *
88d29b2c44Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
89d29b2c44Sab196087 {
90d29b2c44Sab196087 	Msg msg = (Msg)hdl;
91d29b2c44Sab196087 
92d29b2c44Sab196087 	return (MSG_INTL(msg));
93d29b2c44Sab196087 }
94d29b2c44Sab196087 
95d29b2c44Sab196087 
96d29b2c44Sab196087 
97d29b2c44Sab196087 /*
98d29b2c44Sab196087  * The shdr_opt_t enum specifies a bit value for every optional
99d29b2c44Sab196087  * argument allowed by a command in this module.
100d29b2c44Sab196087  */
101d29b2c44Sab196087 typedef enum {
102d29b2c44Sab196087 	SHDR_OPT_F_AND =	1,	/* -and: AND (&) values to dest */
103d29b2c44Sab196087 	SHDR_OPT_F_CMP =	2,	/* -cmp: Complement (~) values */
104d29b2c44Sab196087 	SHDR_OPT_F_NAMOFFSET =	4,	/* -name_offset: Name arg is numeric */
105d29b2c44Sab196087 					/*	 ofset rather than string */
106d29b2c44Sab196087 	SHDR_OPT_F_OR =		8,	/* -or: OR (|) values to dest */
107d29b2c44Sab196087 	SHDR_OPT_F_SHNDX =	16,	/* -shndx: Section by index, not name */
108cce0e03bSab196087 	SHDR_OPT_F_SHTYP =	32,	/* -shtyp: Section by type, not name */
109cce0e03bSab196087 	SHDR_OPT_F_VALUE_SHNAM = 64,	/* -value_shnam: Value of sh_info or */
110cce0e03bSab196087 					/*	sh_link given as section name */
111cce0e03bSab196087 	SHDR_OPT_F_VALUE_SHTYP = 128	/* -value_shtyp: Value of sh_info or */
112cce0e03bSab196087 					/*	sh_link given as section type */
113d29b2c44Sab196087 } shdr_opt_t;
114d29b2c44Sab196087 
115d29b2c44Sab196087 
116d29b2c44Sab196087 /*
117d29b2c44Sab196087  * A variable of type ARGSTATE is used by each command to maintain
118d29b2c44Sab196087  * information about the section headers and related things. It is
119d29b2c44Sab196087  * initialized by process_args(), and used by the other routines.
120d29b2c44Sab196087  */
121d29b2c44Sab196087 typedef struct {
122d29b2c44Sab196087 	elfedit_obj_state_t	*obj_state;
123d29b2c44Sab196087 	shdr_opt_t		optmask;   	/* Mask of options used */
124d29b2c44Sab196087 	int			argc;		/* # of plain arguments */
125d29b2c44Sab196087 	const char		**argv;		/* Plain arguments */
126d29b2c44Sab196087 } ARGSTATE;
127d29b2c44Sab196087 
128d29b2c44Sab196087 
129d29b2c44Sab196087 
130d29b2c44Sab196087 
131d29b2c44Sab196087 /*
132d29b2c44Sab196087  * Standard argument processing for shdr module
133d29b2c44Sab196087  *
134d29b2c44Sab196087  * entry
135d29b2c44Sab196087  *	obj_state, argc, argv - Standard command arguments
136d29b2c44Sab196087  *	optmask - Mask of allowed optional arguments.
137d29b2c44Sab196087  *	cmd - SHDR_CMD_T_* value giving identify of caller
138d29b2c44Sab196087  *	argstate - Address of ARGSTATE block to be initialized
139d29b2c44Sab196087  *
140d29b2c44Sab196087  * exit:
141d29b2c44Sab196087  *	On success, *argstate is initialized. On error,
142d29b2c44Sab196087  *	an error is issued and this routine does not return.
143d29b2c44Sab196087  */
144d29b2c44Sab196087 static void
145d29b2c44Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
146d29b2c44Sab196087     SHDR_CMD_T cmd, ARGSTATE *argstate)
147d29b2c44Sab196087 {
148d29b2c44Sab196087 	elfedit_getopt_state_t	getopt_state;
149d29b2c44Sab196087 	elfedit_getopt_ret_t	*getopt_ret;
150d29b2c44Sab196087 
151d29b2c44Sab196087 	bzero(argstate, sizeof (*argstate));
152d29b2c44Sab196087 	argstate->obj_state = obj_state;
153d29b2c44Sab196087 
154d29b2c44Sab196087 	elfedit_getopt_init(&getopt_state, &argc, &argv);
155d29b2c44Sab196087 
156d29b2c44Sab196087 	/* Add each new option to the options mask */
157d29b2c44Sab196087 	while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL)
158d29b2c44Sab196087 		argstate->optmask |= getopt_ret->gor_idmask;
159d29b2c44Sab196087 
160d29b2c44Sab196087 	/* Are the right number of plain arguments present? */
161d29b2c44Sab196087 	switch (cmd) {
162d29b2c44Sab196087 	case SHDR_CMD_T_DUMP:
163d29b2c44Sab196087 		if (argc > 1)
164d29b2c44Sab196087 			elfedit_command_usage();
165d29b2c44Sab196087 		break;
166d29b2c44Sab196087 	case SHDR_CMD_T_SH_FLAGS:
167d29b2c44Sab196087 		/* shdr:sh_flags allows an arbitrary number of arguments */
168d29b2c44Sab196087 		break;
169d29b2c44Sab196087 	default:
170d29b2c44Sab196087 		/* The remaining commands accept 2 plain arguments */
171d29b2c44Sab196087 		if (argc > 2)
172d29b2c44Sab196087 			elfedit_command_usage();
173d29b2c44Sab196087 		break;
174d29b2c44Sab196087 	}
175d29b2c44Sab196087 
176d29b2c44Sab196087 	/* If there may be an arbitrary amount of output, use a pager */
177d29b2c44Sab196087 	if (argc == 0)
178d29b2c44Sab196087 		elfedit_pager_init();
179d29b2c44Sab196087 
180d29b2c44Sab196087 	/* Return the updated values of argc/argv */
181d29b2c44Sab196087 	argstate->argc = argc;
182d29b2c44Sab196087 	argstate->argv = argv;
183d29b2c44Sab196087 }
184d29b2c44Sab196087 
185d29b2c44Sab196087 
186d29b2c44Sab196087 
187d29b2c44Sab196087 /*
188*4f680cc6SAli Bahrami  * Options for deciding which items print_shdr() displays.
189*4f680cc6SAli Bahrami  */
190*4f680cc6SAli Bahrami typedef enum {
191*4f680cc6SAli Bahrami 	PRINT_SHDR_ALL,		/* Print all shdr[ndx:ndx+cnt-1] */
192*4f680cc6SAli Bahrami 	PRINT_SHDR_TYPE,	/* Print all shdr[ndx:ndx+cnt-1] with type */
193*4f680cc6SAli Bahrami 				/*	 of shdr[ndx] */
194*4f680cc6SAli Bahrami 	PRINT_SHDR_NAME,	/* Print all shdr[ndx:ndx+cnt-1] with name */
195*4f680cc6SAli Bahrami 				/*	 of shdr[ndx] */
196*4f680cc6SAli Bahrami } PRINT_SHDR_T;
197*4f680cc6SAli Bahrami 
198*4f680cc6SAli Bahrami /*
199d29b2c44Sab196087  * Print section header values, taking the calling command, and output style
200d29b2c44Sab196087  * into account.
201d29b2c44Sab196087  *
202d29b2c44Sab196087  * entry:
203d29b2c44Sab196087  *	autoprint - If True, output is only produced if the elfedit
204d29b2c44Sab196087  *		autoprint flag is set. If False, output is always produced.
205d29b2c44Sab196087  *	cmd - SHDR_CMD_T_* value giving identify of caller
206d29b2c44Sab196087  *	argstate - State block for section header array
207d29b2c44Sab196087  *	ndx - Index of first section to display
208d29b2c44Sab196087  *	cnt - Number of sections to display
209*4f680cc6SAli Bahrami  *	print_type - Specifies which items are shown
210d29b2c44Sab196087  */
211d29b2c44Sab196087 static void
212d29b2c44Sab196087 print_shdr(SHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate,
213*4f680cc6SAli Bahrami     Word ndx, Word cnt, PRINT_SHDR_T print_type)
214d29b2c44Sab196087 {
215d29b2c44Sab196087 	elfedit_outstyle_t	outstyle;
216*4f680cc6SAli Bahrami 	Ehdr			*ehdr = argstate->obj_state->os_ehdr;
217*4f680cc6SAli Bahrami 	uchar_t			osabi = ehdr->e_ident[EI_OSABI];
218*4f680cc6SAli Bahrami 	Half			mach = ehdr->e_machine;
219*4f680cc6SAli Bahrami 	elfedit_section_t 	*ref_sec = &argstate->obj_state->os_secarr[ndx];
220*4f680cc6SAli Bahrami 
221d29b2c44Sab196087 
222d29b2c44Sab196087 	if ((autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) ||
223d29b2c44Sab196087 	    (cnt == 0))
224d29b2c44Sab196087 		return;
225d29b2c44Sab196087 
226d29b2c44Sab196087 	/*
227d29b2c44Sab196087 	 * Pick an output style. shdr:dump is required to use the default
228d29b2c44Sab196087 	 * style. The other commands use the current output style.
229d29b2c44Sab196087 	 */
230d29b2c44Sab196087 	outstyle = (cmd == SHDR_CMD_T_DUMP) ?
231d29b2c44Sab196087 	    ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
232d29b2c44Sab196087 
233*4f680cc6SAli Bahrami 	for (; cnt--; ndx++) {
234*4f680cc6SAli Bahrami 		elfedit_section_t *sec = &argstate->obj_state->os_secarr[ndx];
235*4f680cc6SAli Bahrami 		Shdr *shdr = sec->sec_shdr;
236*4f680cc6SAli Bahrami 
237*4f680cc6SAli Bahrami 		switch (print_type) {
238*4f680cc6SAli Bahrami 		case PRINT_SHDR_TYPE:
239*4f680cc6SAli Bahrami 			if (shdr->sh_type != ref_sec->sec_shdr->sh_type)
240*4f680cc6SAli Bahrami 				continue;
241*4f680cc6SAli Bahrami 			break;
242*4f680cc6SAli Bahrami 
243*4f680cc6SAli Bahrami 		case PRINT_SHDR_NAME:
244*4f680cc6SAli Bahrami 			if (strcmp(sec->sec_name, ref_sec->sec_name) != 0)
245*4f680cc6SAli Bahrami 				continue;
246*4f680cc6SAli Bahrami 			break;
247*4f680cc6SAli Bahrami 		}
248*4f680cc6SAli Bahrami 
249d29b2c44Sab196087 		/*
250d29b2c44Sab196087 		 * If doing default output, use elfdump style where we
251d29b2c44Sab196087 		 * show all section header attributes. In this case, the
252d29b2c44Sab196087 		 * command that called us doesn't matter
253d29b2c44Sab196087 		 */
254d29b2c44Sab196087 		if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
255d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_STR_NL));
256d29b2c44Sab196087 			elfedit_printf(MSG_INTL(MSG_ELF_SHDR), ndx,
257d29b2c44Sab196087 			    sec->sec_name);
258*4f680cc6SAli Bahrami 			Elf_shdr(NULL, osabi, mach, sec->sec_shdr);
259*4f680cc6SAli Bahrami 			continue;
260d29b2c44Sab196087 		}
261d29b2c44Sab196087 
262*4f680cc6SAli Bahrami 		/* Non-default output is handled case by case */
263d29b2c44Sab196087 		switch (cmd) {
264d29b2c44Sab196087 		case SHDR_CMD_T_SH_ADDR:
265d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
266d29b2c44Sab196087 			    EC_XWORD(shdr->sh_addr));
267*4f680cc6SAli Bahrami 			break;
268d29b2c44Sab196087 
269d29b2c44Sab196087 		case SHDR_CMD_T_SH_ADDRALIGN:
270d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
271d29b2c44Sab196087 			    EC_XWORD(shdr->sh_addralign));
272*4f680cc6SAli Bahrami 			break;
273d29b2c44Sab196087 
274d29b2c44Sab196087 		case SHDR_CMD_T_SH_ENTSIZE:
275d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
276d29b2c44Sab196087 			    EC_XWORD(shdr->sh_entsize));
277*4f680cc6SAli Bahrami 			break;
278d29b2c44Sab196087 
279d29b2c44Sab196087 		case SHDR_CMD_T_SH_FLAGS:
280d29b2c44Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
281d29b2c44Sab196087 				Conv_sec_flags_buf_t sec_flags_buf;
282d29b2c44Sab196087 
283d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
284*4f680cc6SAli Bahrami 				    conv_sec_flags(osabi, mach, shdr->sh_flags,
285d29b2c44Sab196087 				    CONV_FMT_NOBKT, &sec_flags_buf));
286d29b2c44Sab196087 			} else {
287d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
288d29b2c44Sab196087 				    EC_XWORD(shdr->sh_flags));
289d29b2c44Sab196087 			}
290*4f680cc6SAli Bahrami 			break;
291d29b2c44Sab196087 
292d29b2c44Sab196087 		case SHDR_CMD_T_SH_INFO:
293d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
294d29b2c44Sab196087 			    EC_WORD(shdr->sh_info));
295*4f680cc6SAli Bahrami 			break;
296d29b2c44Sab196087 
297d29b2c44Sab196087 		case SHDR_CMD_T_SH_LINK:
298d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
299d29b2c44Sab196087 			    EC_WORD(shdr->sh_link));
300*4f680cc6SAli Bahrami 			break;
301d29b2c44Sab196087 
302d29b2c44Sab196087 		case SHDR_CMD_T_SH_NAME:
303d29b2c44Sab196087 			/*
304*4f680cc6SAli Bahrami 			 * In simple output mode, we show the string. In
305*4f680cc6SAli Bahrami 			 * numeric mode, we show the string table offset.
306d29b2c44Sab196087 			 */
307d29b2c44Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
308d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
309*4f680cc6SAli Bahrami 				    sec->sec_name);
310d29b2c44Sab196087 			} else {
311d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL),
312*4f680cc6SAli Bahrami 				    EC_WORD(shdr->sh_name));
313d29b2c44Sab196087 			}
314*4f680cc6SAli Bahrami 			break;
315d29b2c44Sab196087 
316d29b2c44Sab196087 		case SHDR_CMD_T_SH_OFFSET:
317d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
318d29b2c44Sab196087 			    EC_XWORD(shdr->sh_offset));
319*4f680cc6SAli Bahrami 			break;
320d29b2c44Sab196087 
321d29b2c44Sab196087 		case SHDR_CMD_T_SH_SIZE:
322d29b2c44Sab196087 			elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL),
323d29b2c44Sab196087 			    EC_XWORD(shdr->sh_size));
324*4f680cc6SAli Bahrami 			break;
325d29b2c44Sab196087 
326d29b2c44Sab196087 		case SHDR_CMD_T_SH_TYPE:
327d29b2c44Sab196087 			if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
328*4f680cc6SAli Bahrami 				Conv_inv_buf_t inv_buf;
329d29b2c44Sab196087 
330d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
331*4f680cc6SAli Bahrami 				    conv_sec_type(osabi, mach, shdr->sh_type, 0,
332d29b2c44Sab196087 				    &inv_buf));
333d29b2c44Sab196087 			} else {
334d29b2c44Sab196087 				elfedit_printf(MSG_ORIG(MSG_FMT_WORDHEXNL),
335d29b2c44Sab196087 				    EC_WORD(shdr->sh_type));
336d29b2c44Sab196087 			}
337*4f680cc6SAli Bahrami 			break;
338d29b2c44Sab196087 		}
339d29b2c44Sab196087 	}
340d29b2c44Sab196087 }
341d29b2c44Sab196087 
342d29b2c44Sab196087 
343d29b2c44Sab196087 /*
344d29b2c44Sab196087  * Common body for the shdr: module commands. These commands
345d29b2c44Sab196087  * share a large amount of common behavior, so it is convenient
346d29b2c44Sab196087  * to centralize things and use the cmd argument to handle the
347d29b2c44Sab196087  * small differences.
348d29b2c44Sab196087  *
349d29b2c44Sab196087  * entry:
350d29b2c44Sab196087  *	cmd - One of the SHDR_CMD_T_* constants listed above, specifying
351d29b2c44Sab196087  *		which command to implement.
352d29b2c44Sab196087  *	obj_state, argc, argv - Standard command arguments
353d29b2c44Sab196087  */
354d29b2c44Sab196087 static elfedit_cmdret_t
355d29b2c44Sab196087 cmd_body(SHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,
356d29b2c44Sab196087     int argc, const char *argv[])
357d29b2c44Sab196087 {
358*4f680cc6SAli Bahrami 	Ehdr			*ehdr = obj_state->os_ehdr;
359*4f680cc6SAli Bahrami 	uchar_t			osabi = ehdr->e_ident[EI_OSABI];
360*4f680cc6SAli Bahrami 	Half			mach = ehdr->e_machine;
361d29b2c44Sab196087 	ARGSTATE		argstate;
362d29b2c44Sab196087 	Word			ndx;
363d29b2c44Sab196087 	elfedit_section_t	*shdr_sec;
364d29b2c44Sab196087 	Shdr			*shdr;
365d29b2c44Sab196087 	elfedit_cmdret_t	ret = ELFEDIT_CMDRET_NONE;
366*4f680cc6SAli Bahrami 	PRINT_SHDR_T		print_type;
367d29b2c44Sab196087 
368d29b2c44Sab196087 	process_args(obj_state, argc, argv, cmd, &argstate);
369d29b2c44Sab196087 
370d29b2c44Sab196087 	/* If there are no arguments, dump the whole table and return */
371d29b2c44Sab196087 	if (argstate.argc == 0) {
372*4f680cc6SAli Bahrami 		print_shdr(cmd, 0, &argstate, 0, obj_state->os_shnum,
373*4f680cc6SAli Bahrami 		    PRINT_SHDR_ALL);
374d29b2c44Sab196087 		return (ELFEDIT_CMDRET_NONE);
375d29b2c44Sab196087 	}
376d29b2c44Sab196087 
377d29b2c44Sab196087 	/*
378d29b2c44Sab196087 	 * The first argument gives the section to use. This can be a
379d29b2c44Sab196087 	 * name (default), section index, or section type, depending on
380d29b2c44Sab196087 	 * the options used.
381d29b2c44Sab196087 	 */
382*4f680cc6SAli Bahrami 	if (argstate.optmask & SHDR_OPT_F_SHNDX) {
383d29b2c44Sab196087 		ndx = elfedit_atoshndx(argstate.argv[0], obj_state->os_shnum);
384*4f680cc6SAli Bahrami 		print_type = PRINT_SHDR_ALL;
385*4f680cc6SAli Bahrami 	} else if (argstate.optmask & SHDR_OPT_F_SHTYP) {
386d29b2c44Sab196087 		ndx = elfedit_type_to_shndx(obj_state,
387d29b2c44Sab196087 		    elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_SHT));
388*4f680cc6SAli Bahrami 		print_type = PRINT_SHDR_TYPE;
389*4f680cc6SAli Bahrami 	} else {
390d29b2c44Sab196087 		ndx = elfedit_name_to_shndx(obj_state, argstate.argv[0]);
391*4f680cc6SAli Bahrami 		print_type = PRINT_SHDR_NAME;
392*4f680cc6SAli Bahrami 	}
393d29b2c44Sab196087 
394d29b2c44Sab196087 	/* If there is a single argument, display that item and return */
395d29b2c44Sab196087 	if (argstate.argc == 1) {
396*4f680cc6SAli Bahrami 		Word	cnt;
397*4f680cc6SAli Bahrami 
398*4f680cc6SAli Bahrami 		cnt = (print_type == PRINT_SHDR_ALL) ?
399*4f680cc6SAli Bahrami 		    1 : obj_state->os_shnum - ndx;
400*4f680cc6SAli Bahrami 		print_shdr(cmd, 0, &argstate, ndx, cnt, print_type);
401d29b2c44Sab196087 		return (ELFEDIT_CMDRET_NONE);
402d29b2c44Sab196087 	}
403d29b2c44Sab196087 
404d29b2c44Sab196087 	/*
405d29b2c44Sab196087 	 * Section [0] is supposed to be all zero unless extended sections
406d29b2c44Sab196087 	 * are in force. Rather than setting extended values directly,
407*4f680cc6SAli Bahrami 	 * it is expected to be handled by libelf. So, a direct change here
408*4f680cc6SAli Bahrami 	 * is probably not what was intended.
409d29b2c44Sab196087 	 */
410d29b2c44Sab196087 	if (ndx == 0)
411d29b2c44Sab196087 		elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CHGSHDR0));
412d29b2c44Sab196087 
413d29b2c44Sab196087 	/* The second value is an integer giving a new value */
414d29b2c44Sab196087 	shdr_sec = &obj_state->os_secarr[ndx];
415d29b2c44Sab196087 	shdr = shdr_sec->sec_shdr;
416d29b2c44Sab196087 	switch (cmd) {
417d29b2c44Sab196087 		/*
418d29b2c44Sab196087 		 * SHDR_CMD_T_DUMP can't get here: It never has more than
419d29b2c44Sab196087 		 * one argument, and is handled above.
420d29b2c44Sab196087 		 */
421d29b2c44Sab196087 
422d29b2c44Sab196087 	case SHDR_CMD_T_SH_ADDR:
423d29b2c44Sab196087 		{
424d29b2c44Sab196087 			Addr sh_addr = elfedit_atoui(argstate.argv[1], NULL);
425d29b2c44Sab196087 
426d29b2c44Sab196087 			if (shdr->sh_addr == sh_addr) {
427d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
428d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
429d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
430d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDR),
431d29b2c44Sab196087 				    EC_ADDR(shdr->sh_addr));
432d29b2c44Sab196087 			} else {
433d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
434d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
435d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
436d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDR),
437d29b2c44Sab196087 				    EC_ADDR(shdr->sh_addr), EC_ADDR(sh_addr));
438d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
439d29b2c44Sab196087 				shdr->sh_addr = sh_addr;
440d29b2c44Sab196087 			}
441d29b2c44Sab196087 		}
442d29b2c44Sab196087 		break;
443d29b2c44Sab196087 
444d29b2c44Sab196087 	case SHDR_CMD_T_SH_ADDRALIGN:
445d29b2c44Sab196087 		{
446d29b2c44Sab196087 			Xword	sh_addralign;
447d29b2c44Sab196087 
448d29b2c44Sab196087 			sh_addralign = elfedit_atoui(argstate.argv[1], NULL);
449d29b2c44Sab196087 			if (elfedit_bits_set(sh_addralign,
450d29b2c44Sab196087 			    sizeof (sh_addralign)) > 1)
451d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
452d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_ADDRALIGN),
453d29b2c44Sab196087 				    argstate.argv[1]);
454d29b2c44Sab196087 			if (shdr->sh_addralign == sh_addralign) {
455d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
456d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
457d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
458d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDRALIGN),
459d29b2c44Sab196087 				    EC_XWORD(shdr->sh_addralign));
460d29b2c44Sab196087 			} else {
461d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
462d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
463d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
464d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ADDRALIGN),
465d29b2c44Sab196087 				    EC_XWORD(shdr->sh_addralign),
466d29b2c44Sab196087 				    EC_XWORD(sh_addralign));
467d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
468d29b2c44Sab196087 				shdr->sh_addralign = sh_addralign;
469d29b2c44Sab196087 			}
470d29b2c44Sab196087 		}
471d29b2c44Sab196087 		break;
472d29b2c44Sab196087 
473d29b2c44Sab196087 	case SHDR_CMD_T_SH_ENTSIZE:
474d29b2c44Sab196087 		{
475d29b2c44Sab196087 			Xword sh_entsize;
476d29b2c44Sab196087 
477d29b2c44Sab196087 			sh_entsize = elfedit_atoui(argstate.argv[1], NULL);
478d29b2c44Sab196087 			if (shdr->sh_entsize == sh_entsize) {
479d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
480d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
481d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
482d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ENTSIZE),
483d29b2c44Sab196087 				    EC_XWORD(shdr->sh_entsize));
484d29b2c44Sab196087 			} else {
485d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
486d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
487d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
488d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_ENTSIZE),
489d29b2c44Sab196087 				    EC_XWORD(shdr->sh_entsize),
490d29b2c44Sab196087 				    EC_XWORD(sh_entsize));
491d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
492d29b2c44Sab196087 				shdr->sh_entsize = sh_entsize;
493d29b2c44Sab196087 			}
494d29b2c44Sab196087 		}
495d29b2c44Sab196087 		break;
496d29b2c44Sab196087 
497d29b2c44Sab196087 	case SHDR_CMD_T_SH_FLAGS:
498d29b2c44Sab196087 		{
499d29b2c44Sab196087 			Conv_sec_flags_buf_t buf1, buf2;
500d29b2c44Sab196087 			Word	sh_flags = 0;
501d29b2c44Sab196087 			int	i;
502d29b2c44Sab196087 
503d29b2c44Sab196087 						/* Collect the flag arguments */
504d29b2c44Sab196087 			for (i = 1; i < argstate.argc; i++)
505d29b2c44Sab196087 				sh_flags |=
506d29b2c44Sab196087 				    (Word) elfedit_atoconst(argstate.argv[i],
507d29b2c44Sab196087 				    ELFEDIT_CONST_SHF);
508d29b2c44Sab196087 
509d29b2c44Sab196087 			/* Complement the value? */
510d29b2c44Sab196087 			if (argstate.optmask & SHDR_OPT_F_CMP)
511d29b2c44Sab196087 				sh_flags = ~sh_flags;
512d29b2c44Sab196087 
513d29b2c44Sab196087 			/* Perform any requested bit operations */
514d29b2c44Sab196087 			if (argstate.optmask & SHDR_OPT_F_AND)
515d29b2c44Sab196087 				sh_flags &= shdr->sh_flags;
516d29b2c44Sab196087 			else if (argstate.optmask & SHDR_OPT_F_OR)
517d29b2c44Sab196087 				sh_flags |= shdr->sh_flags;
518d29b2c44Sab196087 
519d29b2c44Sab196087 			/* Set the value */
520d29b2c44Sab196087 			if (shdr->sh_flags == sh_flags) {
521d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
522d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_S_OK),
523d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
524d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_FLAGS),
525*4f680cc6SAli Bahrami 				    conv_sec_flags(osabi, mach,
526*4f680cc6SAli Bahrami 				    shdr->sh_flags, 0, &buf1));
527d29b2c44Sab196087 			} else {
528d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
529d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_S_CHG),
530d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
531d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_FLAGS),
532*4f680cc6SAli Bahrami 				    conv_sec_flags(osabi, mach,
533*4f680cc6SAli Bahrami 				    shdr->sh_flags, 0, &buf1),
534*4f680cc6SAli Bahrami 				    conv_sec_flags(osabi, mach,
535*4f680cc6SAli Bahrami 				    sh_flags, 0, &buf2));
536d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
537d29b2c44Sab196087 				shdr->sh_flags = sh_flags;
538d29b2c44Sab196087 			}
539d29b2c44Sab196087 		}
540d29b2c44Sab196087 		break;
541d29b2c44Sab196087 
542d29b2c44Sab196087 	case SHDR_CMD_T_SH_INFO:
543d29b2c44Sab196087 		{
544cce0e03bSab196087 			Word sh_info;
545cce0e03bSab196087 
546cce0e03bSab196087 			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM)
547cce0e03bSab196087 				sh_info = elfedit_name_to_shndx(obj_state,
548cce0e03bSab196087 				    argstate.argv[1]);
549cce0e03bSab196087 			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP)
550cce0e03bSab196087 				sh_info = elfedit_type_to_shndx(obj_state,
551cce0e03bSab196087 				    elfedit_atoconst(argstate.argv[1],
552cce0e03bSab196087 				    ELFEDIT_CONST_SHT));
553cce0e03bSab196087 			else
554cce0e03bSab196087 				sh_info = elfedit_atoui(argstate.argv[1], NULL);
555d29b2c44Sab196087 
556d29b2c44Sab196087 			if (shdr->sh_info == sh_info) {
557d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
558d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
559d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
560d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_INFO),
561d29b2c44Sab196087 				    EC_WORD(shdr->sh_info));
562d29b2c44Sab196087 			} else {
563d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
564d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
565d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
566d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_INFO),
567d29b2c44Sab196087 				    EC_WORD(shdr->sh_info), EC_WORD(sh_info));
568d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
569d29b2c44Sab196087 				shdr->sh_info = sh_info;
570d29b2c44Sab196087 			}
571d29b2c44Sab196087 		}
572d29b2c44Sab196087 		break;
573d29b2c44Sab196087 
574d29b2c44Sab196087 	case SHDR_CMD_T_SH_LINK:
575d29b2c44Sab196087 		{
576cce0e03bSab196087 			Word sh_link;
577cce0e03bSab196087 
578cce0e03bSab196087 			if (argstate.optmask & SHDR_OPT_F_VALUE_SHNAM)
579cce0e03bSab196087 				sh_link = elfedit_name_to_shndx(obj_state,
580cce0e03bSab196087 				    argstate.argv[1]);
581cce0e03bSab196087 			else if (argstate.optmask & SHDR_OPT_F_VALUE_SHTYP)
582cce0e03bSab196087 				sh_link = elfedit_type_to_shndx(obj_state,
583cce0e03bSab196087 				    elfedit_atoconst(argstate.argv[1],
584cce0e03bSab196087 				    ELFEDIT_CONST_SHT));
585cce0e03bSab196087 			else
586cce0e03bSab196087 				sh_link = elfedit_atoui(argstate.argv[1], NULL);
587d29b2c44Sab196087 
588d29b2c44Sab196087 			if (shdr->sh_link == sh_link) {
589d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
590d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
591d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
592d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_LINK),
593d29b2c44Sab196087 				    EC_WORD(shdr->sh_link));
594d29b2c44Sab196087 			} else {
595d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
596d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
597d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
598d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_LINK),
599d29b2c44Sab196087 				    EC_WORD(shdr->sh_link), EC_WORD(sh_link));
600d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
601d29b2c44Sab196087 				shdr->sh_link = sh_link;
602d29b2c44Sab196087 			}
603d29b2c44Sab196087 		}
604d29b2c44Sab196087 		break;
605d29b2c44Sab196087 
606d29b2c44Sab196087 	case SHDR_CMD_T_SH_NAME:
607d29b2c44Sab196087 		{
608d29b2c44Sab196087 			elfedit_section_t *shstr_sec =
609d29b2c44Sab196087 			    &obj_state->os_secarr[obj_state->os_shstrndx];
610d29b2c44Sab196087 			Word sh_name;
611d29b2c44Sab196087 
612d29b2c44Sab196087 			/*
613d29b2c44Sab196087 			 * If -name_offset was specified, this is an offset
614d29b2c44Sab196087 			 * into the string table. Otherwise it is a string
615d29b2c44Sab196087 			 * we need to turn into an offset.
616d29b2c44Sab196087 			 */
617d29b2c44Sab196087 			sh_name = (argstate.optmask & SHDR_OPT_F_NAMOFFSET) ?
618d29b2c44Sab196087 			    elfedit_atoui(argstate.argv[1], NULL) :
619d29b2c44Sab196087 			    elfedit_strtab_insert(obj_state,
620d29b2c44Sab196087 			    shstr_sec, NULL, argstate.argv[1]);
621d29b2c44Sab196087 			if (shdr->sh_name == sh_name) {
622d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
623d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_OK),
624d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
625d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_NAME),
626d29b2c44Sab196087 				    EC_WORD(shdr->sh_name));
627d29b2c44Sab196087 			} else {
628d29b2c44Sab196087 				/*
629d29b2c44Sab196087 				 * The section name is cached, so we must
630d29b2c44Sab196087 				 * also update that value. This call will
631d29b2c44Sab196087 				 * warn if the offset is out of range, and
632d29b2c44Sab196087 				 * will supply a safe string in that case.
633d29b2c44Sab196087 				 */
634d29b2c44Sab196087 				shdr_sec->sec_name =
635d29b2c44Sab196087 				    elfedit_offset_to_str(shstr_sec,
636d29b2c44Sab196087 				    sh_name, ELFEDIT_MSG_DEBUG, 1);
637d29b2c44Sab196087 
638d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
639d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_D_CHG),
640d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
641d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_NAME),
642d29b2c44Sab196087 				    EC_WORD(shdr->sh_name), EC_WORD(sh_name));
643d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
644d29b2c44Sab196087 				shdr->sh_name = sh_name;
645d29b2c44Sab196087 			}
646d29b2c44Sab196087 		}
647d29b2c44Sab196087 		break;
648d29b2c44Sab196087 
649d29b2c44Sab196087 	case SHDR_CMD_T_SH_OFFSET:
650d29b2c44Sab196087 		{
651d29b2c44Sab196087 			Off sh_offset;
652d29b2c44Sab196087 
653d29b2c44Sab196087 			sh_offset = elfedit_atoui(argstate.argv[1], NULL);
654d29b2c44Sab196087 			if (shdr->sh_offset == sh_offset) {
655d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
656d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
657d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
658d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_OFFSET),
659d29b2c44Sab196087 				    EC_XWORD(shdr->sh_offset));
660d29b2c44Sab196087 			} else {
661d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
662d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
663d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
664d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_OFFSET),
665d29b2c44Sab196087 				    EC_XWORD(shdr->sh_offset),
666d29b2c44Sab196087 				    EC_XWORD(sh_offset));
667d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
668d29b2c44Sab196087 				shdr->sh_offset = sh_offset;
669d29b2c44Sab196087 			}
670d29b2c44Sab196087 		}
671d29b2c44Sab196087 		break;
672d29b2c44Sab196087 
673d29b2c44Sab196087 	case SHDR_CMD_T_SH_SIZE:
674d29b2c44Sab196087 		{
675d29b2c44Sab196087 			Xword sh_size;
676d29b2c44Sab196087 
677d29b2c44Sab196087 			sh_size = elfedit_atoui(argstate.argv[1], NULL);
678d29b2c44Sab196087 			if (shdr->sh_size == sh_size) {
679d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
680d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_OK),
681d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
682d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_SIZE),
683d29b2c44Sab196087 				    EC_XWORD(shdr->sh_size));
684d29b2c44Sab196087 			} else {
685d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
686d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_LLX_CHG),
687d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
688d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_SIZE),
689d29b2c44Sab196087 				    EC_XWORD(shdr->sh_size),
690d29b2c44Sab196087 				    EC_XWORD(sh_size));
691d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
692d29b2c44Sab196087 				shdr->sh_size = sh_size;
693d29b2c44Sab196087 			}
694d29b2c44Sab196087 		}
695d29b2c44Sab196087 		break;
696d29b2c44Sab196087 
697d29b2c44Sab196087 	case SHDR_CMD_T_SH_TYPE:
698d29b2c44Sab196087 		{
699d29b2c44Sab196087 			Word sh_type = elfedit_atoconst(argstate.argv[1],
700d29b2c44Sab196087 			    ELFEDIT_CONST_SHT);
701d29b2c44Sab196087 			Conv_inv_buf_t inv_buf1, inv_buf2;
702d29b2c44Sab196087 
703d29b2c44Sab196087 			if (shdr->sh_type == sh_type) {
704d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
705d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_S_OK),
706d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
707d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_TYPE),
708*4f680cc6SAli Bahrami 				    conv_sec_type(osabi, mach, shdr->sh_type,
709d29b2c44Sab196087 				    0, &inv_buf1));
710d29b2c44Sab196087 			} else {
711d29b2c44Sab196087 				elfedit_msg(ELFEDIT_MSG_DEBUG,
712d29b2c44Sab196087 				    MSG_INTL(MSG_DEBUG_S_CHG),
713d29b2c44Sab196087 				    ndx, shdr_sec->sec_name,
714d29b2c44Sab196087 				    MSG_ORIG(MSG_CMD_SH_TYPE),
715*4f680cc6SAli Bahrami 				    conv_sec_type(osabi, mach, shdr->sh_type,
716*4f680cc6SAli Bahrami 				    0, &inv_buf1),
717*4f680cc6SAli Bahrami 				    conv_sec_type(osabi, mach, sh_type,
718*4f680cc6SAli Bahrami 				    0, &inv_buf2));
719d29b2c44Sab196087 				ret = ELFEDIT_CMDRET_MOD;
720d29b2c44Sab196087 				shdr->sh_type = sh_type;
721d29b2c44Sab196087 			}
722d29b2c44Sab196087 		}
723d29b2c44Sab196087 		break;
724d29b2c44Sab196087 	}
725d29b2c44Sab196087 
726d29b2c44Sab196087 	/*
727d29b2c44Sab196087 	 * If we modified the section header array, tell libelf.
728d29b2c44Sab196087 	 */
729d29b2c44Sab196087 	if (ret == ELFEDIT_CMDRET_MOD)
730d29b2c44Sab196087 		elfedit_modified_shdr(shdr_sec);
731d29b2c44Sab196087 
732d29b2c44Sab196087 	/* Do autoprint */
733*4f680cc6SAli Bahrami 	print_shdr(cmd, 1, &argstate, ndx, 1, PRINT_SHDR_ALL);
734d29b2c44Sab196087 
735d29b2c44Sab196087 	return (ret);
736d29b2c44Sab196087 }
737d29b2c44Sab196087 
738d29b2c44Sab196087 
739d29b2c44Sab196087 
740d29b2c44Sab196087 
741d29b2c44Sab196087 /*
742d29b2c44Sab196087  * Command completion functions for the various commands
743d29b2c44Sab196087  */
744d29b2c44Sab196087 
745d29b2c44Sab196087 /*
746d29b2c44Sab196087  * All of the commands accept the same first argument (sec) that
747d29b2c44Sab196087  * specifies the section. This argument can be a section name
748d29b2c44Sab196087  * (default), section index, or section type, depending on the
749d29b2c44Sab196087  * options used. This routine determines which case is current,
750d29b2c44Sab196087  * and then supplies completion for the first argument.
751d29b2c44Sab196087  */
752d29b2c44Sab196087 static void
753d29b2c44Sab196087 cpl_1starg_sec(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
754d29b2c44Sab196087     const char *argv[], int num_opt)
755d29b2c44Sab196087 {
756d29b2c44Sab196087 	elfedit_section_t *sec;
757d29b2c44Sab196087 	enum { NAME, INDEX, TYPE } op;
758d29b2c44Sab196087 	Word ndx;
759d29b2c44Sab196087 
760d29b2c44Sab196087 	if (argc != (num_opt + 1))
761d29b2c44Sab196087 		return;
762d29b2c44Sab196087 
763d29b2c44Sab196087 	op = NAME;
764d29b2c44Sab196087 	for (ndx = 0; ndx < num_opt; ndx++) {
765d29b2c44Sab196087 		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0)
766d29b2c44Sab196087 			op = INDEX;
767d29b2c44Sab196087 		else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0)
768d29b2c44Sab196087 			op = TYPE;
769d29b2c44Sab196087 	}
770d29b2c44Sab196087 
771d29b2c44Sab196087 	switch (op) {
772d29b2c44Sab196087 	case NAME:
773d29b2c44Sab196087 		if (obj_state == NULL)
774d29b2c44Sab196087 			break;
775d29b2c44Sab196087 		sec = obj_state->os_secarr;
776d29b2c44Sab196087 		for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++)
777d29b2c44Sab196087 			elfedit_cpl_match(cpldata, sec->sec_name, 0);
778d29b2c44Sab196087 		break;
779d29b2c44Sab196087 
780d29b2c44Sab196087 	case INDEX:
781d29b2c44Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHN);
782d29b2c44Sab196087 		break;
783d29b2c44Sab196087 
784d29b2c44Sab196087 	case TYPE:
785d29b2c44Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
786d29b2c44Sab196087 		break;
787d29b2c44Sab196087 	}
788d29b2c44Sab196087 }
789d29b2c44Sab196087 
790d29b2c44Sab196087 
791d29b2c44Sab196087 /*ARGSUSED*/
792d29b2c44Sab196087 static void
793d29b2c44Sab196087 cpl_sh_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
794d29b2c44Sab196087     const char *argv[], int num_opt)
795d29b2c44Sab196087 {
796d29b2c44Sab196087 	/* Handle -shXXX options */
797d29b2c44Sab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
798d29b2c44Sab196087 
799d29b2c44Sab196087 	/* The second and following arguments can be an SHF_ value */
800d29b2c44Sab196087 	if (argc >= (num_opt + 2))
801d29b2c44Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHF);
802d29b2c44Sab196087 }
803d29b2c44Sab196087 
804cce0e03bSab196087 /*
805cce0e03bSab196087  * For shdr:sh_info and shdr:sh_link: The value argument can be an
806cce0e03bSab196087  * integer, section name, or section type.
807cce0e03bSab196087  */
808cce0e03bSab196087 /*ARGSUSED*/
809cce0e03bSab196087 static void
810cce0e03bSab196087 cpl_sh_infolink(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
811cce0e03bSab196087     const char *argv[], int num_opt)
812cce0e03bSab196087 {
813cce0e03bSab196087 	elfedit_section_t *sec;
814cce0e03bSab196087 	enum { NAME, INTVAL, TYPE } op;
815cce0e03bSab196087 	Word ndx;
816cce0e03bSab196087 
817cce0e03bSab196087 	/* Handle -shXXX options */
818cce0e03bSab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
819cce0e03bSab196087 
820cce0e03bSab196087 	if (argc != (num_opt + 2))
821cce0e03bSab196087 		return;
822cce0e03bSab196087 
823cce0e03bSab196087 	op = INTVAL;
824cce0e03bSab196087 	for (ndx = 0; ndx < num_opt; ndx++) {
825cce0e03bSab196087 		if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM)) == 0)
826cce0e03bSab196087 			op = NAME;
827cce0e03bSab196087 		else if (strcmp(argv[ndx],
828cce0e03bSab196087 		    MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP)) == 0)
829cce0e03bSab196087 			op = TYPE;
830cce0e03bSab196087 	}
831cce0e03bSab196087 
832cce0e03bSab196087 	switch (op) {
833cce0e03bSab196087 	case NAME:
834cce0e03bSab196087 		if (obj_state == NULL)
835cce0e03bSab196087 			break;
836cce0e03bSab196087 		sec = obj_state->os_secarr;
837cce0e03bSab196087 		for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++)
838cce0e03bSab196087 			elfedit_cpl_match(cpldata, sec->sec_name, 0);
839cce0e03bSab196087 		break;
840cce0e03bSab196087 
841cce0e03bSab196087 	case TYPE:
842cce0e03bSab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
843cce0e03bSab196087 		break;
844cce0e03bSab196087 	}
845cce0e03bSab196087 }
846cce0e03bSab196087 
847d29b2c44Sab196087 /*ARGSUSED*/
848d29b2c44Sab196087 static void
849d29b2c44Sab196087 cpl_sh_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
850d29b2c44Sab196087     const char *argv[], int num_opt)
851d29b2c44Sab196087 {
852d29b2c44Sab196087 	/* Handle -shXXX options */
853d29b2c44Sab196087 	cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt);
854d29b2c44Sab196087 
855d29b2c44Sab196087 	/* The second argument can be an SHT_ value */
856d29b2c44Sab196087 	if (argc == (num_opt + 2))
857d29b2c44Sab196087 		elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
858d29b2c44Sab196087 }
859d29b2c44Sab196087 
860d29b2c44Sab196087 
861d29b2c44Sab196087 
862d29b2c44Sab196087 /*
863d29b2c44Sab196087  * Implementation functions for the commands
864d29b2c44Sab196087  */
865d29b2c44Sab196087 static elfedit_cmdret_t
866d29b2c44Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
867d29b2c44Sab196087 {
868d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_DUMP, obj_state, argc, argv));
869d29b2c44Sab196087 }
870d29b2c44Sab196087 
871d29b2c44Sab196087 
872d29b2c44Sab196087 static elfedit_cmdret_t
873d29b2c44Sab196087 cmd_sh_addr(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
874d29b2c44Sab196087 {
875d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ADDR, obj_state, argc, argv));
876d29b2c44Sab196087 }
877d29b2c44Sab196087 
878d29b2c44Sab196087 
879d29b2c44Sab196087 static elfedit_cmdret_t
880d29b2c44Sab196087 cmd_sh_addralign(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
881d29b2c44Sab196087 {
882d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ADDRALIGN, obj_state, argc, argv));
883d29b2c44Sab196087 }
884d29b2c44Sab196087 
885d29b2c44Sab196087 
886d29b2c44Sab196087 static elfedit_cmdret_t
887d29b2c44Sab196087 cmd_sh_entsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
888d29b2c44Sab196087 {
889d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_ENTSIZE, obj_state, argc, argv));
890d29b2c44Sab196087 }
891d29b2c44Sab196087 
892d29b2c44Sab196087 static elfedit_cmdret_t
893d29b2c44Sab196087 cmd_sh_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
894d29b2c44Sab196087 {
895d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_FLAGS, obj_state, argc, argv));
896d29b2c44Sab196087 }
897d29b2c44Sab196087 
898d29b2c44Sab196087 static elfedit_cmdret_t
899d29b2c44Sab196087 cmd_sh_info(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
900d29b2c44Sab196087 {
901d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_INFO, obj_state, argc, argv));
902d29b2c44Sab196087 }
903d29b2c44Sab196087 
904d29b2c44Sab196087 static elfedit_cmdret_t
905d29b2c44Sab196087 cmd_sh_link(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
906d29b2c44Sab196087 {
907d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_LINK, obj_state, argc, argv));
908d29b2c44Sab196087 }
909d29b2c44Sab196087 
910d29b2c44Sab196087 static elfedit_cmdret_t
911d29b2c44Sab196087 cmd_sh_name(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
912d29b2c44Sab196087 {
913d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_NAME, obj_state, argc, argv));
914d29b2c44Sab196087 }
915d29b2c44Sab196087 
916d29b2c44Sab196087 static elfedit_cmdret_t
917d29b2c44Sab196087 cmd_sh_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
918d29b2c44Sab196087 {
919d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_OFFSET, obj_state, argc, argv));
920d29b2c44Sab196087 }
921d29b2c44Sab196087 
922d29b2c44Sab196087 static elfedit_cmdret_t
923d29b2c44Sab196087 cmd_sh_size(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
924d29b2c44Sab196087 {
925d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_SIZE, obj_state, argc, argv));
926d29b2c44Sab196087 }
927d29b2c44Sab196087 
928d29b2c44Sab196087 static elfedit_cmdret_t
929d29b2c44Sab196087 cmd_sh_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
930d29b2c44Sab196087 {
931d29b2c44Sab196087 	return (cmd_body(SHDR_CMD_T_SH_TYPE, obj_state, argc, argv));
932d29b2c44Sab196087 }
933d29b2c44Sab196087 
934d29b2c44Sab196087 
935d29b2c44Sab196087 
936d29b2c44Sab196087 /*ARGSUSED*/
937d29b2c44Sab196087 elfedit_module_t *
938d29b2c44Sab196087 elfedit_init(elfedit_module_version_t version)
939d29b2c44Sab196087 {
940d29b2c44Sab196087 	/* Multiple commands accept only the standard set of options */
941d29b2c44Sab196087 	static elfedit_cmd_optarg_t opt_std[] = {
942d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
943d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
944d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
945d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
946d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
947d29b2c44Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
948d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
949d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
950d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
951d29b2c44Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
952d29b2c44Sab196087 		{ NULL }
953d29b2c44Sab196087 	};
954d29b2c44Sab196087 
955cce0e03bSab196087 	/*
956cce0e03bSab196087 	 * sh_info and sh_link accept the standard options above,
957cce0e03bSab196087 	 * plus -value_shnam and -value_shtyp.
958cce0e03bSab196087 	 */
959cce0e03bSab196087 	static elfedit_cmd_optarg_t opt_infolink[] = {
960cce0e03bSab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
961cce0e03bSab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
962cce0e03bSab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
963cce0e03bSab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
964cce0e03bSab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
965cce0e03bSab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
966cce0e03bSab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
967cce0e03bSab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
968cce0e03bSab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
969cce0e03bSab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
970cce0e03bSab196087 		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHNAM),
971cce0e03bSab196087 		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHNAM) */
972cce0e03bSab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHNAM), 0,
973cce0e03bSab196087 		    SHDR_OPT_F_VALUE_SHNAM, SHDR_OPT_F_VALUE_SHNAM },
974cce0e03bSab196087 		{ MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP),
975cce0e03bSab196087 		    /* MSG_INTL(MSG_OPTDESC_VALUE_SHTYP) */
976cce0e03bSab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_VALUE_SHTYP), 0,
977cce0e03bSab196087 		    SHDR_OPT_F_VALUE_SHTYP, SHDR_OPT_F_VALUE_SHTYP },
978cce0e03bSab196087 		{ NULL }
979cce0e03bSab196087 	};
980cce0e03bSab196087 
981d29b2c44Sab196087 	/* shdr:sh_addr */
982d29b2c44Sab196087 	static const char *name_sh_addr[] = {
983d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_ADDR), NULL };
984d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_addr[] = {
985d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
986d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
987d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
988d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
989d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
990d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ADDR) */
991d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDR),
992d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
993d29b2c44Sab196087 		{ NULL }
994d29b2c44Sab196087 	};
995d29b2c44Sab196087 
996d29b2c44Sab196087 	/* shdr:dump */
997d29b2c44Sab196087 	static const char *name_dump[] = {
998d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_DUMP),
999d29b2c44Sab196087 	    MSG_ORIG(MSG_STR_EMPTY),	/* "" makes this the default command */
1000d29b2c44Sab196087 	    NULL
1001d29b2c44Sab196087 	};
1002d29b2c44Sab196087 	static elfedit_cmd_optarg_t opt_dump[] = {
1003d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
1004d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
1005d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
1006d29b2c44Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
1007d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
1008d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
1009d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
1010d29b2c44Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
1011d29b2c44Sab196087 		{ NULL }
1012d29b2c44Sab196087 	};
1013d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_dump[] = {
1014d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1015d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1016d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1017d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1018d29b2c44Sab196087 		{ NULL }
1019d29b2c44Sab196087 	};
1020d29b2c44Sab196087 
1021d29b2c44Sab196087 	/* shdr:sh_addralign */
1022d29b2c44Sab196087 	static const char *name_sh_addralign[] = {
1023d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_ADDRALIGN), NULL };
1024d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_addralign[] = {
1025d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1026d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1027d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1028d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1029d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1030d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ADDRALIGN) */
1031d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDRALIGN),
1032d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1033d29b2c44Sab196087 		{ NULL }
1034d29b2c44Sab196087 	};
1035d29b2c44Sab196087 
1036d29b2c44Sab196087 	/* shdr:sh_entsize */
1037d29b2c44Sab196087 	static const char *name_sh_entsize[] = {
1038d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_ENTSIZE), NULL };
1039d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_entsize[] = {
1040d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1041d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1042d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1043d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1044d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1045d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_ENTSIZE) */
1046d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ENTSIZE),
1047d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1048d29b2c44Sab196087 		{ NULL }
1049d29b2c44Sab196087 	};
1050d29b2c44Sab196087 
1051d29b2c44Sab196087 	/* shdr:sh_flags */
1052d29b2c44Sab196087 	static const char *name_sh_flags[] = {
1053d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_FLAGS), NULL };
1054d29b2c44Sab196087 	static elfedit_cmd_optarg_t opt_sh_flags[] = {
1055d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_AND, NULL,
1056d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_AND, SHDR_OPT_F_OR },
1057d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_CMP, NULL,
1058d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_CMP, 0 },
1059d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
1060d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1061d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_OR, NULL,
1062d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_OR, SHDR_OPT_F_AND },
1063d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
1064d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
1065d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
1066d29b2c44Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
1067d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
1068d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
1069d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
1070d29b2c44Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
1071d29b2c44Sab196087 		{ NULL }
1072d29b2c44Sab196087 	};
1073d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_flags[] = {
1074d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1075d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1076d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1077d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1078d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1079d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_FLAGS) */
1080d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_FLAGS),
1081d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
1082d29b2c44Sab196087 		{ NULL }
1083d29b2c44Sab196087 	};
1084d29b2c44Sab196087 
1085d29b2c44Sab196087 	/* shdr:sh_info */
1086d29b2c44Sab196087 	static const char *name_sh_info[] = {
1087d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_INFO), NULL };
1088d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_info[] = {
1089d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1090d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1091d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1092d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1093d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1094d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_INFO) */
1095d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_INFO),
1096d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1097d29b2c44Sab196087 		{ NULL }
1098d29b2c44Sab196087 	};
1099d29b2c44Sab196087 
1100d29b2c44Sab196087 	/* shdr:sh_link */
1101d29b2c44Sab196087 	static const char *name_sh_link[] = {
1102d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_LINK), NULL };
1103d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_link[] = {
1104d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1105d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1106d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1107d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1108d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1109d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_LINK) */
1110d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_LINK),
1111d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1112d29b2c44Sab196087 		{ NULL }
1113d29b2c44Sab196087 	};
1114d29b2c44Sab196087 
1115d29b2c44Sab196087 	/* shdr:sh_name */
1116d29b2c44Sab196087 	static const char *name_sh_name[] = {
1117d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_NAME), NULL };
1118d29b2c44Sab196087 	static elfedit_cmd_optarg_t opt_sh_name[] = {
1119d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_NAME_OFFSET),
1120d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */
1121d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_NAME_OFFSET), 0,
1122d29b2c44Sab196087 		    SHDR_OPT_F_NAMOFFSET, 0 },
1123d29b2c44Sab196087 		{ ELFEDIT_STDOA_OPT_O, NULL,
1124d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1125d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHNDX),
1126d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHNDX) */
1127d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
1128d29b2c44Sab196087 		    SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP },
1129d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_MINUS_SHTYP),
1130d29b2c44Sab196087 		    /* MSG_INTL(MSG_OPTDESC_SHTYP) */
1131d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
1132d29b2c44Sab196087 		    SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX },
1133d29b2c44Sab196087 		{ NULL }
1134d29b2c44Sab196087 	};
1135d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_name[] = {
1136d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1137d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1138d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1139d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1140d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_NAME),
1141d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_NAME) */
1142d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_NAME),
1143d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1144d29b2c44Sab196087 		{ NULL }
1145d29b2c44Sab196087 	};
1146d29b2c44Sab196087 
1147d29b2c44Sab196087 	/* shdr:sh_offset */
1148d29b2c44Sab196087 	static const char *name_sh_offset[] = {
1149d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_OFFSET), NULL };
1150d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_offset[] = {
1151d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1152d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1153d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1154d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1155d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1156d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_OFFSET) */
1157d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_OFFSET),
1158d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1159d29b2c44Sab196087 		{ NULL }
1160d29b2c44Sab196087 	};
1161d29b2c44Sab196087 
1162d29b2c44Sab196087 	/* shdr:sh_size */
1163d29b2c44Sab196087 	static const char *name_sh_size[] = {
1164d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_SIZE), NULL };
1165d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_size[] = {
1166d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1167d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1168d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1169d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1170d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1171d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_SIZE) */
1172d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_SIZE),
1173d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1174d29b2c44Sab196087 		{ NULL }
1175d29b2c44Sab196087 	};
1176d29b2c44Sab196087 
1177d29b2c44Sab196087 	/* shdr:sh_type */
1178d29b2c44Sab196087 	static const char *name_sh_type[] = {
1179d29b2c44Sab196087 	    MSG_ORIG(MSG_CMD_SH_TYPE), NULL };
1180d29b2c44Sab196087 	static elfedit_cmd_optarg_t arg_sh_type[] = {
1181d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_SEC),
1182d29b2c44Sab196087 		    /* MSG_INTL(MSG_A1_SEC) */
1183d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A1_SEC),
1184d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1185d29b2c44Sab196087 		{ MSG_ORIG(MSG_STR_VALUE),
1186d29b2c44Sab196087 		    /* MSG_INTL(MSG_A2_DESC_SH_TYPE) */
1187d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_A2_DESC_SH_TYPE),
1188d29b2c44Sab196087 		    ELFEDIT_CMDOA_F_OPT },
1189d29b2c44Sab196087 		{ NULL }
1190d29b2c44Sab196087 	};
1191d29b2c44Sab196087 
1192d29b2c44Sab196087 	static elfedit_cmd_t cmds[] = {
1193d29b2c44Sab196087 		/* shdr:dump */
1194d29b2c44Sab196087 		{ cmd_dump, cpl_1starg_sec, name_dump,
1195d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_DUMP) */
1196d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_DUMP),
1197d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_DUMP) */
1198d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_DUMP),
1199d29b2c44Sab196087 		    opt_dump, arg_dump },
1200d29b2c44Sab196087 
1201d29b2c44Sab196087 		/* shdr:sh_addr */
1202d29b2c44Sab196087 		{ cmd_sh_addr, cpl_1starg_sec, name_sh_addr,
1203d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ADDR) */
1204d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ADDR),
1205d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ADDR) */
1206d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ADDR),
1207d29b2c44Sab196087 		    opt_std, arg_sh_addr },
1208d29b2c44Sab196087 
1209d29b2c44Sab196087 		/* shdr:sh_addralign */
1210d29b2c44Sab196087 		{ cmd_sh_addralign, cpl_1starg_sec, name_sh_addralign,
1211d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ADDRALIGN) */
1212d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ADDRALIGN),
1213d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ADDRALIGN) */
1214d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ADDRALIGN),
1215d29b2c44Sab196087 		    opt_std, arg_sh_addralign },
1216d29b2c44Sab196087 
1217d29b2c44Sab196087 		/* shdr:sh_entsize */
1218d29b2c44Sab196087 		{ cmd_sh_entsize, cpl_1starg_sec, name_sh_entsize,
1219d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_ENTSIZE) */
1220d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_ENTSIZE),
1221d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_ENTSIZE) */
1222d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_ENTSIZE),
1223d29b2c44Sab196087 		    opt_std, arg_sh_entsize },
1224d29b2c44Sab196087 
1225d29b2c44Sab196087 		/* shdr:sh_flags */
1226d29b2c44Sab196087 		{ cmd_sh_flags, cpl_sh_flags, name_sh_flags,
1227d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_FLAGS) */
1228d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_FLAGS),
1229d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_FLAGS) */
1230d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_FLAGS),
1231d29b2c44Sab196087 		    opt_sh_flags, arg_sh_flags },
1232d29b2c44Sab196087 
1233d29b2c44Sab196087 		/* shdr:sh_info */
1234cce0e03bSab196087 		{ cmd_sh_info, cpl_sh_infolink, name_sh_info,
1235d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_INFO) */
1236d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_INFO),
1237d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_INFO) */
1238d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_INFO),
1239cce0e03bSab196087 		    opt_infolink, arg_sh_info },
1240d29b2c44Sab196087 
1241d29b2c44Sab196087 		/* shdr:sh_link */
1242cce0e03bSab196087 		{ cmd_sh_link, cpl_sh_infolink, name_sh_link,
1243d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_LINK) */
1244d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_LINK),
1245d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_LINK) */
1246d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_LINK),
1247cce0e03bSab196087 		    opt_infolink, arg_sh_link },
1248d29b2c44Sab196087 
1249d29b2c44Sab196087 		/* shdr:sh_name */
1250d29b2c44Sab196087 		{ cmd_sh_name, cpl_1starg_sec, name_sh_name,
1251d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_NAME) */
1252d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_NAME),
1253d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_NAME) */
1254d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_NAME),
1255d29b2c44Sab196087 		    opt_sh_name, arg_sh_name },
1256d29b2c44Sab196087 
1257d29b2c44Sab196087 		/* shdr:sh_offset */
1258d29b2c44Sab196087 		{ cmd_sh_offset, cpl_1starg_sec, name_sh_offset,
1259d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_OFFSET) */
1260d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_OFFSET),
1261d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_OFFSET) */
1262d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_OFFSET),
1263d29b2c44Sab196087 		    opt_std, arg_sh_offset },
1264d29b2c44Sab196087 
1265d29b2c44Sab196087 		/* shdr:sh_size */
1266d29b2c44Sab196087 		{ cmd_sh_size, cpl_1starg_sec, name_sh_size,
1267d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_SIZE) */
1268d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_SIZE),
1269d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_SIZE) */
1270d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_SIZE),
1271d29b2c44Sab196087 		    opt_std, arg_sh_size },
1272d29b2c44Sab196087 
1273d29b2c44Sab196087 		/* shdr:sh_type */
1274d29b2c44Sab196087 		{ cmd_sh_type, cpl_sh_type, name_sh_type,
1275d29b2c44Sab196087 		    /* MSG_INTL(MSG_DESC_SH_TYPE) */
1276d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_DESC_SH_TYPE),
1277d29b2c44Sab196087 		    /* MSG_INTL(MSG_HELP_SH_TYPE) */
1278d29b2c44Sab196087 		    ELFEDIT_I18NHDL(MSG_HELP_SH_TYPE),
1279d29b2c44Sab196087 		    opt_std, arg_sh_type },
1280d29b2c44Sab196087 
1281d29b2c44Sab196087 		{ NULL }
1282d29b2c44Sab196087 	};
1283d29b2c44Sab196087 
1284d29b2c44Sab196087 	static elfedit_module_t module = {
1285d29b2c44Sab196087 	    ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
1286d29b2c44Sab196087 	    /* MSG_INTL(MSG_MOD_DESC) */
1287d29b2c44Sab196087 	    ELFEDIT_I18NHDL(MSG_MOD_DESC),
1288d29b2c44Sab196087 	    cmds, mod_i18nhdl_to_str };
1289d29b2c44Sab196087 
1290d29b2c44Sab196087 	return (&module);
1291d29b2c44Sab196087 }
1292