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