1*5088Sab196087 /* 2*5088Sab196087 * CDDL HEADER START 3*5088Sab196087 * 4*5088Sab196087 * The contents of this file are subject to the terms of the 5*5088Sab196087 * Common Development and Distribution License (the "License"). 6*5088Sab196087 * You may not use this file except in compliance with the License. 7*5088Sab196087 * 8*5088Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5088Sab196087 * or http://www.opensolaris.org/os/licensing. 10*5088Sab196087 * See the License for the specific language governing permissions 11*5088Sab196087 * and limitations under the License. 12*5088Sab196087 * 13*5088Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 14*5088Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5088Sab196087 * If applicable, add the following below this CDDL HEADER, with the 16*5088Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 17*5088Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 18*5088Sab196087 * 19*5088Sab196087 * CDDL HEADER END 20*5088Sab196087 */ 21*5088Sab196087 22*5088Sab196087 /* 23*5088Sab196087 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5088Sab196087 * Use is subject to license terms. 25*5088Sab196087 */ 26*5088Sab196087 #pragma ident "%Z%%M% %I% %E% SMI" 27*5088Sab196087 28*5088Sab196087 #include <ctype.h> 29*5088Sab196087 #include <machdep.h> 30*5088Sab196087 #include <elfedit.h> 31*5088Sab196087 #include <sys/elf_SPARC.h> 32*5088Sab196087 #include <strings.h> 33*5088Sab196087 #include <debug.h> 34*5088Sab196087 #include <conv.h> 35*5088Sab196087 #include <cap_msg.h> 36*5088Sab196087 37*5088Sab196087 38*5088Sab196087 /* 39*5088Sab196087 * Capabilities section 40*5088Sab196087 */ 41*5088Sab196087 42*5088Sab196087 43*5088Sab196087 44*5088Sab196087 45*5088Sab196087 /* 46*5088Sab196087 * This module uses shared code for several of the commands. 47*5088Sab196087 * It is sometimes necessary to know which specific command 48*5088Sab196087 * is active. 49*5088Sab196087 */ 50*5088Sab196087 typedef enum { 51*5088Sab196087 /* Dump command, used as module default to display dynamic section */ 52*5088Sab196087 CAP_CMD_T_DUMP = 0, /* cap:dump */ 53*5088Sab196087 54*5088Sab196087 /* Commands that do not correspond directly to a specific DT tag */ 55*5088Sab196087 CAP_CMD_T_TAG = 1, /* cap:tag */ 56*5088Sab196087 CAP_CMD_T_VALUE = 2, /* cap:value */ 57*5088Sab196087 CAP_CMD_T_DELETE = 3, /* cap:delete */ 58*5088Sab196087 CAP_CMD_T_MOVE = 4, /* cap:shift */ 59*5088Sab196087 60*5088Sab196087 /* Commands that embody tag specific knowledge */ 61*5088Sab196087 CAP_CMD_T_HW1 = 5, /* cap:hw1 */ 62*5088Sab196087 CAP_CMD_T_SF1 = 6, /* cap:sf1 */ 63*5088Sab196087 } CAP_CMD_T; 64*5088Sab196087 65*5088Sab196087 66*5088Sab196087 67*5088Sab196087 #ifndef _ELF64 68*5088Sab196087 /* 69*5088Sab196087 * We supply this function for the msg module 70*5088Sab196087 */ 71*5088Sab196087 const char * 72*5088Sab196087 _cap_msg(Msg mid) 73*5088Sab196087 { 74*5088Sab196087 return (gettext(MSG_ORIG(mid))); 75*5088Sab196087 } 76*5088Sab196087 #endif 77*5088Sab196087 78*5088Sab196087 79*5088Sab196087 /* 80*5088Sab196087 * This function is supplied to elfedit through our elfedit_module_t 81*5088Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles 82*5088Sab196087 * in our module interface into the actual strings for elfedit to 83*5088Sab196087 * use. 84*5088Sab196087 * 85*5088Sab196087 * note: 86*5088Sab196087 * This module uses Msg codes for its i18n handle type. 87*5088Sab196087 * So the translation is simply to use MSG_INTL() to turn 88*5088Sab196087 * it into a string and return it. 89*5088Sab196087 */ 90*5088Sab196087 static const char * 91*5088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 92*5088Sab196087 { 93*5088Sab196087 Msg msg = (Msg)hdl; 94*5088Sab196087 95*5088Sab196087 return (MSG_INTL(msg)); 96*5088Sab196087 } 97*5088Sab196087 98*5088Sab196087 99*5088Sab196087 100*5088Sab196087 /* 101*5088Sab196087 * The cap_opt_t enum specifies a bit value for every optional 102*5088Sab196087 * argument allowed by a command in this module. 103*5088Sab196087 */ 104*5088Sab196087 typedef enum { 105*5088Sab196087 CAP_OPT_F_AND = 1, /* -and: AND (&) values to dest */ 106*5088Sab196087 CAP_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ 107*5088Sab196087 CAP_OPT_F_CAPNDX = 4, /* -capndx: elt is tag index, */ 108*5088Sab196087 /* not name */ 109*5088Sab196087 CAP_OPT_F_OR = 8, /* -or: OR (|) values to dest */ 110*5088Sab196087 } cap_opt_t; 111*5088Sab196087 112*5088Sab196087 113*5088Sab196087 /* 114*5088Sab196087 * A variable of type ARGSTATE is used by each command to maintain 115*5088Sab196087 * information about the arguments and related things. It is 116*5088Sab196087 * initialized by process_args(), and used by the other routines. 117*5088Sab196087 */ 118*5088Sab196087 typedef struct { 119*5088Sab196087 elfedit_obj_state_t *obj_state; 120*5088Sab196087 struct { 121*5088Sab196087 elfedit_section_t *sec; /* Capabilities section reference */ 122*5088Sab196087 Cap *data; /* Start of capabilities section data */ 123*5088Sab196087 Word num; /* # Capabilities elts */ 124*5088Sab196087 } cap; 125*5088Sab196087 cap_opt_t optmask; /* Mask of options used */ 126*5088Sab196087 int argc; /* # of plain arguments */ 127*5088Sab196087 const char **argv; /* Plain arguments */ 128*5088Sab196087 } ARGSTATE; 129*5088Sab196087 130*5088Sab196087 131*5088Sab196087 132*5088Sab196087 /* 133*5088Sab196087 * Standard argument processing for cap module 134*5088Sab196087 * 135*5088Sab196087 * entry 136*5088Sab196087 * obj_state, argc, argv - Standard command arguments 137*5088Sab196087 * argstate - Address of ARGSTATE block to be initialized 138*5088Sab196087 * 139*5088Sab196087 * exit: 140*5088Sab196087 * On success, *argstate is initialized. On error, 141*5088Sab196087 * an error is issued and this routine does not return. 142*5088Sab196087 */ 143*5088Sab196087 static void 144*5088Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 145*5088Sab196087 ARGSTATE *argstate) 146*5088Sab196087 { 147*5088Sab196087 elfedit_getopt_state_t getopt_state; 148*5088Sab196087 elfedit_getopt_ret_t *getopt_ret; 149*5088Sab196087 150*5088Sab196087 bzero(argstate, sizeof (*argstate)); 151*5088Sab196087 argstate->obj_state = obj_state; 152*5088Sab196087 153*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 154*5088Sab196087 155*5088Sab196087 /* Add each new option to the options mask */ 156*5088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) 157*5088Sab196087 argstate->optmask |= getopt_ret->gor_idmask; 158*5088Sab196087 159*5088Sab196087 /* If there may be an arbitrary amount of output, use a pager */ 160*5088Sab196087 if (argc == 0) 161*5088Sab196087 elfedit_pager_init(); 162*5088Sab196087 163*5088Sab196087 /* Return the updated values of argc/argv */ 164*5088Sab196087 argstate->argc = argc; 165*5088Sab196087 argstate->argv = argv; 166*5088Sab196087 167*5088Sab196087 /* Locate the capabilities section */ 168*5088Sab196087 argstate->cap.sec = elfedit_sec_getcap(obj_state, &argstate->cap.data, 169*5088Sab196087 &argstate->cap.num); 170*5088Sab196087 } 171*5088Sab196087 172*5088Sab196087 173*5088Sab196087 174*5088Sab196087 /* 175*5088Sab196087 * Print ELF capabilities values, taking the calling command, and output style 176*5088Sab196087 * into account. 177*5088Sab196087 * 178*5088Sab196087 * entry: 179*5088Sab196087 * cmd - CAP_CMD_T_* value giving identify of caller 180*5088Sab196087 * autoprint - If True, output is only produced if the elfedit 181*5088Sab196087 * autoprint flag is set. If False, output is always produced. 182*5088Sab196087 * argstate - Argument state block 183*5088Sab196087 * print_type - Specifies which capabilities elements to display. 184*5088Sab196087 * ndx = If print_type is PRINT_CAP_T_NDX, displays the index specified. 185*5088Sab196087 * Otherwise ignored. 186*5088Sab196087 */ 187*5088Sab196087 typedef enum { 188*5088Sab196087 PRINT_CAP_T_ALL = 0, /* Show all indexes */ 189*5088Sab196087 PRINT_CAP_T_NDX = 1, /* Show capabilities[arg] only */ 190*5088Sab196087 PRINT_CAP_T_TAG = 2 /* Show all elts with tag type */ 191*5088Sab196087 /* given by arg */ 192*5088Sab196087 } PRINT_CAP_T; 193*5088Sab196087 194*5088Sab196087 static void 195*5088Sab196087 print_cap(CAP_CMD_T cmd, int autoprint, ARGSTATE *argstate, 196*5088Sab196087 PRINT_CAP_T print_type, Word arg) 197*5088Sab196087 { 198*5088Sab196087 elfedit_outstyle_t outstyle; 199*5088Sab196087 Word cnt, ndx, printed = 0; 200*5088Sab196087 Cap *cap; 201*5088Sab196087 int header_done = 0; 202*5088Sab196087 Xword last_c_val = 0; 203*5088Sab196087 204*5088Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) 205*5088Sab196087 return; 206*5088Sab196087 207*5088Sab196087 /* 208*5088Sab196087 * Pick an output style. cap:dump is required to use the default 209*5088Sab196087 * style. The other commands use the current output style. 210*5088Sab196087 */ 211*5088Sab196087 outstyle = (cmd == CAP_CMD_T_DUMP) ? 212*5088Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle(); 213*5088Sab196087 214*5088Sab196087 /* How many elements do we examine? */ 215*5088Sab196087 if (print_type == PRINT_CAP_T_NDX) { 216*5088Sab196087 if (arg >= argstate->cap.num) 217*5088Sab196087 return; /* Out of range */ 218*5088Sab196087 ndx = arg; 219*5088Sab196087 cnt = 1; 220*5088Sab196087 } else { 221*5088Sab196087 ndx = 0; 222*5088Sab196087 cnt = argstate->cap.num; 223*5088Sab196087 } 224*5088Sab196087 225*5088Sab196087 cap = &argstate->cap.data[ndx]; 226*5088Sab196087 for (; cnt--; cap++, ndx++) { 227*5088Sab196087 /* 228*5088Sab196087 * If we are only displaying certain tag types and 229*5088Sab196087 * this isn't one of those, move on to next element. 230*5088Sab196087 */ 231*5088Sab196087 if ((print_type == PRINT_CAP_T_TAG) && (cap->c_tag != arg)) 232*5088Sab196087 continue; 233*5088Sab196087 234*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { 235*5088Sab196087 if (header_done == 0) { 236*5088Sab196087 header_done = 1; 237*5088Sab196087 Elf_cap_title(0); 238*5088Sab196087 } 239*5088Sab196087 Elf_cap_entry(NULL, cap, ndx, 240*5088Sab196087 argstate->obj_state->os_ehdr->e_machine); 241*5088Sab196087 } else { 242*5088Sab196087 /* 243*5088Sab196087 * In simple or numeric mode under a print type 244*5088Sab196087 * that is based on tag type rather than on index, 245*5088Sab196087 * quietly: If we've already printed this value, 246*5088Sab196087 * don't print it again. A common example of this 247*5088Sab196087 * is PRINT_CAP_T_RUNPATH when both CA_RPATH and 248*5088Sab196087 * CA_RUNPATH are present with the same value. 249*5088Sab196087 */ 250*5088Sab196087 if ((print_type == PRINT_CAP_T_TAG) && printed && 251*5088Sab196087 (last_c_val == cap->c_un.c_val)) 252*5088Sab196087 continue; 253*5088Sab196087 254*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 255*5088Sab196087 union { 256*5088Sab196087 Conv_cap_val_hw1_buf_t hw1; 257*5088Sab196087 Conv_cap_val_sf1_buf_t sf1; 258*5088Sab196087 } c_buf; 259*5088Sab196087 260*5088Sab196087 switch (cap->c_tag) { 261*5088Sab196087 case CA_SUNW_HW_1: 262*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 263*5088Sab196087 conv_cap_val_hw1(cap->c_un.c_val, 264*5088Sab196087 argstate->obj_state->os_ehdr-> 265*5088Sab196087 e_machine, 266*5088Sab196087 CONV_FMT_NOBKT, &c_buf.hw1)); 267*5088Sab196087 printed = 1; 268*5088Sab196087 continue; 269*5088Sab196087 case CA_SUNW_SF_1: 270*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 271*5088Sab196087 conv_cap_val_sf1(cap->c_un.c_val, 272*5088Sab196087 argstate->obj_state->os_ehdr-> 273*5088Sab196087 e_machine, 274*5088Sab196087 CONV_FMT_NOBKT, &c_buf.sf1)); 275*5088Sab196087 printed = 1; 276*5088Sab196087 continue; 277*5088Sab196087 } 278*5088Sab196087 } 279*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_HEXXWORDNL), 280*5088Sab196087 cap->c_un.c_val); 281*5088Sab196087 } 282*5088Sab196087 printed = 1; 283*5088Sab196087 last_c_val = cap->c_un.c_val; 284*5088Sab196087 } 285*5088Sab196087 286*5088Sab196087 /* 287*5088Sab196087 * If nothing was output under the print types that are 288*5088Sab196087 * based on tag type, issue an error saying it doesn't exist. 289*5088Sab196087 */ 290*5088Sab196087 if (!printed && (print_type == PRINT_CAP_T_TAG)) { 291*5088Sab196087 Conv_inv_buf_t inv_buf; 292*5088Sab196087 293*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT), 294*5088Sab196087 EC_WORD(argstate->cap.sec->sec_shndx), 295*5088Sab196087 argstate->cap.sec->sec_name, conv_cap_tag(arg, &inv_buf)); 296*5088Sab196087 } 297*5088Sab196087 } 298*5088Sab196087 299*5088Sab196087 300*5088Sab196087 /* 301*5088Sab196087 * Process the elt argument: This will be a tag type if -capndx is 302*5088Sab196087 * not present and this is a print request. It will be an index otherwise. 303*5088Sab196087 * 304*5088Sab196087 * entry: 305*5088Sab196087 * argstate - Argument state block 306*5088Sab196087 * arg - Argument string to be converted into an index 307*5088Sab196087 * argname - String giving the name by which the argument is 308*5088Sab196087 * referred in the online help for the command. 309*5088Sab196087 * print_request - True if the command is to print the current 310*5088Sab196087 * value(s) and return without changing anything. 311*5088Sab196087 * print_type - Address of variable containing PRINT_CAP_T_ 312*5088Sab196087 * code specifying how the elements will be displayed. 313*5088Sab196087 * 314*5088Sab196087 * exit: 315*5088Sab196087 * If print_request is False: arg is converted into an integer value. 316*5088Sab196087 * If -capndx was used, we convert it into an integer. If it was not 317*5088Sab196087 * used, then arg is a tag name --- we find the first capabilities entry 318*5088Sab196087 * that matches. If no entry matches, and there is an extra CA_NULL, 319*5088Sab196087 * it is added. Otherwise an error is issued. *print_type is set 320*5088Sab196087 * to PRINT_CAP_T_NDX. 321*5088Sab196087 * 322*5088Sab196087 * If print_request is True: If -capndx was used, arg is converted into 323*5088Sab196087 * an integer value, *print_type is set to PRINT_CAP_T_NDX, and 324*5088Sab196087 * the value is returned. If -capndx was not used, *print_type is set to 325*5088Sab196087 * PRINT_CAP_T_TAG, and the tag value is returned. 326*5088Sab196087 */ 327*5088Sab196087 static Word 328*5088Sab196087 arg_to_index(ARGSTATE *argstate, const char *arg, const char *argname, 329*5088Sab196087 int print_request, PRINT_CAP_T *print_type) 330*5088Sab196087 { 331*5088Sab196087 Word ndx, ca_value; 332*5088Sab196087 333*5088Sab196087 334*5088Sab196087 /* Assume we are returning an index, alter as needed below */ 335*5088Sab196087 *print_type = PRINT_CAP_T_NDX; 336*5088Sab196087 337*5088Sab196087 /* If -capndx was used, this is a simple numeric index */ 338*5088Sab196087 if ((argstate->optmask & CAP_OPT_F_CAPNDX) != 0) 339*5088Sab196087 return ((Word) elfedit_atoui_range(arg, argname, 0, 340*5088Sab196087 argstate->cap.num - 1, NULL)); 341*5088Sab196087 342*5088Sab196087 /* The argument is a CA_ tag type, not a numeric index */ 343*5088Sab196087 ca_value = (Word) elfedit_atoconst(arg, ELFEDIT_CONST_CA); 344*5088Sab196087 345*5088Sab196087 /* 346*5088Sab196087 * If this is a printing request, then we let print_cap() show 347*5088Sab196087 * all the items with this tag type. 348*5088Sab196087 */ 349*5088Sab196087 if (print_request) { 350*5088Sab196087 *print_type = PRINT_CAP_T_TAG; 351*5088Sab196087 return (ca_value); 352*5088Sab196087 } 353*5088Sab196087 354*5088Sab196087 /* Locate the first entry with the given tag type */ 355*5088Sab196087 for (ndx = 0; ndx < argstate->cap.num; ndx++) { 356*5088Sab196087 if (argstate->cap.data[ndx].c_tag == ca_value) { 357*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 358*5088Sab196087 MSG_INTL(MSG_DEBUG_CA2NDX), 359*5088Sab196087 EC_WORD(argstate->cap.sec->sec_shndx), 360*5088Sab196087 argstate->cap.sec->sec_name, EC_WORD(ndx), arg); 361*5088Sab196087 return (ndx); 362*5088Sab196087 } 363*5088Sab196087 } 364*5088Sab196087 365*5088Sab196087 /* No room to create one, so we're out of options and must fail */ 366*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT), 367*5088Sab196087 EC_WORD(argstate->cap.sec->sec_shndx), 368*5088Sab196087 argstate->cap.sec->sec_name, arg); 369*5088Sab196087 370*5088Sab196087 /*NOTREACHED*/ 371*5088Sab196087 return (0); /* For lint */ 372*5088Sab196087 } 373*5088Sab196087 374*5088Sab196087 375*5088Sab196087 /* 376*5088Sab196087 * Argument processing for the bitmask commands. Convert the arguments 377*5088Sab196087 * to integer form, apply -and/-cmp/-or, and return the resulting value. 378*5088Sab196087 * 379*5088Sab196087 * entry: 380*5088Sab196087 * argstate - Argument state block 381*5088Sab196087 * orig - Value of original bitmask 382*5088Sab196087 * const_sym - NULL, or array of name->integer mappings for 383*5088Sab196087 * applicable symbolic constant names. 384*5088Sab196087 */ 385*5088Sab196087 static Word 386*5088Sab196087 flag_bitop(ARGSTATE *argstate, Word orig, const elfedit_atoui_sym_t *const_sym) 387*5088Sab196087 { 388*5088Sab196087 Word flags = 0; 389*5088Sab196087 int i; 390*5088Sab196087 391*5088Sab196087 /* Collect the arguments */ 392*5088Sab196087 for (i = 0; i < argstate->argc; i++) 393*5088Sab196087 flags |= (Word) elfedit_atoui(argstate->argv[i], const_sym); 394*5088Sab196087 395*5088Sab196087 /* Complement the value? */ 396*5088Sab196087 if (argstate->optmask & CAP_OPT_F_CMP) 397*5088Sab196087 flags = ~flags; 398*5088Sab196087 399*5088Sab196087 /* Perform any requested bit operations */ 400*5088Sab196087 if (argstate->optmask & CAP_OPT_F_AND) 401*5088Sab196087 flags &= orig; 402*5088Sab196087 else if (argstate->optmask & CAP_OPT_F_OR) 403*5088Sab196087 flags |= orig; 404*5088Sab196087 405*5088Sab196087 return (flags); 406*5088Sab196087 } 407*5088Sab196087 408*5088Sab196087 409*5088Sab196087 410*5088Sab196087 /* 411*5088Sab196087 * Common body for the cap: module commands. These commands 412*5088Sab196087 * share a large amount of common behavior, so it is convenient 413*5088Sab196087 * to centralize things and use the cmd argument to handle the 414*5088Sab196087 * small differences. 415*5088Sab196087 * 416*5088Sab196087 * entry: 417*5088Sab196087 * cmd - One of the CAP_CMD_T_* constants listed above, specifying 418*5088Sab196087 * which command to implement. 419*5088Sab196087 * obj_state, argc, argv - Standard command arguments 420*5088Sab196087 */ 421*5088Sab196087 static elfedit_cmdret_t 422*5088Sab196087 cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state, 423*5088Sab196087 int argc, const char *argv[]) 424*5088Sab196087 { 425*5088Sab196087 ARGSTATE argstate; 426*5088Sab196087 Cap *cap; 427*5088Sab196087 const char *cap_name; 428*5088Sab196087 Word cap_ndx, cap_num; 429*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 430*5088Sab196087 PRINT_CAP_T print_type = PRINT_CAP_T_ALL; 431*5088Sab196087 Word ndx; 432*5088Sab196087 int print_only = 0; 433*5088Sab196087 int do_autoprint = 1; 434*5088Sab196087 435*5088Sab196087 /* Process the optional arguments */ 436*5088Sab196087 process_args(obj_state, argc, argv, &argstate); 437*5088Sab196087 438*5088Sab196087 cap = argstate.cap.data; 439*5088Sab196087 cap_num = argstate.cap.num; 440*5088Sab196087 cap_name = argstate.cap.sec->sec_name; 441*5088Sab196087 cap_ndx = argstate.cap.sec->sec_shndx; 442*5088Sab196087 443*5088Sab196087 /* Check number of arguments, gather information */ 444*5088Sab196087 switch (cmd) { 445*5088Sab196087 case CAP_CMD_T_DUMP: 446*5088Sab196087 /* cap:dump can accept an optional index argument */ 447*5088Sab196087 if (argstate.argc > 1) 448*5088Sab196087 elfedit_command_usage(); 449*5088Sab196087 print_only = 1; 450*5088Sab196087 if (argstate.argc == 1) 451*5088Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0], 452*5088Sab196087 MSG_ORIG(MSG_STR_ELT), print_only, &print_type); 453*5088Sab196087 break; 454*5088Sab196087 455*5088Sab196087 case CAP_CMD_T_TAG: 456*5088Sab196087 case CAP_CMD_T_VALUE: 457*5088Sab196087 print_only = (argstate.argc != 2); 458*5088Sab196087 if (argstate.argc > 0) { 459*5088Sab196087 if (argstate.argc > 2) 460*5088Sab196087 elfedit_command_usage(); 461*5088Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0], 462*5088Sab196087 MSG_ORIG(MSG_STR_ELT), print_only, &print_type); 463*5088Sab196087 } 464*5088Sab196087 break; 465*5088Sab196087 466*5088Sab196087 case CAP_CMD_T_DELETE: 467*5088Sab196087 if ((argstate.argc < 1) || (argstate.argc > 2)) 468*5088Sab196087 elfedit_command_usage(); 469*5088Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0], 470*5088Sab196087 MSG_ORIG(MSG_STR_ELT), 471*5088Sab196087 0, &print_type); 472*5088Sab196087 do_autoprint = 0; 473*5088Sab196087 break; 474*5088Sab196087 475*5088Sab196087 case CAP_CMD_T_MOVE: 476*5088Sab196087 if ((argstate.argc < 2) || (argstate.argc > 3)) 477*5088Sab196087 elfedit_command_usage(); 478*5088Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0], 479*5088Sab196087 MSG_ORIG(MSG_STR_ELT), 0, &print_type); 480*5088Sab196087 do_autoprint = 0; 481*5088Sab196087 break; 482*5088Sab196087 483*5088Sab196087 case CAP_CMD_T_HW1: 484*5088Sab196087 print_only = (argstate.argc == 0); 485*5088Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str( 486*5088Sab196087 ELFEDIT_CONST_CA, CA_SUNW_HW_1, 1), 487*5088Sab196087 MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); 488*5088Sab196087 break; 489*5088Sab196087 490*5088Sab196087 case CAP_CMD_T_SF1: 491*5088Sab196087 print_only = (argstate.argc == 0); 492*5088Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str( 493*5088Sab196087 ELFEDIT_CONST_CA, CA_SUNW_SF_1, 1), 494*5088Sab196087 MSG_ORIG(MSG_STR_VALUE), print_only, &print_type); 495*5088Sab196087 break; 496*5088Sab196087 497*5088Sab196087 default: 498*5088Sab196087 /* Note expected: All commands should have been caught above */ 499*5088Sab196087 elfedit_command_usage(); 500*5088Sab196087 break; 501*5088Sab196087 } 502*5088Sab196087 503*5088Sab196087 504*5088Sab196087 /* If this is a request to print current values, do it and return */ 505*5088Sab196087 if (print_only) { 506*5088Sab196087 print_cap(cmd, 0, &argstate, print_type, ndx); 507*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 508*5088Sab196087 } 509*5088Sab196087 510*5088Sab196087 511*5088Sab196087 switch (cmd) { 512*5088Sab196087 /* 513*5088Sab196087 * CAP_CMD_T_DUMP can't get here: It is a print-only 514*5088Sab196087 * command. 515*5088Sab196087 */ 516*5088Sab196087 517*5088Sab196087 case CAP_CMD_T_TAG: 518*5088Sab196087 { 519*5088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 520*5088Sab196087 Word c_tag = (Word) elfedit_atoconst(argstate.argv[1], 521*5088Sab196087 ELFEDIT_CONST_CA); 522*5088Sab196087 523*5088Sab196087 if (cap[ndx].c_tag == c_tag) { 524*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 525*5088Sab196087 MSG_INTL(MSG_DEBUG_S_OK), 526*5088Sab196087 cap_ndx, cap_name, EC_WORD(ndx), 527*5088Sab196087 conv_cap_tag(c_tag, &inv_buf1)); 528*5088Sab196087 } else { 529*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 530*5088Sab196087 MSG_INTL(MSG_DEBUG_S_CHG), 531*5088Sab196087 cap_ndx, cap_name, EC_WORD(ndx), 532*5088Sab196087 conv_cap_tag(cap[ndx].c_tag, &inv_buf1), 533*5088Sab196087 conv_cap_tag(c_tag, &inv_buf2)); 534*5088Sab196087 cap[ndx].c_tag = c_tag; 535*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 536*5088Sab196087 } 537*5088Sab196087 } 538*5088Sab196087 break; 539*5088Sab196087 540*5088Sab196087 case CAP_CMD_T_VALUE: 541*5088Sab196087 { 542*5088Sab196087 Xword c_val = (Xword) 543*5088Sab196087 elfedit_atoui(argstate.argv[1], NULL); 544*5088Sab196087 545*5088Sab196087 if (cap[ndx].c_un.c_val == c_val) { 546*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 547*5088Sab196087 MSG_INTL(MSG_DEBUG_X_OK), 548*5088Sab196087 argstate.cap.sec->sec_shndx, 549*5088Sab196087 argstate.cap.sec->sec_name, 550*5088Sab196087 EC_WORD(ndx), EC_XWORD(c_val)); 551*5088Sab196087 } else { 552*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 553*5088Sab196087 MSG_INTL(MSG_DEBUG_X_CHG), 554*5088Sab196087 argstate.cap.sec->sec_shndx, 555*5088Sab196087 argstate.cap.sec->sec_name, 556*5088Sab196087 EC_WORD(ndx), EC_XWORD(cap[ndx].c_un.c_val), 557*5088Sab196087 EC_XWORD(c_val)); 558*5088Sab196087 cap[ndx].c_un.c_val = c_val; 559*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 560*5088Sab196087 } 561*5088Sab196087 } 562*5088Sab196087 break; 563*5088Sab196087 564*5088Sab196087 case CAP_CMD_T_DELETE: 565*5088Sab196087 { 566*5088Sab196087 Word cnt = (argstate.argc == 1) ? 1 : 567*5088Sab196087 (Word) elfedit_atoui_range(argstate.argv[1], 568*5088Sab196087 MSG_ORIG(MSG_STR_COUNT), 1, cap_num - ndx, NULL); 569*5088Sab196087 const char *msg_prefix = 570*5088Sab196087 elfedit_sec_msgprefix(argstate.cap.sec); 571*5088Sab196087 572*5088Sab196087 elfedit_array_elts_delete(msg_prefix, argstate.cap.data, 573*5088Sab196087 sizeof (Cap), cap_num, ndx, cnt); 574*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 575*5088Sab196087 } 576*5088Sab196087 break; 577*5088Sab196087 578*5088Sab196087 case CAP_CMD_T_MOVE: 579*5088Sab196087 { 580*5088Sab196087 Cap save; 581*5088Sab196087 Word cnt; 582*5088Sab196087 Word dstndx; 583*5088Sab196087 const char *msg_prefix = 584*5088Sab196087 elfedit_sec_msgprefix(argstate.cap.sec); 585*5088Sab196087 586*5088Sab196087 dstndx = (Word) 587*5088Sab196087 elfedit_atoui_range(argstate.argv[1], 588*5088Sab196087 MSG_ORIG(MSG_STR_DST_INDEX), 0, cap_num - 1, 589*5088Sab196087 NULL); 590*5088Sab196087 if (argstate.argc == 2) { 591*5088Sab196087 cnt = 1; 592*5088Sab196087 } else { 593*5088Sab196087 cnt = (Word) elfedit_atoui_range( 594*5088Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT), 595*5088Sab196087 1, cap_num, NULL); 596*5088Sab196087 } 597*5088Sab196087 elfedit_array_elts_move(msg_prefix, argstate.cap.data, 598*5088Sab196087 sizeof (save), cap_num, ndx, dstndx, cnt, &save); 599*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 600*5088Sab196087 } 601*5088Sab196087 break; 602*5088Sab196087 603*5088Sab196087 604*5088Sab196087 case CAP_CMD_T_HW1: 605*5088Sab196087 { 606*5088Sab196087 Conv_cap_val_hw1_buf_t buf1, buf2; 607*5088Sab196087 Half mach = argstate.obj_state->os_ehdr->e_machine; 608*5088Sab196087 Xword hw1; 609*5088Sab196087 610*5088Sab196087 hw1 = flag_bitop(&argstate, cap[ndx].c_un.c_val, 611*5088Sab196087 elfedit_mach_sunw_hw1_to_atoui(mach)); 612*5088Sab196087 613*5088Sab196087 /* Set the value */ 614*5088Sab196087 if (cap[ndx].c_un.c_val == hw1) { 615*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 616*5088Sab196087 MSG_INTL(MSG_DEBUG_BSB_OK), cap_ndx, 617*5088Sab196087 cap_name, EC_WORD(ndx), 618*5088Sab196087 conv_cap_val_hw1(cap[ndx].c_un.c_val, mach, 619*5088Sab196087 CONV_FMT_NOBKT, &buf1)); 620*5088Sab196087 } else { 621*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 622*5088Sab196087 MSG_INTL(MSG_DEBUG_BSB_CHG), 623*5088Sab196087 cap_ndx, cap_name, EC_WORD(ndx), 624*5088Sab196087 conv_cap_val_hw1(cap[ndx].c_un.c_val, mach, 625*5088Sab196087 CONV_FMT_NOBKT, &buf1), 626*5088Sab196087 conv_cap_val_hw1(hw1, mach, 627*5088Sab196087 CONV_FMT_NOBKT, &buf2)); 628*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 629*5088Sab196087 cap[ndx].c_un.c_val = hw1; 630*5088Sab196087 } 631*5088Sab196087 } 632*5088Sab196087 break; 633*5088Sab196087 634*5088Sab196087 case CAP_CMD_T_SF1: 635*5088Sab196087 { 636*5088Sab196087 Conv_cap_val_sf1_buf_t buf1, buf2; 637*5088Sab196087 Half mach = argstate.obj_state->os_ehdr->e_machine; 638*5088Sab196087 Xword sf1; 639*5088Sab196087 640*5088Sab196087 sf1 = flag_bitop(&argstate, cap[ndx].c_un.c_val, 641*5088Sab196087 elfedit_const_to_atoui(ELFEDIT_CONST_SF1_SUNW)); 642*5088Sab196087 643*5088Sab196087 /* Set the value */ 644*5088Sab196087 if (cap[ndx].c_un.c_val == sf1) { 645*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 646*5088Sab196087 MSG_INTL(MSG_DEBUG_BSB_OK), cap_ndx, 647*5088Sab196087 cap_name, EC_WORD(ndx), 648*5088Sab196087 conv_cap_val_sf1(cap[ndx].c_un.c_val, mach, 649*5088Sab196087 CONV_FMT_NOBKT, &buf1)); 650*5088Sab196087 } else { 651*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 652*5088Sab196087 MSG_INTL(MSG_DEBUG_BSB_CHG), 653*5088Sab196087 cap_ndx, cap_name, EC_WORD(ndx), 654*5088Sab196087 conv_cap_val_sf1(cap[ndx].c_un.c_val, mach, 655*5088Sab196087 CONV_FMT_NOBKT, &buf1), 656*5088Sab196087 conv_cap_val_sf1(sf1, mach, 657*5088Sab196087 CONV_FMT_NOBKT, &buf2)); 658*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 659*5088Sab196087 cap[ndx].c_un.c_val = sf1; 660*5088Sab196087 } 661*5088Sab196087 } 662*5088Sab196087 break; 663*5088Sab196087 } 664*5088Sab196087 665*5088Sab196087 /* 666*5088Sab196087 * If we modified the capabilities section header, tell libelf. 667*5088Sab196087 */ 668*5088Sab196087 if (ret == ELFEDIT_CMDRET_MOD) 669*5088Sab196087 elfedit_modified_data(argstate.cap.sec); 670*5088Sab196087 671*5088Sab196087 /* Do autoprint */ 672*5088Sab196087 if (do_autoprint) 673*5088Sab196087 print_cap(cmd, 1, &argstate, print_type, ndx); 674*5088Sab196087 675*5088Sab196087 return (ret); 676*5088Sab196087 } 677*5088Sab196087 678*5088Sab196087 679*5088Sab196087 680*5088Sab196087 /* 681*5088Sab196087 * Command completion functions for the commands 682*5088Sab196087 */ 683*5088Sab196087 684*5088Sab196087 /* 685*5088Sab196087 * Command completion for the first argument, which specifies 686*5088Sab196087 * the capabilities element to use. Examines the options to see if 687*5088Sab196087 * -capndx is present, and if not, supplies the completion 688*5088Sab196087 * strings for argument 1. 689*5088Sab196087 */ 690*5088Sab196087 /*ARGSUSED*/ 691*5088Sab196087 static void 692*5088Sab196087 cpl_eltarg(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 693*5088Sab196087 const char *argv[], int num_opt) 694*5088Sab196087 { 695*5088Sab196087 Word i; 696*5088Sab196087 697*5088Sab196087 /* Make sure it's the first argument */ 698*5088Sab196087 if ((argc - num_opt) != 1) 699*5088Sab196087 return; 700*5088Sab196087 701*5088Sab196087 /* Is -capndx present? If so, we don't complete tag types */ 702*5088Sab196087 for (i = 0; i < num_opt; i++) 703*5088Sab196087 if (strcmp(argv[i], MSG_ORIG(MSG_STR_MINUS_CAPNDX)) == 0) 704*5088Sab196087 return; 705*5088Sab196087 706*5088Sab196087 /* 707*5088Sab196087 * Supply capability tag names. There are very few of these, so 708*5088Sab196087 * rather than worry about whether a given tag exists in the 709*5088Sab196087 * file or not, we simply serve up all the possibilities. 710*5088Sab196087 */ 711*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA); 712*5088Sab196087 } 713*5088Sab196087 714*5088Sab196087 715*5088Sab196087 /*ARGSUSED*/ 716*5088Sab196087 static void 717*5088Sab196087 cpl_tag(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 718*5088Sab196087 const char *argv[], int num_opt) 719*5088Sab196087 { 720*5088Sab196087 /* First argument */ 721*5088Sab196087 if ((argc - num_opt) == 1) { 722*5088Sab196087 cpl_eltarg(obj_state, cpldata, argc, argv, num_opt); 723*5088Sab196087 return; 724*5088Sab196087 } 725*5088Sab196087 726*5088Sab196087 /* The second argument is always a tag value */ 727*5088Sab196087 if ((argc - num_opt) == 2) 728*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA); 729*5088Sab196087 } 730*5088Sab196087 731*5088Sab196087 /*ARGSUSED*/ 732*5088Sab196087 static void 733*5088Sab196087 cpl_hw1(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 734*5088Sab196087 const char *argv[], int num_opt) 735*5088Sab196087 { 736*5088Sab196087 elfedit_atoui_sym_t *sym_const; 737*5088Sab196087 738*5088Sab196087 /* This routine allows multiple flags to be specified */ 739*5088Sab196087 740*5088Sab196087 /* 741*5088Sab196087 * If there is no object, then supply all the hardware 742*5088Sab196087 * capabilities we know of. 743*5088Sab196087 */ 744*5088Sab196087 if (obj_state == NULL) { 745*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_AV_386); 746*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_AV_SPARC); 747*5088Sab196087 return; 748*5088Sab196087 } 749*5088Sab196087 750*5088Sab196087 /* 751*5088Sab196087 * Supply the hardware capabilities for the type of 752*5088Sab196087 * machine the object is for, if we know any. 753*5088Sab196087 */ 754*5088Sab196087 sym_const = elfedit_mach_sunw_hw1_to_atoui( 755*5088Sab196087 obj_state->os_ehdr->e_machine); 756*5088Sab196087 if (sym_const != NULL) 757*5088Sab196087 elfedit_cpl_atoui(cpldata, sym_const); 758*5088Sab196087 } 759*5088Sab196087 760*5088Sab196087 /*ARGSUSED*/ 761*5088Sab196087 static void 762*5088Sab196087 cpl_sf1(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 763*5088Sab196087 const char *argv[], int num_opt) 764*5088Sab196087 { 765*5088Sab196087 /* This routine allows multiple flags to be specified */ 766*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SF1_SUNW); 767*5088Sab196087 } 768*5088Sab196087 769*5088Sab196087 770*5088Sab196087 /* 771*5088Sab196087 * Implementation functions for the commands 772*5088Sab196087 */ 773*5088Sab196087 static elfedit_cmdret_t 774*5088Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 775*5088Sab196087 { 776*5088Sab196087 return (cmd_body(CAP_CMD_T_DUMP, obj_state, argc, argv)); 777*5088Sab196087 } 778*5088Sab196087 779*5088Sab196087 static elfedit_cmdret_t 780*5088Sab196087 cmd_tag(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 781*5088Sab196087 { 782*5088Sab196087 return (cmd_body(CAP_CMD_T_TAG, obj_state, argc, argv)); 783*5088Sab196087 } 784*5088Sab196087 785*5088Sab196087 static elfedit_cmdret_t 786*5088Sab196087 cmd_value(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 787*5088Sab196087 { 788*5088Sab196087 return (cmd_body(CAP_CMD_T_VALUE, obj_state, argc, argv)); 789*5088Sab196087 } 790*5088Sab196087 791*5088Sab196087 static elfedit_cmdret_t 792*5088Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 793*5088Sab196087 { 794*5088Sab196087 return (cmd_body(CAP_CMD_T_DELETE, obj_state, argc, argv)); 795*5088Sab196087 } 796*5088Sab196087 797*5088Sab196087 static elfedit_cmdret_t 798*5088Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 799*5088Sab196087 { 800*5088Sab196087 return (cmd_body(CAP_CMD_T_MOVE, obj_state, argc, argv)); 801*5088Sab196087 } 802*5088Sab196087 803*5088Sab196087 static elfedit_cmdret_t 804*5088Sab196087 cmd_hw1(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 805*5088Sab196087 { 806*5088Sab196087 return (cmd_body(CAP_CMD_T_HW1, obj_state, argc, argv)); 807*5088Sab196087 } 808*5088Sab196087 809*5088Sab196087 static elfedit_cmdret_t 810*5088Sab196087 cmd_sf1(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 811*5088Sab196087 { 812*5088Sab196087 return (cmd_body(CAP_CMD_T_SF1, obj_state, argc, argv)); 813*5088Sab196087 } 814*5088Sab196087 815*5088Sab196087 816*5088Sab196087 817*5088Sab196087 /*ARGSUSED*/ 818*5088Sab196087 elfedit_module_t * 819*5088Sab196087 elfedit_init(elfedit_module_version_t version) 820*5088Sab196087 { 821*5088Sab196087 /* For commands that only accept -and, -cmp, -o, and -or */ 822*5088Sab196087 static elfedit_cmd_optarg_t opt_ostyle_bitop[] = { 823*5088Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL, 824*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_AND, CAP_OPT_F_OR }, 825*5088Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL, 826*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_CMP, 0 }, 827*5088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 828*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 829*5088Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL, 830*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_OR, CAP_OPT_F_AND }, 831*5088Sab196087 { NULL } 832*5088Sab196087 }; 833*5088Sab196087 834*5088Sab196087 /* For commands that only accept -capndx */ 835*5088Sab196087 static elfedit_cmd_optarg_t opt_capndx[] = { 836*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_CAPNDX), 837*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_CAPNDX) */ 838*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0, 839*5088Sab196087 CAP_OPT_F_CAPNDX, 0 }, 840*5088Sab196087 { NULL } 841*5088Sab196087 }; 842*5088Sab196087 843*5088Sab196087 /* For commands thataccept -capndx and output styles */ 844*5088Sab196087 static elfedit_cmd_optarg_t opt_ostyle_capndx[] = { 845*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_CAPNDX), 846*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_CAPNDX) */ 847*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0, 848*5088Sab196087 CAP_OPT_F_CAPNDX, 0 }, 849*5088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 850*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 851*5088Sab196087 { NULL } 852*5088Sab196087 }; 853*5088Sab196087 854*5088Sab196087 855*5088Sab196087 /* cap:dump */ 856*5088Sab196087 static const char *name_dump[] = { 857*5088Sab196087 MSG_ORIG(MSG_CMD_DUMP), 858*5088Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 859*5088Sab196087 NULL 860*5088Sab196087 }; 861*5088Sab196087 static elfedit_cmd_optarg_t arg_dump[] = { 862*5088Sab196087 { MSG_ORIG(MSG_STR_ELT), 863*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */ 864*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT), 865*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 866*5088Sab196087 { NULL } 867*5088Sab196087 }; 868*5088Sab196087 869*5088Sab196087 870*5088Sab196087 /* cap:tag */ 871*5088Sab196087 static const char *name_tag[] = { MSG_ORIG(MSG_CMD_TAG), NULL }; 872*5088Sab196087 static elfedit_cmd_optarg_t arg_tag[] = { 873*5088Sab196087 { MSG_ORIG(MSG_STR_ELT), 874*5088Sab196087 /* MSG_INTL(MSG_A1_TAG_ELT) */ 875*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_TAG_ELT), 876*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 877*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 878*5088Sab196087 /* MSG_INTL(MSG_A2_TAG_VALUE) */ 879*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_TAG_VALUE), 880*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 881*5088Sab196087 { NULL } 882*5088Sab196087 }; 883*5088Sab196087 884*5088Sab196087 885*5088Sab196087 /* cap:value */ 886*5088Sab196087 static const char *name_value[] = { MSG_ORIG(MSG_CMD_VALUE), NULL }; 887*5088Sab196087 static elfedit_cmd_optarg_t arg_value[] = { 888*5088Sab196087 { MSG_ORIG(MSG_STR_ELT), 889*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */ 890*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT), 891*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 892*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 893*5088Sab196087 /* MSG_INTL(MSG_A2_VALUE_VALUE) */ 894*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_VALUE_VALUE), 895*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 896*5088Sab196087 { NULL } 897*5088Sab196087 }; 898*5088Sab196087 899*5088Sab196087 /* cap:delete */ 900*5088Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL }; 901*5088Sab196087 static elfedit_cmd_optarg_t arg_delete[] = { 902*5088Sab196087 { MSG_ORIG(MSG_STR_ELT), 903*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */ 904*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT), 905*5088Sab196087 0 }, 906*5088Sab196087 { MSG_ORIG(MSG_STR_COUNT), 907*5088Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */ 908*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT), 909*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 910*5088Sab196087 { NULL } 911*5088Sab196087 }; 912*5088Sab196087 913*5088Sab196087 /* cap:move */ 914*5088Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL }; 915*5088Sab196087 static elfedit_cmd_optarg_t arg_move[] = { 916*5088Sab196087 { MSG_ORIG(MSG_STR_ELT), 917*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */ 918*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT), 919*5088Sab196087 0 }, 920*5088Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX), 921*5088Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */ 922*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX), 923*5088Sab196087 0 }, 924*5088Sab196087 { MSG_ORIG(MSG_STR_COUNT), 925*5088Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */ 926*5088Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT), 927*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 928*5088Sab196087 { NULL } 929*5088Sab196087 }; 930*5088Sab196087 931*5088Sab196087 /* cap:hw1 */ 932*5088Sab196087 static const char *name_hw1[] = { MSG_ORIG(MSG_CMD_HW1), NULL }; 933*5088Sab196087 static elfedit_cmd_optarg_t arg_hw1[] = { 934*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 935*5088Sab196087 /* MSG_INTL(MSG_A1_HW1_VALUE) */ 936*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_HW1_VALUE), 937*5088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 938*5088Sab196087 { NULL } 939*5088Sab196087 }; 940*5088Sab196087 941*5088Sab196087 /* cap:sf1 */ 942*5088Sab196087 static const char *name_sf1[] = { MSG_ORIG(MSG_CMD_SF1), NULL }; 943*5088Sab196087 static elfedit_cmd_optarg_t arg_sf1[] = { 944*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 945*5088Sab196087 /* MSG_INTL(MSG_A1_SF1_VALUE) */ 946*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SF1_VALUE), 947*5088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 948*5088Sab196087 { NULL } 949*5088Sab196087 }; 950*5088Sab196087 951*5088Sab196087 952*5088Sab196087 953*5088Sab196087 954*5088Sab196087 static elfedit_cmd_t cmds[] = { 955*5088Sab196087 /* cap:dump */ 956*5088Sab196087 { cmd_dump, cpl_eltarg, name_dump, 957*5088Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */ 958*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 959*5088Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */ 960*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 961*5088Sab196087 opt_capndx, arg_dump }, 962*5088Sab196087 963*5088Sab196087 /* cap:tag */ 964*5088Sab196087 { cmd_tag, cpl_tag, name_tag, 965*5088Sab196087 /* MSG_INTL(MSG_DESC_TAG) */ 966*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_TAG), 967*5088Sab196087 /* MSG_INTL(MSG_HELP_TAG) */ 968*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_TAG), 969*5088Sab196087 opt_ostyle_capndx, arg_tag }, 970*5088Sab196087 971*5088Sab196087 /* cap:value */ 972*5088Sab196087 { cmd_value, cpl_eltarg, name_value, 973*5088Sab196087 /* MSG_INTL(MSG_DESC_VALUE) */ 974*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_VALUE), 975*5088Sab196087 /* MSG_INTL(MSG_HELP_VALUE) */ 976*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_VALUE), 977*5088Sab196087 opt_ostyle_capndx, arg_value }, 978*5088Sab196087 979*5088Sab196087 /* cap:delete */ 980*5088Sab196087 { cmd_delete, cpl_eltarg, name_delete, 981*5088Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */ 982*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE), 983*5088Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */ 984*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE), 985*5088Sab196087 opt_capndx, arg_delete }, 986*5088Sab196087 987*5088Sab196087 /* cap:move */ 988*5088Sab196087 { cmd_move, cpl_eltarg, name_move, 989*5088Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */ 990*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE), 991*5088Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */ 992*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE), 993*5088Sab196087 opt_capndx, arg_move }, 994*5088Sab196087 995*5088Sab196087 /* cap:hw1 */ 996*5088Sab196087 { cmd_hw1, cpl_hw1, name_hw1, 997*5088Sab196087 /* MSG_INTL(MSG_DESC_HW1) */ 998*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_HW1), 999*5088Sab196087 /* MSG_INTL(MSG_HELP_HW1) */ 1000*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_HW1), 1001*5088Sab196087 opt_ostyle_bitop, arg_hw1 }, 1002*5088Sab196087 1003*5088Sab196087 /* cap:sf1 */ 1004*5088Sab196087 { cmd_sf1, cpl_sf1, name_sf1, 1005*5088Sab196087 /* MSG_INTL(MSG_DESC_SF1) */ 1006*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_SF1), 1007*5088Sab196087 /* MSG_INTL(MSG_HELP_SF1) */ 1008*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_SF1), 1009*5088Sab196087 opt_ostyle_bitop, arg_sf1 }, 1010*5088Sab196087 1011*5088Sab196087 { NULL } 1012*5088Sab196087 }; 1013*5088Sab196087 1014*5088Sab196087 static elfedit_module_t module = { 1015*5088Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 1016*5088Sab196087 /* MSG_INTL(MSG_MOD_DESC) */ 1017*5088Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC), 1018*5088Sab196087 cmds, mod_i18nhdl_to_str }; 1019*5088Sab196087 1020*5088Sab196087 return (&module); 1021*5088Sab196087 } 1022