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