15088Sab196087 /* 25088Sab196087 * CDDL HEADER START 35088Sab196087 * 45088Sab196087 * The contents of this file are subject to the terms of the 55088Sab196087 * Common Development and Distribution License (the "License"). 65088Sab196087 * You may not use this file except in compliance with the License. 75088Sab196087 * 85088Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95088Sab196087 * or http://www.opensolaris.org/os/licensing. 105088Sab196087 * See the License for the specific language governing permissions 115088Sab196087 * and limitations under the License. 125088Sab196087 * 135088Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 145088Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155088Sab196087 * If applicable, add the following below this CDDL HEADER, with the 165088Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 175088Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 185088Sab196087 * 195088Sab196087 * CDDL HEADER END 205088Sab196087 */ 215088Sab196087 225088Sab196087 /* 236206Sab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 245088Sab196087 * Use is subject to license terms. 255088Sab196087 */ 265088Sab196087 #pragma ident "%Z%%M% %I% %E% SMI" 275088Sab196087 285088Sab196087 #include <elfedit.h> 295088Sab196087 #include <strings.h> 305088Sab196087 #include <conv.h> 315088Sab196087 #include <debug.h> 325088Sab196087 #include <phdr_msg.h> 335088Sab196087 345088Sab196087 355088Sab196087 /* 365088Sab196087 * Program headers 375088Sab196087 */ 385088Sab196087 395088Sab196087 405088Sab196087 415088Sab196087 /* 425088Sab196087 * This module uses shared code for several of the commands. 435088Sab196087 * It is sometimes necessary to know which specific command 445088Sab196087 * is active. 455088Sab196087 */ 465088Sab196087 typedef enum { 475088Sab196087 /* Dump command, used as module default to display dynamic section */ 485088Sab196087 PHDR_CMD_T_DUMP = 0, /* phdr:dump */ 495088Sab196087 505088Sab196087 /* Commands that correspond directly to program header fields */ 515088Sab196087 PHDR_CMD_T_P_TYPE = 1, /* phdr:p_type */ 525088Sab196087 PHDR_CMD_T_P_OFFSET = 2, /* phdr:p_offset */ 535088Sab196087 PHDR_CMD_T_P_VADDR = 3, /* phdr:p_vaddr */ 545088Sab196087 PHDR_CMD_T_P_PADDR = 4, /* phdr:p_paddr */ 555088Sab196087 PHDR_CMD_T_P_FILESZ = 5, /* phdr:p_filesz */ 565088Sab196087 PHDR_CMD_T_P_MEMSZ = 6, /* phdr:p_memsz */ 575088Sab196087 PHDR_CMD_T_P_FLAGS = 7, /* phdr:p_flags */ 585088Sab196087 PHDR_CMD_T_P_ALIGN = 8, /* phdr:p_align */ 595088Sab196087 605088Sab196087 /* Commands that do not correspond directly to a specific phdr tag */ 615088Sab196087 PHDR_CMD_T_INTERP = 9, /* phdr:interp */ 625088Sab196087 PHDR_CMD_T_DELETE = 10, /* phdr:delete */ 635088Sab196087 PHDR_CMD_T_MOVE = 11 /* phdr:move */ 645088Sab196087 } PHDR_CMD_T; 655088Sab196087 665088Sab196087 675088Sab196087 685088Sab196087 /* 695088Sab196087 * The following type is ued by locate_interp() to return 705088Sab196087 * information about the interpreter program header. 715088Sab196087 */ 725088Sab196087 typedef struct { 735088Sab196087 Word phndx; /* Index of PT_INTERP header */ 745088Sab196087 Phdr *phdr; /* PT_INTERP header */ 755088Sab196087 elfedit_section_t *sec; /* Section containing string */ 765088Sab196087 Word stroff; /* Offset into string section */ 775088Sab196087 const char *str; /* Interpreter string */ 785088Sab196087 } INTERP_STATE; 795088Sab196087 805088Sab196087 815088Sab196087 #ifndef _ELF64 825088Sab196087 /* 835088Sab196087 * We supply this function for the msg module 845088Sab196087 */ 855088Sab196087 const char * 865088Sab196087 _phdr_msg(Msg mid) 875088Sab196087 { 885088Sab196087 return (gettext(MSG_ORIG(mid))); 895088Sab196087 } 905088Sab196087 #endif 915088Sab196087 925088Sab196087 935088Sab196087 /* 945088Sab196087 * This function is supplied to elfedit through our elfedit_module_t 955088Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles 965088Sab196087 * in our module interface into the actual strings for elfedit to 975088Sab196087 * use. 985088Sab196087 * 995088Sab196087 * note: 1005088Sab196087 * This module uses Msg codes for its i18n handle type. 1015088Sab196087 * So the translation is simply to use MSG_INTL() to turn 1025088Sab196087 * it into a string and return it. 1035088Sab196087 */ 1045088Sab196087 static const char * 1055088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 1065088Sab196087 { 1075088Sab196087 Msg msg = (Msg)hdl; 1085088Sab196087 1095088Sab196087 return (MSG_INTL(msg)); 1105088Sab196087 } 1115088Sab196087 1125088Sab196087 1135088Sab196087 1145088Sab196087 /* 1155088Sab196087 * The phdr_opt_t enum specifies a bit value for every optional 1165088Sab196087 * argument allowed by a command in this module. 1175088Sab196087 */ 1185088Sab196087 typedef enum { 1195088Sab196087 PHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */ 1205088Sab196087 PHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ 1215088Sab196087 PHDR_OPT_F_PHNDX = 4, /* -phndx: Program header by index, */ 1225088Sab196087 /* not by name */ 1235088Sab196087 PHDR_OPT_F_OR = 8 /* -or: OR (|) values to dest */ 1245088Sab196087 } phdr_opt_t; 1255088Sab196087 1265088Sab196087 1275088Sab196087 /* 1285088Sab196087 * A variable of type ARGSTATE is used by each command to maintain 1295088Sab196087 * information about the section headers and related things. It is 1305088Sab196087 * initialized by process_args(), and used by the other routines. 1315088Sab196087 */ 1325088Sab196087 typedef struct { 1335088Sab196087 elfedit_obj_state_t *obj_state; 1345088Sab196087 phdr_opt_t optmask; /* Mask of options used */ 1355088Sab196087 int argc; /* # of plain arguments */ 1365088Sab196087 const char **argv; /* Plain arguments */ 1375088Sab196087 int ndx_set; /* True if ndx is valid */ 1385088Sab196087 Word ndx; /* Index of header if cmd */ 1395088Sab196087 /* accepts it */ 1405088Sab196087 int print_req; /* Call is a print request */ 1415088Sab196087 } ARGSTATE; 1425088Sab196087 1435088Sab196087 1445088Sab196087 /* 1455088Sab196087 * Standard argument processing for phdr module 1465088Sab196087 * 1475088Sab196087 * entry 1485088Sab196087 * obj_state, argc, argv - Standard command arguments 1495088Sab196087 * optmask - Mask of allowed optional arguments. 1505088Sab196087 * cmd - PHDR_CMD_T_* value giving identify of caller 1515088Sab196087 * argstate - Address of ARGSTATE block to be initialized 1525088Sab196087 * 1535088Sab196087 * exit: 1545088Sab196087 * On success, *argstate is initialized. On error, 1555088Sab196087 * an error is issued and this routine does not return. 1565088Sab196087 */ 1575088Sab196087 static void 1585088Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 1595088Sab196087 PHDR_CMD_T cmd, ARGSTATE *argstate) 1605088Sab196087 { 1615088Sab196087 elfedit_getopt_state_t getopt_state; 1625088Sab196087 elfedit_getopt_ret_t *getopt_ret; 1635088Sab196087 1645088Sab196087 bzero(argstate, sizeof (*argstate)); 1655088Sab196087 argstate->obj_state = obj_state; 1665088Sab196087 1675088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 1685088Sab196087 1695088Sab196087 /* Add each new option to the options mask */ 1705088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) 1715088Sab196087 argstate->optmask |= getopt_ret->gor_idmask; 1725088Sab196087 1735088Sab196087 /* Are the right number of plain arguments present? */ 1745088Sab196087 switch (cmd) { 1755088Sab196087 case PHDR_CMD_T_DUMP: 1765088Sab196087 if (argc > 1) 1775088Sab196087 elfedit_command_usage(); 1785088Sab196087 argstate->print_req = 1; 1795088Sab196087 break; 1805088Sab196087 case PHDR_CMD_T_P_FLAGS: 1815088Sab196087 /* phdr:sh_flags allows an arbitrary number of arguments */ 1825088Sab196087 argstate->print_req = (argc < 2); 1835088Sab196087 break; 1845088Sab196087 case PHDR_CMD_T_INTERP: 1855088Sab196087 if (argc > 1) 1865088Sab196087 elfedit_command_usage(); 1875088Sab196087 argstate->print_req = (argc == 0); 1885088Sab196087 break; 1895088Sab196087 case PHDR_CMD_T_DELETE: 1905088Sab196087 if ((argc < 1) || (argc > 2)) 1915088Sab196087 elfedit_command_usage(); 1925088Sab196087 argstate->print_req = 0; 1935088Sab196087 break; 1945088Sab196087 case PHDR_CMD_T_MOVE: 1955088Sab196087 if ((argc < 2) || (argc > 3)) 1965088Sab196087 elfedit_command_usage(); 1975088Sab196087 argstate->print_req = 0; 1985088Sab196087 break; 1995088Sab196087 2005088Sab196087 default: 2015088Sab196087 /* The remaining commands accept 2 plain arguments */ 2025088Sab196087 if (argc > 2) 2035088Sab196087 elfedit_command_usage(); 2045088Sab196087 argstate->print_req = (argc < 2); 2055088Sab196087 break; 2065088Sab196087 } 2075088Sab196087 2085088Sab196087 /* Return the updated values of argc/argv */ 2095088Sab196087 argstate->argc = argc; 2105088Sab196087 argstate->argv = argv; 2115088Sab196087 2125088Sab196087 argstate->ndx_set = 0; 2135088Sab196087 if ((argc > 0) && (cmd != PHDR_CMD_T_INTERP)) { 2145088Sab196087 /* 2155088Sab196087 * If the -phndx option is present, the first argument is 2165088Sab196087 * the index of the header to use. Otherwise, it is a 2175088Sab196087 * name corresponding to its type, similar to the way 2185088Sab196087 * elfdump works with its -N option. 2195088Sab196087 */ 2205088Sab196087 if (argstate->optmask & PHDR_OPT_F_PHNDX) { 2215088Sab196087 argstate->ndx = (Word) elfedit_atoui_range( 2225088Sab196087 argstate->argv[0], MSG_ORIG(MSG_STR_ELEMENT), 0, 2235088Sab196087 argstate->obj_state->os_phnum - 1, NULL); 2245088Sab196087 argstate->ndx_set = 1; 2255088Sab196087 } else { 2265088Sab196087 Conv_inv_buf_t inv_buf; 2275088Sab196087 Word i; 2285088Sab196087 Phdr *phdr; 2295088Sab196087 2305088Sab196087 argstate->ndx = (Word) elfedit_atoconst( 2315088Sab196087 argstate->argv[0], ELFEDIT_CONST_PT); 2325088Sab196087 phdr = obj_state->os_phdr; 2335088Sab196087 for (i = 0; i < obj_state->os_phnum; i++, phdr++) { 2345088Sab196087 if (phdr->p_type == argstate->ndx) { 2355088Sab196087 argstate->ndx = i; 2365088Sab196087 argstate->ndx_set = 1; 2375088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 2385088Sab196087 MSG_INTL(MSG_DEBUG_PHDR), 2395088Sab196087 EC_WORD(i), conv_phdr_type( 2405088Sab196087 obj_state->os_ehdr->e_machine, 2415088Sab196087 phdr->p_type, 0, &inv_buf)); 2425088Sab196087 break; 2435088Sab196087 } 2445088Sab196087 } 2455088Sab196087 if (i == argstate->obj_state->os_phnum) 2465088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, 2475088Sab196087 MSG_INTL(MSG_ERR_NOPHDR), conv_phdr_type( 2485088Sab196087 obj_state->os_ehdr->e_machine, 2495088Sab196087 argstate->ndx, 0, &inv_buf)); 2505088Sab196087 } 2515088Sab196087 } 2525088Sab196087 2535088Sab196087 /* If there may be an arbitrary amount of output, use a pager */ 2545088Sab196087 if (argc == 0) 2555088Sab196087 elfedit_pager_init(); 2565088Sab196087 2575088Sab196087 } 2585088Sab196087 2595088Sab196087 2605088Sab196087 2615088Sab196087 /* 2625088Sab196087 * Locate the interpreter string for the object and related information 2635088Sab196087 * 2645088Sab196087 * entry: 2655088Sab196087 * obj_state - Object state 2665088Sab196087 * interp - NULL, or variable to be filled in with information 2675088Sab196087 * about the interpteter string. 2685088Sab196087 */ 2695088Sab196087 static const char * 2705088Sab196087 locate_interp(elfedit_obj_state_t *obj_state, INTERP_STATE *interp) 2715088Sab196087 { 2725088Sab196087 INTERP_STATE local_interp; 2735088Sab196087 elfedit_section_t *strsec; /* String table */ 2745088Sab196087 size_t phnum; /* # of program headers */ 2755088Sab196087 int phndx; /* Index of PT_INTERP program header */ 2765088Sab196087 Phdr *phdr; /* Program header array */ 2775088Sab196087 Word i; 2785088Sab196087 2795088Sab196087 if (interp == NULL) 2805088Sab196087 interp = &local_interp; 2815088Sab196087 2825088Sab196087 /* Locate the PT_INTERP program header */ 2835088Sab196087 phnum = obj_state->os_phnum; 2845088Sab196087 phdr = obj_state->os_phdr; 2855088Sab196087 2865088Sab196087 for (phndx = 0; phndx < phnum; phndx++) { 2875088Sab196087 if (phdr[phndx].p_type == PT_INTERP) { 2885088Sab196087 interp->phndx = phndx; 2895088Sab196087 interp->phdr = phdr + phndx; 2905088Sab196087 break; 2915088Sab196087 } 2925088Sab196087 } 2935088Sab196087 /* If no PT_INTERP program header found, we cannot proceed */ 2945088Sab196087 if (phndx == phnum) 2955088Sab196087 elfedit_elferr(obj_state->os_file, 2965088Sab196087 MSG_INTL(MSG_ERR_NOINTERPPHDR)); 2975088Sab196087 2985088Sab196087 /* 2995088Sab196087 * Locate the section containing the interpteter string as well 3005088Sab196087 * as the string itself. 3015088Sab196087 * 3025088Sab196087 * The program header contains a direct offset to the string, so 3035088Sab196087 * we find the section by walking through the them looking for 3045088Sab196087 * the one with a base and size that would contain the string. 3055088Sab196087 * Note that this target section cannot be in a NOBITS section. 3065088Sab196087 */ 3075088Sab196087 for (i = 1; i < obj_state->os_shnum; i++) { 3085088Sab196087 strsec = &obj_state->os_secarr[i]; 3095088Sab196087 3105088Sab196087 if ((strsec->sec_shdr->sh_type != SHT_NOBITS) && 3115088Sab196087 (interp->phdr->p_offset >= strsec->sec_shdr->sh_offset) && 3125088Sab196087 ((interp->phdr->p_offset + interp->phdr->p_filesz) <= 3135088Sab196087 (strsec->sec_shdr->sh_offset + 3145088Sab196087 strsec->sec_shdr->sh_size))) { 3155088Sab196087 interp->sec = strsec; 3165088Sab196087 3175088Sab196087 interp->stroff = interp->phdr->p_offset - 3185088Sab196087 strsec->sec_shdr->sh_offset; 3195088Sab196087 interp->str = ((char *)strsec->sec_data->d_buf) + 3205088Sab196087 interp->stroff; 3215088Sab196087 return (interp->str); 3225088Sab196087 } 3235088Sab196087 } 3245088Sab196087 3255088Sab196087 /* 3265088Sab196087 * We don't expect to get here: If there is a PT_INTERP header, 3275088Sab196087 * we fully expect the string to exist. 3285088Sab196087 */ 3295088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOINTERPSEC)); 3305088Sab196087 /*NOTREACHED*/ 3315088Sab196087 3325088Sab196087 return (NULL); /* For lint */ 3335088Sab196087 } 3345088Sab196087 3355088Sab196087 /* 3365088Sab196087 * Print program header values, taking the calling command, and output style 3375088Sab196087 * into account. 3385088Sab196087 * 3395088Sab196087 * entry: 3405088Sab196087 * autoprint - If True, output is only produced if the elfedit 3415088Sab196087 * autoprint flag is set. If False, output is always produced. 3425088Sab196087 * cmd - PHDR_CMD_T_* value giving identify of caller 3435088Sab196087 * argstate - State block for section header array 3445088Sab196087 * ndx - Index of first program header to display 3455088Sab196087 * cnt - Number of program headers to display 3465088Sab196087 */ 3475088Sab196087 static void 3485088Sab196087 print_phdr(PHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate) 3495088Sab196087 { 3505088Sab196087 elfedit_outstyle_t outstyle; 3515088Sab196087 Word ndx, cnt; 3525088Sab196087 3535088Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) 3545088Sab196087 return; 3555088Sab196087 3565088Sab196087 if (argstate->ndx_set) { 3575088Sab196087 ndx = argstate->ndx; 3585088Sab196087 cnt = 1; 3595088Sab196087 } else { 3605088Sab196087 ndx = 0; 3615088Sab196087 cnt = argstate->obj_state->os_phnum; 3625088Sab196087 } 3635088Sab196087 3645088Sab196087 /* 3655088Sab196087 * Pick an output style. phdr:dump is required to use the default 3665088Sab196087 * style. The other commands use the current output style. 3675088Sab196087 */ 3685088Sab196087 outstyle = (cmd == PHDR_CMD_T_DUMP) ? 3695088Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle(); 3705088Sab196087 3715088Sab196087 /* 3725088Sab196087 * If doing default output, use elfdump style where we 3735088Sab196087 * show all program header attributes. In this case, the 3745088Sab196087 * command that called us doesn't matter. 3755088Sab196087 * 3765088Sab196087 * Let PHDR_CMD_T_INTERP fall through: It isn't per-phdr like 3775088Sab196087 * the other commands. 3785088Sab196087 */ 3795088Sab196087 if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) && 3805088Sab196087 (cmd != PHDR_CMD_T_INTERP)) { 3815088Sab196087 Half mach = argstate->obj_state->os_ehdr->e_machine; 3825088Sab196087 Phdr *phdr = argstate->obj_state->os_phdr + ndx; 3835088Sab196087 3845088Sab196087 for (; cnt--; ndx++, phdr++) { 3855088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 3865088Sab196087 elfedit_printf(MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx)); 3875088Sab196087 Elf_phdr(0, mach, phdr); 3885088Sab196087 } 3895088Sab196087 return; 3905088Sab196087 } 3915088Sab196087 3925088Sab196087 switch (cmd) { 3935088Sab196087 case PHDR_CMD_T_P_TYPE: 3945088Sab196087 for (; cnt--; ndx++) { 3955088Sab196087 Word p_type = argstate->obj_state->os_phdr[ndx].p_type; 3965088Sab196087 Conv_inv_buf_t inv_buf; 3975088Sab196087 3985088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 3995088Sab196087 Half mach = 4005088Sab196087 argstate->obj_state->os_ehdr->e_machine; 4015088Sab196087 4025088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 4035088Sab196087 conv_phdr_type(mach, p_type, 0, &inv_buf)); 4045088Sab196087 } else { 4055088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_X_NL), 4065088Sab196087 EC_WORD(p_type)); 4075088Sab196087 } 4085088Sab196087 } 4095088Sab196087 return; 4105088Sab196087 4115088Sab196087 case PHDR_CMD_T_P_OFFSET: 4125088Sab196087 for (; cnt--; ndx++) 4135088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4145088Sab196087 EC_OFF(argstate->obj_state->os_phdr[ndx].p_offset)); 4155088Sab196087 return; 4165088Sab196087 4175088Sab196087 case PHDR_CMD_T_P_VADDR: 4185088Sab196087 for (; cnt--; ndx++) 4195088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4205088Sab196087 EC_ADDR(argstate->obj_state->os_phdr[ndx].p_vaddr)); 4215088Sab196087 return; 4225088Sab196087 4235088Sab196087 case PHDR_CMD_T_P_PADDR: 4245088Sab196087 for (; cnt--; ndx++) 4255088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4265088Sab196087 EC_ADDR(argstate->obj_state->os_phdr[ndx].p_paddr)); 4275088Sab196087 return; 4285088Sab196087 4295088Sab196087 case PHDR_CMD_T_P_FILESZ: 4305088Sab196087 for (; cnt--; ndx++) 4315088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4325088Sab196087 EC_XWORD(argstate->obj_state-> 4335088Sab196087 os_phdr[ndx].p_filesz)); 4345088Sab196087 return; 4355088Sab196087 4365088Sab196087 case PHDR_CMD_T_P_MEMSZ: 4375088Sab196087 for (; cnt--; ndx++) 4385088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4395088Sab196087 EC_XWORD(argstate->obj_state-> 4405088Sab196087 os_phdr[ndx].p_memsz)); 4415088Sab196087 return; 4425088Sab196087 4435088Sab196087 case PHDR_CMD_T_P_FLAGS: 4445088Sab196087 for (; cnt--; ndx++) { 4455088Sab196087 Word p_flags = 4465088Sab196087 argstate->obj_state->os_phdr[ndx].p_flags; 4475088Sab196087 4485088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 4495088Sab196087 Conv_phdr_flags_buf_t phdr_flags_buf; 4505088Sab196087 4515088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 4525088Sab196087 conv_phdr_flags(p_flags, CONV_FMT_NOBKT, 4535088Sab196087 &phdr_flags_buf)); 4545088Sab196087 } else { 4555088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_X_NL), 4565088Sab196087 EC_WORD(p_flags)); 4575088Sab196087 } 4585088Sab196087 } 4595088Sab196087 return; 4605088Sab196087 4615088Sab196087 case PHDR_CMD_T_P_ALIGN: 4625088Sab196087 for (; cnt--; ndx++) 4635088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 4645088Sab196087 EC_XWORD(argstate->obj_state-> 4655088Sab196087 os_phdr[ndx].p_align)); 4665088Sab196087 return; 4675088Sab196087 4685088Sab196087 case PHDR_CMD_T_INTERP: 4695088Sab196087 { 4705088Sab196087 INTERP_STATE interp; 4715088Sab196087 4725088Sab196087 (void) locate_interp(argstate->obj_state, &interp); 4735088Sab196087 switch (outstyle) { 4745088Sab196087 4755088Sab196087 case ELFEDIT_OUTSTYLE_DEFAULT: 4765088Sab196087 elfedit_printf(MSG_INTL(MSG_FMT_ELF_INTERP), 4775088Sab196087 interp.sec->sec_name, interp.str); 4785088Sab196087 break; 4795088Sab196087 case ELFEDIT_OUTSTYLE_SIMPLE: 4805088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 4815088Sab196087 interp.str); 4825088Sab196087 break; 4835088Sab196087 case ELFEDIT_OUTSTYLE_NUM: 4845088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_U_NL), 4855088Sab196087 EC_WORD(interp.stroff)); 4865088Sab196087 break; 4875088Sab196087 } 4885088Sab196087 } 4895088Sab196087 return; 4905088Sab196087 } 4915088Sab196087 } 4925088Sab196087 4935088Sab196087 4945088Sab196087 /* 4955088Sab196087 * Called from cmd_body() in the case where a plain argument 4965088Sab196087 * is given to phdr:interp to change the interpreter. 4975088Sab196087 */ 4985088Sab196087 static elfedit_cmdret_t 4995088Sab196087 cmd_body_set_interp(ARGSTATE *argstate) 5005088Sab196087 { 5015088Sab196087 elfedit_obj_state_t *obj_state = argstate->obj_state; 5025088Sab196087 elfedit_section_t *strsec; /* String table */ 5035088Sab196087 INTERP_STATE interp; 5045088Sab196087 Word numdyn; /* # of elements in dyn arr */ 5055088Sab196087 size_t phnum; /* # of program headers */ 5065088Sab196087 Phdr *phdr; /* Program header array */ 5075088Sab196087 Word i, j; 5085088Sab196087 Word str_offset; /* Offset in strsec to new interp str */ 5095088Sab196087 int str_found = 0; /* True when we have new interp str */ 5105088Sab196087 Word str_size; /* Size of new interp string + NULL */ 5115088Sab196087 5125088Sab196087 phnum = obj_state->os_phnum; 5135088Sab196087 phdr = obj_state->os_phdr; 5145088Sab196087 5155088Sab196087 /* Locate the PT_INTERP program header */ 5165088Sab196087 (void) locate_interp(obj_state, &interp); 5175088Sab196087 strsec = interp.sec; 5185088Sab196087 str_offset = interp.stroff; 5195088Sab196087 5205088Sab196087 /* 5215088Sab196087 * If the given string is the same as the existing interpreter 5225088Sab196087 * string, say so and return. 5235088Sab196087 */ 5245088Sab196087 if (strcmp(interp.str, argstate->argv[0]) == 0) { 5255088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_OLDINTERPOK), 5265088Sab196087 EC_WORD(strsec->sec_shndx), strsec->sec_name, 5275088Sab196087 EC_WORD(str_offset), interp.str); 5285088Sab196087 return (ELFEDIT_CMDRET_NONE); 5295088Sab196087 } 5305088Sab196087 5315088Sab196087 /* 5325088Sab196087 * An ELF PT_INTERP usually references its own special section 5335088Sab196087 * instead of some other string table. The ELF ABI says that this 5345088Sab196087 * section must be named ".interp". Hence, this is a rare case 5355088Sab196087 * in which the name of a section can be taken as an indication 5365088Sab196087 * of its contents. .interp is typically sized to just fit 5375088Sab196087 * the original string, including its NULL termination. You can 5385088Sab196087 * treat it as a string table with one string. 5395088Sab196087 * 5405088Sab196087 * Thanks to 'elfedit', it may be that we encounter a file where 5415088Sab196087 * PT_INTERP does not reference the .interp section. This will happen 5425088Sab196087 * if elfedit is used to change the interpreter to a string that is 5435088Sab196087 * too big to fit in .interp, in which case we will use the 5445088Sab196087 * .dynstr string table (That code is below, in this function). 5455088Sab196087 * 5465088Sab196087 * Given the above facts, our next step is to locate the .interp 5475088Sab196087 * section and see if our new string will fit in it. Since we can't 5485088Sab196087 * depend on PT_INTERP, we search the section headers to find a 5495088Sab196087 * section whith the following characteristics: 5505088Sab196087 * - The name is ".interp". 5515088Sab196087 * - Section is allocable (SHF_ALLOC) and SHT_PROGBITS. 5525088Sab196087 * - It is not part of a writable segment. 5535088Sab196087 * If we find such a section, and the new string fits, we will 5545088Sab196087 * write it there. 5555088Sab196087 */ 5565088Sab196087 str_size = strlen(argstate->argv[0]) + 1; 5575088Sab196087 for (i = 1; i < obj_state->os_shnum; i++) { 5585088Sab196087 strsec = &obj_state->os_secarr[i]; 5595088Sab196087 if ((strcmp(strsec->sec_name, MSG_ORIG(MSG_SEC_INTERP)) == 0) && 5605088Sab196087 (strsec->sec_shdr->sh_flags & SHF_ALLOC) && 5615088Sab196087 (strsec->sec_shdr->sh_type & SHT_PROGBITS)) { 5625088Sab196087 for (j = 0; j < phnum; j++) { 5635088Sab196087 Phdr *tphdr = &phdr[j]; 5645088Sab196087 if ((strsec->sec_shdr->sh_offset >= 5655088Sab196087 tphdr->p_offset) && 5665088Sab196087 ((strsec->sec_shdr->sh_offset + 5675088Sab196087 strsec->sec_shdr->sh_size) <= 5685088Sab196087 (tphdr->p_offset + tphdr->p_filesz)) && 5695088Sab196087 (tphdr->p_flags & PF_W)) { 5705088Sab196087 break; 5715088Sab196087 } 5725088Sab196087 } 5735088Sab196087 if ((j == phnum) && 5745088Sab196087 (str_size <= strsec->sec_shdr->sh_size)) { 5755088Sab196087 /* .interp section found, and has room */ 5765088Sab196087 str_found = 1; 5775088Sab196087 str_offset = 0; 5785088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 5795088Sab196087 MSG_INTL(MSG_DEBUG_NEWISTR), EC_WORD(j), 5805088Sab196087 strsec->sec_name, EC_WORD(str_offset), 5815088Sab196087 argstate->argv[0]); 5825088Sab196087 /* Put new value in section */ 5835088Sab196087 (void) strncpy((char *)strsec->sec_data->d_buf, 5845088Sab196087 argstate->argv[0], 5855088Sab196087 strsec->sec_shdr->sh_size); 5865088Sab196087 /* Set libelf dirty bit so change is flushed */ 5875088Sab196087 elfedit_modified_data(strsec); 5885088Sab196087 break; 5895088Sab196087 } else { 5905088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 5915088Sab196087 MSG_INTL(MSG_DEBUG_LNGISTR), EC_WORD(j), 5925088Sab196087 strsec->sec_name, EC_WORD(str_offset), 5935088Sab196087 EC_WORD(str_size), 5945088Sab196087 EC_WORD(strsec->sec_shdr->sh_size), 5955088Sab196087 argstate->argv[0]); 5965088Sab196087 } 5975088Sab196087 } 5985088Sab196087 } 5995088Sab196087 6005088Sab196087 /* 6015088Sab196087 * If the above did not find a string within the .interp section, 6025088Sab196087 * then we have a second option. If this ELF object has a dynamic 6035088Sab196087 * section, then we are willing to use strings from within the 6045088Sab196087 * associated .dynstr string table. And if there is reserved space 6055088Sab196087 * in .dynstr (as reported by the DT_SUNW_STRPAD dynamic entry), 6065088Sab196087 * then we are even willing to add a new string to .dynstr. 6075088Sab196087 */ 6085088Sab196087 if (!str_found) { 6095088Sab196087 elfedit_section_t *dynsec; 6105088Sab196087 Dyn *dyn; 6115088Sab196087 6125088Sab196087 dynsec = elfedit_sec_getdyn(obj_state, &dyn, &numdyn); 6135088Sab196087 strsec = elfedit_sec_getstr(obj_state, 614*6225Sab196087 dynsec->sec_shdr->sh_link, 0); 6155088Sab196087 6165088Sab196087 /* Does string exist in the table already, or can we add it? */ 6175088Sab196087 str_offset = elfedit_strtab_insert(obj_state, strsec, 6185088Sab196087 dynsec, argstate->argv[0]); 6195088Sab196087 } 6205088Sab196087 6215088Sab196087 6225088Sab196087 /* 6235088Sab196087 * If we are here, we know we have a replacement string, because 6245088Sab196087 * the errors from checking .dynamic/.dynstr will not allow 6255088Sab196087 * things to get here otherwise. 6265088Sab196087 * 6275088Sab196087 * The PT_INTERP program header references the string directly, 6285088Sab196087 * so we add the section offset to the string offset. 6295088Sab196087 */ 6305088Sab196087 interp.phdr->p_offset = strsec->sec_shdr->sh_offset + str_offset; 6315088Sab196087 interp.phdr->p_filesz = str_size; 6325088Sab196087 elfedit_modified_phdr(obj_state); 6335088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SETPHINTERP), 6345088Sab196087 EC_WORD(interp.phndx), EC_XWORD(interp.phdr->p_offset), 6355088Sab196087 EC_XWORD(interp.phdr->p_filesz)); 6365088Sab196087 6375088Sab196087 return (ELFEDIT_CMDRET_MOD); 6385088Sab196087 } 6395088Sab196087 6405088Sab196087 6415088Sab196087 /* 6425088Sab196087 * Common body for the phdr: module commands. These commands 6435088Sab196087 * share a large amount of common behavior, so it is convenient 6445088Sab196087 * to centralize things and use the cmd argument to handle the 6455088Sab196087 * small differences. 6465088Sab196087 * 6475088Sab196087 * entry: 6485088Sab196087 * cmd - One of the PHDR_CMD_T_* constants listed above, specifying 6495088Sab196087 * which command to implement. 6505088Sab196087 * obj_state, argc, argv - Standard command arguments 6515088Sab196087 */ 6525088Sab196087 static elfedit_cmdret_t 6535088Sab196087 cmd_body(PHDR_CMD_T cmd, elfedit_obj_state_t *obj_state, 6545088Sab196087 int argc, const char *argv[]) 6555088Sab196087 { 6565088Sab196087 ARGSTATE argstate; 6575088Sab196087 Phdr *phdr; 6585088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 6595088Sab196087 int do_autoprint = 1; 6605088Sab196087 6615088Sab196087 process_args(obj_state, argc, argv, cmd, &argstate); 6625088Sab196087 6635088Sab196087 /* If this is a printing request, print and return */ 6645088Sab196087 if (argstate.print_req) { 6655088Sab196087 print_phdr(cmd, 0, &argstate); 6665088Sab196087 return (ELFEDIT_CMDRET_NONE); 6675088Sab196087 } 6685088Sab196087 6695088Sab196087 6705088Sab196087 if (argstate.ndx_set) 6715088Sab196087 phdr = &argstate.obj_state->os_phdr[argstate.ndx]; 6725088Sab196087 6735088Sab196087 switch (cmd) { 6745088Sab196087 /* 6755088Sab196087 * PHDR_CMD_T_DUMP can't get here: It never has more than 6765088Sab196087 * one argument, and is handled above. 6775088Sab196087 */ 6785088Sab196087 6795088Sab196087 case PHDR_CMD_T_P_TYPE: 6805088Sab196087 { 6815088Sab196087 Half mach = obj_state->os_ehdr->e_machine; 6825088Sab196087 Word p_type = elfedit_atoconst(argstate.argv[1], 6835088Sab196087 ELFEDIT_CONST_PT); 6845088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 6855088Sab196087 6865088Sab196087 if (phdr->p_type == p_type) { 6875088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 6885088Sab196087 MSG_INTL(MSG_DEBUG_S_OK), 6895088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE), 6905088Sab196087 conv_phdr_type(mach, phdr->p_type, 6915088Sab196087 0, &inv_buf1)); 6925088Sab196087 } else { 6935088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 6945088Sab196087 MSG_INTL(MSG_DEBUG_S_CHG), 6955088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE), 6965088Sab196087 conv_phdr_type(mach, phdr->p_type, 0, 6975088Sab196087 &inv_buf1), 6985088Sab196087 conv_phdr_type(mach, p_type, 0, &inv_buf2)); 6995088Sab196087 ret = ELFEDIT_CMDRET_MOD; 7005088Sab196087 phdr->p_type = p_type; 7015088Sab196087 } 7025088Sab196087 } 7035088Sab196087 break; 7045088Sab196087 7055088Sab196087 case PHDR_CMD_T_P_OFFSET: 7065088Sab196087 { 7075088Sab196087 Off p_offset; 7085088Sab196087 7095088Sab196087 p_offset = elfedit_atoui(argstate.argv[1], NULL); 7105088Sab196087 if (phdr->p_offset == p_offset) { 7115088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7125088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 7135088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET), 7145088Sab196087 EC_XWORD(phdr->p_offset)); 7155088Sab196087 } else { 7165088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7175088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 7185088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET), 7195088Sab196087 EC_XWORD(phdr->p_offset), 7205088Sab196087 EC_XWORD(p_offset)); 7215088Sab196087 ret = ELFEDIT_CMDRET_MOD; 7225088Sab196087 phdr->p_offset = p_offset; 7235088Sab196087 } 7245088Sab196087 } 7255088Sab196087 break; 7265088Sab196087 7275088Sab196087 case PHDR_CMD_T_P_VADDR: 7285088Sab196087 { 7295088Sab196087 Addr p_vaddr = elfedit_atoui(argstate.argv[1], NULL); 7305088Sab196087 7315088Sab196087 if (phdr->p_vaddr == p_vaddr) { 7325088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7335088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 7345088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR), 7355088Sab196087 EC_ADDR(phdr->p_vaddr)); 7365088Sab196087 } else { 7375088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7385088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 7395088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR), 7405088Sab196087 EC_ADDR(phdr->p_vaddr), EC_ADDR(p_vaddr)); 7415088Sab196087 ret = ELFEDIT_CMDRET_MOD; 7425088Sab196087 phdr->p_vaddr = p_vaddr; 7435088Sab196087 } 7445088Sab196087 } 7455088Sab196087 break; 7465088Sab196087 7475088Sab196087 case PHDR_CMD_T_P_PADDR: 7485088Sab196087 { 7495088Sab196087 Addr p_paddr = elfedit_atoui(argstate.argv[1], NULL); 7505088Sab196087 7515088Sab196087 if (phdr->p_paddr == p_paddr) { 7525088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7535088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 7545088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR), 7555088Sab196087 EC_ADDR(phdr->p_paddr)); 7565088Sab196087 } else { 7575088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7585088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 7595088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR), 7605088Sab196087 EC_ADDR(phdr->p_paddr), EC_ADDR(p_paddr)); 7615088Sab196087 ret = ELFEDIT_CMDRET_MOD; 7625088Sab196087 phdr->p_paddr = p_paddr; 7635088Sab196087 } 7645088Sab196087 } 7655088Sab196087 break; 7665088Sab196087 7675088Sab196087 case PHDR_CMD_T_P_FILESZ: 7685088Sab196087 { 7695088Sab196087 Xword p_filesz = elfedit_atoui(argstate.argv[1], NULL); 7705088Sab196087 7715088Sab196087 if (phdr->p_filesz == p_filesz) { 7725088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7735088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 7745088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ), 7755088Sab196087 EC_XWORD(phdr->p_filesz)); 7765088Sab196087 } else { 7775088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7785088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 7795088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ), 7805088Sab196087 EC_XWORD(phdr->p_filesz), 7815088Sab196087 EC_XWORD(p_filesz)); 7825088Sab196087 ret = ELFEDIT_CMDRET_MOD; 7835088Sab196087 phdr->p_filesz = p_filesz; 7845088Sab196087 } 7855088Sab196087 } 7865088Sab196087 break; 7875088Sab196087 7885088Sab196087 case PHDR_CMD_T_P_MEMSZ: 7895088Sab196087 { 7905088Sab196087 Xword p_memsz = elfedit_atoui(argstate.argv[1], NULL); 7915088Sab196087 7925088Sab196087 if (phdr->p_memsz == p_memsz) { 7935088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7945088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 7955088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ), 7965088Sab196087 EC_XWORD(phdr->p_memsz)); 7975088Sab196087 } else { 7985088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 7995088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 8005088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ), 8015088Sab196087 EC_XWORD(phdr->p_memsz), 8025088Sab196087 EC_XWORD(p_memsz)); 8035088Sab196087 ret = ELFEDIT_CMDRET_MOD; 8045088Sab196087 phdr->p_memsz = p_memsz; 8055088Sab196087 } 8065088Sab196087 } 8075088Sab196087 break; 8085088Sab196087 8095088Sab196087 case PHDR_CMD_T_P_FLAGS: 8105088Sab196087 { 8115088Sab196087 Conv_phdr_flags_buf_t buf1, buf2; 8125088Sab196087 Word p_flags = 0; 8135088Sab196087 int i; 8145088Sab196087 8155088Sab196087 /* Collect the flag arguments */ 8165088Sab196087 for (i = 1; i < argstate.argc; i++) 8175088Sab196087 p_flags |= 8185088Sab196087 (Word) elfedit_atoconst(argstate.argv[i], 8195088Sab196087 ELFEDIT_CONST_PF); 8205088Sab196087 8215088Sab196087 /* Complement the value? */ 8225088Sab196087 if (argstate.optmask & PHDR_OPT_F_CMP) 8235088Sab196087 p_flags = ~p_flags; 8245088Sab196087 8255088Sab196087 /* Perform any requested bit operations */ 8265088Sab196087 if (argstate.optmask & PHDR_OPT_F_AND) 8275088Sab196087 p_flags &= phdr->p_flags; 8285088Sab196087 else if (argstate.optmask & PHDR_OPT_F_OR) 8295088Sab196087 p_flags |= phdr->p_flags; 8305088Sab196087 8315088Sab196087 /* Set the value */ 8325088Sab196087 if (phdr->p_flags == p_flags) { 8335088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 8345088Sab196087 MSG_INTL(MSG_DEBUG_S_OK), 8355088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS), 8365088Sab196087 conv_phdr_flags(phdr->p_flags, 0, &buf1)); 8375088Sab196087 } else { 8385088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 8395088Sab196087 MSG_INTL(MSG_DEBUG_S_CHG), 8405088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS), 8415088Sab196087 conv_phdr_flags(phdr->p_flags, 0, &buf1), 8425088Sab196087 conv_phdr_flags(p_flags, 0, &buf2)); 8435088Sab196087 ret = ELFEDIT_CMDRET_MOD; 8445088Sab196087 phdr->p_flags = p_flags; 8455088Sab196087 } 8465088Sab196087 } 8475088Sab196087 break; 8485088Sab196087 8495088Sab196087 case PHDR_CMD_T_P_ALIGN: 8505088Sab196087 { 8515088Sab196087 Xword p_align = elfedit_atoui(argstate.argv[1], NULL); 8525088Sab196087 8535088Sab196087 if (phdr->p_align == p_align) { 8545088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 8555088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 8565088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN), 8575088Sab196087 EC_XWORD(phdr->p_align)); 8585088Sab196087 } else { 8595088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 8605088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 8615088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN), 8625088Sab196087 EC_XWORD(phdr->p_align), 8635088Sab196087 EC_XWORD(p_align)); 8645088Sab196087 ret = ELFEDIT_CMDRET_MOD; 8655088Sab196087 phdr->p_align = p_align; 8665088Sab196087 } 8675088Sab196087 } 8685088Sab196087 break; 8695088Sab196087 8705088Sab196087 case PHDR_CMD_T_INTERP: 8715088Sab196087 ret = cmd_body_set_interp(&argstate); 8725088Sab196087 break; 8735088Sab196087 8745088Sab196087 case PHDR_CMD_T_DELETE: 8755088Sab196087 { 8765088Sab196087 Word cnt = (argstate.argc == 1) ? 1 : 8775088Sab196087 (Word) elfedit_atoui_range(argstate.argv[1], 8785088Sab196087 MSG_ORIG(MSG_STR_COUNT), 1, 8795088Sab196087 obj_state->os_phnum - argstate.ndx, NULL); 8805088Sab196087 8815088Sab196087 elfedit_array_elts_delete(MSG_ORIG(MSG_MOD_NAME), 8825088Sab196087 obj_state->os_phdr, sizeof (Phdr), 8835088Sab196087 obj_state->os_phnum, argstate.ndx, cnt); 8845088Sab196087 do_autoprint = 0; 8855088Sab196087 ret = ELFEDIT_CMDRET_MOD; 8865088Sab196087 } 8875088Sab196087 break; 8885088Sab196087 8895088Sab196087 case PHDR_CMD_T_MOVE: 8905088Sab196087 { 8915088Sab196087 Phdr save; 8925088Sab196087 Word cnt; 8935088Sab196087 Word dstndx; 8945088Sab196087 8955088Sab196087 do_autoprint = 0; 8965088Sab196087 dstndx = (Word) 8975088Sab196087 elfedit_atoui_range(argstate.argv[1], 8985088Sab196087 MSG_ORIG(MSG_STR_DST_INDEX), 0, 8995088Sab196087 obj_state->os_phnum - 1, NULL); 9005088Sab196087 if (argstate.argc == 2) { 9015088Sab196087 cnt = 1; 9025088Sab196087 } else { 9035088Sab196087 cnt = (Word) elfedit_atoui_range( 9045088Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT), 9055088Sab196087 1, obj_state->os_phnum, NULL); 9065088Sab196087 } 9075088Sab196087 elfedit_array_elts_move(MSG_ORIG(MSG_MOD_NAME), 9085088Sab196087 obj_state->os_phdr, sizeof (save), 9095088Sab196087 obj_state->os_phnum, argstate.ndx, dstndx, 9105088Sab196087 cnt, &save); 9115088Sab196087 ret = ELFEDIT_CMDRET_MOD; 9125088Sab196087 } 9135088Sab196087 break; 9145088Sab196087 } 9155088Sab196087 9165088Sab196087 /* 9175088Sab196087 * If we modified the section header array, tell libelf. 9185088Sab196087 */ 9195088Sab196087 if (ret == ELFEDIT_CMDRET_MOD) 9205088Sab196087 elfedit_modified_phdr(obj_state); 9215088Sab196087 9225088Sab196087 /* Do autoprint */ 9235088Sab196087 if (do_autoprint) 9245088Sab196087 print_phdr(cmd, 1, &argstate); 9255088Sab196087 9265088Sab196087 return (ret); 9275088Sab196087 } 9285088Sab196087 9295088Sab196087 9305088Sab196087 9315088Sab196087 /* 9325088Sab196087 * Command completion functions for the various commands 9335088Sab196087 */ 9345088Sab196087 9355088Sab196087 /* 9365088Sab196087 * A number of the commands accept a PT_ constant as their first 9375088Sab196087 * argument as long as the -phndx option is not used. 9385088Sab196087 */ 9395088Sab196087 /*ARGSUSED*/ 9405088Sab196087 static void 9415088Sab196087 cpl_1starg_pt(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 9425088Sab196087 const char *argv[], int num_opt) 9435088Sab196087 { 9445088Sab196087 int i; 9455088Sab196087 9465088Sab196087 for (i = 0; i < num_opt; i++) 9475088Sab196087 if (strcmp(MSG_ORIG(MSG_STR_MINUS_PHNDX), argv[i]) == 0) 9485088Sab196087 return; 9495088Sab196087 9505088Sab196087 if (argc == (num_opt + 1)) 9515088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT); 9525088Sab196087 } 9535088Sab196087 9545088Sab196087 /*ARGSUSED*/ 9555088Sab196087 static void 9565088Sab196087 cpl_p_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 9575088Sab196087 const char *argv[], int num_opt) 9585088Sab196087 { 9595088Sab196087 /* The first argument follows the standard rules */ 9605088Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt); 9615088Sab196087 9625088Sab196087 /* The second argument can be a PT_ value */ 9635088Sab196087 if (argc == (num_opt + 2)) 9645088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT); 9655088Sab196087 } 9665088Sab196087 9675088Sab196087 9685088Sab196087 /*ARGSUSED*/ 9695088Sab196087 static void 9705088Sab196087 cpl_p_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 9715088Sab196087 const char *argv[], int num_opt) 9725088Sab196087 { 9735088Sab196087 /* The first argument follows the standard rules */ 9745088Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt); 9755088Sab196087 9765088Sab196087 /* The second and following arguments can be an PF_ value */ 9775088Sab196087 if (argc >= (num_opt + 2)) 9785088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PF); 9795088Sab196087 } 9805088Sab196087 9815088Sab196087 9825088Sab196087 9835088Sab196087 /* 9845088Sab196087 * Implementation functions for the commands 9855088Sab196087 */ 9865088Sab196087 static elfedit_cmdret_t 9875088Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 9885088Sab196087 { 9895088Sab196087 return (cmd_body(PHDR_CMD_T_DUMP, obj_state, argc, argv)); 9905088Sab196087 } 9915088Sab196087 9925088Sab196087 static elfedit_cmdret_t 9935088Sab196087 cmd_p_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 9945088Sab196087 { 9955088Sab196087 return (cmd_body(PHDR_CMD_T_P_TYPE, obj_state, argc, argv)); 9965088Sab196087 } 9975088Sab196087 9985088Sab196087 static elfedit_cmdret_t 9995088Sab196087 cmd_p_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10005088Sab196087 { 10015088Sab196087 return (cmd_body(PHDR_CMD_T_P_OFFSET, obj_state, argc, argv)); 10025088Sab196087 } 10035088Sab196087 10045088Sab196087 static elfedit_cmdret_t 10055088Sab196087 cmd_p_vaddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10065088Sab196087 { 10075088Sab196087 return (cmd_body(PHDR_CMD_T_P_VADDR, obj_state, argc, argv)); 10085088Sab196087 } 10095088Sab196087 10105088Sab196087 static elfedit_cmdret_t 10115088Sab196087 cmd_p_paddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10125088Sab196087 { 10135088Sab196087 return (cmd_body(PHDR_CMD_T_P_PADDR, obj_state, argc, argv)); 10145088Sab196087 } 10155088Sab196087 10165088Sab196087 static elfedit_cmdret_t 10175088Sab196087 cmd_p_filesz(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10185088Sab196087 { 10195088Sab196087 return (cmd_body(PHDR_CMD_T_P_FILESZ, obj_state, argc, argv)); 10205088Sab196087 } 10215088Sab196087 10225088Sab196087 static elfedit_cmdret_t 10235088Sab196087 cmd_p_memsz(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10245088Sab196087 { 10255088Sab196087 return (cmd_body(PHDR_CMD_T_P_MEMSZ, obj_state, argc, argv)); 10265088Sab196087 } 10275088Sab196087 10285088Sab196087 static elfedit_cmdret_t 10295088Sab196087 cmd_p_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10305088Sab196087 { 10315088Sab196087 return (cmd_body(PHDR_CMD_T_P_FLAGS, obj_state, argc, argv)); 10325088Sab196087 } 10335088Sab196087 10345088Sab196087 static elfedit_cmdret_t 10355088Sab196087 cmd_p_align(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10365088Sab196087 { 10375088Sab196087 return (cmd_body(PHDR_CMD_T_P_ALIGN, obj_state, argc, argv)); 10385088Sab196087 } 10395088Sab196087 10405088Sab196087 static elfedit_cmdret_t 10415088Sab196087 cmd_interp(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10425088Sab196087 { 10435088Sab196087 return (cmd_body(PHDR_CMD_T_INTERP, obj_state, argc, argv)); 10445088Sab196087 } 10455088Sab196087 10465088Sab196087 static elfedit_cmdret_t 10475088Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10485088Sab196087 { 10495088Sab196087 return (cmd_body(PHDR_CMD_T_DELETE, obj_state, argc, argv)); 10505088Sab196087 } 10515088Sab196087 10525088Sab196087 static elfedit_cmdret_t 10535088Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 10545088Sab196087 { 10555088Sab196087 return (cmd_body(PHDR_CMD_T_MOVE, obj_state, argc, argv)); 10565088Sab196087 } 10575088Sab196087 10585088Sab196087 10595088Sab196087 /*ARGSUSED*/ 10605088Sab196087 elfedit_module_t * 10615088Sab196087 elfedit_init(elfedit_module_version_t version) 10625088Sab196087 { 10635088Sab196087 /* Multiple commands accept a standard set of options */ 10645088Sab196087 static elfedit_cmd_optarg_t opt_std[] = { 10655088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 10665088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 10675088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 10685088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 10695088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 10705088Sab196087 PHDR_OPT_F_PHNDX, 0 }, 10715088Sab196087 { NULL } 10725088Sab196087 }; 10735088Sab196087 10745088Sab196087 /* For commands that only accept -phndx */ 10755088Sab196087 static elfedit_cmd_optarg_t opt_minus_phndx[] = { 10765088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 10775088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 10785088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 10795088Sab196087 PHDR_OPT_F_PHNDX, 0 }, 10805088Sab196087 { NULL } 10815088Sab196087 }; 10825088Sab196087 10835088Sab196087 10845088Sab196087 /* phdr:dump */ 10855088Sab196087 static const char *name_dump[] = { 10865088Sab196087 MSG_ORIG(MSG_CMD_DUMP), 10875088Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 10885088Sab196087 NULL 10895088Sab196087 }; 10905088Sab196087 static elfedit_cmd_optarg_t arg_dump[] = { 10915088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 10925088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 10935088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 10945088Sab196087 ELFEDIT_CMDOA_F_OPT }, 10955088Sab196087 { NULL } 10965088Sab196087 }; 10975088Sab196087 10985088Sab196087 /* phdr:p_type */ 10995088Sab196087 static const char *name_p_type[] = { MSG_ORIG(MSG_CMD_P_TYPE), NULL }; 11005088Sab196087 static elfedit_cmd_optarg_t arg_p_type[] = { 11015088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 11025088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11035088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11045088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11055088Sab196087 { MSG_ORIG(MSG_STR_TYPE), 11065088Sab196087 /* MSG_INTL(MSG_A2_P_TYPE_TYPE) */ 11075088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_TYPE_TYPE), 11085088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11095088Sab196087 { NULL } 11105088Sab196087 }; 11115088Sab196087 11125088Sab196087 /* phdr:p_offset */ 11135088Sab196087 static const char *name_p_offset[] = { MSG_ORIG(MSG_CMD_P_OFFSET), 11145088Sab196087 NULL }; 11155088Sab196087 static elfedit_cmd_optarg_t arg_p_offset[] = { 11165088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 11175088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11185088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11195088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11205088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 11215088Sab196087 /* MSG_INTL(MSG_A2_P_OFFSET_VALUE) */ 11225088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_OFFSET_VALUE), 11235088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11245088Sab196087 { NULL } 11255088Sab196087 }; 11265088Sab196087 11275088Sab196087 /* phdr:p_vaddr */ 11285088Sab196087 static const char *name_p_vaddr[] = { MSG_ORIG(MSG_CMD_P_VADDR), 11295088Sab196087 NULL }; 11305088Sab196087 static elfedit_cmd_optarg_t arg_p_vaddr[] = { 11315088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 11325088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11335088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11345088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11355088Sab196087 { MSG_ORIG(MSG_STR_ADDR), 11365088Sab196087 /* MSG_INTL(MSG_A2_P_VADDR_ADDR) */ 11375088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_VADDR_ADDR), 11385088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11395088Sab196087 { NULL } 11405088Sab196087 }; 11415088Sab196087 11425088Sab196087 /* phdr:p_paddr */ 11435088Sab196087 static const char *name_p_paddr[] = { MSG_ORIG(MSG_CMD_P_PADDR), 11445088Sab196087 NULL }; 11455088Sab196087 static elfedit_cmd_optarg_t arg_p_paddr[] = { 11465088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 11475088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11485088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11495088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11505088Sab196087 { MSG_ORIG(MSG_STR_ADDR), 11515088Sab196087 /* MSG_INTL(MSG_A2_P_PADDR_ADDR) */ 11525088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_PADDR_ADDR), 11535088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11545088Sab196087 { NULL } 11555088Sab196087 }; 11565088Sab196087 11575088Sab196087 /* phdr:p_filesz */ 11585088Sab196087 static const char *name_p_filesz[] = { MSG_ORIG(MSG_CMD_P_FILESZ), 11595088Sab196087 NULL }; 11605088Sab196087 static elfedit_cmd_optarg_t arg_p_filesz[] = { 11615088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11625088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11635088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11645088Sab196087 { MSG_ORIG(MSG_STR_SIZE), 11655088Sab196087 /* MSG_INTL(MSG_A2_P_FILESZ_SIZE) */ 11665088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FILESZ_SIZE), 11675088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11685088Sab196087 { NULL } 11695088Sab196087 }; 11705088Sab196087 11715088Sab196087 /* phdr:p_memsz */ 11725088Sab196087 static const char *name_p_memsz[] = { MSG_ORIG(MSG_CMD_P_MEMSZ), 11735088Sab196087 NULL }; 11745088Sab196087 static elfedit_cmd_optarg_t arg_p_memsz[] = { 11755088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 11765088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 11775088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 11785088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11795088Sab196087 { MSG_ORIG(MSG_STR_SIZE), 11805088Sab196087 /* MSG_INTL(MSG_A2_P_MEMSZ_SIZE) */ 11815088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_MEMSZ_SIZE), 11825088Sab196087 ELFEDIT_CMDOA_F_OPT }, 11835088Sab196087 { NULL } 11845088Sab196087 }; 11855088Sab196087 11865088Sab196087 /* shdr:p_flags */ 11875088Sab196087 static const char *name_p_flags[] = { 11885088Sab196087 MSG_ORIG(MSG_CMD_P_FLAGS), NULL }; 11895088Sab196087 static elfedit_cmd_optarg_t opt_p_flags[] = { 11905088Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL, 11915088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_AND, PHDR_OPT_F_OR }, 11925088Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL, 11935088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_CMP, 0 }, 11945088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 11955088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 11965088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 11975088Sab196087 PHDR_OPT_F_PHNDX, 0 }, 11985088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 11995088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 12005088Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL, 12015088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_OR, PHDR_OPT_F_AND }, 12025088Sab196087 { NULL } 12035088Sab196087 }; 12045088Sab196087 static elfedit_cmd_optarg_t arg_p_flags[] = { 12055088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 12065088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 12075088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 12085088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12095088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 12105088Sab196087 /* MSG_INTL(MSG_A2_P_FLAGS_VALUE) */ 12115088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FLAGS_VALUE), 12125088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 12135088Sab196087 { NULL } 12145088Sab196087 }; 12155088Sab196087 12165088Sab196087 /* phdr:p_align */ 12175088Sab196087 static const char *name_p_align[] = { MSG_ORIG(MSG_CMD_P_ALIGN), 12185088Sab196087 NULL }; 12195088Sab196087 static elfedit_cmd_optarg_t arg_p_align[] = { 12205088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 12215088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 12225088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 12235088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12245088Sab196087 { MSG_ORIG(MSG_STR_ALIGN), 12255088Sab196087 /* MSG_INTL(MSG_A2_P_ALIGN_ALIGN) */ 12265088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_ALIGN_ALIGN), 12275088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12285088Sab196087 { NULL } 12295088Sab196087 }; 12305088Sab196087 12315088Sab196087 /* phdr:interp */ 12325088Sab196087 static const char *name_interp[] = { MSG_ORIG(MSG_CMD_INTERP), NULL }; 12335088Sab196087 static elfedit_cmd_optarg_t opt_interp[] = { 12345088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 12355088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 12365088Sab196087 { NULL } 12375088Sab196087 }; 12385088Sab196087 static elfedit_cmd_optarg_t arg_interp[] = { 12395088Sab196087 { MSG_ORIG(MSG_STR_NEWPATH), 12405088Sab196087 /* MSG_INTL(MSG_A1_INTERP_NEWPATH) */ 12415088Sab196087 ELFEDIT_I18NHDL(MSG_A1_INTERP_NEWPATH), 12425088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12435088Sab196087 { NULL } 12445088Sab196087 }; 12455088Sab196087 12465088Sab196087 /* phdr:delete */ 12475088Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL }; 12485088Sab196087 static elfedit_cmd_optarg_t arg_delete[] = { 12495088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 12505088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 12515088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 12525088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12535088Sab196087 { MSG_ORIG(MSG_STR_COUNT), 12545088Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */ 12555088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT), 12565088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12575088Sab196087 { NULL } 12585088Sab196087 }; 12595088Sab196087 12605088Sab196087 /* phdr:move */ 12615088Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL }; 12625088Sab196087 static elfedit_cmd_optarg_t arg_move[] = { 12635088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 12645088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 12655088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 12665088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12675088Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX), 12685088Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */ 12695088Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX), 12705088Sab196087 0 }, 12715088Sab196087 { MSG_ORIG(MSG_STR_COUNT), 12725088Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */ 12735088Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT), 12745088Sab196087 ELFEDIT_CMDOA_F_OPT }, 12755088Sab196087 { NULL } 12765088Sab196087 }; 12775088Sab196087 12785088Sab196087 static elfedit_cmd_t cmds[] = { 12795088Sab196087 /* phdr:dump */ 12805088Sab196087 { cmd_dump, cpl_1starg_pt, name_dump, 12815088Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */ 12825088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 12835088Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */ 12845088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 12855088Sab196087 opt_minus_phndx, arg_dump }, 12865088Sab196087 12875088Sab196087 /* phdr:p_type */ 12885088Sab196087 { cmd_p_type, cpl_p_type, name_p_type, 12895088Sab196087 /* MSG_INTL(MSG_DESC_P_TYPE) */ 12905088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_TYPE), 12915088Sab196087 /* MSG_INTL(MSG_HELP_P_TYPE) */ 12925088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_TYPE), 12935088Sab196087 opt_std, arg_p_type }, 12945088Sab196087 12955088Sab196087 /* phdr:p_offset */ 12965088Sab196087 { cmd_p_offset, cpl_1starg_pt, name_p_offset, 12975088Sab196087 /* MSG_INTL(MSG_DESC_P_OFFSET) */ 12985088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_OFFSET), 12995088Sab196087 /* MSG_INTL(MSG_HELP_P_OFFSET) */ 13005088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_OFFSET), 13015088Sab196087 opt_std, arg_p_offset }, 13025088Sab196087 13035088Sab196087 /* phdr:p_vaddr */ 13045088Sab196087 { cmd_p_vaddr, cpl_1starg_pt, name_p_vaddr, 13055088Sab196087 /* MSG_INTL(MSG_DESC_P_VADDR) */ 13065088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_VADDR), 13075088Sab196087 /* MSG_INTL(MSG_HELP_P_VADDR) */ 13085088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_VADDR), 13095088Sab196087 opt_std, arg_p_vaddr }, 13105088Sab196087 13115088Sab196087 /* phdr:p_paddr */ 13125088Sab196087 { cmd_p_paddr, cpl_1starg_pt, name_p_paddr, 13135088Sab196087 /* MSG_INTL(MSG_DESC_P_PADDR) */ 13145088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_PADDR), 13155088Sab196087 /* MSG_INTL(MSG_HELP_P_PADDR) */ 13165088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_PADDR), 13175088Sab196087 opt_std, arg_p_paddr }, 13185088Sab196087 13195088Sab196087 /* phdr:p_filesz */ 13205088Sab196087 { cmd_p_filesz, cpl_1starg_pt, name_p_filesz, 13215088Sab196087 /* MSG_INTL(MSG_DESC_P_FILESZ) */ 13225088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FILESZ), 13235088Sab196087 /* MSG_INTL(MSG_HELP_P_FILESZ) */ 13245088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FILESZ), 13255088Sab196087 opt_std, arg_p_filesz }, 13265088Sab196087 13275088Sab196087 /* phdr:p_memsz */ 13285088Sab196087 { cmd_p_memsz, cpl_1starg_pt, name_p_memsz, 13295088Sab196087 /* MSG_INTL(MSG_DESC_P_MEMSZ) */ 13305088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_MEMSZ), 13315088Sab196087 /* MSG_INTL(MSG_HELP_P_MEMSZ) */ 13325088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_MEMSZ), 13335088Sab196087 opt_std, arg_p_memsz }, 13345088Sab196087 13355088Sab196087 /* phdr:p_flags */ 13365088Sab196087 { cmd_p_flags, cpl_p_flags, name_p_flags, 13375088Sab196087 /* MSG_INTL(MSG_DESC_P_FLAGS) */ 13385088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FLAGS), 13395088Sab196087 /* MSG_INTL(MSG_HELP_P_FLAGS) */ 13405088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FLAGS), 13415088Sab196087 opt_p_flags, arg_p_flags }, 13425088Sab196087 13435088Sab196087 /* phdr:p_align */ 13445088Sab196087 { cmd_p_align, cpl_1starg_pt, name_p_align, 13455088Sab196087 /* MSG_INTL(MSG_DESC_P_ALIGN) */ 13465088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_ALIGN), 13475088Sab196087 /* MSG_INTL(MSG_HELP_P_ALIGN) */ 13485088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_ALIGN), 13495088Sab196087 opt_std, arg_p_align }, 13505088Sab196087 13515088Sab196087 /* phdr:interp */ 13525088Sab196087 { cmd_interp, NULL, name_interp, 13535088Sab196087 /* MSG_INTL(MSG_DESC_INTERP) */ 13545088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_INTERP), 13555088Sab196087 /* MSG_INTL(MSG_HELP_INTERP) */ 13565088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_INTERP), 13575088Sab196087 opt_interp, arg_interp }, 13585088Sab196087 13595088Sab196087 /* phdr:delete */ 13605088Sab196087 { cmd_delete, cpl_1starg_pt, name_delete, 13615088Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */ 13625088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE), 13635088Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */ 13645088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE), 13655088Sab196087 opt_minus_phndx, arg_delete }, 13665088Sab196087 13675088Sab196087 /* phdr:move */ 13685088Sab196087 { cmd_move, cpl_1starg_pt, name_move, 13695088Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */ 13705088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE), 13715088Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */ 13725088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE), 13735088Sab196087 opt_minus_phndx, arg_move }, 13745088Sab196087 13755088Sab196087 { NULL } 13765088Sab196087 }; 13775088Sab196087 13785088Sab196087 static elfedit_module_t module = { 13795088Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 13805088Sab196087 /* MSG_INTL(MSG_MOD_DESC) */ 13815088Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC), 13825088Sab196087 cmds, mod_i18nhdl_to_str }; 13835088Sab196087 13845088Sab196087 return (&module); 13855088Sab196087 } 1386