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 * 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 * 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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