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