1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <ctype.h> 30 #include <machdep.h> 31 #include <elfedit.h> 32 #include <sys/elf_SPARC.h> 33 #include <sys/elf_amd64.h> 34 #include <strings.h> 35 #include <conv.h> 36 #include <debug.h> 37 #include <ehdr_msg.h> 38 39 40 41 42 #define MAXNDXSIZE 10 43 44 45 46 47 /* 48 * This module handles changes to the ELF header 49 */ 50 51 52 53 /* 54 * This module uses shared code for several of the commands. 55 * It is sometimes necessary to know which specific command 56 * is active. 57 */ 58 typedef enum { 59 /* Dump command, used as module default to display ELF header */ 60 EHDR_CMD_T_DUMP = 0, /* ehdr:dump */ 61 62 /* Commands that correspond directly to ELF header fields */ 63 EHDR_CMD_T_E_IDENT = 1, /* ehdr:e_ident */ 64 EHDR_CMD_T_E_TYPE = 2, /* ehdr:e_type */ 65 EHDR_CMD_T_E_MACHINE = 3, /* ehdr:e_machine */ 66 EHDR_CMD_T_E_VERSION = 4, /* ehdr:e_version */ 67 EHDR_CMD_T_E_ENTRY = 5, /* ehdr:e_entry */ 68 EHDR_CMD_T_E_PHOFF = 6, /* ehdr:e_phoff */ 69 EHDR_CMD_T_E_SHOFF = 7, /* ehdr:e_shoff */ 70 EHDR_CMD_T_E_FLAGS = 8, /* ehdr:e_flags */ 71 EHDR_CMD_T_E_EHSIZE = 9, /* ehdr:e_ehsize */ 72 EHDR_CMD_T_E_PHENTSIZE = 10, /* ehdr:e_phentsize */ 73 EHDR_CMD_T_E_PHNUM = 11, /* ehdr:e_phnum */ 74 EHDR_CMD_T_E_SHENTSIZE = 12, /* ehdr:e_shentsize */ 75 EHDR_CMD_T_E_SHNUM = 13, /* ehdr:e_shnum */ 76 EHDR_CMD_T_E_SHSTRNDX = 14, /* ehdr:e_shstrndx */ 77 78 /* Commands that correspond to the e_ident[] array in ELF hdr */ 79 EHDR_CMD_T_EI_MAG0 = 15, /* ehdr:ei_mag0 */ 80 EHDR_CMD_T_EI_MAG1 = 16, /* ehdr:ei_mag1 */ 81 EHDR_CMD_T_EI_MAG2 = 17, /* ehdr:ei_mag2 */ 82 EHDR_CMD_T_EI_MAG3 = 18, /* ehdr:ei_mag3 */ 83 EHDR_CMD_T_EI_CLASS = 19, /* ehdr:ei_class */ 84 EHDR_CMD_T_EI_DATA = 20, /* ehdr:ei_data */ 85 EHDR_CMD_T_EI_VERSION = 21, /* ehdr:ei_version */ 86 EHDR_CMD_T_EI_OSABI = 22, /* ehdr:ei_osabi */ 87 EHDR_CMD_T_EI_ABIVERSION = 23 /* ehdr:ei_abiversion */ 88 } EHDR_CMD_T; 89 90 91 92 93 94 95 #ifndef _ELF64 96 /* 97 * We supply this function for the msg module 98 */ 99 const char * 100 _ehdr_msg(Msg mid) 101 { 102 return (gettext(MSG_ORIG(mid))); 103 } 104 #endif 105 106 107 /* 108 * This function is supplied to elfedit through our elfedit_module_t 109 * definition. It translates the opaque elfedit_i18nhdl_t handles 110 * in our module interface into the actual strings for elfedit to 111 * use. 112 * 113 * note: 114 * This module uses Msg codes for its i18n handle type. 115 * So the translation is simply to use MSG_INTL() to turn 116 * it into a string and return it. 117 */ 118 static const char * 119 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 120 { 121 Msg msg = (Msg)hdl; 122 123 return (MSG_INTL(msg)); 124 } 125 126 127 128 /* 129 * The ehdr_opt_t enum specifies a bit value for every optional 130 * argument allowed by a command in this module. 131 */ 132 typedef enum { 133 EHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */ 134 EHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ 135 EHDR_OPT_F_OR = 4, /* -or: OR (|) values to dest */ 136 EHDR_OPT_F_SHNDX = 8, /* -shndx: sec argument is index of */ 137 /* section, not name */ 138 EHDR_OPT_F_SHTYP = 16 /* -shtyp: sec argument is type of */ 139 /* section, not name */ 140 } ehdr_opt_t; 141 142 143 /* 144 * A variable of type ARGSTATE is used by each command to maintain 145 * information about the arguments and related things. It is 146 * initialized by process_args(), and used by the other routines. 147 */ 148 typedef struct { 149 elfedit_obj_state_t *obj_state; 150 ehdr_opt_t optmask; /* Mask of options used */ 151 int argc; /* # of plain arguments */ 152 const char **argv; /* Plain arguments */ 153 } ARGSTATE; 154 155 156 157 /* 158 * Standard argument processing for ehdr module 159 * 160 * entry 161 * obj_state, argc, argv - Standard command arguments 162 * argstate - Address of ARGSTATE block to be initialized 163 * 164 * exit: 165 * On success, *argstate is initialized. On error, 166 * an error is issued and this routine does not return. 167 */ 168 static void 169 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 170 ARGSTATE *argstate) 171 { 172 elfedit_getopt_state_t getopt_state; 173 elfedit_getopt_ret_t *getopt_ret; 174 175 bzero(argstate, sizeof (*argstate)); 176 argstate->obj_state = obj_state; 177 178 elfedit_getopt_init(&getopt_state, &argc, &argv); 179 /* Add each new option to the options mask */ 180 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) 181 argstate->optmask |= getopt_ret->gor_idmask; 182 183 /* If there may be an arbitrary amount of output, use a pager */ 184 if (argc == 0) 185 elfedit_pager_init(); 186 187 /* Return the updated values of argc/argv */ 188 argstate->argc = argc; 189 argstate->argv = argv; 190 } 191 192 193 194 195 196 197 /* 198 * Format the given magic number byte into a buffer 199 * 200 * entry: 201 * value - Value of the magic value byte given by 202 * ehdr->ei_ident[EI_MAG?] 203 */ 204 static const char * 205 conv_magic_value(int value) 206 { 207 /* 208 * This routine can be called twice within a single C statement, 209 * so we use alternating buffers on each call to allow this 210 * without requiring the caller to supply a buffer (the size of 211 * which they don't know). 212 */ 213 static char buf1[20]; 214 static char buf2[20]; 215 static char *buf; 216 217 /* Switch buffers */ 218 buf = (buf == buf1) ? buf2 : buf1; 219 220 if (isprint(value)) 221 (void) snprintf(buf, sizeof (buf1), 222 MSG_ORIG(MSG_FMT_HEXNUM_QCHR), value, value); 223 else 224 (void) snprintf(buf, sizeof (buf1), 225 MSG_ORIG(MSG_FMT_HEXNUM), value); 226 return (buf); 227 } 228 229 230 231 /* 232 * Print ELF header values, taking the calling command, and output style 233 * into account. 234 * 235 * entry: 236 * cmd - EHDR_CMD_T_* value giving identify of caller 237 * e_ident_ndx - Ignored unless cmd is EHDR_CMD_T_E_IDENT. In IDENT 238 * case, index of item in e_ident[] array to display, or 239 * -1 to display the entire array. 240 * autoprint - If True, output is only produced if the elfedit 241 * autoprint flag is set. If False, output is always produced. 242 * argstate - Argument state block 243 */ 244 static void 245 print_ehdr(EHDR_CMD_T cmd, int e_ident_ndx, int autoprint, 246 ARGSTATE *argstate) 247 { 248 elfedit_outstyle_t outstyle; 249 Conv_fmt_flags_t flags_fmt_flags = 0; 250 Ehdr *ehdr; 251 int c; 252 Conv_inv_buf_t inv_buf; 253 254 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) 255 return; 256 257 /* 258 * Pick an output style. ehdr:dump is required to use the default 259 * style. The other commands use the current output style. 260 */ 261 if (cmd == EHDR_CMD_T_DUMP) { 262 outstyle = ELFEDIT_OUTSTYLE_DEFAULT; 263 } else { 264 outstyle = elfedit_outstyle(); 265 266 /* 267 * When the caller specifies the simple output style, 268 * omit the brackets from around the values. 269 */ 270 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 271 flags_fmt_flags = CONV_FMT_NOBKT; 272 273 /* 274 * For things that show a single header item, switch 275 * from default to simple mode. 276 */ 277 if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) && 278 ((cmd != EHDR_CMD_T_E_IDENT) || (e_ident_ndx != -1))) 279 outstyle = ELFEDIT_OUTSTYLE_SIMPLE; 280 } 281 282 ehdr = argstate->obj_state->os_ehdr; 283 284 /* 285 * If doing default output, use elfdump style where we 286 * show the full ELF header. In this case, the command 287 * that called us doesn't matter. This can only happen 288 * from ehdr:dump or ehdr:e_ident/ 289 */ 290 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { 291 const char *ndx, *value; 292 char ndx_buf[64], value_buf[20]; 293 int i; 294 295 if (cmd == EHDR_CMD_T_DUMP) { 296 Elf_ehdr(NULL, ehdr, 297 argstate->obj_state->os_secarr[0].sec_shdr); 298 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 299 } 300 301 /* 302 * Elf_ehdr() does not display all of e_ident[], so we 303 * augment by displaying the entire array separately. 304 */ 305 elfedit_printf(MSG_ORIG(MSG_STR_EIDENT_HDR)); 306 307 for (i = 0; i < EI_NIDENT; i++) { 308 ndx = value = NULL; 309 310 switch (i) { 311 case EI_MAG0: 312 case EI_MAG1: 313 case EI_MAG2: 314 case EI_MAG3: 315 ndx = elfedit_atoconst_value_to_str( 316 ELFEDIT_CONST_EI, i, 1); 317 value = conv_magic_value(ehdr->e_ident[i]); 318 break; 319 case EI_CLASS: 320 ndx = elfedit_atoconst_value_to_str( 321 ELFEDIT_CONST_EI, EI_CLASS, 1); 322 value = conv_ehdr_class(ehdr->e_ident[EI_CLASS], 323 0, &inv_buf); 324 break; 325 case EI_DATA: 326 ndx = elfedit_atoconst_value_to_str( 327 ELFEDIT_CONST_EI, EI_DATA, 1); 328 value = conv_ehdr_data(ehdr->e_ident[EI_DATA], 329 0, &inv_buf); 330 break; 331 case EI_VERSION: 332 ndx = elfedit_atoconst_value_to_str( 333 ELFEDIT_CONST_EI, EI_VERSION, 1); 334 value = conv_ehdr_vers( 335 ehdr->e_ident[EI_VERSION], 0, &inv_buf); 336 break; 337 case EI_OSABI: 338 ndx = elfedit_atoconst_value_to_str( 339 ELFEDIT_CONST_EI, EI_OSABI, 1); 340 value = conv_ehdr_osabi(ehdr->e_ident[EI_OSABI], 341 0, &inv_buf); 342 break; 343 case EI_ABIVERSION: 344 ndx = elfedit_atoconst_value_to_str( 345 ELFEDIT_CONST_EI, EI_ABIVERSION, 1); 346 value = value_buf; 347 (void) snprintf(value_buf, sizeof (value_buf), 348 MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]); 349 break; 350 default: 351 value = value_buf; 352 (void) snprintf(value_buf, sizeof (value_buf), 353 MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]); 354 break; 355 } 356 357 if (ndx == NULL) 358 (void) snprintf(ndx_buf, sizeof (ndx_buf), 359 MSG_ORIG(MSG_FMT_BKTINT), i); 360 else 361 (void) snprintf(ndx_buf, sizeof (ndx_buf), 362 MSG_ORIG(MSG_FMT_BKTSTR), ndx); 363 elfedit_printf(MSG_ORIG(MSG_FMT_EI_ELT), 364 ndx_buf, value); 365 } 366 return; 367 } 368 369 370 switch (cmd) { 371 case EHDR_CMD_T_E_IDENT: 372 { 373 int i, cnt; 374 375 /* Show one element, or the entire thing? */ 376 if (e_ident_ndx == -1) { 377 i = 0; 378 cnt = EI_NIDENT; 379 } else { 380 i = e_ident_ndx; 381 cnt = 1; 382 } 383 384 for (; cnt-- > 0; i++) { 385 /* 386 * If using numeric style, or there is 387 * no conversion routine for this item, 388 * print a simple hex value. 389 */ 390 if ((outstyle == ELFEDIT_OUTSTYLE_NUM) || 391 (i >= EI_ABIVERSION)) { 392 elfedit_printf( 393 MSG_ORIG(MSG_FMT_HEXNUMNL), 394 ehdr->e_ident[i]); 395 continue; 396 } 397 398 /* Handle special cases in simple mode */ 399 switch (i) { 400 case EI_MAG0: 401 case EI_MAG1: 402 case EI_MAG2: 403 case EI_MAG3: 404 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 405 conv_magic_value(ehdr->e_ident[i])); 406 continue; 407 case EI_CLASS: 408 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 409 conv_ehdr_class( 410 ehdr->e_ident[EI_CLASS], 0, 411 &inv_buf)); 412 continue; 413 case EI_DATA: 414 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 415 conv_ehdr_data( 416 ehdr->e_ident[EI_DATA], 0, 417 &inv_buf)); 418 continue; 419 case EI_VERSION: 420 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 421 conv_ehdr_vers( 422 ehdr->e_ident[EI_VERSION], 0, 423 &inv_buf)); 424 continue; 425 case EI_OSABI: 426 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 427 conv_ehdr_osabi( 428 ehdr->e_ident[EI_OSABI], 0, 429 &inv_buf)); 430 continue; 431 } 432 } 433 } 434 return; 435 436 case EHDR_CMD_T_E_TYPE: 437 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 438 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 439 conv_ehdr_type(ehdr->e_type, 0, &inv_buf)); 440 else 441 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 442 ehdr->e_type); 443 return; 444 445 case EHDR_CMD_T_E_MACHINE: 446 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 447 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 448 conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf)); 449 } else { 450 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 451 EC_WORD(ehdr->e_machine)); 452 } 453 return; 454 455 case EHDR_CMD_T_E_VERSION: 456 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 457 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 458 conv_ehdr_vers(ehdr->e_version, 0, &inv_buf)); 459 else 460 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 461 ehdr->e_version); 462 return; 463 464 case EHDR_CMD_T_E_ENTRY: 465 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 466 EC_WORD(ehdr->e_entry)); 467 return; 468 469 case EHDR_CMD_T_E_PHOFF: 470 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 471 EC_WORD(ehdr->e_phoff)); 472 return; 473 474 case EHDR_CMD_T_E_SHOFF: 475 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 476 EC_WORD(ehdr->e_shoff)); 477 return; 478 479 case EHDR_CMD_T_E_FLAGS: 480 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 481 Conv_ehdr_flags_buf_t flags_buf; 482 483 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 484 conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags, 485 flags_fmt_flags, &flags_buf)); 486 } else { 487 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 488 ehdr->e_flags); 489 } 490 return; 491 492 case EHDR_CMD_T_E_EHSIZE: 493 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 494 EC_WORD(ehdr->e_ehsize)); 495 return; 496 497 case EHDR_CMD_T_E_PHENTSIZE: 498 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 499 EC_WORD(ehdr->e_phentsize)); 500 return; 501 502 case EHDR_CMD_T_E_PHNUM: 503 { 504 Word num = ehdr->e_phnum; 505 506 /* 507 * If using extended indexes, fetch the real 508 * value from shdr[0].sh_info 509 */ 510 if (num == PN_XNUM) 511 num = argstate->obj_state-> 512 os_secarr[0].sec_shdr->sh_info; 513 514 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 515 EC_WORD(num)); 516 } 517 return; 518 519 case EHDR_CMD_T_E_SHENTSIZE: 520 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 521 EC_WORD(ehdr->e_shentsize)); 522 return; 523 524 case EHDR_CMD_T_E_SHNUM: 525 { 526 Word num = ehdr->e_shnum; 527 528 /* 529 * If using extended indexes, fetch the real 530 * value from shdr[0].sh_size 531 */ 532 if (num == 0) 533 num = argstate->obj_state-> 534 os_secarr[0].sec_shdr->sh_size; 535 536 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 537 EC_WORD(num)); 538 } 539 return; 540 541 case EHDR_CMD_T_E_SHSTRNDX: 542 { 543 Word num = ehdr->e_shstrndx; 544 545 /* 546 * If using extended indexes, fetch the real 547 * value from shdr[0].sh_link 548 */ 549 if (num == SHN_XINDEX) 550 num = argstate->obj_state-> 551 os_secarr[0].sec_shdr->sh_link; 552 553 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), 554 EC_WORD(num)); 555 } 556 return; 557 558 case EHDR_CMD_T_EI_MAG0: 559 case EHDR_CMD_T_EI_MAG1: 560 case EHDR_CMD_T_EI_MAG2: 561 case EHDR_CMD_T_EI_MAG3: 562 /* This depends on EHDR_CMD_T_EI_MAG[0-3] being contiguous */ 563 c = ehdr->e_ident[cmd - EHDR_CMD_T_EI_MAG0]; 564 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 565 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 566 conv_magic_value(c)); 567 else 568 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); 569 return; 570 571 case EHDR_CMD_T_EI_CLASS: 572 c = ehdr->e_ident[EI_CLASS]; 573 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 574 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 575 conv_ehdr_class(c, 0, &inv_buf)); 576 else 577 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); 578 return; 579 580 case EHDR_CMD_T_EI_DATA: 581 c = ehdr->e_ident[EI_DATA]; 582 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 583 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 584 conv_ehdr_data(c, 0, &inv_buf)); 585 else 586 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); 587 return; 588 589 case EHDR_CMD_T_EI_VERSION: 590 c = ehdr->e_ident[EI_VERSION]; 591 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) 592 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 593 conv_ehdr_vers(c, 0, &inv_buf)); 594 else 595 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); 596 return; 597 598 case EHDR_CMD_T_EI_OSABI: 599 c = ehdr->e_ident[EI_OSABI]; 600 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 601 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 602 conv_ehdr_osabi(c, 0, &inv_buf)); 603 } else { 604 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 605 EC_WORD(c)); 606 } 607 return; 608 609 case EHDR_CMD_T_EI_ABIVERSION: 610 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), 611 EC_WORD(ehdr->e_ident[EI_ABIVERSION])); 612 return; 613 } 614 } 615 616 617 /* 618 * Common body for the ehdr: module commands. These commands 619 * share a large amount of common behavior, so it is convenient 620 * to centralize things and use the cmd argument to handle the 621 * small differences. 622 * 623 * entry: 624 * cmd - One of the EHDR_CMD_T_* constants listed above, specifying 625 * which command to implement. 626 * obj_state, argc, argv - Standard command arguments 627 */ 628 static elfedit_cmdret_t 629 cmd_body(EHDR_CMD_T cmd, elfedit_obj_state_t *obj_state, 630 int argc, const char *argv[]) 631 { 632 /* 633 * When a call comes in for ehdr:e_ident[ndx], and the 634 * specified element is one that we have a special command 635 * for, then we revector to that special command instead 636 * of using the generic ehdr:e_ident processing. This array, 637 * which is indexed by the e_ident[] index value is used 638 * to decide if that is the case. If the resulting value 639 * is EHDR_CMD_T_E_IDENT, then the generic processing is 640 * used. Otherwise, we revector to the specified command. 641 */ 642 static const int e_ident_revector[16] = { 643 EHDR_CMD_T_EI_MAG0, /* 0: EI_MAG0 */ 644 EHDR_CMD_T_EI_MAG1, /* 1: EI_MAG1 */ 645 EHDR_CMD_T_EI_MAG2, /* 2: EI_MAG2 */ 646 EHDR_CMD_T_EI_MAG3, /* 3: EI_MAG3 */ 647 EHDR_CMD_T_EI_CLASS, /* 4: EI_CLASS */ 648 EHDR_CMD_T_EI_DATA, /* 5: EI_DATA */ 649 EHDR_CMD_T_EI_VERSION, /* 6: EI_VERSION */ 650 EHDR_CMD_T_EI_OSABI, /* 7: EI_OSABI */ 651 EHDR_CMD_T_EI_ABIVERSION, /* 8: EI_ABIVERSION */ 652 EHDR_CMD_T_E_IDENT, /* 9: generic */ 653 EHDR_CMD_T_E_IDENT, /* 10: generic */ 654 EHDR_CMD_T_E_IDENT, /* 11: generic */ 655 EHDR_CMD_T_E_IDENT, /* 12: generic */ 656 EHDR_CMD_T_E_IDENT, /* 13: generic */ 657 EHDR_CMD_T_E_IDENT, /* 14: generic */ 658 EHDR_CMD_T_E_IDENT, /* 15: generic */ 659 }; 660 661 662 ARGSTATE argstate; 663 Ehdr *ehdr; 664 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 665 int e_ident_ndx = -1; 666 Conv_inv_buf_t inv_buf1, inv_buf2; 667 668 /* Process the optional arguments */ 669 process_args(obj_state, argc, argv, &argstate); 670 671 /* Check number of arguments */ 672 switch (cmd) { 673 case EHDR_CMD_T_DUMP: 674 /* ehdr:dump does not accept arguments */ 675 if (argstate.argc > 0) 676 elfedit_command_usage(); 677 break; 678 case EHDR_CMD_T_E_IDENT: 679 /* 680 * ehdr:e_ident accepts 1 or 2 arguments, the first 681 * being the index into the array, and the second being 682 * the value. If there are arguments, then process the 683 * index, and remove it from the argument list. 684 */ 685 if (argstate.argc > 0) { 686 if (argstate.argc > 2) 687 elfedit_command_usage(); 688 e_ident_ndx = (int) 689 elfedit_atoconst_range(argstate.argv[0], 690 MSG_ORIG(MSG_STR_INDEX), 0, EI_NIDENT - 1, 691 ELFEDIT_CONST_EI); 692 argstate.argc--; 693 argstate.argv++; 694 695 /* 696 * If the index is for one of the e_ident elements 697 * that we have a special command for, then switch 698 * to that command. e_ident_revector[] returns 699 * EHDR_CMD_T_E_IDENT in the cases where such a command 700 * does not exist, in which case we'll continue with the 701 * generic code. 702 */ 703 cmd = e_ident_revector[e_ident_ndx]; 704 } 705 break; 706 case EHDR_CMD_T_E_FLAGS: 707 /* ehdr:e_flags accepts an arbitrary number of arguments */ 708 break; 709 default: 710 /* The remaining commands accept a single optional argument */ 711 if (argstate.argc > 1) 712 elfedit_command_usage(); 713 break; 714 } 715 716 /* If there are no arguments, dump the ELF header and return */ 717 if (argstate.argc == 0) { 718 print_ehdr(cmd, e_ident_ndx, 0, &argstate); 719 return (ELFEDIT_CMDRET_NONE); 720 } 721 722 ehdr = obj_state->os_ehdr; 723 switch (cmd) { 724 /* 725 * EHDR_CMD_T_DUMP can't get here: It never has an 726 * argument, and is handled above. 727 */ 728 729 case EHDR_CMD_T_E_IDENT: 730 { 731 /* 732 * Only those e_ident[] elements for which we 733 * don't have a specialized command come here. 734 * The argument is a value to be set in 735 * e_ident[e_ident_ndx]. 736 */ 737 uchar_t value = (uchar_t) 738 elfedit_atoui_range(argstate.argv[0], 739 MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL); 740 741 if (ehdr->e_ident[e_ident_ndx] == value) { 742 elfedit_msg(ELFEDIT_MSG_DEBUG, 743 MSG_INTL(MSG_DEBUG_EI_D_X_OK), 744 e_ident_ndx, EC_WORD(value)); 745 } else { 746 elfedit_msg(ELFEDIT_MSG_DEBUG, 747 MSG_INTL(MSG_DEBUG_EI_D_X_CHG), 748 e_ident_ndx, ehdr->e_ident[e_ident_ndx], 749 value); 750 ret = ELFEDIT_CMDRET_MOD; 751 ehdr->e_ident[e_ident_ndx] = value; 752 } 753 } 754 break; 755 756 case EHDR_CMD_T_E_TYPE: 757 { 758 /* The argument gives the object type */ 759 Half type = (Half) elfedit_atoconst(argstate.argv[0], 760 ELFEDIT_CONST_ET); 761 const char *name = MSG_ORIG(MSG_CMD_E_TYPE); 762 763 if (ehdr->e_type == type) { 764 elfedit_msg(ELFEDIT_MSG_DEBUG, 765 MSG_INTL(MSG_DEBUG_E_S_OK), name, 766 conv_ehdr_type(ehdr->e_type, 0, &inv_buf1)); 767 } else { 768 elfedit_msg(ELFEDIT_MSG_DEBUG, 769 MSG_INTL(MSG_DEBUG_E_S_CHG), name, 770 conv_ehdr_type(ehdr->e_type, 0, &inv_buf1), 771 conv_ehdr_type(type, 0, &inv_buf2)); 772 ret = ELFEDIT_CMDRET_MOD; 773 ehdr->e_type = type; 774 } 775 } 776 break; 777 778 case EHDR_CMD_T_E_MACHINE: 779 { 780 /* The argument gives the machine code */ 781 Half mach = (Half) elfedit_atoconst(argstate.argv[0], 782 ELFEDIT_CONST_EM); 783 const char *name = MSG_ORIG(MSG_CMD_E_MACHINE); 784 785 if (ehdr->e_machine == mach) { 786 elfedit_msg(ELFEDIT_MSG_DEBUG, 787 MSG_INTL(MSG_DEBUG_E_S_OK), name, 788 conv_ehdr_mach(ehdr->e_machine, 0, 789 &inv_buf1)); 790 } else { 791 elfedit_msg(ELFEDIT_MSG_DEBUG, 792 MSG_INTL(MSG_DEBUG_E_S_CHG), name, 793 conv_ehdr_mach(ehdr->e_machine, 0, 794 &inv_buf1), 795 conv_ehdr_mach(mach, 0, &inv_buf2)); 796 ret = ELFEDIT_CMDRET_MOD; 797 ehdr->e_machine = mach; 798 } 799 } 800 break; 801 802 case EHDR_CMD_T_E_VERSION: 803 { 804 /* The argument gives the version */ 805 Word ver = (Word) elfedit_atoconst(argstate.argv[0], 806 ELFEDIT_CONST_EV); 807 const char *name = MSG_ORIG(MSG_CMD_E_VERSION); 808 809 if (ehdr->e_version == ver) { 810 elfedit_msg(ELFEDIT_MSG_DEBUG, 811 MSG_INTL(MSG_DEBUG_E_S_OK), name, 812 conv_ehdr_vers(ehdr->e_version, 0, 813 &inv_buf1)); 814 } else { 815 elfedit_msg(ELFEDIT_MSG_DEBUG, 816 MSG_INTL(MSG_DEBUG_E_S_CHG), name, 817 conv_ehdr_vers(ehdr->e_version, 0, 818 &inv_buf1), 819 conv_ehdr_vers(ver, 0, &inv_buf2)); 820 ret = ELFEDIT_CMDRET_MOD; 821 ehdr->e_version = ver; 822 } 823 } 824 break; 825 826 case EHDR_CMD_T_E_ENTRY: 827 { 828 /* The argument gives the entry address */ 829 Addr entry = (Addr) 830 elfedit_atoui(argstate.argv[0], NULL); 831 const char *name = MSG_ORIG(MSG_CMD_E_ENTRY); 832 833 if (ehdr->e_entry == entry) { 834 elfedit_msg(ELFEDIT_MSG_DEBUG, 835 MSG_INTL(MSG_DEBUG_E_LLX_OK), name, 836 EC_ADDR(ehdr->e_entry)); 837 } else { 838 elfedit_msg(ELFEDIT_MSG_DEBUG, 839 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, 840 EC_ADDR(ehdr->e_entry), EC_ADDR(entry)); 841 ret = ELFEDIT_CMDRET_MOD; 842 ehdr->e_entry = entry; 843 } 844 } 845 break; 846 847 case EHDR_CMD_T_E_PHOFF: 848 { 849 /* The argument gives the program header offset */ 850 Off off = (Off) elfedit_atoui(argstate.argv[0], 851 NULL); 852 const char *name = MSG_ORIG(MSG_CMD_E_PHOFF); 853 854 if (ehdr->e_phoff == off) { 855 elfedit_msg(ELFEDIT_MSG_DEBUG, 856 MSG_INTL(MSG_DEBUG_E_LLX_OK), name, 857 EC_OFF(ehdr->e_phoff)); 858 } else { 859 elfedit_msg(ELFEDIT_MSG_DEBUG, 860 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, 861 EC_OFF(ehdr->e_phoff), EC_OFF(off)); 862 ret = ELFEDIT_CMDRET_MOD; 863 ehdr->e_phoff = off; 864 } 865 } 866 break; 867 868 case EHDR_CMD_T_E_SHOFF: 869 { 870 /* The argument gives the section header offset */ 871 Off off = (Off) elfedit_atoui(argstate.argv[0], 872 NULL); 873 const char *name = MSG_ORIG(MSG_CMD_E_SHOFF); 874 875 if (ehdr->e_shoff == off) { 876 elfedit_msg(ELFEDIT_MSG_DEBUG, 877 MSG_INTL(MSG_DEBUG_E_LLX_OK), name, 878 EC_OFF(ehdr->e_shoff)); 879 } else { 880 elfedit_msg(ELFEDIT_MSG_DEBUG, 881 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, 882 EC_OFF(ehdr->e_shoff), EC_OFF(off)); 883 ret = ELFEDIT_CMDRET_MOD; 884 ehdr->e_shoff = off; 885 } 886 } 887 break; 888 889 case EHDR_CMD_T_E_FLAGS: 890 { 891 Conv_ehdr_flags_buf_t flags_buf1, flags_buf2; 892 const char *name = MSG_ORIG(MSG_CMD_E_FLAGS); 893 Word flags = 0; 894 int i; 895 896 /* Collect the arguments */ 897 for (i = 0; i < argstate.argc; i++) 898 flags |= (Word) 899 elfedit_atoconst(argstate.argv[i], 900 ELFEDIT_CONST_EF); 901 902 /* Complement the value? */ 903 if (argstate.optmask & EHDR_OPT_F_CMP) 904 flags = ~flags; 905 906 /* Perform any requested bit operations */ 907 if (argstate.optmask & EHDR_OPT_F_AND) 908 flags &= ehdr->e_flags; 909 else if (argstate.optmask & EHDR_OPT_F_OR) 910 flags |= ehdr->e_flags; 911 912 /* Set the value */ 913 if (ehdr->e_flags == flags) { 914 elfedit_msg(ELFEDIT_MSG_DEBUG, 915 MSG_INTL(MSG_DEBUG_E_S_OK), name, 916 conv_ehdr_flags(ehdr->e_machine, 917 ehdr->e_flags, 0, &flags_buf1)); 918 } else { 919 elfedit_msg(ELFEDIT_MSG_DEBUG, 920 MSG_INTL(MSG_DEBUG_E_S_CHG), name, 921 conv_ehdr_flags(ehdr->e_machine, 922 ehdr->e_flags, 0, &flags_buf1), 923 conv_ehdr_flags(ehdr->e_machine, 924 flags, 0, &flags_buf2)); 925 ret = ELFEDIT_CMDRET_MOD; 926 ehdr->e_flags = flags; 927 } 928 } 929 break; 930 931 case EHDR_CMD_T_E_EHSIZE: 932 { 933 /* The argument gives the ELF header size */ 934 Half ehsize = (Half) elfedit_atoui(argstate.argv[0], 935 NULL); 936 const char *name = MSG_ORIG(MSG_CMD_E_EHSIZE); 937 938 if (ehdr->e_ehsize == ehsize) { 939 elfedit_msg(ELFEDIT_MSG_DEBUG, 940 MSG_INTL(MSG_DEBUG_E_D_OK), name, 941 EC_WORD(ehdr->e_ehsize)); 942 } else { 943 elfedit_msg(ELFEDIT_MSG_DEBUG, 944 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 945 EC_WORD(ehdr->e_ehsize), EC_WORD(ehsize)); 946 ret = ELFEDIT_CMDRET_MOD; 947 ehdr->e_ehsize = ehsize; 948 } 949 } 950 break; 951 952 case EHDR_CMD_T_E_PHENTSIZE: 953 { 954 /* 955 * The argument gives the size of a program 956 * header element. 957 */ 958 Half phentsize = (Half) elfedit_atoui(argstate.argv[0], 959 NULL); 960 const char *name = MSG_ORIG(MSG_CMD_E_PHENTSIZE); 961 962 if (ehdr->e_phentsize == phentsize) { 963 elfedit_msg(ELFEDIT_MSG_DEBUG, 964 MSG_INTL(MSG_DEBUG_E_D_OK), name, 965 EC_WORD(ehdr->e_phentsize)); 966 } else { 967 elfedit_msg(ELFEDIT_MSG_DEBUG, 968 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 969 EC_WORD(ehdr->e_phentsize), 970 EC_WORD(phentsize)); 971 ret = ELFEDIT_CMDRET_MOD; 972 ehdr->e_phentsize = phentsize; 973 } 974 } 975 break; 976 977 case EHDR_CMD_T_E_PHNUM: 978 { 979 /* The argument gives the number of program headers */ 980 Word phnum = (Word) elfedit_atoui(argstate.argv[0], 981 NULL); 982 const char *name = MSG_ORIG(MSG_CMD_E_PHNUM); 983 elfedit_section_t *sec0 = &obj_state->os_secarr[0]; 984 Shdr *shdr0 = sec0->sec_shdr; 985 Half e_phnum; 986 Word sh_info; 987 988 if (phnum >= PN_XNUM) { 989 e_phnum = PN_XNUM; 990 sh_info = phnum; 991 } else { 992 e_phnum = phnum; 993 sh_info = 0; 994 } 995 996 if (ehdr->e_phnum == e_phnum) { 997 elfedit_msg(ELFEDIT_MSG_DEBUG, 998 MSG_INTL(MSG_DEBUG_E_D_OK), name, 999 EC_WORD(ehdr->e_phnum)); 1000 } else { 1001 elfedit_msg(ELFEDIT_MSG_DEBUG, 1002 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 1003 EC_WORD(ehdr->e_phnum), e_phnum); 1004 ret = ELFEDIT_CMDRET_MOD; 1005 ehdr->e_phnum = e_phnum; 1006 } 1007 if (shdr0->sh_info == sh_info) { 1008 elfedit_msg(ELFEDIT_MSG_DEBUG, 1009 MSG_INTL(MSG_DEBUG_SHDR0_D_OK), 1010 MSG_ORIG(MSG_STR_SH_INFO), 1011 EC_WORD(shdr0->sh_info)); 1012 } else { 1013 elfedit_msg(ELFEDIT_MSG_DEBUG, 1014 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), 1015 MSG_ORIG(MSG_STR_SH_INFO), 1016 EC_WORD(shdr0->sh_info), sh_info); 1017 ret = ELFEDIT_CMDRET_MOD; 1018 shdr0->sh_info = sh_info; 1019 elfedit_modified_shdr(sec0); 1020 } 1021 } 1022 break; 1023 1024 case EHDR_CMD_T_E_SHENTSIZE: 1025 { 1026 /* 1027 * The argument gives the size of a program 1028 * header element. 1029 */ 1030 Half shentsize = (Half) elfedit_atoui(argstate.argv[0], 1031 NULL); 1032 const char *name = MSG_ORIG(MSG_CMD_E_SHENTSIZE); 1033 1034 if (ehdr->e_shentsize == shentsize) { 1035 elfedit_msg(ELFEDIT_MSG_DEBUG, 1036 MSG_INTL(MSG_DEBUG_E_D_OK), name, 1037 EC_WORD(ehdr->e_shentsize)); 1038 } else { 1039 elfedit_msg(ELFEDIT_MSG_DEBUG, 1040 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 1041 EC_WORD(ehdr->e_shentsize), 1042 EC_WORD(shentsize)); 1043 ret = ELFEDIT_CMDRET_MOD; 1044 ehdr->e_shentsize = shentsize; 1045 } 1046 } 1047 break; 1048 1049 case EHDR_CMD_T_E_SHNUM: 1050 { 1051 /* The argument gives the number of section headers */ 1052 Word shnum = (Word) elfedit_atoui(argstate.argv[0], 1053 NULL); 1054 const char *name = MSG_ORIG(MSG_CMD_E_SHNUM); 1055 elfedit_section_t *sec0 = &obj_state->os_secarr[0]; 1056 Shdr *shdr0 = sec0->sec_shdr; 1057 Half e_shnum; 1058 Word sh_size; 1059 1060 if (shnum >= SHN_LORESERVE) { 1061 e_shnum = 0; 1062 sh_size = shnum; 1063 } else { 1064 e_shnum = shnum; 1065 sh_size = 0; 1066 } 1067 1068 if (ehdr->e_shnum == e_shnum) { 1069 elfedit_msg(ELFEDIT_MSG_DEBUG, 1070 MSG_INTL(MSG_DEBUG_E_D_OK), name, 1071 EC_WORD(ehdr->e_shnum)); 1072 } else { 1073 elfedit_msg(ELFEDIT_MSG_DEBUG, 1074 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 1075 EC_WORD(ehdr->e_shnum), e_shnum); 1076 ret = ELFEDIT_CMDRET_MOD; 1077 ehdr->e_shnum = e_shnum; 1078 } 1079 if (shdr0->sh_size == sh_size) { 1080 elfedit_msg(ELFEDIT_MSG_DEBUG, 1081 MSG_INTL(MSG_DEBUG_SHDR0_D_OK), 1082 MSG_ORIG(MSG_STR_SH_SIZE), 1083 EC_WORD(shdr0->sh_size)); 1084 } else { 1085 elfedit_msg(ELFEDIT_MSG_DEBUG, 1086 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), 1087 MSG_ORIG(MSG_STR_SH_SIZE), 1088 EC_WORD(shdr0->sh_size), sh_size); 1089 ret = ELFEDIT_CMDRET_MOD; 1090 shdr0->sh_size = sh_size; 1091 elfedit_modified_shdr(sec0); 1092 } 1093 } 1094 break; 1095 1096 case EHDR_CMD_T_E_SHSTRNDX: 1097 { 1098 const char *name = MSG_ORIG(MSG_CMD_E_SHSTRNDX); 1099 Word shstrndx; 1100 elfedit_section_t *sec0 = &obj_state->os_secarr[0]; 1101 Shdr *shdr0 = sec0->sec_shdr; 1102 Half e_shstrndx; 1103 Word sh_link; 1104 1105 /* 1106 * By default, sec argument is name of section. 1107 * If -shndx is used, it is a numeric index, and 1108 * if -shtyp is used, it is a section type. 1109 */ 1110 if (argstate.optmask & EHDR_OPT_F_SHNDX) 1111 shstrndx = elfedit_atoshndx(argstate.argv[0], 1112 obj_state->os_shnum); 1113 else if (argstate.optmask & EHDR_OPT_F_SHTYP) 1114 shstrndx = elfedit_type_to_shndx(obj_state, 1115 elfedit_atoconst(argstate.argv[0], 1116 ELFEDIT_CONST_SHT)); 1117 else 1118 shstrndx = elfedit_name_to_shndx(obj_state, 1119 argstate.argv[0]); 1120 1121 /* Warn if the section isn't a string table */ 1122 if ((shstrndx >= obj_state->os_shnum) || 1123 ((shstrndx >= SHN_LORESERVE) && 1124 (shstrndx <= SHN_HIRESERVE)) || 1125 (obj_state->os_secarr[shstrndx].sec_shdr->sh_type != 1126 SHT_STRTAB)) 1127 elfedit_msg(ELFEDIT_MSG_DEBUG, 1128 MSG_INTL(MSG_DEBUG_NOTSTRTAB), name, 1129 EC_WORD(shstrndx)); 1130 1131 if (shstrndx >= SHN_LORESERVE) { 1132 e_shstrndx = SHN_XINDEX; 1133 sh_link = shstrndx; 1134 } else { 1135 e_shstrndx = shstrndx; 1136 sh_link = 0; 1137 } 1138 1139 if (ehdr->e_shstrndx == e_shstrndx) { 1140 elfedit_msg(ELFEDIT_MSG_DEBUG, 1141 MSG_INTL(MSG_DEBUG_E_D_OK), name, 1142 EC_WORD(ehdr->e_shstrndx)); 1143 } else { 1144 elfedit_msg(ELFEDIT_MSG_DEBUG, 1145 MSG_INTL(MSG_DEBUG_E_D_CHG), name, 1146 EC_WORD(ehdr->e_shstrndx), e_shstrndx); 1147 ret = ELFEDIT_CMDRET_MOD; 1148 ehdr->e_shstrndx = e_shstrndx; 1149 } 1150 if (shdr0->sh_link == sh_link) { 1151 elfedit_msg(ELFEDIT_MSG_DEBUG, 1152 MSG_INTL(MSG_DEBUG_SHDR0_D_OK), 1153 MSG_ORIG(MSG_STR_SH_LINK), 1154 EC_WORD(shdr0->sh_link)); 1155 } else { 1156 elfedit_msg(ELFEDIT_MSG_DEBUG, 1157 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), 1158 MSG_ORIG(MSG_STR_SH_LINK), 1159 EC_WORD(shdr0->sh_link), sh_link); 1160 ret = ELFEDIT_CMDRET_MOD; 1161 shdr0->sh_link = sh_link; 1162 elfedit_modified_shdr(sec0); 1163 } 1164 } 1165 break; 1166 1167 case EHDR_CMD_T_EI_MAG0: 1168 case EHDR_CMD_T_EI_MAG1: 1169 case EHDR_CMD_T_EI_MAG2: 1170 case EHDR_CMD_T_EI_MAG3: 1171 { 1172 /* 1173 * This depends on EHDR_CMD_T_EI_MAG[0-3] 1174 * being contiguous 1175 */ 1176 int ei_ndx = (cmd - EHDR_CMD_T_EI_MAG0) + EI_MAG0; 1177 1178 /* The argument gives the magic number byte */ 1179 int mag = (int)elfedit_atoui_range(argstate.argv[0], 1180 MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL); 1181 1182 if (ehdr->e_ident[ei_ndx] == mag) { 1183 elfedit_msg(ELFEDIT_MSG_DEBUG, 1184 MSG_INTL(MSG_DEBUG_EI_S_S_OK), 1185 elfedit_atoconst_value_to_str( 1186 ELFEDIT_CONST_EI, ei_ndx, 1), 1187 conv_magic_value(ehdr->e_ident[ei_ndx])); 1188 } else { 1189 elfedit_msg(ELFEDIT_MSG_DEBUG, 1190 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), 1191 elfedit_atoconst_value_to_str( 1192 ELFEDIT_CONST_EI, ei_ndx, 1), 1193 conv_magic_value(ehdr->e_ident[ei_ndx]), 1194 conv_magic_value(mag)); 1195 ret = ELFEDIT_CMDRET_MOD; 1196 ehdr->e_ident[ei_ndx] = mag; 1197 } 1198 } 1199 break; 1200 1201 case EHDR_CMD_T_EI_CLASS: 1202 { 1203 /* The argument gives the ELFCLASS value */ 1204 int class = (int)elfedit_atoconst_range( 1205 argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, 1206 ELFEDIT_CONST_ELFCLASS); 1207 const char *name = elfedit_atoconst_value_to_str( 1208 ELFEDIT_CONST_EI, EI_CLASS, 1); 1209 1210 if (ehdr->e_ident[EI_CLASS] == class) { 1211 elfedit_msg(ELFEDIT_MSG_DEBUG, 1212 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, 1213 conv_ehdr_class(class, 0, &inv_buf1)); 1214 } else { 1215 elfedit_msg(ELFEDIT_MSG_DEBUG, 1216 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, 1217 conv_ehdr_class(ehdr->e_ident[EI_CLASS], 1218 0, &inv_buf1), 1219 conv_ehdr_class(class, 0, &inv_buf2)); 1220 ret = ELFEDIT_CMDRET_MOD; 1221 ehdr->e_ident[EI_CLASS] = class; 1222 } 1223 } 1224 break; 1225 1226 case EHDR_CMD_T_EI_DATA: 1227 { 1228 /* The argument gives the ELFDATA value */ 1229 int data = (int)elfedit_atoconst_range(argstate.argv[0], 1230 MSG_ORIG(MSG_STR_VALUE), 0, 255, 1231 ELFEDIT_CONST_ELFDATA); 1232 const char *name = elfedit_atoconst_value_to_str( 1233 ELFEDIT_CONST_EI, EI_DATA, 1); 1234 1235 if (ehdr->e_ident[EI_DATA] == data) { 1236 elfedit_msg(ELFEDIT_MSG_DEBUG, 1237 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, 1238 conv_ehdr_data(data, 0, &inv_buf1)); 1239 } else { 1240 elfedit_msg(ELFEDIT_MSG_DEBUG, 1241 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, 1242 conv_ehdr_data(ehdr->e_ident[EI_DATA], 1243 0, &inv_buf1), 1244 conv_ehdr_data(data, 0, &inv_buf2)); 1245 ret = ELFEDIT_CMDRET_MOD; 1246 ehdr->e_ident[EI_DATA] = data; 1247 } 1248 } 1249 break; 1250 1251 case EHDR_CMD_T_EI_VERSION: 1252 { 1253 /* The argument gives the version */ 1254 int ver = (int)elfedit_atoconst_range(argstate.argv[0], 1255 MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_EV); 1256 const char *name = elfedit_atoconst_value_to_str( 1257 ELFEDIT_CONST_EI, EI_VERSION, 1); 1258 1259 if (ehdr->e_ident[EI_VERSION] == ver) { 1260 elfedit_msg(ELFEDIT_MSG_DEBUG, 1261 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, 1262 conv_ehdr_vers(ver, 0, &inv_buf1)); 1263 } else { 1264 elfedit_msg(ELFEDIT_MSG_DEBUG, 1265 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, 1266 conv_ehdr_vers(ehdr->e_ident[EI_VERSION], 1267 0, &inv_buf1), 1268 conv_ehdr_vers(ver, 0, &inv_buf2)); 1269 ret = ELFEDIT_CMDRET_MOD; 1270 ehdr->e_ident[EI_VERSION] = ver; 1271 } 1272 } 1273 break; 1274 1275 case EHDR_CMD_T_EI_OSABI: 1276 { 1277 /* The argument gives the ABI code */ 1278 int osabi = (int)elfedit_atoconst_range( 1279 argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, 1280 ELFEDIT_CONST_ELFOSABI); 1281 const char *name = elfedit_atoconst_value_to_str( 1282 ELFEDIT_CONST_EI, EI_OSABI, 1); 1283 1284 if (ehdr->e_ident[EI_OSABI] == osabi) { 1285 elfedit_msg(ELFEDIT_MSG_DEBUG, 1286 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, 1287 conv_ehdr_osabi(osabi, 0, &inv_buf1)); 1288 } else { 1289 elfedit_msg(ELFEDIT_MSG_DEBUG, 1290 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, 1291 conv_ehdr_osabi(ehdr->e_ident[EI_OSABI], 1292 0, &inv_buf1), 1293 conv_ehdr_osabi(osabi, 0, &inv_buf2)); 1294 ret = ELFEDIT_CMDRET_MOD; 1295 ehdr->e_ident[EI_OSABI] = osabi; 1296 } 1297 } 1298 break; 1299 1300 case EHDR_CMD_T_EI_ABIVERSION: 1301 { 1302 /* The argument gives the ABI version */ 1303 int abiver = (int)elfedit_atoui_range(argstate.argv[0], 1304 MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL); 1305 const char *name = elfedit_atoconst_value_to_str( 1306 ELFEDIT_CONST_EI, EI_ABIVERSION, 1); 1307 1308 if (ehdr->e_ident[EI_ABIVERSION] == abiver) { 1309 elfedit_msg(ELFEDIT_MSG_DEBUG, 1310 MSG_INTL(MSG_DEBUG_EI_S_X_OK), name, 1311 EC_WORD(abiver)); 1312 } else { 1313 elfedit_msg(ELFEDIT_MSG_DEBUG, 1314 MSG_INTL(MSG_DEBUG_EI_S_X_CHG), name, 1315 EC_WORD(ehdr->e_ident[EI_ABIVERSION]), 1316 EC_WORD(abiver)); 1317 ret = ELFEDIT_CMDRET_MOD; 1318 ehdr->e_ident[EI_ABIVERSION] = abiver; 1319 } 1320 } 1321 break; 1322 } 1323 1324 /* 1325 * If we modified the ELF header, tell libelf. 1326 */ 1327 if (ret == ELFEDIT_CMDRET_MOD) 1328 elfedit_modified_ehdr(obj_state); 1329 1330 /* Do autoprint */ 1331 print_ehdr(cmd, e_ident_ndx, 1, &argstate); 1332 1333 return (ret); 1334 } 1335 1336 1337 1338 1339 /* 1340 * Command completion functions for the various commands 1341 */ 1342 1343 /*ARGSUSED*/ 1344 static void 1345 cpl_e_ident(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1346 const char *argv[], int num_opt) 1347 { 1348 elfedit_atoui_t ndx; 1349 1350 /* 1351 * This command doesn't accept options, so num_opt should be 1352 * 0. This is a defensive measure, in case that should change. 1353 */ 1354 argc -= num_opt; 1355 argv += num_opt; 1356 1357 if (argc == 1) { 1358 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EI); 1359 return; 1360 } 1361 1362 if (argc != 2) 1363 return; 1364 1365 /* 1366 * In order to offer up the right completion strings for 1367 * the value, we need to know what index was given for 1368 * the first argument. If we don't recognize the index, 1369 * we want to return quietly without issuing an error, 1370 * so we use elfedit_atoui_range2(), which returns 1371 * a success/failure result and does not throw any errors. 1372 */ 1373 if (elfedit_atoconst_range2(argv[0], 0, EI_NIDENT - 1, 1374 ELFEDIT_CONST_EI, &ndx) == 0) 1375 return; 1376 switch (ndx) { 1377 case EI_CLASS: 1378 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS); 1379 break; 1380 case EI_DATA: 1381 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA); 1382 break; 1383 case EI_VERSION: 1384 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV); 1385 break; 1386 case EI_OSABI: 1387 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI); 1388 break; 1389 } 1390 } 1391 1392 /*ARGSUSED*/ 1393 static void 1394 cpl_e_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1395 const char *argv[], int num_opt) 1396 { 1397 /* 1398 * This command doesn't accept options, so num_opt should be 1399 * 0. This is a defensive measure, in case that should change. 1400 */ 1401 argc -= num_opt; 1402 argv += num_opt; 1403 1404 if (argc == 1) 1405 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ET); 1406 } 1407 1408 /*ARGSUSED*/ 1409 static void 1410 cpl_e_machine(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1411 const char *argv[], int num_opt) 1412 { 1413 /* 1414 * This command doesn't accept options, so num_opt should be 1415 * 0. This is a defensive measure, in case that should change. 1416 */ 1417 argc -= num_opt; 1418 argv += num_opt; 1419 1420 if (argc == 1) 1421 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM); 1422 } 1423 1424 /*ARGSUSED*/ 1425 static void 1426 cpl_e_version(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1427 const char *argv[], int num_opt) 1428 { 1429 /* 1430 * This command doesn't accept options, so num_opt should be 1431 * 0. This is a defensive measure, in case that should change. 1432 */ 1433 argc -= num_opt; 1434 argv += num_opt; 1435 1436 if (argc == 1) 1437 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV); 1438 } 1439 1440 /*ARGSUSED*/ 1441 static void 1442 cpl_e_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1443 const char *argv[], int num_opt) 1444 { 1445 /* This routine allows multiple flags to be specified */ 1446 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EF); 1447 } 1448 1449 /*ARGSUSED*/ 1450 static void 1451 cpl_e_shstrndx(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1452 const char *argv[], int num_opt) 1453 { 1454 enum { NAME, INDEX, TYPE } op; 1455 Word ndx; 1456 1457 /* 1458 * The plainargument can be a section name, index, or 1459 * type, based on the options used. All have completions. 1460 */ 1461 if (argc != (num_opt + 1)) 1462 return; 1463 1464 op = NAME; 1465 for (ndx = 0; ndx < num_opt; ndx++) { 1466 if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0) 1467 op = INDEX; 1468 else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0) 1469 op = TYPE; 1470 } 1471 1472 if (obj_state == NULL) { /* No object available */ 1473 if (op == TYPE) 1474 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); 1475 return; 1476 } 1477 1478 /* 1479 * Loop over the sections and supply command completion 1480 * for the string tables in the file. 1481 */ 1482 for (ndx = 0; ndx < obj_state->os_shnum; ndx++) { 1483 elfedit_section_t *sec = &obj_state->os_secarr[ndx]; 1484 1485 if (sec->sec_shdr->sh_type != SHT_STRTAB) 1486 continue; 1487 1488 switch (op) { 1489 case NAME: 1490 elfedit_cpl_match(cpldata, sec->sec_name, 0); 1491 break; 1492 case INDEX: 1493 { 1494 char index[MAXNDXSIZE]; 1495 1496 (void) snprintf(index, sizeof (index), 1497 MSG_ORIG(MSG_FMT_WORDVAL), 1498 ndx); 1499 elfedit_cpl_match(cpldata, index, 1); 1500 } 1501 break; 1502 case TYPE: 1503 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT_STRTAB); 1504 break; 1505 } 1506 } 1507 } 1508 1509 /*ARGSUSED*/ 1510 static void 1511 cpl_ei_class(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1512 const char *argv[], int num_opt) 1513 { 1514 /* 1515 * This command doesn't accept options, so num_opt should be 1516 * 0. This is a defensive measure, in case that should change. 1517 */ 1518 argc -= num_opt; 1519 argv += num_opt; 1520 1521 if (argc == 1) 1522 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS); 1523 } 1524 1525 /*ARGSUSED*/ 1526 static void 1527 cpl_ei_data(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1528 const char *argv[], int num_opt) 1529 { 1530 /* 1531 * This command doesn't accept options, so num_opt should be 1532 * 0. This is a defensive measure, in case that should change. 1533 */ 1534 argc -= num_opt; 1535 argv += num_opt; 1536 1537 if (argc == 1) 1538 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA); 1539 } 1540 1541 /*ARGSUSED*/ 1542 static void 1543 cpl_ei_osabi(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1544 const char *argv[], int num_opt) 1545 { 1546 /* 1547 * This command doesn't accept options, so num_opt should be 1548 * 0. This is a defensive measure, in case that should change. 1549 */ 1550 argc -= num_opt; 1551 argv += num_opt; 1552 1553 if (argc == 1) 1554 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI); 1555 } 1556 1557 1558 1559 1560 /* 1561 * Implementation functions for the commands 1562 */ 1563 static elfedit_cmdret_t 1564 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1565 { 1566 return (cmd_body(EHDR_CMD_T_DUMP, obj_state, argc, argv)); 1567 } 1568 1569 1570 static elfedit_cmdret_t 1571 cmd_e_ident(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1572 { 1573 return (cmd_body(EHDR_CMD_T_E_IDENT, obj_state, argc, argv)); 1574 } 1575 1576 1577 static elfedit_cmdret_t 1578 cmd_e_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1579 { 1580 return (cmd_body(EHDR_CMD_T_E_TYPE, obj_state, argc, argv)); 1581 } 1582 1583 1584 static elfedit_cmdret_t 1585 cmd_e_machine(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1586 { 1587 return (cmd_body(EHDR_CMD_T_E_MACHINE, obj_state, argc, argv)); 1588 } 1589 1590 1591 static elfedit_cmdret_t 1592 cmd_e_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1593 { 1594 return (cmd_body(EHDR_CMD_T_E_VERSION, obj_state, argc, argv)); 1595 } 1596 1597 1598 static elfedit_cmdret_t 1599 cmd_e_entry(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1600 { 1601 return (cmd_body(EHDR_CMD_T_E_ENTRY, obj_state, argc, argv)); 1602 } 1603 1604 1605 static elfedit_cmdret_t 1606 cmd_e_phoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1607 { 1608 return (cmd_body(EHDR_CMD_T_E_PHOFF, obj_state, argc, argv)); 1609 } 1610 1611 1612 static elfedit_cmdret_t 1613 cmd_e_shoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1614 { 1615 return (cmd_body(EHDR_CMD_T_E_SHOFF, obj_state, argc, argv)); 1616 } 1617 1618 1619 static elfedit_cmdret_t 1620 cmd_e_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1621 { 1622 return (cmd_body(EHDR_CMD_T_E_FLAGS, obj_state, argc, argv)); 1623 } 1624 1625 1626 static elfedit_cmdret_t 1627 cmd_e_ehsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1628 { 1629 return (cmd_body(EHDR_CMD_T_E_EHSIZE, obj_state, argc, argv)); 1630 } 1631 1632 1633 static elfedit_cmdret_t 1634 cmd_e_phentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1635 { 1636 return (cmd_body(EHDR_CMD_T_E_PHENTSIZE, obj_state, argc, argv)); 1637 } 1638 1639 1640 static elfedit_cmdret_t 1641 cmd_e_phnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1642 { 1643 return (cmd_body(EHDR_CMD_T_E_PHNUM, obj_state, argc, argv)); 1644 } 1645 1646 1647 static elfedit_cmdret_t 1648 cmd_e_shentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1649 { 1650 return (cmd_body(EHDR_CMD_T_E_SHENTSIZE, obj_state, argc, argv)); 1651 } 1652 1653 1654 static elfedit_cmdret_t 1655 cmd_e_shnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1656 { 1657 return (cmd_body(EHDR_CMD_T_E_SHNUM, obj_state, argc, argv)); 1658 } 1659 1660 1661 static elfedit_cmdret_t 1662 cmd_e_shstrndx(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1663 { 1664 return (cmd_body(EHDR_CMD_T_E_SHSTRNDX, obj_state, argc, argv)); 1665 } 1666 1667 1668 static elfedit_cmdret_t 1669 cmd_ei_mag0(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1670 { 1671 return (cmd_body(EHDR_CMD_T_EI_MAG0, obj_state, argc, argv)); 1672 } 1673 1674 1675 static elfedit_cmdret_t 1676 cmd_ei_mag1(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1677 { 1678 return (cmd_body(EHDR_CMD_T_EI_MAG1, obj_state, argc, argv)); 1679 } 1680 1681 1682 static elfedit_cmdret_t 1683 cmd_ei_mag2(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1684 { 1685 return (cmd_body(EHDR_CMD_T_EI_MAG2, obj_state, argc, argv)); 1686 } 1687 1688 1689 static elfedit_cmdret_t 1690 cmd_ei_mag3(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1691 { 1692 return (cmd_body(EHDR_CMD_T_EI_MAG3, obj_state, argc, argv)); 1693 } 1694 1695 1696 static elfedit_cmdret_t 1697 cmd_ei_class(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1698 { 1699 return (cmd_body(EHDR_CMD_T_EI_CLASS, obj_state, argc, argv)); 1700 } 1701 1702 1703 static elfedit_cmdret_t 1704 cmd_ei_data(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1705 { 1706 return (cmd_body(EHDR_CMD_T_EI_DATA, obj_state, argc, argv)); 1707 } 1708 1709 1710 static elfedit_cmdret_t 1711 cmd_ei_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1712 { 1713 return (cmd_body(EHDR_CMD_T_EI_VERSION, obj_state, argc, argv)); 1714 } 1715 1716 1717 static elfedit_cmdret_t 1718 cmd_ei_osabi(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1719 { 1720 return (cmd_body(EHDR_CMD_T_EI_OSABI, obj_state, argc, argv)); 1721 } 1722 1723 1724 static elfedit_cmdret_t 1725 cmd_ei_abiversion(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1726 { 1727 return (cmd_body(EHDR_CMD_T_EI_ABIVERSION, obj_state, argc, argv)); 1728 } 1729 1730 1731 1732 1733 /*ARGSUSED*/ 1734 elfedit_module_t * 1735 elfedit_init(elfedit_module_version_t version) 1736 { 1737 /* Many of the commands only accept -o */ 1738 static elfedit_cmd_optarg_t opt_std[] = { 1739 { ELFEDIT_STDOA_OPT_O, NULL, 1740 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1741 { NULL } 1742 }; 1743 1744 1745 /* ehdr:dump */ 1746 static const char *name_dump[] = { 1747 MSG_ORIG(MSG_CMD_DUMP), 1748 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 1749 NULL 1750 }; 1751 1752 /* ehdr:e_ident */ 1753 static const char *name_e_ident[] = { 1754 MSG_ORIG(MSG_CMD_E_IDENT), NULL }; 1755 static elfedit_cmd_optarg_t arg_e_ident[] = { 1756 { MSG_ORIG(MSG_STR_INDEX), 1757 /* MSG_INTL(MSG_ARGDESC_E_IDENT_NDX) */ 1758 ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_NDX), 1759 ELFEDIT_CMDOA_F_OPT, 0 }, 1760 { MSG_ORIG(MSG_STR_VALUE), 1761 /* MSG_INTL(MSG_ARGDESC_E_IDENT_VALUE) */ 1762 ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_VALUE), 1763 ELFEDIT_CMDOA_F_OPT, 0 }, 1764 { NULL } 1765 }; 1766 1767 /* ehdr:e_type */ 1768 static const char *name_e_type[] = { 1769 MSG_ORIG(MSG_CMD_E_TYPE), NULL }; 1770 static elfedit_cmd_optarg_t arg_e_type[] = { 1771 { MSG_ORIG(MSG_STR_VALUE), 1772 /* MSG_INTL(MSG_ARGDESC_E_TYPE_VALUE) */ 1773 ELFEDIT_I18NHDL(MSG_ARGDESC_E_TYPE_VALUE), 1774 ELFEDIT_CMDOA_F_OPT, 0 }, 1775 { NULL } 1776 }; 1777 1778 /* ehdr:e_machine */ 1779 static const char *name_e_machine[] = { 1780 MSG_ORIG(MSG_CMD_E_MACHINE), NULL }; 1781 static elfedit_cmd_optarg_t arg_e_machine[] = { 1782 { MSG_ORIG(MSG_STR_TYPE), 1783 /* MSG_INTL(MSG_ARGDESC_E_MACHINE_VALUE) */ 1784 ELFEDIT_I18NHDL(MSG_ARGDESC_E_MACHINE_VALUE), 1785 ELFEDIT_CMDOA_F_OPT, 0 }, 1786 { NULL } 1787 }; 1788 1789 /* ehdr:e_version */ 1790 static const char *name_e_version[] = { 1791 MSG_ORIG(MSG_CMD_E_VERSION), NULL }; 1792 static elfedit_cmd_optarg_t arg_e_version[] = { 1793 { MSG_ORIG(MSG_STR_VERSION), 1794 /* MSG_INTL(MSG_ARGDESC_E_VERSION_VALUE) */ 1795 ELFEDIT_I18NHDL(MSG_ARGDESC_E_VERSION_VALUE), 1796 ELFEDIT_CMDOA_F_OPT, 0 }, 1797 { NULL } 1798 }; 1799 1800 /* ehdr:e_entry */ 1801 static const char *name_e_entry[] = { 1802 MSG_ORIG(MSG_CMD_E_ENTRY), NULL }; 1803 static elfedit_cmd_optarg_t arg_e_entry[] = { 1804 { MSG_ORIG(MSG_STR_VALUE), 1805 /* MSG_INTL(MSG_ARGDESC_E_ENTRY_VALUE) */ 1806 ELFEDIT_I18NHDL(MSG_ARGDESC_E_ENTRY_VALUE), 1807 ELFEDIT_CMDOA_F_OPT, 0 }, 1808 { NULL } 1809 }; 1810 1811 /* ehdr:e_phoff */ 1812 static const char *name_e_phoff[] = { 1813 MSG_ORIG(MSG_CMD_E_PHOFF), NULL }; 1814 static elfedit_cmd_optarg_t arg_e_phoff[] = { 1815 { MSG_ORIG(MSG_STR_OFFSET), 1816 /* MSG_INTL(MSG_ARGDESC_E_PHOFF_VALUE) */ 1817 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHOFF_VALUE), 1818 ELFEDIT_CMDOA_F_OPT, 0 }, 1819 { NULL } 1820 }; 1821 1822 /* ehdr:e_shoff */ 1823 static const char *name_e_shoff[] = { 1824 MSG_ORIG(MSG_CMD_E_SHOFF), NULL }; 1825 static elfedit_cmd_optarg_t arg_e_shoff[] = { 1826 { MSG_ORIG(MSG_STR_OFFSET), 1827 /* MSG_INTL(MSG_ARGDESC_E_SHOFF_VALUE) */ 1828 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHOFF_VALUE), 1829 ELFEDIT_CMDOA_F_OPT, 0 }, 1830 { NULL } 1831 }; 1832 1833 /* ehdr:e_flags */ 1834 static const char *name_e_flags[] = { 1835 MSG_ORIG(MSG_CMD_E_FLAGS), NULL }; 1836 static elfedit_cmd_optarg_t opt_e_flags[] = { 1837 { ELFEDIT_STDOA_OPT_AND, NULL, 1838 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_AND, EHDR_OPT_F_OR }, 1839 { ELFEDIT_STDOA_OPT_CMP, NULL, 1840 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_CMP, 0 }, 1841 { ELFEDIT_STDOA_OPT_O, NULL, 1842 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1843 { ELFEDIT_STDOA_OPT_OR, NULL, 1844 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_OR, EHDR_OPT_F_AND }, 1845 { NULL } 1846 }; 1847 static elfedit_cmd_optarg_t arg_e_flags[] = { 1848 { MSG_ORIG(MSG_STR_FLAGVALUE), 1849 /* MSG_INTL(MSG_ARGDESC_E_FLAGS_VALUE) */ 1850 ELFEDIT_I18NHDL(MSG_ARGDESC_E_FLAGS_VALUE), 1851 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT, 0 }, 1852 { NULL } 1853 }; 1854 1855 /* ehdr:e_ehsize */ 1856 static const char *name_e_ehsize[] = { 1857 MSG_ORIG(MSG_CMD_E_EHSIZE), NULL }; 1858 static elfedit_cmd_optarg_t arg_e_ehsize[] = { 1859 { MSG_ORIG(MSG_STR_VALUE), 1860 /* MSG_INTL(MSG_ARGDESC_E_EHSIZE_VALUE) */ 1861 ELFEDIT_I18NHDL(MSG_ARGDESC_E_EHSIZE_VALUE), 1862 ELFEDIT_CMDOA_F_OPT, 0 }, 1863 { NULL } 1864 }; 1865 1866 /* ehdr:e_phentsize */ 1867 static const char *name_e_phentsize[] = { 1868 MSG_ORIG(MSG_CMD_E_PHENTSIZE), NULL }; 1869 static elfedit_cmd_optarg_t arg_e_phentsize[] = { 1870 { MSG_ORIG(MSG_STR_VALUE), 1871 /* MSG_INTL(MSG_ARGDESC_E_PHENTSIZE_VALUE) */ 1872 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHENTSIZE_VALUE), 1873 ELFEDIT_CMDOA_F_OPT, 0 }, 1874 { NULL } 1875 }; 1876 1877 /* ehdr:e_phnum */ 1878 static const char *name_e_phnum[] = { 1879 MSG_ORIG(MSG_CMD_E_PHNUM), NULL }; 1880 static elfedit_cmd_optarg_t arg_e_phnum[] = { 1881 { MSG_ORIG(MSG_STR_VALUE), 1882 /* MSG_INTL(MSG_ARGDESC_E_PHNUM_VALUE) */ 1883 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHNUM_VALUE), 1884 ELFEDIT_CMDOA_F_OPT, 0 }, 1885 { NULL } 1886 }; 1887 1888 /* ehdr:e_shentsize */ 1889 static const char *name_e_shentsize[] = { 1890 MSG_ORIG(MSG_CMD_E_SHENTSIZE), NULL }; 1891 static elfedit_cmd_optarg_t arg_e_shentsize[] = { 1892 { MSG_ORIG(MSG_STR_VALUE), 1893 /* MSG_INTL(MSG_ARGDESC_E_SHENTSIZE_VALUE) */ 1894 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHENTSIZE_VALUE), 1895 ELFEDIT_CMDOA_F_OPT, 0 }, 1896 { NULL } 1897 }; 1898 1899 /* ehdr:e_shnum */ 1900 static const char *name_e_shnum[] = { 1901 MSG_ORIG(MSG_CMD_E_SHNUM), NULL }; 1902 static elfedit_cmd_optarg_t arg_e_shnum[] = { 1903 { MSG_ORIG(MSG_STR_VALUE), 1904 /* MSG_INTL(MSG_ARGDESC_E_SHNUM_VALUE) */ 1905 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHNUM_VALUE), 1906 ELFEDIT_CMDOA_F_OPT, 0 }, 1907 { NULL } 1908 }; 1909 1910 /* ehdr:e_shstrndx */ 1911 static const char *name_e_shstrndx[] = { 1912 MSG_ORIG(MSG_CMD_E_SHSTRNDX), NULL }; 1913 static elfedit_cmd_optarg_t opt_e_shstrndx[] = { 1914 { ELFEDIT_STDOA_OPT_O, NULL, 1915 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1916 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1917 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1918 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, 1919 EHDR_OPT_F_SHNDX, EHDR_OPT_F_SHTYP }, 1920 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1921 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1922 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, 1923 EHDR_OPT_F_SHTYP, EHDR_OPT_F_SHNDX, }, 1924 { NULL } 1925 }; 1926 static elfedit_cmd_optarg_t arg_e_shstrndx[] = { 1927 { MSG_ORIG(MSG_STR_SEC), 1928 /* MSG_INTL(MSG_ARGDESC_E_SHSTRNDX_SEC) */ 1929 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHSTRNDX_SEC), 1930 ELFEDIT_CMDOA_F_OPT, 0 }, 1931 { NULL } 1932 }; 1933 1934 /* ehdr:ei_mag0 */ 1935 static const char *name_ei_mag0[] = { 1936 MSG_ORIG(MSG_CMD_EI_MAG0), NULL }; 1937 static elfedit_cmd_optarg_t arg_ei_mag0[] = { 1938 { MSG_ORIG(MSG_STR_VALUE), 1939 /* MSG_INTL(MSG_ARGDESC_EI_MAG0_VALUE) */ 1940 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG0_VALUE), 1941 ELFEDIT_CMDOA_F_OPT, 0 }, 1942 { NULL } 1943 }; 1944 1945 /* ehdr:ei_mag1 */ 1946 static const char *name_ei_mag1[] = { 1947 MSG_ORIG(MSG_CMD_EI_MAG1), NULL }; 1948 static elfedit_cmd_optarg_t arg_ei_mag1[] = { 1949 { MSG_ORIG(MSG_STR_VALUE), 1950 /* MSG_INTL(MSG_ARGDESC_EI_MAG1_VALUE) */ 1951 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG1_VALUE), 1952 ELFEDIT_CMDOA_F_OPT, 0 }, 1953 { NULL } 1954 }; 1955 1956 /* ehdr:ei_mag2 */ 1957 static const char *name_ei_mag2[] = { 1958 MSG_ORIG(MSG_CMD_EI_MAG2), NULL }; 1959 static elfedit_cmd_optarg_t arg_ei_mag2[] = { 1960 { MSG_ORIG(MSG_STR_VALUE), 1961 /* MSG_INTL(MSG_ARGDESC_EI_MAG2_VALUE) */ 1962 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG2_VALUE), 1963 ELFEDIT_CMDOA_F_OPT, 0 }, 1964 { NULL } 1965 }; 1966 1967 /* ehdr:ei_mag3 */ 1968 static const char *name_ei_mag3[] = { 1969 MSG_ORIG(MSG_CMD_EI_MAG3), NULL }; 1970 static elfedit_cmd_optarg_t arg_ei_mag3[] = { 1971 { MSG_ORIG(MSG_STR_VALUE), 1972 /* MSG_INTL(MSG_ARGDESC_EI_MAG3_VALUE) */ 1973 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG3_VALUE), 1974 ELFEDIT_CMDOA_F_OPT, 0 }, 1975 { NULL } 1976 }; 1977 1978 /* ehdr:ei_class */ 1979 static const char *name_ei_class[] = { 1980 MSG_ORIG(MSG_CMD_EI_CLASS), NULL }; 1981 static elfedit_cmd_optarg_t arg_ei_class[] = { 1982 { MSG_ORIG(MSG_STR_VALUE), 1983 /* MSG_INTL(MSG_ARGDESC_EI_CLASS_VALUE) */ 1984 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_CLASS_VALUE), 1985 ELFEDIT_CMDOA_F_OPT, 0 }, 1986 { NULL } 1987 }; 1988 1989 /* ehdr:ei_data */ 1990 static const char *name_ei_data[] = { 1991 MSG_ORIG(MSG_CMD_EI_DATA), NULL }; 1992 static elfedit_cmd_optarg_t arg_ei_data[] = { 1993 { MSG_ORIG(MSG_STR_VALUE), 1994 /* MSG_INTL(MSG_ARGDESC_EI_DATA_VALUE) */ 1995 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_DATA_VALUE), 1996 ELFEDIT_CMDOA_F_OPT, 0 }, 1997 { NULL } 1998 }; 1999 2000 /* ehdr:ei_version */ 2001 static const char *name_ei_version[] = { 2002 MSG_ORIG(MSG_CMD_EI_VERSION), NULL }; 2003 /* Note: arg_e_version is also used for this command */ 2004 2005 /* ehdr:ei_osabi */ 2006 static const char *name_ei_osabi[] = { 2007 MSG_ORIG(MSG_CMD_EI_OSABI), NULL }; 2008 static elfedit_cmd_optarg_t arg_ei_osabi[] = { 2009 { MSG_ORIG(MSG_STR_VALUE), 2010 /* MSG_INTL(MSG_ARGDESC_EI_OSABI_VALUE) */ 2011 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_OSABI_VALUE), 2012 ELFEDIT_CMDOA_F_OPT, 0 }, 2013 { NULL } 2014 }; 2015 2016 /* ehdr:ei_abiversion */ 2017 static const char *name_ei_abiversion[] = { 2018 MSG_ORIG(MSG_CMD_EI_ABIVERSION), NULL }; 2019 static elfedit_cmd_optarg_t arg_ei_abiversion[] = { 2020 { MSG_ORIG(MSG_STR_VALUE), 2021 /* MSG_INTL(MSG_ARGDESC_EI_ABIVERSION_VALUE) */ 2022 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_ABIVERSION_VALUE), 2023 ELFEDIT_CMDOA_F_OPT, 0 }, 2024 { NULL } 2025 }; 2026 2027 2028 2029 2030 static elfedit_cmd_t cmds[] = { 2031 /* ehdr:dump */ 2032 { cmd_dump, NULL, name_dump, 2033 /* MSG_INTL(MSG_DESC_DUMP) */ 2034 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 2035 /* MSG_INTL(MSG_HELP_DUMP) */ 2036 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 2037 NULL, NULL }, 2038 2039 /* ehdr:e_ident */ 2040 { cmd_e_ident, cpl_e_ident, name_e_ident, 2041 /* MSG_INTL(MSG_DESC_E_IDENT) */ 2042 ELFEDIT_I18NHDL(MSG_DESC_E_IDENT), 2043 /* MSG_INTL(MSG_HELP_E_IDENT) */ 2044 ELFEDIT_I18NHDL(MSG_HELP_E_IDENT), 2045 opt_std, arg_e_ident }, 2046 2047 /* ehdr:e_type */ 2048 { cmd_e_type, cpl_e_type, name_e_type, 2049 /* MSG_INTL(MSG_DESC_E_TYPE) */ 2050 ELFEDIT_I18NHDL(MSG_DESC_E_TYPE), 2051 /* MSG_INTL(MSG_HELP_E_TYPE) */ 2052 ELFEDIT_I18NHDL(MSG_HELP_E_TYPE), 2053 opt_std, arg_e_type }, 2054 2055 /* ehdr:e_machine */ 2056 { cmd_e_machine, cpl_e_machine, name_e_machine, 2057 /* MSG_INTL(MSG_DESC_E_MACHINE) */ 2058 ELFEDIT_I18NHDL(MSG_DESC_E_MACHINE), 2059 /* MSG_INTL(MSG_HELP_E_MACHINE) */ 2060 ELFEDIT_I18NHDL(MSG_HELP_E_MACHINE), 2061 opt_std, arg_e_machine }, 2062 2063 /* ehdr:e_version */ 2064 { cmd_e_version, cpl_e_version, name_e_version, 2065 /* MSG_INTL(MSG_DESC_E_VERSION) */ 2066 ELFEDIT_I18NHDL(MSG_DESC_E_VERSION), 2067 /* MSG_INTL(MSG_HELP_E_VERSION) */ 2068 ELFEDIT_I18NHDL(MSG_HELP_E_VERSION), 2069 opt_std, arg_e_version }, 2070 2071 /* ehdr:e_entry */ 2072 { cmd_e_entry, NULL, name_e_entry, 2073 /* MSG_INTL(MSG_DESC_E_ENTRY) */ 2074 ELFEDIT_I18NHDL(MSG_DESC_E_ENTRY), 2075 /* MSG_INTL(MSG_HELP_E_ENTRY) */ 2076 ELFEDIT_I18NHDL(MSG_HELP_E_ENTRY), 2077 opt_std, arg_e_entry }, 2078 2079 /* ehdr:e_phoff */ 2080 { cmd_e_phoff, NULL, name_e_phoff, 2081 /* MSG_INTL(MSG_DESC_E_PHOFF) */ 2082 ELFEDIT_I18NHDL(MSG_DESC_E_PHOFF), 2083 /* MSG_INTL(MSG_HELP_E_PHOFF) */ 2084 ELFEDIT_I18NHDL(MSG_HELP_E_PHOFF), 2085 opt_std, arg_e_phoff }, 2086 2087 /* ehdr:e_shoff */ 2088 { cmd_e_shoff, NULL, name_e_shoff, 2089 /* MSG_INTL(MSG_DESC_E_SHOFF) */ 2090 ELFEDIT_I18NHDL(MSG_DESC_E_SHOFF), 2091 /* MSG_INTL(MSG_HELP_E_SHOFF) */ 2092 ELFEDIT_I18NHDL(MSG_HELP_E_SHOFF), 2093 opt_std, arg_e_shoff }, 2094 2095 /* ehdr:e_flags */ 2096 { cmd_e_flags, cpl_e_flags, name_e_flags, 2097 /* MSG_INTL(MSG_DESC_E_FLAGS) */ 2098 ELFEDIT_I18NHDL(MSG_DESC_E_FLAGS), 2099 /* MSG_INTL(MSG_HELP_E_FLAGS) */ 2100 ELFEDIT_I18NHDL(MSG_HELP_E_FLAGS), 2101 opt_e_flags, arg_e_flags }, 2102 2103 /* ehdr:e_ehsize */ 2104 { cmd_e_ehsize, NULL, name_e_ehsize, 2105 /* MSG_INTL(MSG_DESC_E_EHSIZE) */ 2106 ELFEDIT_I18NHDL(MSG_DESC_E_EHSIZE), 2107 /* MSG_INTL(MSG_HELP_E_EHSIZE) */ 2108 ELFEDIT_I18NHDL(MSG_HELP_E_EHSIZE), 2109 opt_std, arg_e_ehsize }, 2110 2111 /* ehdr:e_phentsize */ 2112 { cmd_e_phentsize, NULL, name_e_phentsize, 2113 /* MSG_INTL(MSG_DESC_E_PHENTSIZE) */ 2114 ELFEDIT_I18NHDL(MSG_DESC_E_PHENTSIZE), 2115 /* MSG_INTL(MSG_HELP_E_PHENTSIZE) */ 2116 ELFEDIT_I18NHDL(MSG_HELP_E_PHENTSIZE), 2117 opt_std, arg_e_phentsize }, 2118 2119 /* ehdr:e_phnum */ 2120 { cmd_e_phnum, NULL, name_e_phnum, 2121 /* MSG_INTL(MSG_DESC_E_PHNUM) */ 2122 ELFEDIT_I18NHDL(MSG_DESC_E_PHNUM), 2123 /* MSG_INTL(MSG_HELP_E_PHNUM) */ 2124 ELFEDIT_I18NHDL(MSG_HELP_E_PHNUM), 2125 opt_std, arg_e_phnum }, 2126 2127 /* ehdr:e_shentsize */ 2128 { cmd_e_shentsize, NULL, name_e_shentsize, 2129 /* MSG_INTL(MSG_DESC_E_SHENTSIZE) */ 2130 ELFEDIT_I18NHDL(MSG_DESC_E_SHENTSIZE), 2131 /* MSG_INTL(MSG_HELP_E_SHENTSIZE) */ 2132 ELFEDIT_I18NHDL(MSG_HELP_E_SHENTSIZE), 2133 opt_std, arg_e_shentsize }, 2134 2135 /* ehdr:e_shnum */ 2136 { cmd_e_shnum, NULL, name_e_shnum, 2137 /* MSG_INTL(MSG_DESC_E_SHNUM) */ 2138 ELFEDIT_I18NHDL(MSG_DESC_E_SHNUM), 2139 /* MSG_INTL(MSG_HELP_E_SHNUM) */ 2140 ELFEDIT_I18NHDL(MSG_HELP_E_SHNUM), 2141 opt_std, arg_e_shnum }, 2142 2143 /* ehdr:e_shstrndx */ 2144 { cmd_e_shstrndx, cpl_e_shstrndx, name_e_shstrndx, 2145 /* MSG_INTL(MSG_DESC_E_SHSTRNDX) */ 2146 ELFEDIT_I18NHDL(MSG_DESC_E_SHSTRNDX), 2147 /* MSG_INTL(MSG_HELP_E_SHSTRNDX) */ 2148 ELFEDIT_I18NHDL(MSG_HELP_E_SHSTRNDX), 2149 opt_e_shstrndx, arg_e_shstrndx }, 2150 2151 /* ehdr:ei_mag0 */ 2152 { cmd_ei_mag0, NULL, name_ei_mag0, 2153 /* MSG_INTL(MSG_DESC_EI_MAG0) */ 2154 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG0), 2155 /* MSG_INTL(MSG_HELP_EI_MAG0) */ 2156 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG0), 2157 opt_std, arg_ei_mag0 }, 2158 2159 /* ehdr:ei_mag1 */ 2160 { cmd_ei_mag1, NULL, name_ei_mag1, 2161 /* MSG_INTL(MSG_DESC_EI_MAG1) */ 2162 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG1), 2163 /* MSG_INTL(MSG_HELP_EI_MAG1) */ 2164 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG1), 2165 opt_std, arg_ei_mag1 }, 2166 2167 /* ehdr:ei_mag2 */ 2168 { cmd_ei_mag2, NULL, name_ei_mag2, 2169 /* MSG_INTL(MSG_DESC_EI_MAG2) */ 2170 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG2), 2171 /* MSG_INTL(MSG_HELP_EI_MAG2) */ 2172 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG2), 2173 opt_std, arg_ei_mag2 }, 2174 2175 /* ehdr:ei_mag3 */ 2176 { cmd_ei_mag3, NULL, name_ei_mag3, 2177 /* MSG_INTL(MSG_DESC_EI_MAG3) */ 2178 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG3), 2179 /* MSG_INTL(MSG_HELP_EI_MAG3) */ 2180 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG3), 2181 opt_std, arg_ei_mag3 }, 2182 2183 /* ehdr:ei_class */ 2184 { cmd_ei_class, cpl_ei_class, name_ei_class, 2185 /* MSG_INTL(MSG_DESC_EI_CLASS) */ 2186 ELFEDIT_I18NHDL(MSG_DESC_EI_CLASS), 2187 /* MSG_INTL(MSG_HELP_EI_CLASS) */ 2188 ELFEDIT_I18NHDL(MSG_HELP_EI_CLASS), 2189 opt_std, arg_ei_class }, 2190 2191 /* ehdr:ei_data */ 2192 { cmd_ei_data, cpl_ei_data, name_ei_data, 2193 /* MSG_INTL(MSG_DESC_EI_DATA) */ 2194 ELFEDIT_I18NHDL(MSG_DESC_EI_DATA), 2195 /* MSG_INTL(MSG_HELP_EI_DATA) */ 2196 ELFEDIT_I18NHDL(MSG_HELP_EI_DATA), 2197 opt_std, arg_ei_data }, 2198 2199 /* ehdr:ei_version */ 2200 { cmd_ei_version, cpl_e_version, name_ei_version, 2201 /* MSG_INTL(MSG_DESC_EI_VERSION) */ 2202 ELFEDIT_I18NHDL(MSG_DESC_EI_VERSION), 2203 /* MSG_INTL(MSG_HELP_EI_VERSION) */ 2204 ELFEDIT_I18NHDL(MSG_HELP_EI_VERSION), 2205 opt_std, arg_e_version }, 2206 2207 /* ehdr:ei_osabi */ 2208 { cmd_ei_osabi, cpl_ei_osabi, name_ei_osabi, 2209 /* MSG_INTL(MSG_DESC_EI_OSABI) */ 2210 ELFEDIT_I18NHDL(MSG_DESC_EI_OSABI), 2211 /* MSG_INTL(MSG_HELP_EI_OSABI) */ 2212 ELFEDIT_I18NHDL(MSG_HELP_EI_OSABI), 2213 opt_std, arg_ei_osabi }, 2214 2215 /* ehdr:ei_abiversion */ 2216 { cmd_ei_abiversion, NULL, name_ei_abiversion, 2217 /* MSG_INTL(MSG_DESC_EI_ABIVERSION) */ 2218 ELFEDIT_I18NHDL(MSG_DESC_EI_ABIVERSION), 2219 /* MSG_INTL(MSG_HELP_EI_ABIVERSION) */ 2220 ELFEDIT_I18NHDL(MSG_HELP_EI_ABIVERSION), 2221 opt_std, arg_ei_abiversion }, 2222 2223 { NULL } 2224 }; 2225 2226 static elfedit_module_t module = { 2227 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 2228 /* MSG_INTL(MSG_MOD_DESC) */ 2229 ELFEDIT_I18NHDL(MSG_MOD_DESC), 2230 cmds, mod_i18nhdl_to_str }; 2231 2232 return (&module); 2233 } 2234