1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <unistd.h> 30 #include <machdep.h> 31 #include <elfedit.h> 32 #include <sys/elf_SPARC.h> 33 #include <sys/elf_amd64.h> 34 #include <strings.h> 35 #include <debug.h> 36 #include <conv.h> 37 #include <shdr_msg.h> 38 39 40 41 42 /* 43 * This module uses shared code for several of the commands. 44 * It is sometimes necessary to know which specific command 45 * is active. 46 */ 47 typedef enum { 48 SHDR_CMD_T_DUMP = 0, /* shdr:dump */ 49 50 SHDR_CMD_T_SH_ADDR = 1, /* shdr:sh_addr */ 51 SHDR_CMD_T_SH_ADDRALIGN = 2, /* shdr:sh_addralign */ 52 SHDR_CMD_T_SH_ENTSIZE = 3, /* shdr:sh_entsize */ 53 SHDR_CMD_T_SH_FLAGS = 4, /* shdr:sh_flags */ 54 SHDR_CMD_T_SH_INFO = 5, /* shdr:sh_info */ 55 SHDR_CMD_T_SH_LINK = 6, /* shdr:sh_link */ 56 SHDR_CMD_T_SH_NAME = 7, /* shdr:sh_name */ 57 SHDR_CMD_T_SH_OFFSET = 8, /* shdr:sh_offset */ 58 SHDR_CMD_T_SH_SIZE = 9, /* shdr:sh_size */ 59 SHDR_CMD_T_SH_TYPE = 10 /* shdr:sh_type */ 60 } SHDR_CMD_T; 61 62 63 64 #ifndef _ELF64 65 /* 66 * We supply this function for the msg module. Only one copy is needed. 67 */ 68 const char * 69 _shdr_msg(Msg mid) 70 { 71 return (gettext(MSG_ORIG(mid))); 72 } 73 74 #endif 75 76 77 78 /* 79 * This function is supplied to elfedit through our elfedit_module_t 80 * definition. It translates the opaque elfedit_i18nhdl_t handles 81 * in our module interface into the actual strings for elfedit to 82 * use. 83 * 84 * note: 85 * This module uses Msg codes for its i18n handle type. 86 * So the translation is simply to use MSG_INTL() to turn 87 * it into a string and return it. 88 */ 89 static const char * 90 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 91 { 92 Msg msg = (Msg)hdl; 93 94 return (MSG_INTL(msg)); 95 } 96 97 98 99 /* 100 * The shdr_opt_t enum specifies a bit value for every optional 101 * argument allowed by a command in this module. 102 */ 103 typedef enum { 104 SHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */ 105 SHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ 106 SHDR_OPT_F_NAMOFFSET = 4, /* -name_offset: Name arg is numeric */ 107 /* ofset rather than string */ 108 SHDR_OPT_F_OR = 8, /* -or: OR (|) values to dest */ 109 SHDR_OPT_F_SHNDX = 16, /* -shndx: Section by index, not name */ 110 SHDR_OPT_F_SHTYP = 32 /* -shtyp: Section by type, not name */ 111 } shdr_opt_t; 112 113 114 /* 115 * A variable of type ARGSTATE is used by each command to maintain 116 * information about the section headers and related things. It is 117 * initialized by process_args(), and used by the other routines. 118 */ 119 typedef struct { 120 elfedit_obj_state_t *obj_state; 121 shdr_opt_t optmask; /* Mask of options used */ 122 int argc; /* # of plain arguments */ 123 const char **argv; /* Plain arguments */ 124 } ARGSTATE; 125 126 127 128 129 /* 130 * Standard argument processing for shdr module 131 * 132 * entry 133 * obj_state, argc, argv - Standard command arguments 134 * optmask - Mask of allowed optional arguments. 135 * cmd - SHDR_CMD_T_* value giving identify of caller 136 * argstate - Address of ARGSTATE block to be initialized 137 * 138 * exit: 139 * On success, *argstate is initialized. On error, 140 * an error is issued and this routine does not return. 141 */ 142 static void 143 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 144 SHDR_CMD_T cmd, ARGSTATE *argstate) 145 { 146 elfedit_getopt_state_t getopt_state; 147 elfedit_getopt_ret_t *getopt_ret; 148 149 bzero(argstate, sizeof (*argstate)); 150 argstate->obj_state = obj_state; 151 152 elfedit_getopt_init(&getopt_state, &argc, &argv); 153 154 /* Add each new option to the options mask */ 155 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) 156 argstate->optmask |= getopt_ret->gor_idmask; 157 158 /* Are the right number of plain arguments present? */ 159 switch (cmd) { 160 case SHDR_CMD_T_DUMP: 161 if (argc > 1) 162 elfedit_command_usage(); 163 break; 164 case SHDR_CMD_T_SH_FLAGS: 165 /* shdr:sh_flags allows an arbitrary number of arguments */ 166 break; 167 default: 168 /* The remaining commands accept 2 plain arguments */ 169 if (argc > 2) 170 elfedit_command_usage(); 171 break; 172 } 173 174 /* If there may be an arbitrary amount of output, use a pager */ 175 if (argc == 0) 176 elfedit_pager_init(); 177 178 /* Return the updated values of argc/argv */ 179 argstate->argc = argc; 180 argstate->argv = argv; 181 } 182 183 184 185 /* 186 * Print section header values, taking the calling command, and output style 187 * into account. 188 * 189 * entry: 190 * autoprint - If True, output is only produced if the elfedit 191 * autoprint flag is set. If False, output is always produced. 192 * cmd - SHDR_CMD_T_* value giving identify of caller 193 * argstate - State block for section header array 194 * ndx - Index of first section to display 195 * cnt - Number of sections to display 196 */ 197 static void 198 print_shdr(SHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate, 199 Word ndx, Word cnt) 200 { 201 elfedit_outstyle_t outstyle; 202 203 if ((autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) || 204 (cnt == 0)) 205 return; 206 207 /* 208 * Pick an output style. shdr:dump is required to use the default 209 * style. The other commands use the current output style. 210 */ 211 outstyle = (cmd == SHDR_CMD_T_DUMP) ? 212 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle(); 213 214 /* 215 * If doing default output, use elfdump style where we 216 * show all section header attributes. In this case, the 217 * command that called us doesn't matter 218 */ 219 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { 220 Half mach = argstate->obj_state->os_ehdr->e_machine; 221 222 for (; cnt--; ndx++) { 223 elfedit_section_t *sec = 224 &argstate->obj_state->os_secarr[ndx]; 225 226 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 227 elfedit_printf(MSG_INTL(MSG_ELF_SHDR), ndx, 228 sec->sec_name); 229 Elf_shdr(NULL, mach, sec->sec_shdr); 230 } 231 return; 232 } 233 234 235 switch (cmd) { 236 case SHDR_CMD_T_SH_ADDR: 237 for (; cnt--; ndx++) { 238 Shdr *shdr = 239 argstate->obj_state->os_secarr[ndx].sec_shdr; 240 241 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 242 EC_XWORD(shdr->sh_addr)); 243 } 244 return; 245 246 case SHDR_CMD_T_SH_ADDRALIGN: 247 for (; cnt--; ndx++) { 248 Shdr *shdr = 249 argstate->obj_state->os_secarr[ndx].sec_shdr; 250 251 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 252 EC_XWORD(shdr->sh_addralign)); 253 } 254 return; 255 256 case SHDR_CMD_T_SH_ENTSIZE: 257 for (; cnt--; ndx++) { 258 Shdr *shdr = 259 argstate->obj_state->os_secarr[ndx].sec_shdr; 260 261 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 262 EC_XWORD(shdr->sh_entsize)); 263 } 264 return; 265 266 case SHDR_CMD_T_SH_FLAGS: 267 for (; cnt--; ndx++) { 268 Shdr *shdr = 269 argstate->obj_state->os_secarr[ndx].sec_shdr; 270 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 271 Conv_sec_flags_buf_t sec_flags_buf; 272 273 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 274 conv_sec_flags(shdr->sh_flags, 275 CONV_FMT_NOBKT, &sec_flags_buf)); 276 } else { 277 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 278 EC_XWORD(shdr->sh_flags)); 279 } 280 } 281 return; 282 283 case SHDR_CMD_T_SH_INFO: 284 for (; cnt--; ndx++) { 285 Shdr *shdr = 286 argstate->obj_state->os_secarr[ndx].sec_shdr; 287 288 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 289 EC_WORD(shdr->sh_info)); 290 } 291 return; 292 293 case SHDR_CMD_T_SH_LINK: 294 for (; cnt--; ndx++) { 295 Shdr *shdr = 296 argstate->obj_state->os_secarr[ndx].sec_shdr; 297 298 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 299 EC_WORD(shdr->sh_link)); 300 } 301 return; 302 303 case SHDR_CMD_T_SH_NAME: 304 /* 305 * In simple output mode, we show the string. In numeric 306 * mode, we show the string table offset. 307 */ 308 for (; cnt--; ndx++) { 309 elfedit_section_t *shdr_sec = 310 &argstate->obj_state->os_secarr[ndx]; 311 312 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 313 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 314 shdr_sec->sec_name); 315 } else { 316 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 317 EC_WORD(shdr_sec->sec_shdr->sh_name)); 318 } 319 } 320 return; 321 322 case SHDR_CMD_T_SH_OFFSET: 323 for (; cnt--; ndx++) { 324 Shdr *shdr = 325 argstate->obj_state->os_secarr[ndx].sec_shdr; 326 327 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 328 EC_XWORD(shdr->sh_offset)); 329 } 330 return; 331 332 case SHDR_CMD_T_SH_SIZE: 333 for (; cnt--; ndx++) { 334 Shdr *shdr = 335 argstate->obj_state->os_secarr[ndx].sec_shdr; 336 337 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDHEXNL), 338 EC_XWORD(shdr->sh_size)); 339 } 340 return; 341 342 case SHDR_CMD_T_SH_TYPE: 343 for (; cnt--; ndx++) { 344 Shdr *shdr = 345 argstate->obj_state->os_secarr[ndx].sec_shdr; 346 Conv_inv_buf_t inv_buf; 347 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 348 Half mach = 349 argstate->obj_state->os_ehdr->e_machine; 350 351 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 352 conv_sec_type(mach, shdr->sh_type, 0, 353 &inv_buf)); 354 } else { 355 elfedit_printf(MSG_ORIG(MSG_FMT_WORDHEXNL), 356 EC_WORD(shdr->sh_type)); 357 } 358 } 359 return; 360 } 361 } 362 363 364 /* 365 * Common body for the shdr: module commands. These commands 366 * share a large amount of common behavior, so it is convenient 367 * to centralize things and use the cmd argument to handle the 368 * small differences. 369 * 370 * entry: 371 * cmd - One of the SHDR_CMD_T_* constants listed above, specifying 372 * which command to implement. 373 * obj_state, argc, argv - Standard command arguments 374 */ 375 static elfedit_cmdret_t 376 cmd_body(SHDR_CMD_T cmd, elfedit_obj_state_t *obj_state, 377 int argc, const char *argv[]) 378 { 379 ARGSTATE argstate; 380 Word ndx; 381 elfedit_section_t *shdr_sec; 382 Shdr *shdr; 383 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 384 385 process_args(obj_state, argc, argv, cmd, &argstate); 386 387 /* If there are no arguments, dump the whole table and return */ 388 if (argstate.argc == 0) { 389 print_shdr(cmd, 0, &argstate, 0, obj_state->os_shnum); 390 return (ELFEDIT_CMDRET_NONE); 391 } 392 393 /* 394 * The first argument gives the section to use. This can be a 395 * name (default), section index, or section type, depending on 396 * the options used. 397 */ 398 if (argstate.optmask & SHDR_OPT_F_SHNDX) 399 ndx = elfedit_atoshndx(argstate.argv[0], obj_state->os_shnum); 400 else if (argstate.optmask & SHDR_OPT_F_SHTYP) 401 ndx = elfedit_type_to_shndx(obj_state, 402 elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_SHT)); 403 else 404 ndx = elfedit_name_to_shndx(obj_state, argstate.argv[0]); 405 406 /* If there is a single argument, display that item and return */ 407 if (argstate.argc == 1) { 408 print_shdr(cmd, 0, &argstate, ndx, 1); 409 return (ELFEDIT_CMDRET_NONE); 410 } 411 412 /* 413 * Section [0] is supposed to be all zero unless extended sections 414 * are in force. Rather than setting extended values directly, 415 * it is expected to be handled by the ELF header module. So, a 416 * direct change here is probably not what was intended. 417 */ 418 if (ndx == 0) 419 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CHGSHDR0)); 420 421 /* The second value is an integer giving a new value */ 422 shdr_sec = &obj_state->os_secarr[ndx]; 423 shdr = shdr_sec->sec_shdr; 424 switch (cmd) { 425 /* 426 * SHDR_CMD_T_DUMP can't get here: It never has more than 427 * one argument, and is handled above. 428 */ 429 430 case SHDR_CMD_T_SH_ADDR: 431 { 432 Addr sh_addr = elfedit_atoui(argstate.argv[1], NULL); 433 434 if (shdr->sh_addr == sh_addr) { 435 elfedit_msg(ELFEDIT_MSG_DEBUG, 436 MSG_INTL(MSG_DEBUG_LLX_OK), 437 ndx, shdr_sec->sec_name, 438 MSG_ORIG(MSG_CMD_SH_ADDR), 439 EC_ADDR(shdr->sh_addr)); 440 } else { 441 elfedit_msg(ELFEDIT_MSG_DEBUG, 442 MSG_INTL(MSG_DEBUG_LLX_CHG), 443 ndx, shdr_sec->sec_name, 444 MSG_ORIG(MSG_CMD_SH_ADDR), 445 EC_ADDR(shdr->sh_addr), EC_ADDR(sh_addr)); 446 ret = ELFEDIT_CMDRET_MOD; 447 shdr->sh_addr = sh_addr; 448 } 449 } 450 break; 451 452 case SHDR_CMD_T_SH_ADDRALIGN: 453 { 454 Xword sh_addralign; 455 456 sh_addralign = elfedit_atoui(argstate.argv[1], NULL); 457 if (elfedit_bits_set(sh_addralign, 458 sizeof (sh_addralign)) > 1) 459 elfedit_msg(ELFEDIT_MSG_DEBUG, 460 MSG_INTL(MSG_DEBUG_ADDRALIGN), 461 argstate.argv[1]); 462 if (shdr->sh_addralign == sh_addralign) { 463 elfedit_msg(ELFEDIT_MSG_DEBUG, 464 MSG_INTL(MSG_DEBUG_LLX_OK), 465 ndx, shdr_sec->sec_name, 466 MSG_ORIG(MSG_CMD_SH_ADDRALIGN), 467 EC_XWORD(shdr->sh_addralign)); 468 } else { 469 elfedit_msg(ELFEDIT_MSG_DEBUG, 470 MSG_INTL(MSG_DEBUG_LLX_CHG), 471 ndx, shdr_sec->sec_name, 472 MSG_ORIG(MSG_CMD_SH_ADDRALIGN), 473 EC_XWORD(shdr->sh_addralign), 474 EC_XWORD(sh_addralign)); 475 ret = ELFEDIT_CMDRET_MOD; 476 shdr->sh_addralign = sh_addralign; 477 } 478 } 479 break; 480 481 case SHDR_CMD_T_SH_ENTSIZE: 482 { 483 Xword sh_entsize; 484 485 sh_entsize = elfedit_atoui(argstate.argv[1], NULL); 486 if (shdr->sh_entsize == sh_entsize) { 487 elfedit_msg(ELFEDIT_MSG_DEBUG, 488 MSG_INTL(MSG_DEBUG_LLX_OK), 489 ndx, shdr_sec->sec_name, 490 MSG_ORIG(MSG_CMD_SH_ENTSIZE), 491 EC_XWORD(shdr->sh_entsize)); 492 } else { 493 elfedit_msg(ELFEDIT_MSG_DEBUG, 494 MSG_INTL(MSG_DEBUG_LLX_CHG), 495 ndx, shdr_sec->sec_name, 496 MSG_ORIG(MSG_CMD_SH_ENTSIZE), 497 EC_XWORD(shdr->sh_entsize), 498 EC_XWORD(sh_entsize)); 499 ret = ELFEDIT_CMDRET_MOD; 500 shdr->sh_entsize = sh_entsize; 501 } 502 } 503 break; 504 505 case SHDR_CMD_T_SH_FLAGS: 506 { 507 Conv_sec_flags_buf_t buf1, buf2; 508 Word sh_flags = 0; 509 int i; 510 511 /* Collect the flag arguments */ 512 for (i = 1; i < argstate.argc; i++) 513 sh_flags |= 514 (Word) elfedit_atoconst(argstate.argv[i], 515 ELFEDIT_CONST_SHF); 516 517 /* Complement the value? */ 518 if (argstate.optmask & SHDR_OPT_F_CMP) 519 sh_flags = ~sh_flags; 520 521 /* Perform any requested bit operations */ 522 if (argstate.optmask & SHDR_OPT_F_AND) 523 sh_flags &= shdr->sh_flags; 524 else if (argstate.optmask & SHDR_OPT_F_OR) 525 sh_flags |= shdr->sh_flags; 526 527 /* Set the value */ 528 if (shdr->sh_flags == sh_flags) { 529 elfedit_msg(ELFEDIT_MSG_DEBUG, 530 MSG_INTL(MSG_DEBUG_S_OK), 531 ndx, shdr_sec->sec_name, 532 MSG_ORIG(MSG_CMD_SH_FLAGS), 533 conv_sec_flags(shdr->sh_flags, 0, &buf1)); 534 } else { 535 elfedit_msg(ELFEDIT_MSG_DEBUG, 536 MSG_INTL(MSG_DEBUG_S_CHG), 537 ndx, shdr_sec->sec_name, 538 MSG_ORIG(MSG_CMD_SH_FLAGS), 539 conv_sec_flags(shdr->sh_flags, 0, &buf1), 540 conv_sec_flags(sh_flags, 0, &buf2)); 541 ret = ELFEDIT_CMDRET_MOD; 542 shdr->sh_flags = sh_flags; 543 } 544 } 545 break; 546 547 case SHDR_CMD_T_SH_INFO: 548 { 549 Word sh_info = elfedit_atoui(argstate.argv[1], NULL); 550 551 if (shdr->sh_info == sh_info) { 552 elfedit_msg(ELFEDIT_MSG_DEBUG, 553 MSG_INTL(MSG_DEBUG_D_OK), 554 ndx, shdr_sec->sec_name, 555 MSG_ORIG(MSG_CMD_SH_INFO), 556 EC_WORD(shdr->sh_info)); 557 } else { 558 elfedit_msg(ELFEDIT_MSG_DEBUG, 559 MSG_INTL(MSG_DEBUG_D_CHG), 560 ndx, shdr_sec->sec_name, 561 MSG_ORIG(MSG_CMD_SH_INFO), 562 EC_WORD(shdr->sh_info), EC_WORD(sh_info)); 563 ret = ELFEDIT_CMDRET_MOD; 564 shdr->sh_info = sh_info; 565 } 566 } 567 break; 568 569 case SHDR_CMD_T_SH_LINK: 570 { 571 Word sh_link = elfedit_atoui(argstate.argv[1], NULL); 572 573 if (shdr->sh_link == sh_link) { 574 elfedit_msg(ELFEDIT_MSG_DEBUG, 575 MSG_INTL(MSG_DEBUG_D_OK), 576 ndx, shdr_sec->sec_name, 577 MSG_ORIG(MSG_CMD_SH_LINK), 578 EC_WORD(shdr->sh_link)); 579 } else { 580 elfedit_msg(ELFEDIT_MSG_DEBUG, 581 MSG_INTL(MSG_DEBUG_D_CHG), 582 ndx, shdr_sec->sec_name, 583 MSG_ORIG(MSG_CMD_SH_LINK), 584 EC_WORD(shdr->sh_link), EC_WORD(sh_link)); 585 ret = ELFEDIT_CMDRET_MOD; 586 shdr->sh_link = sh_link; 587 } 588 } 589 break; 590 591 case SHDR_CMD_T_SH_NAME: 592 { 593 elfedit_section_t *shstr_sec = 594 &obj_state->os_secarr[obj_state->os_shstrndx]; 595 Word sh_name; 596 597 /* 598 * If -name_offset was specified, this is an offset 599 * into the string table. Otherwise it is a string 600 * we need to turn into an offset. 601 */ 602 sh_name = (argstate.optmask & SHDR_OPT_F_NAMOFFSET) ? 603 elfedit_atoui(argstate.argv[1], NULL) : 604 elfedit_strtab_insert(obj_state, 605 shstr_sec, NULL, argstate.argv[1]); 606 if (shdr->sh_name == sh_name) { 607 elfedit_msg(ELFEDIT_MSG_DEBUG, 608 MSG_INTL(MSG_DEBUG_D_OK), 609 ndx, shdr_sec->sec_name, 610 MSG_ORIG(MSG_CMD_SH_NAME), 611 EC_WORD(shdr->sh_name)); 612 } else { 613 /* 614 * The section name is cached, so we must 615 * also update that value. This call will 616 * warn if the offset is out of range, and 617 * will supply a safe string in that case. 618 */ 619 shdr_sec->sec_name = 620 elfedit_offset_to_str(shstr_sec, 621 sh_name, ELFEDIT_MSG_DEBUG, 1); 622 623 elfedit_msg(ELFEDIT_MSG_DEBUG, 624 MSG_INTL(MSG_DEBUG_D_CHG), 625 ndx, shdr_sec->sec_name, 626 MSG_ORIG(MSG_CMD_SH_NAME), 627 EC_WORD(shdr->sh_name), EC_WORD(sh_name)); 628 ret = ELFEDIT_CMDRET_MOD; 629 shdr->sh_name = sh_name; 630 } 631 } 632 break; 633 634 case SHDR_CMD_T_SH_OFFSET: 635 { 636 Off sh_offset; 637 638 sh_offset = elfedit_atoui(argstate.argv[1], NULL); 639 if (shdr->sh_offset == sh_offset) { 640 elfedit_msg(ELFEDIT_MSG_DEBUG, 641 MSG_INTL(MSG_DEBUG_LLX_OK), 642 ndx, shdr_sec->sec_name, 643 MSG_ORIG(MSG_CMD_SH_OFFSET), 644 EC_XWORD(shdr->sh_offset)); 645 } else { 646 elfedit_msg(ELFEDIT_MSG_DEBUG, 647 MSG_INTL(MSG_DEBUG_LLX_CHG), 648 ndx, shdr_sec->sec_name, 649 MSG_ORIG(MSG_CMD_SH_OFFSET), 650 EC_XWORD(shdr->sh_offset), 651 EC_XWORD(sh_offset)); 652 ret = ELFEDIT_CMDRET_MOD; 653 shdr->sh_offset = sh_offset; 654 } 655 } 656 break; 657 658 case SHDR_CMD_T_SH_SIZE: 659 { 660 Xword sh_size; 661 662 sh_size = elfedit_atoui(argstate.argv[1], NULL); 663 if (shdr->sh_size == sh_size) { 664 elfedit_msg(ELFEDIT_MSG_DEBUG, 665 MSG_INTL(MSG_DEBUG_LLX_OK), 666 ndx, shdr_sec->sec_name, 667 MSG_ORIG(MSG_CMD_SH_SIZE), 668 EC_XWORD(shdr->sh_size)); 669 } else { 670 elfedit_msg(ELFEDIT_MSG_DEBUG, 671 MSG_INTL(MSG_DEBUG_LLX_CHG), 672 ndx, shdr_sec->sec_name, 673 MSG_ORIG(MSG_CMD_SH_SIZE), 674 EC_XWORD(shdr->sh_size), 675 EC_XWORD(sh_size)); 676 ret = ELFEDIT_CMDRET_MOD; 677 shdr->sh_size = sh_size; 678 } 679 } 680 break; 681 682 case SHDR_CMD_T_SH_TYPE: 683 { 684 Half mach = obj_state->os_ehdr->e_machine; 685 Word sh_type = elfedit_atoconst(argstate.argv[1], 686 ELFEDIT_CONST_SHT); 687 Conv_inv_buf_t inv_buf1, inv_buf2; 688 689 if (shdr->sh_type == sh_type) { 690 elfedit_msg(ELFEDIT_MSG_DEBUG, 691 MSG_INTL(MSG_DEBUG_S_OK), 692 ndx, shdr_sec->sec_name, 693 MSG_ORIG(MSG_CMD_SH_TYPE), 694 conv_sec_type(mach, shdr->sh_type, 695 0, &inv_buf1)); 696 } else { 697 elfedit_msg(ELFEDIT_MSG_DEBUG, 698 MSG_INTL(MSG_DEBUG_S_CHG), 699 ndx, shdr_sec->sec_name, 700 MSG_ORIG(MSG_CMD_SH_TYPE), 701 conv_sec_type(mach, shdr->sh_type, 0, 702 &inv_buf1), 703 conv_sec_type(mach, sh_type, 0, &inv_buf2)); 704 ret = ELFEDIT_CMDRET_MOD; 705 shdr->sh_type = sh_type; 706 } 707 } 708 break; 709 } 710 711 /* 712 * If we modified the section header array, tell libelf. 713 */ 714 if (ret == ELFEDIT_CMDRET_MOD) 715 elfedit_modified_shdr(shdr_sec); 716 717 /* Do autoprint */ 718 print_shdr(cmd, 1, &argstate, ndx, 1); 719 720 return (ret); 721 } 722 723 724 725 726 /* 727 * Command completion functions for the various commands 728 */ 729 730 /* 731 * All of the commands accept the same first argument (sec) that 732 * specifies the section. This argument can be a section name 733 * (default), section index, or section type, depending on the 734 * options used. This routine determines which case is current, 735 * and then supplies completion for the first argument. 736 */ 737 static void 738 cpl_1starg_sec(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 739 const char *argv[], int num_opt) 740 { 741 elfedit_section_t *sec; 742 enum { NAME, INDEX, TYPE } op; 743 Word ndx; 744 745 if (argc != (num_opt + 1)) 746 return; 747 748 op = NAME; 749 for (ndx = 0; ndx < num_opt; ndx++) { 750 if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0) 751 op = INDEX; 752 else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0) 753 op = TYPE; 754 } 755 756 switch (op) { 757 case NAME: 758 if (obj_state == NULL) 759 break; 760 sec = obj_state->os_secarr; 761 for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++) 762 elfedit_cpl_match(cpldata, sec->sec_name, 0); 763 break; 764 765 case INDEX: 766 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHN); 767 break; 768 769 case TYPE: 770 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); 771 break; 772 } 773 } 774 775 776 /*ARGSUSED*/ 777 static void 778 cpl_sh_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 779 const char *argv[], int num_opt) 780 { 781 /* Handle -shXXX options */ 782 cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt); 783 784 /* The second and following arguments can be an SHF_ value */ 785 if (argc >= (num_opt + 2)) 786 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHF); 787 } 788 789 /*ARGSUSED*/ 790 static void 791 cpl_sh_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 792 const char *argv[], int num_opt) 793 { 794 /* Handle -shXXX options */ 795 cpl_1starg_sec(obj_state, cpldata, argc, argv, num_opt); 796 797 /* The second argument can be an SHT_ value */ 798 if (argc == (num_opt + 2)) 799 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); 800 } 801 802 803 804 /* 805 * Implementation functions for the commands 806 */ 807 static elfedit_cmdret_t 808 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 809 { 810 return (cmd_body(SHDR_CMD_T_DUMP, obj_state, argc, argv)); 811 } 812 813 814 static elfedit_cmdret_t 815 cmd_sh_addr(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 816 { 817 return (cmd_body(SHDR_CMD_T_SH_ADDR, obj_state, argc, argv)); 818 } 819 820 821 static elfedit_cmdret_t 822 cmd_sh_addralign(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 823 { 824 return (cmd_body(SHDR_CMD_T_SH_ADDRALIGN, obj_state, argc, argv)); 825 } 826 827 828 static elfedit_cmdret_t 829 cmd_sh_entsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 830 { 831 return (cmd_body(SHDR_CMD_T_SH_ENTSIZE, obj_state, argc, argv)); 832 } 833 834 static elfedit_cmdret_t 835 cmd_sh_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 836 { 837 return (cmd_body(SHDR_CMD_T_SH_FLAGS, obj_state, argc, argv)); 838 } 839 840 static elfedit_cmdret_t 841 cmd_sh_info(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 842 { 843 return (cmd_body(SHDR_CMD_T_SH_INFO, obj_state, argc, argv)); 844 } 845 846 static elfedit_cmdret_t 847 cmd_sh_link(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 848 { 849 return (cmd_body(SHDR_CMD_T_SH_LINK, obj_state, argc, argv)); 850 } 851 852 static elfedit_cmdret_t 853 cmd_sh_name(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 854 { 855 return (cmd_body(SHDR_CMD_T_SH_NAME, obj_state, argc, argv)); 856 } 857 858 static elfedit_cmdret_t 859 cmd_sh_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 860 { 861 return (cmd_body(SHDR_CMD_T_SH_OFFSET, obj_state, argc, argv)); 862 } 863 864 static elfedit_cmdret_t 865 cmd_sh_size(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 866 { 867 return (cmd_body(SHDR_CMD_T_SH_SIZE, obj_state, argc, argv)); 868 } 869 870 static elfedit_cmdret_t 871 cmd_sh_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 872 { 873 return (cmd_body(SHDR_CMD_T_SH_TYPE, obj_state, argc, argv)); 874 } 875 876 877 878 /*ARGSUSED*/ 879 elfedit_module_t * 880 elfedit_init(elfedit_module_version_t version) 881 { 882 /* Multiple commands accept only the standard set of options */ 883 static elfedit_cmd_optarg_t opt_std[] = { 884 { ELFEDIT_STDOA_OPT_O, NULL, 885 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 886 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 887 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 888 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, 889 SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP }, 890 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 891 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 892 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, 893 SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX }, 894 { NULL } 895 }; 896 897 /* shdr:sh_addr */ 898 static const char *name_sh_addr[] = { 899 MSG_ORIG(MSG_CMD_SH_ADDR), NULL }; 900 static elfedit_cmd_optarg_t arg_sh_addr[] = { 901 { MSG_ORIG(MSG_STR_SEC), 902 /* MSG_INTL(MSG_A1_SEC) */ 903 ELFEDIT_I18NHDL(MSG_A1_SEC), 904 ELFEDIT_CMDOA_F_OPT }, 905 { MSG_ORIG(MSG_STR_VALUE), 906 /* MSG_INTL(MSG_A2_DESC_SH_ADDR) */ 907 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDR), 908 ELFEDIT_CMDOA_F_OPT }, 909 { NULL } 910 }; 911 912 /* shdr:dump */ 913 static const char *name_dump[] = { 914 MSG_ORIG(MSG_CMD_DUMP), 915 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 916 NULL 917 }; 918 static elfedit_cmd_optarg_t opt_dump[] = { 919 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 920 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 921 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, 922 SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP }, 923 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 924 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 925 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, 926 SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX }, 927 { NULL } 928 }; 929 static elfedit_cmd_optarg_t arg_dump[] = { 930 { MSG_ORIG(MSG_STR_SEC), 931 /* MSG_INTL(MSG_A1_SEC) */ 932 ELFEDIT_I18NHDL(MSG_A1_SEC), 933 ELFEDIT_CMDOA_F_OPT }, 934 { NULL } 935 }; 936 937 /* shdr:sh_addralign */ 938 static const char *name_sh_addralign[] = { 939 MSG_ORIG(MSG_CMD_SH_ADDRALIGN), NULL }; 940 static elfedit_cmd_optarg_t arg_sh_addralign[] = { 941 { MSG_ORIG(MSG_STR_SEC), 942 /* MSG_INTL(MSG_A1_SEC) */ 943 ELFEDIT_I18NHDL(MSG_A1_SEC), 944 ELFEDIT_CMDOA_F_OPT }, 945 { MSG_ORIG(MSG_STR_VALUE), 946 /* MSG_INTL(MSG_A2_DESC_SH_ADDRALIGN) */ 947 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ADDRALIGN), 948 ELFEDIT_CMDOA_F_OPT }, 949 { NULL } 950 }; 951 952 /* shdr:sh_entsize */ 953 static const char *name_sh_entsize[] = { 954 MSG_ORIG(MSG_CMD_SH_ENTSIZE), NULL }; 955 static elfedit_cmd_optarg_t arg_sh_entsize[] = { 956 { MSG_ORIG(MSG_STR_SEC), 957 /* MSG_INTL(MSG_A1_SEC) */ 958 ELFEDIT_I18NHDL(MSG_A1_SEC), 959 ELFEDIT_CMDOA_F_OPT }, 960 { MSG_ORIG(MSG_STR_VALUE), 961 /* MSG_INTL(MSG_A2_DESC_SH_ENTSIZE) */ 962 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_ENTSIZE), 963 ELFEDIT_CMDOA_F_OPT }, 964 { NULL } 965 }; 966 967 /* shdr:sh_flags */ 968 static const char *name_sh_flags[] = { 969 MSG_ORIG(MSG_CMD_SH_FLAGS), NULL }; 970 static elfedit_cmd_optarg_t opt_sh_flags[] = { 971 { ELFEDIT_STDOA_OPT_AND, NULL, 972 ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_AND, SHDR_OPT_F_OR }, 973 { ELFEDIT_STDOA_OPT_CMP, NULL, 974 ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_CMP, 0 }, 975 { ELFEDIT_STDOA_OPT_O, NULL, 976 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 977 { ELFEDIT_STDOA_OPT_OR, NULL, 978 ELFEDIT_CMDOA_F_INHERIT, SHDR_OPT_F_OR, SHDR_OPT_F_AND }, 979 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 980 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 981 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, 982 SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP }, 983 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 984 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 985 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, 986 SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX }, 987 { NULL } 988 }; 989 static elfedit_cmd_optarg_t arg_sh_flags[] = { 990 { MSG_ORIG(MSG_STR_SEC), 991 /* MSG_INTL(MSG_A1_SEC) */ 992 ELFEDIT_I18NHDL(MSG_A1_SEC), 993 ELFEDIT_CMDOA_F_OPT }, 994 { MSG_ORIG(MSG_STR_VALUE), 995 /* MSG_INTL(MSG_A2_DESC_SH_FLAGS) */ 996 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_FLAGS), 997 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 998 { NULL } 999 }; 1000 1001 /* shdr:sh_info */ 1002 static const char *name_sh_info[] = { 1003 MSG_ORIG(MSG_CMD_SH_INFO), NULL }; 1004 static elfedit_cmd_optarg_t arg_sh_info[] = { 1005 { MSG_ORIG(MSG_STR_SEC), 1006 /* MSG_INTL(MSG_A1_SEC) */ 1007 ELFEDIT_I18NHDL(MSG_A1_SEC), 1008 ELFEDIT_CMDOA_F_OPT }, 1009 { MSG_ORIG(MSG_STR_VALUE), 1010 /* MSG_INTL(MSG_A2_DESC_SH_INFO) */ 1011 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_INFO), 1012 ELFEDIT_CMDOA_F_OPT }, 1013 { NULL } 1014 }; 1015 1016 /* shdr:sh_link */ 1017 static const char *name_sh_link[] = { 1018 MSG_ORIG(MSG_CMD_SH_LINK), NULL }; 1019 static elfedit_cmd_optarg_t arg_sh_link[] = { 1020 { MSG_ORIG(MSG_STR_SEC), 1021 /* MSG_INTL(MSG_A1_SEC) */ 1022 ELFEDIT_I18NHDL(MSG_A1_SEC), 1023 ELFEDIT_CMDOA_F_OPT }, 1024 { MSG_ORIG(MSG_STR_VALUE), 1025 /* MSG_INTL(MSG_A2_DESC_SH_LINK) */ 1026 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_LINK), 1027 ELFEDIT_CMDOA_F_OPT }, 1028 { NULL } 1029 }; 1030 1031 /* shdr:sh_name */ 1032 static const char *name_sh_name[] = { 1033 MSG_ORIG(MSG_CMD_SH_NAME), NULL }; 1034 static elfedit_cmd_optarg_t opt_sh_name[] = { 1035 { MSG_ORIG(MSG_STR_MINUS_NAME_OFFSET), 1036 /* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */ 1037 ELFEDIT_I18NHDL(MSG_OPTDESC_NAME_OFFSET), 0, 1038 SHDR_OPT_F_NAMOFFSET, 0 }, 1039 { ELFEDIT_STDOA_OPT_O, NULL, 1040 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1041 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1042 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1043 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, 1044 SHDR_OPT_F_SHNDX, SHDR_OPT_F_SHTYP }, 1045 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1046 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1047 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, 1048 SHDR_OPT_F_SHTYP, SHDR_OPT_F_SHNDX }, 1049 { NULL } 1050 }; 1051 static elfedit_cmd_optarg_t arg_sh_name[] = { 1052 { MSG_ORIG(MSG_STR_SEC), 1053 /* MSG_INTL(MSG_A1_SEC) */ 1054 ELFEDIT_I18NHDL(MSG_A1_SEC), 1055 ELFEDIT_CMDOA_F_OPT }, 1056 { MSG_ORIG(MSG_STR_NAME), 1057 /* MSG_INTL(MSG_A2_DESC_SH_NAME) */ 1058 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_NAME), 1059 ELFEDIT_CMDOA_F_OPT }, 1060 { NULL } 1061 }; 1062 1063 /* shdr:sh_offset */ 1064 static const char *name_sh_offset[] = { 1065 MSG_ORIG(MSG_CMD_SH_OFFSET), NULL }; 1066 static elfedit_cmd_optarg_t arg_sh_offset[] = { 1067 { MSG_ORIG(MSG_STR_SEC), 1068 /* MSG_INTL(MSG_A1_SEC) */ 1069 ELFEDIT_I18NHDL(MSG_A1_SEC), 1070 ELFEDIT_CMDOA_F_OPT }, 1071 { MSG_ORIG(MSG_STR_VALUE), 1072 /* MSG_INTL(MSG_A2_DESC_SH_OFFSET) */ 1073 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_OFFSET), 1074 ELFEDIT_CMDOA_F_OPT }, 1075 { NULL } 1076 }; 1077 1078 /* shdr:sh_size */ 1079 static const char *name_sh_size[] = { 1080 MSG_ORIG(MSG_CMD_SH_SIZE), NULL }; 1081 static elfedit_cmd_optarg_t arg_sh_size[] = { 1082 { MSG_ORIG(MSG_STR_SEC), 1083 /* MSG_INTL(MSG_A1_SEC) */ 1084 ELFEDIT_I18NHDL(MSG_A1_SEC), 1085 ELFEDIT_CMDOA_F_OPT }, 1086 { MSG_ORIG(MSG_STR_VALUE), 1087 /* MSG_INTL(MSG_A2_DESC_SH_SIZE) */ 1088 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_SIZE), 1089 ELFEDIT_CMDOA_F_OPT }, 1090 { NULL } 1091 }; 1092 1093 /* shdr:sh_type */ 1094 static const char *name_sh_type[] = { 1095 MSG_ORIG(MSG_CMD_SH_TYPE), NULL }; 1096 static elfedit_cmd_optarg_t arg_sh_type[] = { 1097 { MSG_ORIG(MSG_STR_SEC), 1098 /* MSG_INTL(MSG_A1_SEC) */ 1099 ELFEDIT_I18NHDL(MSG_A1_SEC), 1100 ELFEDIT_CMDOA_F_OPT }, 1101 { MSG_ORIG(MSG_STR_VALUE), 1102 /* MSG_INTL(MSG_A2_DESC_SH_TYPE) */ 1103 ELFEDIT_I18NHDL(MSG_A2_DESC_SH_TYPE), 1104 ELFEDIT_CMDOA_F_OPT }, 1105 { NULL } 1106 }; 1107 1108 static elfedit_cmd_t cmds[] = { 1109 /* shdr:dump */ 1110 { cmd_dump, cpl_1starg_sec, name_dump, 1111 /* MSG_INTL(MSG_DESC_DUMP) */ 1112 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 1113 /* MSG_INTL(MSG_HELP_DUMP) */ 1114 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 1115 opt_dump, arg_dump }, 1116 1117 /* shdr:sh_addr */ 1118 { cmd_sh_addr, cpl_1starg_sec, name_sh_addr, 1119 /* MSG_INTL(MSG_DESC_SH_ADDR) */ 1120 ELFEDIT_I18NHDL(MSG_DESC_SH_ADDR), 1121 /* MSG_INTL(MSG_HELP_SH_ADDR) */ 1122 ELFEDIT_I18NHDL(MSG_HELP_SH_ADDR), 1123 opt_std, arg_sh_addr }, 1124 1125 /* shdr:sh_addralign */ 1126 { cmd_sh_addralign, cpl_1starg_sec, name_sh_addralign, 1127 /* MSG_INTL(MSG_DESC_SH_ADDRALIGN) */ 1128 ELFEDIT_I18NHDL(MSG_DESC_SH_ADDRALIGN), 1129 /* MSG_INTL(MSG_HELP_SH_ADDRALIGN) */ 1130 ELFEDIT_I18NHDL(MSG_HELP_SH_ADDRALIGN), 1131 opt_std, arg_sh_addralign }, 1132 1133 /* shdr:sh_entsize */ 1134 { cmd_sh_entsize, cpl_1starg_sec, name_sh_entsize, 1135 /* MSG_INTL(MSG_DESC_SH_ENTSIZE) */ 1136 ELFEDIT_I18NHDL(MSG_DESC_SH_ENTSIZE), 1137 /* MSG_INTL(MSG_HELP_SH_ENTSIZE) */ 1138 ELFEDIT_I18NHDL(MSG_HELP_SH_ENTSIZE), 1139 opt_std, arg_sh_entsize }, 1140 1141 /* shdr:sh_flags */ 1142 { cmd_sh_flags, cpl_sh_flags, name_sh_flags, 1143 /* MSG_INTL(MSG_DESC_SH_FLAGS) */ 1144 ELFEDIT_I18NHDL(MSG_DESC_SH_FLAGS), 1145 /* MSG_INTL(MSG_HELP_SH_FLAGS) */ 1146 ELFEDIT_I18NHDL(MSG_HELP_SH_FLAGS), 1147 opt_sh_flags, arg_sh_flags }, 1148 1149 /* shdr:sh_info */ 1150 { cmd_sh_info, cpl_1starg_sec, name_sh_info, 1151 /* MSG_INTL(MSG_DESC_SH_INFO) */ 1152 ELFEDIT_I18NHDL(MSG_DESC_SH_INFO), 1153 /* MSG_INTL(MSG_HELP_SH_INFO) */ 1154 ELFEDIT_I18NHDL(MSG_HELP_SH_INFO), 1155 opt_std, arg_sh_info }, 1156 1157 /* shdr:sh_link */ 1158 { cmd_sh_link, cpl_1starg_sec, name_sh_link, 1159 /* MSG_INTL(MSG_DESC_SH_LINK) */ 1160 ELFEDIT_I18NHDL(MSG_DESC_SH_LINK), 1161 /* MSG_INTL(MSG_HELP_SH_LINK) */ 1162 ELFEDIT_I18NHDL(MSG_HELP_SH_LINK), 1163 opt_std, arg_sh_link }, 1164 1165 /* shdr:sh_name */ 1166 { cmd_sh_name, cpl_1starg_sec, name_sh_name, 1167 /* MSG_INTL(MSG_DESC_SH_NAME) */ 1168 ELFEDIT_I18NHDL(MSG_DESC_SH_NAME), 1169 /* MSG_INTL(MSG_HELP_SH_NAME) */ 1170 ELFEDIT_I18NHDL(MSG_HELP_SH_NAME), 1171 opt_sh_name, arg_sh_name }, 1172 1173 /* shdr:sh_offset */ 1174 { cmd_sh_offset, cpl_1starg_sec, name_sh_offset, 1175 /* MSG_INTL(MSG_DESC_SH_OFFSET) */ 1176 ELFEDIT_I18NHDL(MSG_DESC_SH_OFFSET), 1177 /* MSG_INTL(MSG_HELP_SH_OFFSET) */ 1178 ELFEDIT_I18NHDL(MSG_HELP_SH_OFFSET), 1179 opt_std, arg_sh_offset }, 1180 1181 /* shdr:sh_size */ 1182 { cmd_sh_size, cpl_1starg_sec, name_sh_size, 1183 /* MSG_INTL(MSG_DESC_SH_SIZE) */ 1184 ELFEDIT_I18NHDL(MSG_DESC_SH_SIZE), 1185 /* MSG_INTL(MSG_HELP_SH_SIZE) */ 1186 ELFEDIT_I18NHDL(MSG_HELP_SH_SIZE), 1187 opt_std, arg_sh_size }, 1188 1189 /* shdr:sh_type */ 1190 { cmd_sh_type, cpl_sh_type, name_sh_type, 1191 /* MSG_INTL(MSG_DESC_SH_TYPE) */ 1192 ELFEDIT_I18NHDL(MSG_DESC_SH_TYPE), 1193 /* MSG_INTL(MSG_HELP_SH_TYPE) */ 1194 ELFEDIT_I18NHDL(MSG_HELP_SH_TYPE), 1195 opt_std, arg_sh_type }, 1196 1197 { NULL } 1198 }; 1199 1200 static elfedit_module_t module = { 1201 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 1202 /* MSG_INTL(MSG_MOD_DESC) */ 1203 ELFEDIT_I18NHDL(MSG_MOD_DESC), 1204 cmds, mod_i18nhdl_to_str }; 1205 1206 return (&module); 1207 } 1208