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 /*
2308278a5eSRod Evans * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24d29b2c44Sab196087 * Use is subject to license terms.
25*33f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
26d29b2c44Sab196087 */
27d29b2c44Sab196087
28d29b2c44Sab196087 #include <ctype.h>
29d29b2c44Sab196087 #include <elfedit.h>
30d29b2c44Sab196087 #include <sys/elf_SPARC.h>
31d29b2c44Sab196087 #include <strings.h>
32d29b2c44Sab196087 #include <debug.h>
33d29b2c44Sab196087 #include <conv.h>
34d29b2c44Sab196087 #include <cap_msg.h>
35d29b2c44Sab196087
36d29b2c44Sab196087
37d29b2c44Sab196087 /*
38d29b2c44Sab196087 * Capabilities section
39d29b2c44Sab196087 */
40d29b2c44Sab196087
41d29b2c44Sab196087
42d29b2c44Sab196087
43d29b2c44Sab196087
44d29b2c44Sab196087 /*
45d29b2c44Sab196087 * This module uses shared code for several of the commands.
46d29b2c44Sab196087 * It is sometimes necessary to know which specific command
47d29b2c44Sab196087 * is active.
48d29b2c44Sab196087 */
49d29b2c44Sab196087 typedef enum {
50d29b2c44Sab196087 /* Dump command, used as module default to display dynamic section */
51d29b2c44Sab196087 CAP_CMD_T_DUMP = 0, /* cap:dump */
52d29b2c44Sab196087
53d29b2c44Sab196087 /* Commands that do not correspond directly to a specific DT tag */
54d29b2c44Sab196087 CAP_CMD_T_TAG = 1, /* cap:tag */
55d29b2c44Sab196087 CAP_CMD_T_VALUE = 2, /* cap:value */
56d29b2c44Sab196087 CAP_CMD_T_DELETE = 3, /* cap:delete */
57d29b2c44Sab196087 CAP_CMD_T_MOVE = 4, /* cap:shift */
58d29b2c44Sab196087
59d29b2c44Sab196087 /* Commands that embody tag specific knowledge */
60d29b2c44Sab196087 CAP_CMD_T_HW1 = 5, /* cap:hw1 */
61d29b2c44Sab196087 CAP_CMD_T_SF1 = 6, /* cap:sf1 */
6208278a5eSRod Evans CAP_CMD_T_HW2 = 7, /* cap:hw2 */
63d29b2c44Sab196087 } CAP_CMD_T;
64d29b2c44Sab196087
65d29b2c44Sab196087
66d29b2c44Sab196087
67d29b2c44Sab196087 #ifndef _ELF64
68d29b2c44Sab196087 /*
69d29b2c44Sab196087 * We supply this function for the msg module
70d29b2c44Sab196087 */
71d29b2c44Sab196087 const char *
_cap_msg(Msg mid)72d29b2c44Sab196087 _cap_msg(Msg mid)
73d29b2c44Sab196087 {
74d29b2c44Sab196087 return (gettext(MSG_ORIG(mid)));
75d29b2c44Sab196087 }
76d29b2c44Sab196087 #endif
77d29b2c44Sab196087
78d29b2c44Sab196087
79d29b2c44Sab196087 /*
80d29b2c44Sab196087 * This function is supplied to elfedit through our elfedit_module_t
81d29b2c44Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles
82d29b2c44Sab196087 * in our module interface into the actual strings for elfedit to
83d29b2c44Sab196087 * use.
84d29b2c44Sab196087 *
85d29b2c44Sab196087 * note:
86d29b2c44Sab196087 * This module uses Msg codes for its i18n handle type.
87d29b2c44Sab196087 * So the translation is simply to use MSG_INTL() to turn
88d29b2c44Sab196087 * it into a string and return it.
89d29b2c44Sab196087 */
90d29b2c44Sab196087 static const char *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)91d29b2c44Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
92d29b2c44Sab196087 {
93d29b2c44Sab196087 Msg msg = (Msg)hdl;
94d29b2c44Sab196087
95d29b2c44Sab196087 return (MSG_INTL(msg));
96d29b2c44Sab196087 }
97d29b2c44Sab196087
98d29b2c44Sab196087
99d29b2c44Sab196087
100d29b2c44Sab196087 /*
101d29b2c44Sab196087 * The cap_opt_t enum specifies a bit value for every optional
102d29b2c44Sab196087 * argument allowed by a command in this module.
103d29b2c44Sab196087 */
104d29b2c44Sab196087 typedef enum {
105d29b2c44Sab196087 CAP_OPT_F_AND = 1, /* -and: AND (&) values to dest */
106d29b2c44Sab196087 CAP_OPT_F_CMP = 2, /* -cmp: Complement (~) values */
10708278a5eSRod Evans CAP_OPT_F_CAPID = 4, /* -capid id: elt limited to given */
10808278a5eSRod Evans /* capabilities group */
10908278a5eSRod Evans CAP_OPT_F_CAPNDX = 8, /* -capndx: elt is tag index, */
110d29b2c44Sab196087 /* not name */
11108278a5eSRod Evans CAP_OPT_F_OR = 16, /* -or: OR (|) values to dest */
11208278a5eSRod Evans CAP_OPT_F_STRVAL = 32 /* -s: value is string, not integer */
113d29b2c44Sab196087 } cap_opt_t;
114d29b2c44Sab196087
115d29b2c44Sab196087
116d29b2c44Sab196087 /*
117d29b2c44Sab196087 * A variable of type ARGSTATE is used by each command to maintain
118d29b2c44Sab196087 * information about the arguments 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 struct {
124d29b2c44Sab196087 elfedit_section_t *sec; /* Capabilities section reference */
125d29b2c44Sab196087 Cap *data; /* Start of capabilities section data */
126d29b2c44Sab196087 Word num; /* # Capabilities elts */
12708278a5eSRod Evans Boolean grp_set; /* TRUE when cap group is set */
12808278a5eSRod Evans Word grp_start_ndx; /* capabilities group starting index */
12908278a5eSRod Evans Word grp_end_ndx; /* capabilities group ending index */
130d29b2c44Sab196087 } cap;
13108278a5eSRod Evans struct { /* String table */
13208278a5eSRod Evans elfedit_section_t *sec;
13308278a5eSRod Evans } str;
134d29b2c44Sab196087 cap_opt_t optmask; /* Mask of options used */
135d29b2c44Sab196087 int argc; /* # of plain arguments */
136d29b2c44Sab196087 const char **argv; /* Plain arguments */
137d29b2c44Sab196087 } ARGSTATE;
138d29b2c44Sab196087
139d29b2c44Sab196087
140d29b2c44Sab196087
141d29b2c44Sab196087 /*
14208278a5eSRod Evans * Lookup the string table associated with the capabilities
14308278a5eSRod Evans * section.
14408278a5eSRod Evans *
14508278a5eSRod Evans * entry:
14608278a5eSRod Evans * argstate - Argument state block
14708278a5eSRod Evans * required - If TRUE, failure to obtain a string table should be
14808278a5eSRod Evans * considered to be an error.
14908278a5eSRod Evans *
15008278a5eSRod Evans * exit:
15108278a5eSRod Evans * If a string table is found, argstate->str is updated to reference it.
15208278a5eSRod Evans * If no string table is found, and required is TRUE, an error is issued
15308278a5eSRod Evans * and this routine does not return to the caller. Otherwise, this
15408278a5eSRod Evans * routine returns quietly without modifying argstate->str.
15508278a5eSRod Evans */
15608278a5eSRod Evans static void
argstate_add_str(ARGSTATE * argstate,Boolean required)15708278a5eSRod Evans argstate_add_str(ARGSTATE *argstate, Boolean required)
15808278a5eSRod Evans {
15908278a5eSRod Evans /* String table already loaded? */
16008278a5eSRod Evans if (argstate->str.sec != NULL)
16108278a5eSRod Evans return;
16208278a5eSRod Evans
16308278a5eSRod Evans /*
16408278a5eSRod Evans * We can't proceed if the capabilities section does not have
16508278a5eSRod Evans * an associated string table.
16608278a5eSRod Evans */
16708278a5eSRod Evans if (argstate->cap.sec->sec_shdr->sh_info == 0) {
16808278a5eSRod Evans /* Error if the operation requires a string table */
16908278a5eSRod Evans if (required)
17008278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSTRTAB),
17108278a5eSRod Evans EC_WORD(argstate->cap.sec->sec_shndx),
17208278a5eSRod Evans argstate->cap.sec->sec_name);
17308278a5eSRod Evans return;
17408278a5eSRod Evans }
17508278a5eSRod Evans
17608278a5eSRod Evans argstate->str.sec = elfedit_sec_getstr(argstate->obj_state,
17708278a5eSRod Evans argstate->cap.sec->sec_shdr->sh_info, 0);
17808278a5eSRod Evans }
17908278a5eSRod Evans
18008278a5eSRod Evans /*
18108278a5eSRod Evans * Given an index into the capabilities array, locate the index of the
18208278a5eSRod Evans * initial element in its capabilities group, and the number of elements
18308278a5eSRod Evans * in the group.
18408278a5eSRod Evans */
18508278a5eSRod Evans static void
cap_group_extents(ARGSTATE * argstate,Word ndx,Word * ret_start_ndx,Word * ret_end_ndx)18608278a5eSRod Evans cap_group_extents(ARGSTATE *argstate, Word ndx, Word *ret_start_ndx,
18708278a5eSRod Evans Word *ret_end_ndx)
18808278a5eSRod Evans {
18908278a5eSRod Evans *ret_end_ndx = ndx;
19008278a5eSRod Evans
19108278a5eSRod Evans /*
19208278a5eSRod Evans * The group starts with a non-NULL tag that is either the
19308278a5eSRod Evans * first tag in the array, or is preceded by a NULL tag.
19408278a5eSRod Evans */
19508278a5eSRod Evans while ((ndx > 0) && (argstate->cap.data[ndx].c_tag == CA_SUNW_NULL))
19608278a5eSRod Evans ndx--;
19708278a5eSRod Evans while ((ndx > 0) && (argstate->cap.data[ndx - 1].c_tag != CA_SUNW_NULL))
19808278a5eSRod Evans ndx--;
19908278a5eSRod Evans *ret_start_ndx = ndx;
20008278a5eSRod Evans
20108278a5eSRod Evans
20208278a5eSRod Evans /*
20308278a5eSRod Evans * The group is terminated by a series of 1 or more NULL tags.
20408278a5eSRod Evans */
20508278a5eSRod Evans ndx = *ret_end_ndx;
20608278a5eSRod Evans while (((ndx + 1) < argstate->cap.num) &&
20708278a5eSRod Evans (argstate->cap.data[ndx].c_tag != CA_SUNW_NULL))
20808278a5eSRod Evans ndx++;
20908278a5eSRod Evans while (((ndx + 1) < argstate->cap.num) &&
21008278a5eSRod Evans (argstate->cap.data[ndx + 1].c_tag == CA_SUNW_NULL))
21108278a5eSRod Evans ndx++;
21208278a5eSRod Evans *ret_end_ndx = ndx;
21308278a5eSRod Evans }
21408278a5eSRod Evans
21508278a5eSRod Evans /*
21608278a5eSRod Evans * If a CA_SUNW_ID element exists within the current capabilities group
21708278a5eSRod Evans * in the given argument state, return the string pointer to the name.
21808278a5eSRod Evans * Otherwise return a pointer to a descriptive "noname" string.
21908278a5eSRod Evans */
22008278a5eSRod Evans static const char *
cap_group_id(ARGSTATE * argstate)22108278a5eSRod Evans cap_group_id(ARGSTATE *argstate)
22208278a5eSRod Evans {
22308278a5eSRod Evans Word ndx = argstate->cap.grp_start_ndx;
22408278a5eSRod Evans Cap *cap = argstate->cap.data + ndx;
22508278a5eSRod Evans
22608278a5eSRod Evans for (; ndx <= argstate->cap.grp_end_ndx; ndx++, cap++) {
22708278a5eSRod Evans if (cap->c_tag == CA_SUNW_ID) {
22808278a5eSRod Evans argstate_add_str(argstate, TRUE);
22908278a5eSRod Evans return (elfedit_offset_to_str(argstate->str.sec,
23008278a5eSRod Evans cap->c_un.c_val, ELFEDIT_MSG_ERR, 0));
23108278a5eSRod Evans }
23208278a5eSRod Evans
23308278a5eSRod Evans if (cap->c_tag == CA_SUNW_NULL)
23408278a5eSRod Evans break;
23508278a5eSRod Evans }
23608278a5eSRod Evans
23708278a5eSRod Evans return ((argstate->cap.grp_start_ndx == 0) ?
23808278a5eSRod Evans MSG_INTL(MSG_STR_OBJECT) : MSG_INTL(MSG_STR_NONAME));
23908278a5eSRod Evans }
24008278a5eSRod Evans
24108278a5eSRod Evans
24208278a5eSRod Evans /*
24308278a5eSRod Evans * Given an index into the capabilities array, set the argstate cap.grp_*
24408278a5eSRod Evans * fields to reflect the capabilities group containing the index.
24508278a5eSRod Evans *
24608278a5eSRod Evans * The group concept is used to limit operations to a related group
24708278a5eSRod Evans * of capabilities, and prevent insert/delete/move operations from
24808278a5eSRod Evans * spilling across groups.
24908278a5eSRod Evans */
25008278a5eSRod Evans static void
argstate_cap_group(ARGSTATE * argstate,Word ndx)25108278a5eSRod Evans argstate_cap_group(ARGSTATE *argstate, Word ndx)
25208278a5eSRod Evans {
25308278a5eSRod Evans if (argstate->cap.grp_set == TRUE)
25408278a5eSRod Evans return;
25508278a5eSRod Evans
25608278a5eSRod Evans cap_group_extents(argstate, ndx, &argstate->cap.grp_start_ndx,
25708278a5eSRod Evans &argstate->cap.grp_end_ndx);
25808278a5eSRod Evans
25908278a5eSRod Evans argstate->cap.grp_set = TRUE;
26008278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CAPGRP),
26108278a5eSRod Evans EC_WORD(argstate->cap.sec->sec_shndx), argstate->cap.sec->sec_name,
26208278a5eSRod Evans EC_WORD(argstate->cap.grp_start_ndx),
26308278a5eSRod Evans EC_WORD(argstate->cap.grp_end_ndx), cap_group_id(argstate));
26408278a5eSRod Evans }
26508278a5eSRod Evans
26608278a5eSRod Evans /*
26708278a5eSRod Evans * Given an index into the capabilities array, issue a group title for
26808278a5eSRod Evans * the capabilities group that contains it.
26908278a5eSRod Evans */
27008278a5eSRod Evans static void
group_title(ARGSTATE * argstate,Word ndx)27108278a5eSRod Evans group_title(ARGSTATE *argstate, Word ndx)
27208278a5eSRod Evans {
27308278a5eSRod Evans ARGSTATE loc_argstate;
27408278a5eSRod Evans
27508278a5eSRod Evans loc_argstate = *argstate;
27608278a5eSRod Evans cap_group_extents(argstate, ndx, &loc_argstate.cap.grp_start_ndx,
27708278a5eSRod Evans &loc_argstate.cap.grp_end_ndx);
27808278a5eSRod Evans elfedit_printf(MSG_INTL(MSG_FMT_CAPGRP),
27908278a5eSRod Evans EC_WORD(loc_argstate.cap.grp_start_ndx),
28008278a5eSRod Evans EC_WORD(loc_argstate.cap.grp_end_ndx), cap_group_id(&loc_argstate));
28108278a5eSRod Evans }
28208278a5eSRod Evans
28308278a5eSRod Evans /*
284d29b2c44Sab196087 * Standard argument processing for cap module
285d29b2c44Sab196087 *
286d29b2c44Sab196087 * entry
287d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments
288d29b2c44Sab196087 * argstate - Address of ARGSTATE block to be initialized
289d29b2c44Sab196087 *
290d29b2c44Sab196087 * exit:
291d29b2c44Sab196087 * On success, *argstate is initialized. On error,
292d29b2c44Sab196087 * an error is issued and this routine does not return.
293d29b2c44Sab196087 */
294d29b2c44Sab196087 static void
process_args(elfedit_obj_state_t * obj_state,int argc,const char * argv[],ARGSTATE * argstate)295d29b2c44Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
296d29b2c44Sab196087 ARGSTATE *argstate)
297d29b2c44Sab196087 {
298d29b2c44Sab196087 elfedit_getopt_state_t getopt_state;
299d29b2c44Sab196087 elfedit_getopt_ret_t *getopt_ret;
30008278a5eSRod Evans const char *capid = NULL;
301d29b2c44Sab196087
302d29b2c44Sab196087 bzero(argstate, sizeof (*argstate));
303d29b2c44Sab196087 argstate->obj_state = obj_state;
304d29b2c44Sab196087
305d29b2c44Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv);
306d29b2c44Sab196087
307d29b2c44Sab196087 /* Add each new option to the options mask */
30808278a5eSRod Evans while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) {
309d29b2c44Sab196087 argstate->optmask |= getopt_ret->gor_idmask;
310d29b2c44Sab196087
31108278a5eSRod Evans if (getopt_ret->gor_idmask == CAP_OPT_F_CAPID)
31208278a5eSRod Evans capid = getopt_ret->gor_value;
31308278a5eSRod Evans }
31408278a5eSRod Evans
315d29b2c44Sab196087 /* If there may be an arbitrary amount of output, use a pager */
316d29b2c44Sab196087 if (argc == 0)
317d29b2c44Sab196087 elfedit_pager_init();
318d29b2c44Sab196087
319d29b2c44Sab196087 /* Return the updated values of argc/argv */
320d29b2c44Sab196087 argstate->argc = argc;
321d29b2c44Sab196087 argstate->argv = argv;
322d29b2c44Sab196087
323d29b2c44Sab196087 /* Locate the capabilities section */
324d29b2c44Sab196087 argstate->cap.sec = elfedit_sec_getcap(obj_state, &argstate->cap.data,
325d29b2c44Sab196087 &argstate->cap.num);
32608278a5eSRod Evans
32708278a5eSRod Evans /*
32808278a5eSRod Evans * If -capid was specified, locate the specified capabilities group,
32908278a5eSRod Evans * and narrow the section data to use only that group. Otherwise,
33008278a5eSRod Evans * use the whole array.
33108278a5eSRod Evans */
33208278a5eSRod Evans if (capid != NULL) {
33308278a5eSRod Evans Word i;
33408278a5eSRod Evans Cap *cap = argstate->cap.data;
33508278a5eSRod Evans
33608278a5eSRod Evans /*
33708278a5eSRod Evans * -capid requires the capability section to have an
33808278a5eSRod Evans * associated string table.
33908278a5eSRod Evans */
34008278a5eSRod Evans argstate_add_str(argstate, TRUE);
34108278a5eSRod Evans
34208278a5eSRod Evans for (i = 0; i < argstate->cap.num; i++, cap++)
34308278a5eSRod Evans if ((cap->c_tag == CA_SUNW_ID) &&
34408278a5eSRod Evans (strcmp(capid, elfedit_offset_to_str(
34508278a5eSRod Evans argstate->str.sec, cap->c_un.c_val,
34608278a5eSRod Evans ELFEDIT_MSG_ERR, 0)) == 0))
34708278a5eSRod Evans break;
34808278a5eSRod Evans
34908278a5eSRod Evans if (i == argstate->cap.num)
35008278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCAPID),
35108278a5eSRod Evans EC_WORD(argstate->cap.sec->sec_shndx),
35208278a5eSRod Evans argstate->cap.sec->sec_name, capid);
35308278a5eSRod Evans argstate_cap_group(argstate, i);
35408278a5eSRod Evans } else {
35508278a5eSRod Evans argstate->cap.grp_start_ndx = 0;
35608278a5eSRod Evans argstate->cap.grp_end_ndx = argstate->cap.num - 1;
35708278a5eSRod Evans }
358d29b2c44Sab196087 }
359d29b2c44Sab196087
360d29b2c44Sab196087
361d29b2c44Sab196087
362d29b2c44Sab196087 /*
363d29b2c44Sab196087 * Print ELF capabilities values, taking the calling command, and output style
364d29b2c44Sab196087 * into account.
365d29b2c44Sab196087 *
366d29b2c44Sab196087 * entry:
367d29b2c44Sab196087 * cmd - CAP_CMD_T_* value giving identify of caller
368d29b2c44Sab196087 * autoprint - If True, output is only produced if the elfedit
369d29b2c44Sab196087 * autoprint flag is set. If False, output is always produced.
370d29b2c44Sab196087 * argstate - Argument state block
371d29b2c44Sab196087 * print_type - Specifies which capabilities elements to display.
372d29b2c44Sab196087 * ndx = If print_type is PRINT_CAP_T_NDX, displays the index specified.
373d29b2c44Sab196087 * Otherwise ignored.
374d29b2c44Sab196087 */
375d29b2c44Sab196087 typedef enum {
376d29b2c44Sab196087 PRINT_CAP_T_ALL = 0, /* Show all indexes */
377d29b2c44Sab196087 PRINT_CAP_T_NDX = 1, /* Show capabilities[arg] only */
378d29b2c44Sab196087 PRINT_CAP_T_TAG = 2 /* Show all elts with tag type */
379d29b2c44Sab196087 /* given by arg */
380d29b2c44Sab196087 } PRINT_CAP_T;
381d29b2c44Sab196087
382d29b2c44Sab196087 static void
print_cap(CAP_CMD_T cmd,int autoprint,ARGSTATE * argstate,PRINT_CAP_T print_type,Word arg)383d29b2c44Sab196087 print_cap(CAP_CMD_T cmd, int autoprint, ARGSTATE *argstate,
384d29b2c44Sab196087 PRINT_CAP_T print_type, Word arg)
385d29b2c44Sab196087 {
386d29b2c44Sab196087 elfedit_outstyle_t outstyle;
387d29b2c44Sab196087 Word cnt, ndx, printed = 0;
388d29b2c44Sab196087 Cap *cap;
38908278a5eSRod Evans Boolean header_done = FALSE, null_seen = FALSE;
39098c080d5SRod Evans const char *str;
39198c080d5SRod Evans size_t str_size;
392d29b2c44Sab196087
393d29b2c44Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
394d29b2c44Sab196087 return;
395d29b2c44Sab196087
396d29b2c44Sab196087 /*
397d29b2c44Sab196087 * Pick an output style. cap:dump is required to use the default
398d29b2c44Sab196087 * style. The other commands use the current output style.
399d29b2c44Sab196087 */
400d29b2c44Sab196087 outstyle = (cmd == CAP_CMD_T_DUMP) ?
401d29b2c44Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
402d29b2c44Sab196087
403d29b2c44Sab196087 /* How many elements do we examine? */
404d29b2c44Sab196087 if (print_type == PRINT_CAP_T_NDX) {
405d29b2c44Sab196087 if (arg >= argstate->cap.num)
406d29b2c44Sab196087 return; /* Out of range */
407d29b2c44Sab196087 ndx = arg;
408d29b2c44Sab196087 cnt = 1;
409d29b2c44Sab196087 } else {
41008278a5eSRod Evans ndx = argstate->cap.grp_start_ndx;
41108278a5eSRod Evans cnt = argstate->cap.grp_end_ndx - ndx + 1;
412d29b2c44Sab196087 }
413d29b2c44Sab196087
41408278a5eSRod Evans /* Load string table if there is one */
41508278a5eSRod Evans argstate_add_str(argstate, FALSE);
41698c080d5SRod Evans if (argstate->str.sec == NULL) {
41798c080d5SRod Evans str = NULL;
41898c080d5SRod Evans str_size = 0;
41998c080d5SRod Evans } else {
42098c080d5SRod Evans str = (const char *)argstate->str.sec->sec_data->d_buf;
42198c080d5SRod Evans str_size = argstate->str.sec->sec_data->d_size;
42298c080d5SRod Evans }
42308278a5eSRod Evans
424d29b2c44Sab196087 cap = &argstate->cap.data[ndx];
425d29b2c44Sab196087 for (; cnt--; cap++, ndx++) {
426d29b2c44Sab196087 /*
427d29b2c44Sab196087 * If we are only displaying certain tag types and
428d29b2c44Sab196087 * this isn't one of those, move on to next element.
429d29b2c44Sab196087 */
43008278a5eSRod Evans if ((print_type == PRINT_CAP_T_TAG) && (cap->c_tag != arg)) {
43108278a5eSRod Evans if (cap->c_tag == CA_SUNW_NULL)
43208278a5eSRod Evans null_seen = TRUE;
433d29b2c44Sab196087 continue;
43408278a5eSRod Evans }
43508278a5eSRod Evans
43608278a5eSRod Evans /*
43708278a5eSRod Evans * If capability type requires a string table, and we don't
43808278a5eSRod Evans * have one, force an error.
43908278a5eSRod Evans */
44008278a5eSRod Evans switch (cap->c_tag) {
44108278a5eSRod Evans case CA_SUNW_PLAT:
44208278a5eSRod Evans case CA_SUNW_MACH:
44308278a5eSRod Evans case CA_SUNW_ID:
44408278a5eSRod Evans if (argstate->str.sec == NULL)
44508278a5eSRod Evans argstate_add_str(argstate, TRUE);
44608278a5eSRod Evans break;
44708278a5eSRod Evans }
448d29b2c44Sab196087
449d29b2c44Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
45008278a5eSRod Evans if (null_seen && (cap->c_tag != CA_SUNW_NULL)) {
45108278a5eSRod Evans null_seen = FALSE;
45208278a5eSRod Evans if (header_done) {
45308278a5eSRod Evans elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
45408278a5eSRod Evans MSG_ORIG(MSG_STR_EMPTY));
45508278a5eSRod Evans header_done = FALSE;
45608278a5eSRod Evans }
45708278a5eSRod Evans }
45808278a5eSRod Evans
45908278a5eSRod Evans if (header_done == FALSE) {
46008278a5eSRod Evans header_done = TRUE;
46108278a5eSRod Evans group_title(argstate, ndx);
462d29b2c44Sab196087 Elf_cap_title(0);
463d29b2c44Sab196087 }
46498c080d5SRod Evans Elf_cap_entry(NULL, cap, ndx, str, str_size,
465d29b2c44Sab196087 argstate->obj_state->os_ehdr->e_machine);
466d29b2c44Sab196087 } else {
467d29b2c44Sab196087 /*
46808278a5eSRod Evans * If CAP_CMD_T_TAG, and not in default output
46908278a5eSRod Evans * style, display the tag rather than the value.
470d29b2c44Sab196087 */
47108278a5eSRod Evans if (cmd == CAP_CMD_T_TAG) {
472d29b2c44Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
47308278a5eSRod Evans Conv_inv_buf_t inv_buf;
47408278a5eSRod Evans
47508278a5eSRod Evans elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
47608278a5eSRod Evans conv_cap_tag(cap->c_tag, 0,
47708278a5eSRod Evans &inv_buf));
47808278a5eSRod Evans } else {
47908278a5eSRod Evans elfedit_printf(
48008278a5eSRod Evans MSG_ORIG(MSG_FMT_WORDVALNL),
48108278a5eSRod Evans EC_WORD(cap->c_tag));
48208278a5eSRod Evans }
48308278a5eSRod Evans printed = 1;
48408278a5eSRod Evans continue;
48508278a5eSRod Evans }
48608278a5eSRod Evans
48708278a5eSRod Evans /* Displaying the value in simple or numeric mode */
48808278a5eSRod Evans if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
48908278a5eSRod Evans Conv_cap_val_buf_t cap_val_buf;
49008278a5eSRod Evans
49108278a5eSRod Evans if (print_type == PRINT_CAP_T_TAG) {
49208278a5eSRod Evans elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
49308278a5eSRod Evans conv_cap_val_hw1(cap->c_un.c_val,
49408278a5eSRod Evans argstate->obj_state->os_ehdr->
49508278a5eSRod Evans e_machine, CONV_FMT_NOBKT,
49608278a5eSRod Evans &cap_val_buf.cap_val_hw1_buf));
49708278a5eSRod Evans printed = 1;
49808278a5eSRod Evans continue;
49908278a5eSRod Evans }
500d29b2c44Sab196087
501d29b2c44Sab196087 switch (cap->c_tag) {
502d29b2c44Sab196087 case CA_SUNW_HW_1:
503d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
504d29b2c44Sab196087 conv_cap_val_hw1(cap->c_un.c_val,
505d29b2c44Sab196087 argstate->obj_state->os_ehdr->
50608278a5eSRod Evans e_machine, CONV_FMT_NOBKT,
50708278a5eSRod Evans &cap_val_buf.cap_val_hw1_buf));
508d29b2c44Sab196087 printed = 1;
509d29b2c44Sab196087 continue;
510d29b2c44Sab196087 case CA_SUNW_SF_1:
511d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
512d29b2c44Sab196087 conv_cap_val_sf1(cap->c_un.c_val,
513d29b2c44Sab196087 argstate->obj_state->os_ehdr->
51408278a5eSRod Evans e_machine, CONV_FMT_NOBKT,
51508278a5eSRod Evans &cap_val_buf.cap_val_sf1_buf));
51608278a5eSRod Evans printed = 1;
51708278a5eSRod Evans continue;
51808278a5eSRod Evans case CA_SUNW_HW_2:
51908278a5eSRod Evans elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
52008278a5eSRod Evans conv_cap_val_hw2(cap->c_un.c_val,
52108278a5eSRod Evans argstate->obj_state->os_ehdr->
52208278a5eSRod Evans e_machine, CONV_FMT_NOBKT,
52308278a5eSRod Evans &cap_val_buf.cap_val_hw2_buf));
52408278a5eSRod Evans printed = 1;
52508278a5eSRod Evans continue;
52608278a5eSRod Evans case CA_SUNW_PLAT:
52708278a5eSRod Evans case CA_SUNW_MACH:
52808278a5eSRod Evans case CA_SUNW_ID:
52908278a5eSRod Evans elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
53008278a5eSRod Evans elfedit_offset_to_str(
53108278a5eSRod Evans argstate->str.sec, cap->c_un.c_val,
53208278a5eSRod Evans ELFEDIT_MSG_ERR, 0));
533d29b2c44Sab196087 printed = 1;
534d29b2c44Sab196087 continue;
535d29b2c44Sab196087 }
536d29b2c44Sab196087 }
537d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_HEXXWORDNL),
53808278a5eSRod Evans EC_XWORD(cap->c_un.c_val));
539d29b2c44Sab196087 }
540d29b2c44Sab196087 printed = 1;
54108278a5eSRod Evans if (cap->c_tag == CA_SUNW_NULL)
54208278a5eSRod Evans null_seen = TRUE;
543d29b2c44Sab196087 }
544d29b2c44Sab196087
545d29b2c44Sab196087 /*
546d29b2c44Sab196087 * If nothing was output under the print types that are
547d29b2c44Sab196087 * based on tag type, issue an error saying it doesn't exist.
548d29b2c44Sab196087 */
549d29b2c44Sab196087 if (!printed && (print_type == PRINT_CAP_T_TAG)) {
550d29b2c44Sab196087 Conv_inv_buf_t inv_buf;
551d29b2c44Sab196087
552d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT),
553d29b2c44Sab196087 EC_WORD(argstate->cap.sec->sec_shndx),
55408278a5eSRod Evans argstate->cap.sec->sec_name, argstate->cap.grp_start_ndx,
55508278a5eSRod Evans argstate->cap.grp_end_ndx, cap_group_id(argstate),
5564f680cc6SAli Bahrami conv_cap_tag(arg, 0, &inv_buf));
557d29b2c44Sab196087 }
558d29b2c44Sab196087 }
559d29b2c44Sab196087
560d29b2c44Sab196087
561d29b2c44Sab196087 /*
562d29b2c44Sab196087 * Process the elt argument: This will be a tag type if -capndx is
563d29b2c44Sab196087 * not present and this is a print request. It will be an index otherwise.
564d29b2c44Sab196087 *
565d29b2c44Sab196087 * entry:
566d29b2c44Sab196087 * argstate - Argument state block
567d29b2c44Sab196087 * arg - Argument string to be converted into an index
568d29b2c44Sab196087 * argname - String giving the name by which the argument is
569d29b2c44Sab196087 * referred in the online help for the command.
570d29b2c44Sab196087 * print_request - True if the command is to print the current
571d29b2c44Sab196087 * value(s) and return without changing anything.
572d29b2c44Sab196087 * print_type - Address of variable containing PRINT_CAP_T_
573d29b2c44Sab196087 * code specifying how the elements will be displayed.
574d29b2c44Sab196087 *
575d29b2c44Sab196087 * exit:
576d29b2c44Sab196087 * If print_request is False: arg is converted into an integer value.
577d29b2c44Sab196087 * If -capndx was used, we convert it into an integer. If it was not
578d29b2c44Sab196087 * used, then arg is a tag name --- we find the first capabilities entry
579d29b2c44Sab196087 * that matches. If no entry matches, and there is an extra CA_NULL,
580d29b2c44Sab196087 * it is added. Otherwise an error is issued. *print_type is set
581d29b2c44Sab196087 * to PRINT_CAP_T_NDX.
582d29b2c44Sab196087 *
583d29b2c44Sab196087 * If print_request is True: If -capndx was used, arg is converted into
584d29b2c44Sab196087 * an integer value, *print_type is set to PRINT_CAP_T_NDX, and
585d29b2c44Sab196087 * the value is returned. If -capndx was not used, *print_type is set to
586d29b2c44Sab196087 * PRINT_CAP_T_TAG, and the tag value is returned.
587d29b2c44Sab196087 */
588d29b2c44Sab196087 static Word
arg_to_index(ARGSTATE * argstate,const char * arg,const char * argname,int print_request,PRINT_CAP_T * print_type)589d29b2c44Sab196087 arg_to_index(ARGSTATE *argstate, const char *arg, const char *argname,
590d29b2c44Sab196087 int print_request, PRINT_CAP_T *print_type)
591d29b2c44Sab196087 {
592d29b2c44Sab196087 Word ndx, ca_value;
593d29b2c44Sab196087
594d29b2c44Sab196087
595d29b2c44Sab196087 /* Assume we are returning an index, alter as needed below */
596d29b2c44Sab196087 *print_type = PRINT_CAP_T_NDX;
597d29b2c44Sab196087
59808278a5eSRod Evans /*
59908278a5eSRod Evans * If -capndx was used, this is a simple numeric index.
60008278a5eSRod Evans * Determine its capability group because some operations
60108278a5eSRod Evans * (move, delete) are limited to operate within it.
60208278a5eSRod Evans */
60308278a5eSRod Evans if ((argstate->optmask & CAP_OPT_F_CAPNDX) != 0) {
60408278a5eSRod Evans ndx = (Word) elfedit_atoui_range(arg, argname, 0,
60508278a5eSRod Evans argstate->cap.num - 1, NULL);
60608278a5eSRod Evans argstate_cap_group(argstate, ndx);
60708278a5eSRod Evans return (ndx);
60808278a5eSRod Evans }
609d29b2c44Sab196087
610d29b2c44Sab196087 /* The argument is a CA_ tag type, not a numeric index */
611d29b2c44Sab196087 ca_value = (Word) elfedit_atoconst(arg, ELFEDIT_CONST_CA);
612d29b2c44Sab196087
613d29b2c44Sab196087 /*
614d29b2c44Sab196087 * If this is a printing request, then we let print_cap() show
615d29b2c44Sab196087 * all the items with this tag type.
616d29b2c44Sab196087 */
617d29b2c44Sab196087 if (print_request) {
618d29b2c44Sab196087 *print_type = PRINT_CAP_T_TAG;
619d29b2c44Sab196087 return (ca_value);
620d29b2c44Sab196087 }
621d29b2c44Sab196087
62208278a5eSRod Evans /*
62308278a5eSRod Evans * If we haven't determined a capability group yet, either via
62408278a5eSRod Evans * -capid, or -capndx, then make it the initial group, which
62508278a5eSRod Evans * represent the object capabilities.
62608278a5eSRod Evans */
62708278a5eSRod Evans if (!argstate->cap.grp_set)
62808278a5eSRod Evans argstate_cap_group(argstate, 0);
62908278a5eSRod Evans
63008278a5eSRod Evans /*
63108278a5eSRod Evans * Locate the first entry with the given tag type within the
63208278a5eSRod Evans * capabilities group.
63308278a5eSRod Evans */
63408278a5eSRod Evans for (ndx = argstate->cap.grp_start_ndx;
63508278a5eSRod Evans ndx <= argstate->cap.grp_end_ndx; ndx++) {
636d29b2c44Sab196087 if (argstate->cap.data[ndx].c_tag == ca_value) {
637d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
638d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_CA2NDX),
639d29b2c44Sab196087 EC_WORD(argstate->cap.sec->sec_shndx),
640d29b2c44Sab196087 argstate->cap.sec->sec_name, EC_WORD(ndx), arg);
641d29b2c44Sab196087 return (ndx);
642d29b2c44Sab196087 }
64308278a5eSRod Evans
64408278a5eSRod Evans /*
64508278a5eSRod Evans * If we hit a NULL, then only more NULLs can follow it and
64608278a5eSRod Evans * there's no need to look further. If there is more than
64708278a5eSRod Evans * one NULL, we can grab the first one and turn it into
64808278a5eSRod Evans * an element of the desired type.
64908278a5eSRod Evans */
65008278a5eSRod Evans if (argstate->cap.data[ndx].c_tag == CA_SUNW_NULL) {
65108278a5eSRod Evans if (ndx < argstate->cap.grp_end_ndx) {
65208278a5eSRod Evans Conv_inv_buf_t inv_buf;
65308278a5eSRod Evans
65408278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_DEBUG,
65508278a5eSRod Evans MSG_INTL(MSG_DEBUG_CONVNULL),
65608278a5eSRod Evans EC_WORD(argstate->cap.sec->sec_shndx),
65708278a5eSRod Evans argstate->cap.sec->sec_name, EC_WORD(ndx),
65808278a5eSRod Evans conv_cap_tag(ca_value, 0, &inv_buf));
65908278a5eSRod Evans argstate->cap.data[ndx].c_tag = ca_value;
66008278a5eSRod Evans bzero(&argstate->cap.data[ndx].c_un,
66108278a5eSRod Evans sizeof (argstate->cap.data[ndx].c_un));
66208278a5eSRod Evans return (ndx);
66308278a5eSRod Evans }
66408278a5eSRod Evans break;
66508278a5eSRod Evans }
666d29b2c44Sab196087 }
667d29b2c44Sab196087
668d29b2c44Sab196087 /* No room to create one, so we're out of options and must fail */
669d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT),
670d29b2c44Sab196087 EC_WORD(argstate->cap.sec->sec_shndx),
67108278a5eSRod Evans argstate->cap.sec->sec_name, argstate->cap.grp_start_ndx,
67208278a5eSRod Evans argstate->cap.grp_end_ndx, cap_group_id(argstate), arg);
673d29b2c44Sab196087
674d29b2c44Sab196087 /*NOTREACHED*/
675d29b2c44Sab196087 return (0); /* For lint */
676d29b2c44Sab196087 }
677d29b2c44Sab196087
678d29b2c44Sab196087
679d29b2c44Sab196087 /*
680d29b2c44Sab196087 * Argument processing for the bitmask commands. Convert the arguments
681d29b2c44Sab196087 * to integer form, apply -and/-cmp/-or, and return the resulting value.
682d29b2c44Sab196087 *
683d29b2c44Sab196087 * entry:
684d29b2c44Sab196087 * argstate - Argument state block
685d29b2c44Sab196087 * orig - Value of original bitmask
686d29b2c44Sab196087 * const_sym - NULL, or array of name->integer mappings for
687d29b2c44Sab196087 * applicable symbolic constant names.
688d29b2c44Sab196087 */
689d29b2c44Sab196087 static Word
flag_bitop(ARGSTATE * argstate,Word orig,const elfedit_atoui_sym_t * const_sym)690d29b2c44Sab196087 flag_bitop(ARGSTATE *argstate, Word orig, const elfedit_atoui_sym_t *const_sym)
691d29b2c44Sab196087 {
692d29b2c44Sab196087 Word flags = 0;
693d29b2c44Sab196087 int i;
694d29b2c44Sab196087
695d29b2c44Sab196087 /* Collect the arguments */
696d29b2c44Sab196087 for (i = 0; i < argstate->argc; i++)
697d29b2c44Sab196087 flags |= (Word) elfedit_atoui(argstate->argv[i], const_sym);
698d29b2c44Sab196087
699d29b2c44Sab196087 /* Complement the value? */
700d29b2c44Sab196087 if (argstate->optmask & CAP_OPT_F_CMP)
701d29b2c44Sab196087 flags = ~flags;
702d29b2c44Sab196087
703d29b2c44Sab196087 /* Perform any requested bit operations */
704d29b2c44Sab196087 if (argstate->optmask & CAP_OPT_F_AND)
705d29b2c44Sab196087 flags &= orig;
706d29b2c44Sab196087 else if (argstate->optmask & CAP_OPT_F_OR)
707d29b2c44Sab196087 flags |= orig;
708d29b2c44Sab196087
709d29b2c44Sab196087 return (flags);
710d29b2c44Sab196087 }
711d29b2c44Sab196087
71208278a5eSRod Evans /*
71308278a5eSRod Evans * Common processing for capabilities value setting.
71408278a5eSRod Evans *
71508278a5eSRod Evans * entry:
71608278a5eSRod Evans * argstate - Argument state block
71708278a5eSRod Evans * cap - capabilities data pointer
71808278a5eSRod Evans * ndx - capabilities data index
71908278a5eSRod Evans * cap_ndx - capabilities section index
72008278a5eSRod Evans * cap_name - capabilities section name
72108278a5eSRod Evans * cap_tag - capabilities tag
72208278a5eSRod Evans * const_type - data conversion type
72308278a5eSRod Evans */
72408278a5eSRod Evans static elfedit_cmdret_t
cap_set(ARGSTATE * argstate,Cap * cap,Word ndx,Word cap_ndx,const char * cap_name,Xword cap_tag,elfedit_const_t const_type)72508278a5eSRod Evans cap_set(ARGSTATE *argstate, Cap *cap, Word ndx, Word cap_ndx,
72608278a5eSRod Evans const char *cap_name, Xword cap_tag, elfedit_const_t const_type)
72708278a5eSRod Evans {
72808278a5eSRod Evans Conv_cap_val_buf_t buf1, buf2;
72908278a5eSRod Evans Half mach = argstate->obj_state->os_ehdr->e_machine;
73008278a5eSRod Evans Xword ncap, ocap;
731d29b2c44Sab196087
73208278a5eSRod Evans ncap = flag_bitop(argstate, cap[ndx].c_un.c_val,
73308278a5eSRod Evans elfedit_const_to_atoui(const_type));
73408278a5eSRod Evans
73508278a5eSRod Evans /* Set the value */
73608278a5eSRod Evans if ((ocap = cap[ndx].c_un.c_val) == ncap) {
73708278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_BSB_OK),
73808278a5eSRod Evans cap_ndx, cap_name, EC_WORD(ndx),
73908278a5eSRod Evans conv_cap_val(cap_tag, ocap, mach, CONV_FMT_NOBKT, &buf1));
74008278a5eSRod Evans
74108278a5eSRod Evans return (ELFEDIT_CMDRET_NONE);
74208278a5eSRod Evans } else {
74308278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_BSB_CHG),
74408278a5eSRod Evans cap_ndx, cap_name, EC_WORD(ndx),
74508278a5eSRod Evans conv_cap_val(cap_tag, ocap, mach, CONV_FMT_NOBKT, &buf1),
74608278a5eSRod Evans conv_cap_val(cap_tag, ncap, mach, CONV_FMT_NOBKT, &buf2));
74708278a5eSRod Evans
74808278a5eSRod Evans cap[ndx].c_un.c_val = ncap;
74908278a5eSRod Evans return (ELFEDIT_CMDRET_MOD);
75008278a5eSRod Evans }
75108278a5eSRod Evans }
752d29b2c44Sab196087
753d29b2c44Sab196087 /*
754d29b2c44Sab196087 * Common body for the cap: module commands. These commands
755d29b2c44Sab196087 * share a large amount of common behavior, so it is convenient
756d29b2c44Sab196087 * to centralize things and use the cmd argument to handle the
757d29b2c44Sab196087 * small differences.
758d29b2c44Sab196087 *
759d29b2c44Sab196087 * entry:
760d29b2c44Sab196087 * cmd - One of the CAP_CMD_T_* constants listed above, specifying
761d29b2c44Sab196087 * which command to implement.
762d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments
763d29b2c44Sab196087 */
764d29b2c44Sab196087 static elfedit_cmdret_t
cmd_body(CAP_CMD_T cmd,elfedit_obj_state_t * obj_state,int argc,const char * argv[])765d29b2c44Sab196087 cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state,
766d29b2c44Sab196087 int argc, const char *argv[])
767d29b2c44Sab196087 {
768d29b2c44Sab196087 ARGSTATE argstate;
769d29b2c44Sab196087 Cap *cap;
770d29b2c44Sab196087 const char *cap_name;
77108278a5eSRod Evans Word cap_ndx;
772d29b2c44Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE;
773d29b2c44Sab196087 PRINT_CAP_T print_type = PRINT_CAP_T_ALL;
774d29b2c44Sab196087 Word ndx;
775d29b2c44Sab196087 int print_only = 0;
776d29b2c44Sab196087 int do_autoprint = 1;
777d29b2c44Sab196087
778d29b2c44Sab196087 /* Process the optional arguments */
779d29b2c44Sab196087 process_args(obj_state, argc, argv, &argstate);
780d29b2c44Sab196087
781d29b2c44Sab196087 cap = argstate.cap.data;
782d29b2c44Sab196087 cap_name = argstate.cap.sec->sec_name;
783d29b2c44Sab196087 cap_ndx = argstate.cap.sec->sec_shndx;
784d29b2c44Sab196087
785d29b2c44Sab196087 /* Check number of arguments, gather information */
786d29b2c44Sab196087 switch (cmd) {
787d29b2c44Sab196087 case CAP_CMD_T_DUMP:
788d29b2c44Sab196087 /* cap:dump can accept an optional index argument */
789d29b2c44Sab196087 if (argstate.argc > 1)
790d29b2c44Sab196087 elfedit_command_usage();
791d29b2c44Sab196087 print_only = 1;
792d29b2c44Sab196087 if (argstate.argc == 1)
793d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
794d29b2c44Sab196087 MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
795d29b2c44Sab196087 break;
796d29b2c44Sab196087
797d29b2c44Sab196087 case CAP_CMD_T_TAG:
798d29b2c44Sab196087 case CAP_CMD_T_VALUE:
799d29b2c44Sab196087 print_only = (argstate.argc != 2);
800d29b2c44Sab196087 if (argstate.argc > 0) {
801d29b2c44Sab196087 if (argstate.argc > 2)
802d29b2c44Sab196087 elfedit_command_usage();
803d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
804d29b2c44Sab196087 MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
805d29b2c44Sab196087 }
806d29b2c44Sab196087 break;
807d29b2c44Sab196087
808d29b2c44Sab196087 case CAP_CMD_T_DELETE:
809d29b2c44Sab196087 if ((argstate.argc < 1) || (argstate.argc > 2))
810d29b2c44Sab196087 elfedit_command_usage();
811d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
812d29b2c44Sab196087 MSG_ORIG(MSG_STR_ELT),
813d29b2c44Sab196087 0, &print_type);
814d29b2c44Sab196087 do_autoprint = 0;
815d29b2c44Sab196087 break;
816d29b2c44Sab196087
817d29b2c44Sab196087 case CAP_CMD_T_MOVE:
818d29b2c44Sab196087 if ((argstate.argc < 2) || (argstate.argc > 3))
819d29b2c44Sab196087 elfedit_command_usage();
820d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
821d29b2c44Sab196087 MSG_ORIG(MSG_STR_ELT), 0, &print_type);
822d29b2c44Sab196087 do_autoprint = 0;
823d29b2c44Sab196087 break;
824d29b2c44Sab196087
825d29b2c44Sab196087 case CAP_CMD_T_HW1:
826d29b2c44Sab196087 print_only = (argstate.argc == 0);
827d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
828d29b2c44Sab196087 ELFEDIT_CONST_CA, CA_SUNW_HW_1, 1),
829d29b2c44Sab196087 MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
830d29b2c44Sab196087 break;
831d29b2c44Sab196087
832d29b2c44Sab196087 case CAP_CMD_T_SF1:
833d29b2c44Sab196087 print_only = (argstate.argc == 0);
834d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
835d29b2c44Sab196087 ELFEDIT_CONST_CA, CA_SUNW_SF_1, 1),
836d29b2c44Sab196087 MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
837d29b2c44Sab196087 break;
838d29b2c44Sab196087
83908278a5eSRod Evans case CAP_CMD_T_HW2:
84008278a5eSRod Evans print_only = (argstate.argc == 0);
84108278a5eSRod Evans ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
84208278a5eSRod Evans ELFEDIT_CONST_CA, CA_SUNW_HW_2, 1),
84308278a5eSRod Evans MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
84408278a5eSRod Evans break;
84508278a5eSRod Evans
846d29b2c44Sab196087 default:
847d29b2c44Sab196087 /* Note expected: All commands should have been caught above */
848d29b2c44Sab196087 elfedit_command_usage();
849d29b2c44Sab196087 break;
850d29b2c44Sab196087 }
851d29b2c44Sab196087
852d29b2c44Sab196087
853d29b2c44Sab196087 /* If this is a request to print current values, do it and return */
854d29b2c44Sab196087 if (print_only) {
855d29b2c44Sab196087 print_cap(cmd, 0, &argstate, print_type, ndx);
856d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE);
857d29b2c44Sab196087 }
858d29b2c44Sab196087
859d29b2c44Sab196087
860d29b2c44Sab196087 switch (cmd) {
861d29b2c44Sab196087 /*
862d29b2c44Sab196087 * CAP_CMD_T_DUMP can't get here: It is a print-only
863d29b2c44Sab196087 * command.
864d29b2c44Sab196087 */
865d29b2c44Sab196087
866d29b2c44Sab196087 case CAP_CMD_T_TAG:
867d29b2c44Sab196087 {
868d29b2c44Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
869d29b2c44Sab196087 Word c_tag = (Word) elfedit_atoconst(argstate.argv[1],
870d29b2c44Sab196087 ELFEDIT_CONST_CA);
871d29b2c44Sab196087
872d29b2c44Sab196087 if (cap[ndx].c_tag == c_tag) {
873d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
874d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK),
875d29b2c44Sab196087 cap_ndx, cap_name, EC_WORD(ndx),
8764f680cc6SAli Bahrami conv_cap_tag(c_tag, 0, &inv_buf1));
877d29b2c44Sab196087 } else {
878d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
879d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
880d29b2c44Sab196087 cap_ndx, cap_name, EC_WORD(ndx),
8814f680cc6SAli Bahrami conv_cap_tag(cap[ndx].c_tag, 0, &inv_buf1),
8824f680cc6SAli Bahrami conv_cap_tag(c_tag, 0, &inv_buf2));
883d29b2c44Sab196087 cap[ndx].c_tag = c_tag;
884d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
885d29b2c44Sab196087 }
886d29b2c44Sab196087 }
887d29b2c44Sab196087 break;
888d29b2c44Sab196087
889d29b2c44Sab196087 case CAP_CMD_T_VALUE:
890d29b2c44Sab196087 {
89108278a5eSRod Evans Xword c_val;
89208278a5eSRod Evans
89308278a5eSRod Evans if (argstate.optmask & CAP_OPT_F_STRVAL) {
89408278a5eSRod Evans argstate_add_str(&argstate, TRUE);
89508278a5eSRod Evans c_val = elfedit_strtab_insert(obj_state,
89608278a5eSRod Evans argstate.str.sec, NULL, argstate.argv[1]);
89708278a5eSRod Evans } else {
89808278a5eSRod Evans c_val = (Xword)
899d29b2c44Sab196087 elfedit_atoui(argstate.argv[1], NULL);
90008278a5eSRod Evans }
901d29b2c44Sab196087
902d29b2c44Sab196087 if (cap[ndx].c_un.c_val == c_val) {
903d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
904d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_OK),
905d29b2c44Sab196087 argstate.cap.sec->sec_shndx,
906d29b2c44Sab196087 argstate.cap.sec->sec_name,
907d29b2c44Sab196087 EC_WORD(ndx), EC_XWORD(c_val));
908d29b2c44Sab196087 } else {
909d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
910d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_CHG),
911d29b2c44Sab196087 argstate.cap.sec->sec_shndx,
912d29b2c44Sab196087 argstate.cap.sec->sec_name,
913d29b2c44Sab196087 EC_WORD(ndx), EC_XWORD(cap[ndx].c_un.c_val),
914d29b2c44Sab196087 EC_XWORD(c_val));
915d29b2c44Sab196087 cap[ndx].c_un.c_val = c_val;
916d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
917d29b2c44Sab196087 }
918d29b2c44Sab196087 }
919d29b2c44Sab196087 break;
920d29b2c44Sab196087
921d29b2c44Sab196087 case CAP_CMD_T_DELETE:
922d29b2c44Sab196087 {
923d29b2c44Sab196087 Word cnt = (argstate.argc == 1) ? 1 :
924d29b2c44Sab196087 (Word) elfedit_atoui_range(argstate.argv[1],
92508278a5eSRod Evans MSG_ORIG(MSG_STR_COUNT), 1,
92608278a5eSRod Evans argstate.cap.grp_end_ndx - ndx + 1, NULL);
927d29b2c44Sab196087 const char *msg_prefix =
928d29b2c44Sab196087 elfedit_sec_msgprefix(argstate.cap.sec);
929d29b2c44Sab196087
93008278a5eSRod Evans /*
93108278a5eSRod Evans * We want to limit the deleted elements to be
93208278a5eSRod Evans * in the range of the current capabilities group,
93308278a5eSRod Evans * and for the resulting NULL elements to be inserted
93408278a5eSRod Evans * at the end of the group, rather than at the end
93508278a5eSRod Evans * of the section. To do this, we set the array length
93608278a5eSRod Evans * in the call to the delete function so that it thinks
93708278a5eSRod Evans * the array ends with the current group.
93808278a5eSRod Evans *
93908278a5eSRod Evans * The delete function will catch attempts to delete
94008278a5eSRod Evans * past this virtual end, but the error message will
94108278a5eSRod Evans * not make sense to the user. In order to prevent that,
94208278a5eSRod Evans * we check for the condition here and provide a more
94308278a5eSRod Evans * useful error.
94408278a5eSRod Evans */
94508278a5eSRod Evans if ((ndx + cnt - 1) > argstate.cap.grp_end_ndx)
94608278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_ERR,
94708278a5eSRod Evans MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
94808278a5eSRod Evans argstate.cap.grp_start_ndx,
94908278a5eSRod Evans argstate.cap.grp_end_ndx,
95008278a5eSRod Evans cap_group_id(&argstate));
95108278a5eSRod Evans elfedit_array_elts_delete(msg_prefix, cap, sizeof (Cap),
95208278a5eSRod Evans argstate.cap.grp_end_ndx + 1, ndx, cnt);
953d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
954d29b2c44Sab196087 }
955d29b2c44Sab196087 break;
956d29b2c44Sab196087
957d29b2c44Sab196087 case CAP_CMD_T_MOVE:
958d29b2c44Sab196087 {
959d29b2c44Sab196087 Cap save;
960d29b2c44Sab196087 Word cnt;
961d29b2c44Sab196087 Word dstndx;
962d29b2c44Sab196087 const char *msg_prefix =
963d29b2c44Sab196087 elfedit_sec_msgprefix(argstate.cap.sec);
964d29b2c44Sab196087
965d29b2c44Sab196087 dstndx = (Word)
966d29b2c44Sab196087 elfedit_atoui_range(argstate.argv[1],
96708278a5eSRod Evans MSG_ORIG(MSG_STR_DST_INDEX),
96808278a5eSRod Evans argstate.cap.grp_start_ndx,
96908278a5eSRod Evans argstate.cap.grp_end_ndx, NULL);
970d29b2c44Sab196087 if (argstate.argc == 2) {
971d29b2c44Sab196087 cnt = 1;
972d29b2c44Sab196087 } else {
97308278a5eSRod Evans Word max;
97408278a5eSRod Evans
97508278a5eSRod Evans max = argstate.cap.grp_end_ndx -
97608278a5eSRod Evans ((ndx > dstndx) ? ndx : dstndx) + 1;
977d29b2c44Sab196087 cnt = (Word) elfedit_atoui_range(
978d29b2c44Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT),
97908278a5eSRod Evans 1, max, NULL);
980d29b2c44Sab196087 }
98108278a5eSRod Evans
98208278a5eSRod Evans /*
98308278a5eSRod Evans * Moves are required to be self contained within
98408278a5eSRod Evans * the bounds of the selected capability group.
98508278a5eSRod Evans * The move utility function contains bounds checking,
98608278a5eSRod Evans * but is not sub-array aware. Hence, we bounds check
98708278a5eSRod Evans * check it here, and then hand of the validated
98808278a5eSRod Evans * operation to the move utility function to execute.
98908278a5eSRod Evans */
99008278a5eSRod Evans if ((ndx < argstate.cap.grp_start_ndx) ||
99108278a5eSRod Evans ((ndx + cnt) > argstate.cap.grp_end_ndx) ||
99208278a5eSRod Evans (dstndx < argstate.cap.grp_start_ndx) ||
99308278a5eSRod Evans ((dstndx + cnt) > argstate.cap.grp_end_ndx))
99408278a5eSRod Evans elfedit_msg(ELFEDIT_MSG_ERR,
99508278a5eSRod Evans MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
99608278a5eSRod Evans argstate.cap.grp_start_ndx,
99708278a5eSRod Evans argstate.cap.grp_end_ndx,
99808278a5eSRod Evans cap_group_id(&argstate));
99908278a5eSRod Evans elfedit_array_elts_move(msg_prefix, cap, sizeof (save),
100008278a5eSRod Evans argstate.cap.grp_end_ndx + 1, ndx, dstndx,
100108278a5eSRod Evans cnt, &save);
1002d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1003d29b2c44Sab196087 }
1004d29b2c44Sab196087 break;
1005d29b2c44Sab196087
1006d29b2c44Sab196087
1007d29b2c44Sab196087 case CAP_CMD_T_HW1:
1008d29b2c44Sab196087 {
100908278a5eSRod Evans ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
101008278a5eSRod Evans CA_SUNW_HW_1, ELFEDIT_CONST_HW1_SUNW);
1011d29b2c44Sab196087 }
1012d29b2c44Sab196087 break;
1013d29b2c44Sab196087
1014d29b2c44Sab196087 case CAP_CMD_T_SF1:
1015d29b2c44Sab196087 {
101608278a5eSRod Evans ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
101708278a5eSRod Evans CA_SUNW_SF_1, ELFEDIT_CONST_SF1_SUNW);
1018d29b2c44Sab196087 }
101908278a5eSRod Evans break;
102008278a5eSRod Evans
102108278a5eSRod Evans case CAP_CMD_T_HW2:
102208278a5eSRod Evans {
102308278a5eSRod Evans ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
102408278a5eSRod Evans CA_SUNW_HW_2, ELFEDIT_CONST_HW2_SUNW);
1025d29b2c44Sab196087 }
1026d29b2c44Sab196087 break;
1027d29b2c44Sab196087 }
1028d29b2c44Sab196087
1029d29b2c44Sab196087 /*
1030d29b2c44Sab196087 * If we modified the capabilities section header, tell libelf.
1031d29b2c44Sab196087 */
1032d29b2c44Sab196087 if (ret == ELFEDIT_CMDRET_MOD)
1033d29b2c44Sab196087 elfedit_modified_data(argstate.cap.sec);
1034d29b2c44Sab196087
1035d29b2c44Sab196087 /* Do autoprint */
1036d29b2c44Sab196087 if (do_autoprint)
1037d29b2c44Sab196087 print_cap(cmd, 1, &argstate, print_type, ndx);
1038d29b2c44Sab196087
1039d29b2c44Sab196087 return (ret);
1040d29b2c44Sab196087 }
1041d29b2c44Sab196087
1042d29b2c44Sab196087
1043d29b2c44Sab196087
1044d29b2c44Sab196087 /*
1045d29b2c44Sab196087 * Command completion functions for the commands
1046d29b2c44Sab196087 */
1047d29b2c44Sab196087
1048d29b2c44Sab196087 /*
104908278a5eSRod Evans * -capid command completion: Supply all CA_SUNW_ID names found in the object.
105008278a5eSRod Evans */
105108278a5eSRod Evans static void
cpl_capid_opt(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)105208278a5eSRod Evans cpl_capid_opt(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
105308278a5eSRod Evans const char *argv[], int num_opt)
105408278a5eSRod Evans {
105508278a5eSRod Evans elfedit_section_t *cap_sec, *str_sec;
105608278a5eSRod Evans Cap *cap;
105708278a5eSRod Evans Word num;
105808278a5eSRod Evans
105908278a5eSRod Evans if (obj_state == NULL) /* No object available */
106008278a5eSRod Evans return;
106108278a5eSRod Evans
106208278a5eSRod Evans if ((argc > num_opt) || (argc < 2) ||
106308278a5eSRod Evans (strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_CAPID)) != 0))
106408278a5eSRod Evans return;
106508278a5eSRod Evans
106608278a5eSRod Evans cap_sec = elfedit_sec_getcap(obj_state, &cap, &num);
106708278a5eSRod Evans
106808278a5eSRod Evans /* If no associated string table, we have no strings to complete */
106908278a5eSRod Evans if (cap_sec->sec_shdr->sh_info == 0)
107008278a5eSRod Evans return;
107108278a5eSRod Evans
107208278a5eSRod Evans str_sec = elfedit_sec_getstr(obj_state, cap_sec->sec_shdr->sh_info, 0);
107308278a5eSRod Evans
107408278a5eSRod Evans for (; num--; cap++)
107508278a5eSRod Evans if (cap->c_tag == CA_SUNW_ID)
107608278a5eSRod Evans elfedit_cpl_match(cpldata, elfedit_offset_to_str(
107708278a5eSRod Evans str_sec, cap->c_un.c_val, ELFEDIT_MSG_ERR, 0), 0);
107808278a5eSRod Evans }
107908278a5eSRod Evans
108008278a5eSRod Evans /*
1081d29b2c44Sab196087 * Command completion for the first argument, which specifies
1082d29b2c44Sab196087 * the capabilities element to use. Examines the options to see if
1083d29b2c44Sab196087 * -capndx is present, and if not, supplies the completion
1084d29b2c44Sab196087 * strings for argument 1.
1085d29b2c44Sab196087 */
1086d29b2c44Sab196087 /*ARGSUSED*/
1087d29b2c44Sab196087 static void
cpl_eltarg(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1088d29b2c44Sab196087 cpl_eltarg(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1089d29b2c44Sab196087 const char *argv[], int num_opt)
1090d29b2c44Sab196087 {
1091d29b2c44Sab196087 Word i;
1092d29b2c44Sab196087
109308278a5eSRod Evans /* -capid id_name */
109408278a5eSRod Evans if (argc <= num_opt) {
109508278a5eSRod Evans cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
109608278a5eSRod Evans return;
109708278a5eSRod Evans }
109808278a5eSRod Evans
1099d29b2c44Sab196087 /* Make sure it's the first argument */
1100d29b2c44Sab196087 if ((argc - num_opt) != 1)
1101d29b2c44Sab196087 return;
1102d29b2c44Sab196087
1103d29b2c44Sab196087 /* Is -capndx present? If so, we don't complete tag types */
1104d29b2c44Sab196087 for (i = 0; i < num_opt; i++)
1105d29b2c44Sab196087 if (strcmp(argv[i], MSG_ORIG(MSG_STR_MINUS_CAPNDX)) == 0)
1106d29b2c44Sab196087 return;
1107d29b2c44Sab196087
1108d29b2c44Sab196087 /*
1109d29b2c44Sab196087 * Supply capability tag names. There are very few of these, so
1110d29b2c44Sab196087 * rather than worry about whether a given tag exists in the
1111d29b2c44Sab196087 * file or not, we simply serve up all the possibilities.
1112d29b2c44Sab196087 */
1113d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA);
1114d29b2c44Sab196087 }
1115d29b2c44Sab196087
1116d29b2c44Sab196087 /*ARGSUSED*/
1117d29b2c44Sab196087 static void
cpl_tag(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1118d29b2c44Sab196087 cpl_tag(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1119d29b2c44Sab196087 const char *argv[], int num_opt)
1120d29b2c44Sab196087 {
112108278a5eSRod Evans /* -capid id_name */
112208278a5eSRod Evans if (argc <= num_opt) {
112308278a5eSRod Evans cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
112408278a5eSRod Evans return;
112508278a5eSRod Evans }
112608278a5eSRod Evans
112708278a5eSRod Evans /* First plain argument */
1128d29b2c44Sab196087 if ((argc - num_opt) == 1) {
1129d29b2c44Sab196087 cpl_eltarg(obj_state, cpldata, argc, argv, num_opt);
1130d29b2c44Sab196087 return;
1131d29b2c44Sab196087 }
1132d29b2c44Sab196087
1133d29b2c44Sab196087 /* The second argument is always a tag value */
1134d29b2c44Sab196087 if ((argc - num_opt) == 2)
1135d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA);
1136d29b2c44Sab196087 }
1137d29b2c44Sab196087
1138d29b2c44Sab196087 /*ARGSUSED*/
1139d29b2c44Sab196087 static void
cpl_hw1(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1140d29b2c44Sab196087 cpl_hw1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1141d29b2c44Sab196087 const char *argv[], int num_opt)
1142d29b2c44Sab196087 {
114308278a5eSRod Evans /* -capid id_name */
114408278a5eSRod Evans if (argc <= num_opt) {
114508278a5eSRod Evans cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
114608278a5eSRod Evans return;
114708278a5eSRod Evans }
1148d29b2c44Sab196087
114908278a5eSRod Evans /* This routine allows multiple flags to be specified */
115008278a5eSRod Evans elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW1_SUNW);
1151d29b2c44Sab196087 }
1152d29b2c44Sab196087
1153d29b2c44Sab196087 /*ARGSUSED*/
1154d29b2c44Sab196087 static void
cpl_sf1(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1155d29b2c44Sab196087 cpl_sf1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1156d29b2c44Sab196087 const char *argv[], int num_opt)
1157d29b2c44Sab196087 {
115808278a5eSRod Evans /* -capid id_name */
115908278a5eSRod Evans if (argc <= num_opt) {
116008278a5eSRod Evans cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
116108278a5eSRod Evans return;
116208278a5eSRod Evans }
116308278a5eSRod Evans
1164d29b2c44Sab196087 /* This routine allows multiple flags to be specified */
1165d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SF1_SUNW);
1166d29b2c44Sab196087 }
1167d29b2c44Sab196087
116808278a5eSRod Evans /*ARGSUSED*/
116908278a5eSRod Evans static void
cpl_hw2(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)117008278a5eSRod Evans cpl_hw2(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
117108278a5eSRod Evans const char *argv[], int num_opt)
117208278a5eSRod Evans {
117308278a5eSRod Evans /* -capid id_name */
117408278a5eSRod Evans if (argc <= num_opt) {
117508278a5eSRod Evans cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
117608278a5eSRod Evans return;
117708278a5eSRod Evans }
117808278a5eSRod Evans
117908278a5eSRod Evans /* This routine allows multiple flags to be specified */
118008278a5eSRod Evans elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW2_SUNW);
118108278a5eSRod Evans }
1182d29b2c44Sab196087
1183d29b2c44Sab196087 /*
1184d29b2c44Sab196087 * Implementation functions for the commands
1185d29b2c44Sab196087 */
1186d29b2c44Sab196087 static elfedit_cmdret_t
cmd_dump(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1187d29b2c44Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1188d29b2c44Sab196087 {
1189d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_DUMP, obj_state, argc, argv));
1190d29b2c44Sab196087 }
1191d29b2c44Sab196087
1192d29b2c44Sab196087 static elfedit_cmdret_t
cmd_tag(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1193d29b2c44Sab196087 cmd_tag(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1194d29b2c44Sab196087 {
1195d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_TAG, obj_state, argc, argv));
1196d29b2c44Sab196087 }
1197d29b2c44Sab196087
1198d29b2c44Sab196087 static elfedit_cmdret_t
cmd_value(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1199d29b2c44Sab196087 cmd_value(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1200d29b2c44Sab196087 {
1201d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_VALUE, obj_state, argc, argv));
1202d29b2c44Sab196087 }
1203d29b2c44Sab196087
1204d29b2c44Sab196087 static elfedit_cmdret_t
cmd_delete(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1205d29b2c44Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1206d29b2c44Sab196087 {
1207d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_DELETE, obj_state, argc, argv));
1208d29b2c44Sab196087 }
1209d29b2c44Sab196087
1210d29b2c44Sab196087 static elfedit_cmdret_t
cmd_move(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1211d29b2c44Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1212d29b2c44Sab196087 {
1213d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_MOVE, obj_state, argc, argv));
1214d29b2c44Sab196087 }
1215d29b2c44Sab196087
1216d29b2c44Sab196087 static elfedit_cmdret_t
cmd_hw1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1217d29b2c44Sab196087 cmd_hw1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1218d29b2c44Sab196087 {
1219d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_HW1, obj_state, argc, argv));
1220d29b2c44Sab196087 }
1221d29b2c44Sab196087
1222d29b2c44Sab196087 static elfedit_cmdret_t
cmd_sf1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1223d29b2c44Sab196087 cmd_sf1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1224d29b2c44Sab196087 {
1225d29b2c44Sab196087 return (cmd_body(CAP_CMD_T_SF1, obj_state, argc, argv));
1226d29b2c44Sab196087 }
1227d29b2c44Sab196087
122808278a5eSRod Evans static elfedit_cmdret_t
cmd_hw2(elfedit_obj_state_t * obj_state,int argc,const char * argv[])122908278a5eSRod Evans cmd_hw2(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
123008278a5eSRod Evans {
123108278a5eSRod Evans return (cmd_body(CAP_CMD_T_HW2, obj_state, argc, argv));
123208278a5eSRod Evans }
1233d29b2c44Sab196087
1234d29b2c44Sab196087 /*ARGSUSED*/
1235d29b2c44Sab196087 elfedit_module_t *
elfedit_init(elfedit_module_version_t version)1236d29b2c44Sab196087 elfedit_init(elfedit_module_version_t version)
1237d29b2c44Sab196087 {
123808278a5eSRod Evans /* For commands that only accept -capid, -and, -cmp, -o, and -or */
123908278a5eSRod Evans static elfedit_cmd_optarg_t opt_ostyle_capid_bitop[] = {
1240d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL,
1241d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_AND, CAP_OPT_F_OR },
124208278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPID),
124308278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPID) */
124408278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
124508278a5eSRod Evans CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
124608278a5eSRod Evans { MSG_ORIG(MSG_STR_IDNAME), NULL, 0 },
1247d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL,
1248d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_CMP, 0 },
1249d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
1250d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1251d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL,
1252d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_OR, CAP_OPT_F_AND },
1253d29b2c44Sab196087 { NULL }
1254d29b2c44Sab196087 };
1255d29b2c44Sab196087
125608278a5eSRod Evans /* For commands that only accept -capid and -capndx */
125708278a5eSRod Evans static elfedit_cmd_optarg_t opt_capid_capndx[] = {
125808278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPID),
125908278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPID) */
126008278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
126108278a5eSRod Evans CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
126208278a5eSRod Evans { MSG_ORIG(MSG_STR_IDNAME), NULL, 0 },
1263d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_CAPNDX),
1264d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_CAPNDX) */
1265d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
126608278a5eSRod Evans CAP_OPT_F_CAPNDX, CAP_OPT_F_CAPID },
1267d29b2c44Sab196087 { NULL }
1268d29b2c44Sab196087 };
1269d29b2c44Sab196087
1270d29b2c44Sab196087
1271d29b2c44Sab196087 /* cap:dump */
1272d29b2c44Sab196087 static const char *name_dump[] = {
1273d29b2c44Sab196087 MSG_ORIG(MSG_CMD_DUMP),
1274d29b2c44Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */
1275d29b2c44Sab196087 NULL
1276d29b2c44Sab196087 };
1277d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_dump[] = {
1278d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1279d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1280d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1281d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1282d29b2c44Sab196087 { NULL }
1283d29b2c44Sab196087 };
1284d29b2c44Sab196087
1285d29b2c44Sab196087
1286d29b2c44Sab196087 /* cap:tag */
1287d29b2c44Sab196087 static const char *name_tag[] = { MSG_ORIG(MSG_CMD_TAG), NULL };
128808278a5eSRod Evans static elfedit_cmd_optarg_t opt_tag[] = {
128908278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPID),
129008278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPID) */
129108278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
129208278a5eSRod Evans CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
129308278a5eSRod Evans { MSG_ORIG(MSG_STR_IDNAME), NULL, 0 },
129408278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPNDX),
129508278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPNDX) */
129608278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
129708278a5eSRod Evans CAP_OPT_F_CAPNDX, 0 },
129808278a5eSRod Evans { ELFEDIT_STDOA_OPT_O, NULL,
129908278a5eSRod Evans ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
130008278a5eSRod Evans { NULL }
130108278a5eSRod Evans };
1302d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_tag[] = {
1303d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1304d29b2c44Sab196087 /* MSG_INTL(MSG_A1_TAG_ELT) */
1305d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_TAG_ELT),
1306d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1307d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1308d29b2c44Sab196087 /* MSG_INTL(MSG_A2_TAG_VALUE) */
1309d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_TAG_VALUE),
1310d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1311d29b2c44Sab196087 { NULL }
1312d29b2c44Sab196087 };
1313d29b2c44Sab196087
1314d29b2c44Sab196087
1315d29b2c44Sab196087 /* cap:value */
1316d29b2c44Sab196087 static const char *name_value[] = { MSG_ORIG(MSG_CMD_VALUE), NULL };
131708278a5eSRod Evans static elfedit_cmd_optarg_t opt_value[] = {
131808278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPID),
131908278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPID) */
132008278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
132108278a5eSRod Evans CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
132208278a5eSRod Evans { MSG_ORIG(MSG_STR_IDNAME), NULL, 0 },
132308278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_CAPNDX),
132408278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_CAPNDX) */
132508278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
132608278a5eSRod Evans CAP_OPT_F_CAPNDX, 0 },
132708278a5eSRod Evans { ELFEDIT_STDOA_OPT_O, NULL,
132808278a5eSRod Evans ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
132908278a5eSRod Evans { MSG_ORIG(MSG_STR_MINUS_S),
133008278a5eSRod Evans /* MSG_INTL(MSG_OPTDESC_S) */
133108278a5eSRod Evans ELFEDIT_I18NHDL(MSG_OPTDESC_S), 0,
133208278a5eSRod Evans CAP_OPT_F_STRVAL, 0 },
133308278a5eSRod Evans { NULL }
133408278a5eSRod Evans };
1335d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_value[] = {
1336d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1337d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1338d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1339d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1340d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1341d29b2c44Sab196087 /* MSG_INTL(MSG_A2_VALUE_VALUE) */
1342d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_VALUE_VALUE),
1343d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1344d29b2c44Sab196087 { NULL }
1345d29b2c44Sab196087 };
1346d29b2c44Sab196087
1347d29b2c44Sab196087 /* cap:delete */
1348d29b2c44Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL };
1349d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_delete[] = {
1350d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1351d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1352d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1353d29b2c44Sab196087 0 },
1354d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT),
1355d29b2c44Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */
1356d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT),
1357d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1358d29b2c44Sab196087 { NULL }
1359d29b2c44Sab196087 };
1360d29b2c44Sab196087
1361d29b2c44Sab196087 /* cap:move */
1362d29b2c44Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL };
1363d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_move[] = {
1364d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1365d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1366d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1367d29b2c44Sab196087 0 },
1368d29b2c44Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX),
1369d29b2c44Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */
1370d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX),
1371d29b2c44Sab196087 0 },
1372d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT),
1373d29b2c44Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */
1374d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT),
1375d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1376d29b2c44Sab196087 { NULL }
1377d29b2c44Sab196087 };
1378d29b2c44Sab196087
1379d29b2c44Sab196087 /* cap:hw1 */
1380d29b2c44Sab196087 static const char *name_hw1[] = { MSG_ORIG(MSG_CMD_HW1), NULL };
1381d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_hw1[] = {
1382d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1383d29b2c44Sab196087 /* MSG_INTL(MSG_A1_HW1_VALUE) */
1384d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_HW1_VALUE),
1385d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
1386d29b2c44Sab196087 { NULL }
1387d29b2c44Sab196087 };
1388d29b2c44Sab196087
1389d29b2c44Sab196087 /* cap:sf1 */
1390d29b2c44Sab196087 static const char *name_sf1[] = { MSG_ORIG(MSG_CMD_SF1), NULL };
1391d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_sf1[] = {
1392d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1393d29b2c44Sab196087 /* MSG_INTL(MSG_A1_SF1_VALUE) */
1394d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_SF1_VALUE),
1395d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
1396d29b2c44Sab196087 { NULL }
1397d29b2c44Sab196087 };
1398d29b2c44Sab196087
139908278a5eSRod Evans /* cap:hw2 */
140008278a5eSRod Evans static const char *name_hw2[] = { MSG_ORIG(MSG_CMD_HW2), NULL };
140108278a5eSRod Evans static elfedit_cmd_optarg_t arg_hw2[] = {
140208278a5eSRod Evans { MSG_ORIG(MSG_STR_VALUE),
140308278a5eSRod Evans /* MSG_INTL(MSG_A1_HW2_VALUE) */
140408278a5eSRod Evans ELFEDIT_I18NHDL(MSG_A1_HW2_VALUE),
140508278a5eSRod Evans ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
140608278a5eSRod Evans { NULL }
140708278a5eSRod Evans };
1408d29b2c44Sab196087
1409d29b2c44Sab196087
1410d29b2c44Sab196087 static elfedit_cmd_t cmds[] = {
1411d29b2c44Sab196087 /* cap:dump */
1412d29b2c44Sab196087 { cmd_dump, cpl_eltarg, name_dump,
1413d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */
1414d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP),
1415d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */
1416d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP),
141708278a5eSRod Evans opt_capid_capndx, arg_dump },
1418d29b2c44Sab196087
1419d29b2c44Sab196087 /* cap:tag */
1420d29b2c44Sab196087 { cmd_tag, cpl_tag, name_tag,
1421d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_TAG) */
1422d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_TAG),
1423d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_TAG) */
1424d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_TAG),
142508278a5eSRod Evans opt_tag, arg_tag },
1426d29b2c44Sab196087
1427d29b2c44Sab196087 /* cap:value */
1428d29b2c44Sab196087 { cmd_value, cpl_eltarg, name_value,
1429d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_VALUE) */
1430d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_VALUE),
1431d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_VALUE) */
1432d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_VALUE),
143308278a5eSRod Evans opt_value, arg_value },
1434d29b2c44Sab196087
1435d29b2c44Sab196087 /* cap:delete */
1436d29b2c44Sab196087 { cmd_delete, cpl_eltarg, name_delete,
1437d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */
1438d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE),
1439d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */
1440d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE),
144108278a5eSRod Evans opt_capid_capndx, arg_delete },
1442d29b2c44Sab196087
1443d29b2c44Sab196087 /* cap:move */
1444d29b2c44Sab196087 { cmd_move, cpl_eltarg, name_move,
1445d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */
1446d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE),
1447d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */
1448d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE),
144908278a5eSRod Evans opt_capid_capndx, arg_move },
1450d29b2c44Sab196087
1451d29b2c44Sab196087 /* cap:hw1 */
1452d29b2c44Sab196087 { cmd_hw1, cpl_hw1, name_hw1,
1453d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_HW1) */
1454d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_HW1),
1455d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_HW1) */
1456d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_HW1),
145708278a5eSRod Evans opt_ostyle_capid_bitop, arg_hw1 },
1458d29b2c44Sab196087
1459d29b2c44Sab196087 /* cap:sf1 */
1460d29b2c44Sab196087 { cmd_sf1, cpl_sf1, name_sf1,
1461d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_SF1) */
1462d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_SF1),
1463d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_SF1) */
1464d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_SF1),
146508278a5eSRod Evans opt_ostyle_capid_bitop, arg_sf1 },
146608278a5eSRod Evans
146708278a5eSRod Evans /* cap:hw2 */
146808278a5eSRod Evans { cmd_hw2, cpl_hw2, name_hw2,
146908278a5eSRod Evans /* MSG_INTL(MSG_DESC_HW2) */
147008278a5eSRod Evans ELFEDIT_I18NHDL(MSG_DESC_HW2),
147108278a5eSRod Evans /* MSG_INTL(MSG_HELP_HW2) */
147208278a5eSRod Evans ELFEDIT_I18NHDL(MSG_HELP_HW2),
147308278a5eSRod Evans opt_ostyle_capid_bitop, arg_hw2 },
1474d29b2c44Sab196087
1475d29b2c44Sab196087 { NULL }
1476d29b2c44Sab196087 };
1477d29b2c44Sab196087
1478d29b2c44Sab196087 static elfedit_module_t module = {
1479d29b2c44Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
1480d29b2c44Sab196087 /* MSG_INTL(MSG_MOD_DESC) */
1481d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC),
1482d29b2c44Sab196087 cmds, mod_i18nhdl_to_str };
1483d29b2c44Sab196087
1484d29b2c44Sab196087 return (&module);
1485d29b2c44Sab196087 }
1486