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