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