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 /*
23*9273SAli.Bahrami@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245088Sab196087 * Use is subject to license terms.
255088Sab196087 */
265088Sab196087
275088Sab196087 #include <elfedit.h>
285088Sab196087 #include <strings.h>
295088Sab196087 #include <conv.h>
305088Sab196087 #include <debug.h>
315088Sab196087 #include <phdr_msg.h>
325088Sab196087
335088Sab196087
345088Sab196087 /*
355088Sab196087 * Program headers
365088Sab196087 */
375088Sab196087
385088Sab196087
395088Sab196087
405088Sab196087 /*
415088Sab196087 * This module uses shared code for several of the commands.
425088Sab196087 * It is sometimes necessary to know which specific command
435088Sab196087 * is active.
445088Sab196087 */
455088Sab196087 typedef enum {
465088Sab196087 /* Dump command, used as module default to display dynamic section */
475088Sab196087 PHDR_CMD_T_DUMP = 0, /* phdr:dump */
485088Sab196087
495088Sab196087 /* Commands that correspond directly to program header fields */
505088Sab196087 PHDR_CMD_T_P_TYPE = 1, /* phdr:p_type */
515088Sab196087 PHDR_CMD_T_P_OFFSET = 2, /* phdr:p_offset */
525088Sab196087 PHDR_CMD_T_P_VADDR = 3, /* phdr:p_vaddr */
535088Sab196087 PHDR_CMD_T_P_PADDR = 4, /* phdr:p_paddr */
545088Sab196087 PHDR_CMD_T_P_FILESZ = 5, /* phdr:p_filesz */
555088Sab196087 PHDR_CMD_T_P_MEMSZ = 6, /* phdr:p_memsz */
565088Sab196087 PHDR_CMD_T_P_FLAGS = 7, /* phdr:p_flags */
575088Sab196087 PHDR_CMD_T_P_ALIGN = 8, /* phdr:p_align */
585088Sab196087
595088Sab196087 /* Commands that do not correspond directly to a specific phdr tag */
605088Sab196087 PHDR_CMD_T_INTERP = 9, /* phdr:interp */
615088Sab196087 PHDR_CMD_T_DELETE = 10, /* phdr:delete */
625088Sab196087 PHDR_CMD_T_MOVE = 11 /* phdr:move */
635088Sab196087 } PHDR_CMD_T;
645088Sab196087
655088Sab196087
665088Sab196087
675088Sab196087 /*
685088Sab196087 * The following type is ued by locate_interp() to return
695088Sab196087 * information about the interpreter program header.
705088Sab196087 */
715088Sab196087 typedef struct {
725088Sab196087 Word phndx; /* Index of PT_INTERP header */
735088Sab196087 Phdr *phdr; /* PT_INTERP header */
745088Sab196087 elfedit_section_t *sec; /* Section containing string */
755088Sab196087 Word stroff; /* Offset into string section */
765088Sab196087 const char *str; /* Interpreter string */
775088Sab196087 } INTERP_STATE;
785088Sab196087
795088Sab196087
805088Sab196087 #ifndef _ELF64
815088Sab196087 /*
825088Sab196087 * We supply this function for the msg module
835088Sab196087 */
845088Sab196087 const char *
_phdr_msg(Msg mid)855088Sab196087 _phdr_msg(Msg mid)
865088Sab196087 {
875088Sab196087 return (gettext(MSG_ORIG(mid)));
885088Sab196087 }
895088Sab196087 #endif
905088Sab196087
915088Sab196087
925088Sab196087 /*
935088Sab196087 * This function is supplied to elfedit through our elfedit_module_t
945088Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles
955088Sab196087 * in our module interface into the actual strings for elfedit to
965088Sab196087 * use.
975088Sab196087 *
985088Sab196087 * note:
995088Sab196087 * This module uses Msg codes for its i18n handle type.
1005088Sab196087 * So the translation is simply to use MSG_INTL() to turn
1015088Sab196087 * it into a string and return it.
1025088Sab196087 */
1035088Sab196087 static const char *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)1045088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
1055088Sab196087 {
1065088Sab196087 Msg msg = (Msg)hdl;
1075088Sab196087
1085088Sab196087 return (MSG_INTL(msg));
1095088Sab196087 }
1105088Sab196087
1115088Sab196087
1125088Sab196087
1135088Sab196087 /*
1145088Sab196087 * The phdr_opt_t enum specifies a bit value for every optional
1155088Sab196087 * argument allowed by a command in this module.
1165088Sab196087 */
1175088Sab196087 typedef enum {
1185088Sab196087 PHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */
1195088Sab196087 PHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */
1205088Sab196087 PHDR_OPT_F_PHNDX = 4, /* -phndx: Program header by index, */
1215088Sab196087 /* not by name */
1225088Sab196087 PHDR_OPT_F_OR = 8 /* -or: OR (|) values to dest */
1235088Sab196087 } phdr_opt_t;
1245088Sab196087
1255088Sab196087
1265088Sab196087 /*
1275088Sab196087 * A variable of type ARGSTATE is used by each command to maintain
1285088Sab196087 * information about the section headers and related things. It is
1295088Sab196087 * initialized by process_args(), and used by the other routines.
1305088Sab196087 */
1315088Sab196087 typedef struct {
1325088Sab196087 elfedit_obj_state_t *obj_state;
1335088Sab196087 phdr_opt_t optmask; /* Mask of options used */
1345088Sab196087 int argc; /* # of plain arguments */
1355088Sab196087 const char **argv; /* Plain arguments */
1365088Sab196087 int ndx_set; /* True if ndx is valid */
1375088Sab196087 Word ndx; /* Index of header if cmd */
1385088Sab196087 /* accepts it */
1395088Sab196087 int print_req; /* Call is a print request */
1405088Sab196087 } ARGSTATE;
1415088Sab196087
1425088Sab196087
1435088Sab196087 /*
1445088Sab196087 * Standard argument processing for phdr module
1455088Sab196087 *
1465088Sab196087 * entry
1475088Sab196087 * obj_state, argc, argv - Standard command arguments
1485088Sab196087 * optmask - Mask of allowed optional arguments.
1495088Sab196087 * cmd - PHDR_CMD_T_* value giving identify of caller
1505088Sab196087 * argstate - Address of ARGSTATE block to be initialized
1515088Sab196087 *
1525088Sab196087 * exit:
1535088Sab196087 * On success, *argstate is initialized. On error,
1545088Sab196087 * an error is issued and this routine does not return.
1555088Sab196087 */
1565088Sab196087 static void
process_args(elfedit_obj_state_t * obj_state,int argc,const char * argv[],PHDR_CMD_T cmd,ARGSTATE * argstate)1575088Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
1585088Sab196087 PHDR_CMD_T cmd, ARGSTATE *argstate)
1595088Sab196087 {
1605088Sab196087 elfedit_getopt_state_t getopt_state;
1615088Sab196087 elfedit_getopt_ret_t *getopt_ret;
1625088Sab196087
1635088Sab196087 bzero(argstate, sizeof (*argstate));
1645088Sab196087 argstate->obj_state = obj_state;
1655088Sab196087
1665088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv);
1675088Sab196087
1685088Sab196087 /* Add each new option to the options mask */
1695088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL)
1705088Sab196087 argstate->optmask |= getopt_ret->gor_idmask;
1715088Sab196087
1725088Sab196087 /* Are the right number of plain arguments present? */
1735088Sab196087 switch (cmd) {
1745088Sab196087 case PHDR_CMD_T_DUMP:
1755088Sab196087 if (argc > 1)
1765088Sab196087 elfedit_command_usage();
1775088Sab196087 argstate->print_req = 1;
1785088Sab196087 break;
1795088Sab196087 case PHDR_CMD_T_P_FLAGS:
1805088Sab196087 /* phdr:sh_flags allows an arbitrary number of arguments */
1815088Sab196087 argstate->print_req = (argc < 2);
1825088Sab196087 break;
1835088Sab196087 case PHDR_CMD_T_INTERP:
1845088Sab196087 if (argc > 1)
1855088Sab196087 elfedit_command_usage();
1865088Sab196087 argstate->print_req = (argc == 0);
1875088Sab196087 break;
1885088Sab196087 case PHDR_CMD_T_DELETE:
1895088Sab196087 if ((argc < 1) || (argc > 2))
1905088Sab196087 elfedit_command_usage();
1915088Sab196087 argstate->print_req = 0;
1925088Sab196087 break;
1935088Sab196087 case PHDR_CMD_T_MOVE:
1945088Sab196087 if ((argc < 2) || (argc > 3))
1955088Sab196087 elfedit_command_usage();
1965088Sab196087 argstate->print_req = 0;
1975088Sab196087 break;
1985088Sab196087
1995088Sab196087 default:
2005088Sab196087 /* The remaining commands accept 2 plain arguments */
2015088Sab196087 if (argc > 2)
2025088Sab196087 elfedit_command_usage();
2035088Sab196087 argstate->print_req = (argc < 2);
2045088Sab196087 break;
2055088Sab196087 }
2065088Sab196087
2075088Sab196087 /* Return the updated values of argc/argv */
2085088Sab196087 argstate->argc = argc;
2095088Sab196087 argstate->argv = argv;
2105088Sab196087
2115088Sab196087 argstate->ndx_set = 0;
2125088Sab196087 if ((argc > 0) && (cmd != PHDR_CMD_T_INTERP)) {
2135088Sab196087 /*
2145088Sab196087 * If the -phndx option is present, the first argument is
2155088Sab196087 * the index of the header to use. Otherwise, it is a
2165088Sab196087 * name corresponding to its type, similar to the way
2175088Sab196087 * elfdump works with its -N option.
2185088Sab196087 */
2195088Sab196087 if (argstate->optmask & PHDR_OPT_F_PHNDX) {
2205088Sab196087 argstate->ndx = (Word) elfedit_atoui_range(
2215088Sab196087 argstate->argv[0], MSG_ORIG(MSG_STR_ELEMENT), 0,
2225088Sab196087 argstate->obj_state->os_phnum - 1, NULL);
2235088Sab196087 argstate->ndx_set = 1;
2245088Sab196087 } else {
2255088Sab196087 Conv_inv_buf_t inv_buf;
226*9273SAli.Bahrami@Sun.COM Ehdr *ehdr = obj_state->os_ehdr;
227*9273SAli.Bahrami@Sun.COM Half mach = ehdr->e_machine;
228*9273SAli.Bahrami@Sun.COM uchar_t osabi = ehdr->e_ident[EI_OSABI];
2295088Sab196087 Word i;
2305088Sab196087 Phdr *phdr;
2315088Sab196087
2325088Sab196087 argstate->ndx = (Word) elfedit_atoconst(
2335088Sab196087 argstate->argv[0], ELFEDIT_CONST_PT);
2345088Sab196087 phdr = obj_state->os_phdr;
2355088Sab196087 for (i = 0; i < obj_state->os_phnum; i++, phdr++) {
2365088Sab196087 if (phdr->p_type == argstate->ndx) {
2375088Sab196087 argstate->ndx = i;
2385088Sab196087 argstate->ndx_set = 1;
2395088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
2405088Sab196087 MSG_INTL(MSG_DEBUG_PHDR),
241*9273SAli.Bahrami@Sun.COM EC_WORD(i), conv_phdr_type(osabi,
242*9273SAli.Bahrami@Sun.COM mach, phdr->p_type, 0, &inv_buf));
2435088Sab196087 break;
2445088Sab196087 }
2455088Sab196087 }
2465088Sab196087 if (i == argstate->obj_state->os_phnum)
2475088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR,
2485088Sab196087 MSG_INTL(MSG_ERR_NOPHDR), conv_phdr_type(
249*9273SAli.Bahrami@Sun.COM osabi, mach, 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 *
locate_interp(elfedit_obj_state_t * obj_state,INTERP_STATE * interp)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
343*9273SAli.Bahrami@Sun.COM * argstate - State block for section header array. The following
344*9273SAli.Bahrami@Sun.COM * fields are examined in order to determine the form
345*9273SAli.Bahrami@Sun.COM * of output: ndx_set, ndx, print_req.
3465088Sab196087 */
3475088Sab196087 static void
print_phdr(PHDR_CMD_T cmd,int autoprint,ARGSTATE * argstate)3485088Sab196087 print_phdr(PHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate)
3495088Sab196087 {
3505088Sab196087 elfedit_outstyle_t outstyle;
351*9273SAli.Bahrami@Sun.COM Ehdr *ehdr = argstate->obj_state->os_ehdr;
352*9273SAli.Bahrami@Sun.COM uchar_t osabi = ehdr->e_ident[EI_OSABI];
353*9273SAli.Bahrami@Sun.COM Half mach = ehdr->e_machine;
354*9273SAli.Bahrami@Sun.COM Word ndx, cnt, by_type, type;
355*9273SAli.Bahrami@Sun.COM Phdr *phdr;
3565088Sab196087
3575088Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
3585088Sab196087 return;
3595088Sab196087
360*9273SAli.Bahrami@Sun.COM /*
361*9273SAli.Bahrami@Sun.COM * Determine which indexes to display:
362*9273SAli.Bahrami@Sun.COM *
363*9273SAli.Bahrami@Sun.COM * - If the user specified an index, the display starts
364*9273SAli.Bahrami@Sun.COM * with that item. If it was a print_request, and the
365*9273SAli.Bahrami@Sun.COM * index was specified by type, then all items of the
366*9273SAli.Bahrami@Sun.COM * same type are shown. If not a print request, or the index
367*9273SAli.Bahrami@Sun.COM * was given numerically, then just the single item is shown.
368*9273SAli.Bahrami@Sun.COM *
369*9273SAli.Bahrami@Sun.COM * - If no index is specified, every program header is shown.
370*9273SAli.Bahrami@Sun.COM */
371*9273SAli.Bahrami@Sun.COM by_type = 0;
3725088Sab196087 if (argstate->ndx_set) {
3735088Sab196087 ndx = argstate->ndx;
374*9273SAli.Bahrami@Sun.COM if (argstate->print_req &&
375*9273SAli.Bahrami@Sun.COM ((argstate->optmask & PHDR_OPT_F_PHNDX) == 0)) {
376*9273SAli.Bahrami@Sun.COM by_type = 1;
377*9273SAli.Bahrami@Sun.COM type = argstate->obj_state->os_phdr[ndx].p_type;
378*9273SAli.Bahrami@Sun.COM cnt = argstate->obj_state->os_phnum - ndx;
379*9273SAli.Bahrami@Sun.COM } else {
380*9273SAli.Bahrami@Sun.COM cnt = 1;
381*9273SAli.Bahrami@Sun.COM }
3825088Sab196087 } else {
3835088Sab196087 ndx = 0;
3845088Sab196087 cnt = argstate->obj_state->os_phnum;
3855088Sab196087 }
386*9273SAli.Bahrami@Sun.COM phdr = argstate->obj_state->os_phdr + ndx;
3875088Sab196087
3885088Sab196087 /*
3895088Sab196087 * Pick an output style. phdr:dump is required to use the default
3905088Sab196087 * style. The other commands use the current output style.
3915088Sab196087 */
3925088Sab196087 outstyle = (cmd == PHDR_CMD_T_DUMP) ?
3935088Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
3945088Sab196087
3955088Sab196087 /*
3965088Sab196087 * If doing default output, use elfdump style where we
3975088Sab196087 * show all program header attributes. In this case, the
3985088Sab196087 * command that called us doesn't matter.
3995088Sab196087 *
400*9273SAli.Bahrami@Sun.COM * Exclude PHDR_CMD_T_INTERP from this: It isn't per-phdr like
4015088Sab196087 * the other commands.
4025088Sab196087 */
4035088Sab196087 if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) &&
4045088Sab196087 (cmd != PHDR_CMD_T_INTERP)) {
405*9273SAli.Bahrami@Sun.COM for (; cnt--; ndx++, phdr++) {
406*9273SAli.Bahrami@Sun.COM if (by_type && (type != phdr->p_type))
407*9273SAli.Bahrami@Sun.COM continue;
4085088Sab196087
4095088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL));
4105088Sab196087 elfedit_printf(MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx));
411*9273SAli.Bahrami@Sun.COM Elf_phdr(0, osabi, mach, phdr);
412*9273SAli.Bahrami@Sun.COM }
413*9273SAli.Bahrami@Sun.COM return;
414*9273SAli.Bahrami@Sun.COM }
415*9273SAli.Bahrami@Sun.COM
416*9273SAli.Bahrami@Sun.COM if (cmd == PHDR_CMD_T_INTERP) {
417*9273SAli.Bahrami@Sun.COM INTERP_STATE interp;
418*9273SAli.Bahrami@Sun.COM
419*9273SAli.Bahrami@Sun.COM (void) locate_interp(argstate->obj_state, &interp);
420*9273SAli.Bahrami@Sun.COM switch (outstyle) {
421*9273SAli.Bahrami@Sun.COM case ELFEDIT_OUTSTYLE_DEFAULT:
422*9273SAli.Bahrami@Sun.COM elfedit_printf(MSG_INTL(MSG_FMT_ELF_INTERP),
423*9273SAli.Bahrami@Sun.COM interp.sec->sec_name, interp.str);
424*9273SAli.Bahrami@Sun.COM break;
425*9273SAli.Bahrami@Sun.COM case ELFEDIT_OUTSTYLE_SIMPLE:
426*9273SAli.Bahrami@Sun.COM elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), interp.str);
427*9273SAli.Bahrami@Sun.COM break;
428*9273SAli.Bahrami@Sun.COM case ELFEDIT_OUTSTYLE_NUM:
429*9273SAli.Bahrami@Sun.COM elfedit_printf(MSG_ORIG(MSG_FMT_U_NL),
430*9273SAli.Bahrami@Sun.COM EC_WORD(interp.stroff));
431*9273SAli.Bahrami@Sun.COM break;
4325088Sab196087 }
4335088Sab196087 return;
4345088Sab196087 }
4355088Sab196087
436*9273SAli.Bahrami@Sun.COM /* Handle the remaining commands */
437*9273SAli.Bahrami@Sun.COM for (; cnt--; ndx++, phdr++) {
438*9273SAli.Bahrami@Sun.COM if (by_type && (type != phdr->p_type))
439*9273SAli.Bahrami@Sun.COM continue;
4405088Sab196087
441*9273SAli.Bahrami@Sun.COM switch (cmd) {
442*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_TYPE:
4435088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
444*9273SAli.Bahrami@Sun.COM Conv_inv_buf_t inv_buf;
4455088Sab196087
4465088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
447*9273SAli.Bahrami@Sun.COM conv_phdr_type(osabi,
448*9273SAli.Bahrami@Sun.COM argstate->obj_state->os_ehdr->e_machine,
449*9273SAli.Bahrami@Sun.COM phdr->p_type, 0, &inv_buf));
4505088Sab196087 } else {
4515088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_X_NL),
452*9273SAli.Bahrami@Sun.COM EC_WORD(phdr->p_type));
4535088Sab196087 }
454*9273SAli.Bahrami@Sun.COM break;
4555088Sab196087
456*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_OFFSET:
4575088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
458*9273SAli.Bahrami@Sun.COM EC_OFF(phdr->p_offset));
459*9273SAli.Bahrami@Sun.COM break;
4605088Sab196087
461*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_VADDR:
4625088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
463*9273SAli.Bahrami@Sun.COM EC_ADDR(phdr->p_vaddr));
464*9273SAli.Bahrami@Sun.COM break;
4655088Sab196087
466*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_PADDR:
4675088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
468*9273SAli.Bahrami@Sun.COM EC_ADDR(phdr->p_paddr));
469*9273SAli.Bahrami@Sun.COM break;
4705088Sab196087
471*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_FILESZ:
4725088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
473*9273SAli.Bahrami@Sun.COM EC_XWORD(phdr->p_filesz));
474*9273SAli.Bahrami@Sun.COM break;
4755088Sab196087
476*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_MEMSZ:
477*9273SAli.Bahrami@Sun.COM elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
478*9273SAli.Bahrami@Sun.COM EC_XWORD(phdr->p_memsz));
479*9273SAli.Bahrami@Sun.COM break;
4805088Sab196087
481*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_FLAGS:
4825088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
4835088Sab196087 Conv_phdr_flags_buf_t phdr_flags_buf;
4845088Sab196087
4855088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
486*9273SAli.Bahrami@Sun.COM conv_phdr_flags(osabi, phdr->p_flags,
487*9273SAli.Bahrami@Sun.COM CONV_FMT_NOBKT, &phdr_flags_buf));
4885088Sab196087 } else {
4895088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_X_NL),
490*9273SAli.Bahrami@Sun.COM EC_WORD(phdr->p_flags));
4915088Sab196087 }
492*9273SAli.Bahrami@Sun.COM break;
4935088Sab196087
494*9273SAli.Bahrami@Sun.COM case PHDR_CMD_T_P_ALIGN:
495*9273SAli.Bahrami@Sun.COM elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL),
496*9273SAli.Bahrami@Sun.COM EC_XWORD(phdr->p_align));
497*9273SAli.Bahrami@Sun.COM break;
4985088Sab196087 }
4995088Sab196087 }
5005088Sab196087 }
5015088Sab196087
5025088Sab196087
5035088Sab196087 /*
5045088Sab196087 * Called from cmd_body() in the case where a plain argument
5055088Sab196087 * is given to phdr:interp to change the interpreter.
5065088Sab196087 */
5075088Sab196087 static elfedit_cmdret_t
cmd_body_set_interp(ARGSTATE * argstate)5085088Sab196087 cmd_body_set_interp(ARGSTATE *argstate)
5095088Sab196087 {
5105088Sab196087 elfedit_obj_state_t *obj_state = argstate->obj_state;
5115088Sab196087 elfedit_section_t *strsec; /* String table */
5125088Sab196087 INTERP_STATE interp;
5135088Sab196087 Word numdyn; /* # of elements in dyn arr */
5145088Sab196087 size_t phnum; /* # of program headers */
5155088Sab196087 Phdr *phdr; /* Program header array */
5165088Sab196087 Word i, j;
5175088Sab196087 Word str_offset; /* Offset in strsec to new interp str */
5185088Sab196087 int str_found = 0; /* True when we have new interp str */
5195088Sab196087 Word str_size; /* Size of new interp string + NULL */
5205088Sab196087
5215088Sab196087 phnum = obj_state->os_phnum;
5225088Sab196087 phdr = obj_state->os_phdr;
5235088Sab196087
5245088Sab196087 /* Locate the PT_INTERP program header */
5255088Sab196087 (void) locate_interp(obj_state, &interp);
5265088Sab196087 strsec = interp.sec;
5275088Sab196087 str_offset = interp.stroff;
5285088Sab196087
5295088Sab196087 /*
5305088Sab196087 * If the given string is the same as the existing interpreter
5315088Sab196087 * string, say so and return.
5325088Sab196087 */
5335088Sab196087 if (strcmp(interp.str, argstate->argv[0]) == 0) {
5345088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_OLDINTERPOK),
5355088Sab196087 EC_WORD(strsec->sec_shndx), strsec->sec_name,
5365088Sab196087 EC_WORD(str_offset), interp.str);
5375088Sab196087 return (ELFEDIT_CMDRET_NONE);
5385088Sab196087 }
5395088Sab196087
5405088Sab196087 /*
5415088Sab196087 * An ELF PT_INTERP usually references its own special section
5425088Sab196087 * instead of some other string table. The ELF ABI says that this
5435088Sab196087 * section must be named ".interp". Hence, this is a rare case
5445088Sab196087 * in which the name of a section can be taken as an indication
5455088Sab196087 * of its contents. .interp is typically sized to just fit
5465088Sab196087 * the original string, including its NULL termination. You can
5475088Sab196087 * treat it as a string table with one string.
5485088Sab196087 *
5495088Sab196087 * Thanks to 'elfedit', it may be that we encounter a file where
5505088Sab196087 * PT_INTERP does not reference the .interp section. This will happen
5515088Sab196087 * if elfedit is used to change the interpreter to a string that is
5525088Sab196087 * too big to fit in .interp, in which case we will use the
5535088Sab196087 * .dynstr string table (That code is below, in this function).
5545088Sab196087 *
5555088Sab196087 * Given the above facts, our next step is to locate the .interp
5565088Sab196087 * section and see if our new string will fit in it. Since we can't
5575088Sab196087 * depend on PT_INTERP, we search the section headers to find a
5585088Sab196087 * section whith the following characteristics:
5595088Sab196087 * - The name is ".interp".
5605088Sab196087 * - Section is allocable (SHF_ALLOC) and SHT_PROGBITS.
5615088Sab196087 * - It is not part of a writable segment.
5625088Sab196087 * If we find such a section, and the new string fits, we will
5635088Sab196087 * write it there.
5645088Sab196087 */
5655088Sab196087 str_size = strlen(argstate->argv[0]) + 1;
5665088Sab196087 for (i = 1; i < obj_state->os_shnum; i++) {
5675088Sab196087 strsec = &obj_state->os_secarr[i];
5685088Sab196087 if ((strcmp(strsec->sec_name, MSG_ORIG(MSG_SEC_INTERP)) == 0) &&
5695088Sab196087 (strsec->sec_shdr->sh_flags & SHF_ALLOC) &&
5705088Sab196087 (strsec->sec_shdr->sh_type & SHT_PROGBITS)) {
5715088Sab196087 for (j = 0; j < phnum; j++) {
5725088Sab196087 Phdr *tphdr = &phdr[j];
5735088Sab196087 if ((strsec->sec_shdr->sh_offset >=
5745088Sab196087 tphdr->p_offset) &&
5755088Sab196087 ((strsec->sec_shdr->sh_offset +
5765088Sab196087 strsec->sec_shdr->sh_size) <=
5775088Sab196087 (tphdr->p_offset + tphdr->p_filesz)) &&
5785088Sab196087 (tphdr->p_flags & PF_W)) {
5795088Sab196087 break;
5805088Sab196087 }
5815088Sab196087 }
5825088Sab196087 if ((j == phnum) &&
5835088Sab196087 (str_size <= strsec->sec_shdr->sh_size)) {
5845088Sab196087 /* .interp section found, and has room */
5855088Sab196087 str_found = 1;
5865088Sab196087 str_offset = 0;
5875088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
5885088Sab196087 MSG_INTL(MSG_DEBUG_NEWISTR), EC_WORD(j),
5895088Sab196087 strsec->sec_name, EC_WORD(str_offset),
5905088Sab196087 argstate->argv[0]);
5915088Sab196087 /* Put new value in section */
5925088Sab196087 (void) strncpy((char *)strsec->sec_data->d_buf,
5935088Sab196087 argstate->argv[0],
5945088Sab196087 strsec->sec_shdr->sh_size);
5955088Sab196087 /* Set libelf dirty bit so change is flushed */
5965088Sab196087 elfedit_modified_data(strsec);
5975088Sab196087 break;
5985088Sab196087 } else {
5995088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
6005088Sab196087 MSG_INTL(MSG_DEBUG_LNGISTR), EC_WORD(j),
6015088Sab196087 strsec->sec_name, EC_WORD(str_offset),
6025088Sab196087 EC_WORD(str_size),
6035088Sab196087 EC_WORD(strsec->sec_shdr->sh_size),
6045088Sab196087 argstate->argv[0]);
6055088Sab196087 }
6065088Sab196087 }
6075088Sab196087 }
6085088Sab196087
6095088Sab196087 /*
6105088Sab196087 * If the above did not find a string within the .interp section,
6115088Sab196087 * then we have a second option. If this ELF object has a dynamic
6125088Sab196087 * section, then we are willing to use strings from within the
6135088Sab196087 * associated .dynstr string table. And if there is reserved space
6145088Sab196087 * in .dynstr (as reported by the DT_SUNW_STRPAD dynamic entry),
6155088Sab196087 * then we are even willing to add a new string to .dynstr.
6165088Sab196087 */
6175088Sab196087 if (!str_found) {
6185088Sab196087 elfedit_section_t *dynsec;
6195088Sab196087 Dyn *dyn;
6205088Sab196087
6215088Sab196087 dynsec = elfedit_sec_getdyn(obj_state, &dyn, &numdyn);
6225088Sab196087 strsec = elfedit_sec_getstr(obj_state,
6236225Sab196087 dynsec->sec_shdr->sh_link, 0);
6245088Sab196087
6255088Sab196087 /* Does string exist in the table already, or can we add it? */
6265088Sab196087 str_offset = elfedit_strtab_insert(obj_state, strsec,
6275088Sab196087 dynsec, argstate->argv[0]);
6285088Sab196087 }
6295088Sab196087
6305088Sab196087
6315088Sab196087 /*
6325088Sab196087 * If we are here, we know we have a replacement string, because
6335088Sab196087 * the errors from checking .dynamic/.dynstr will not allow
6345088Sab196087 * things to get here otherwise.
6355088Sab196087 *
6365088Sab196087 * The PT_INTERP program header references the string directly,
6375088Sab196087 * so we add the section offset to the string offset.
6385088Sab196087 */
6395088Sab196087 interp.phdr->p_offset = strsec->sec_shdr->sh_offset + str_offset;
6405088Sab196087 interp.phdr->p_filesz = str_size;
6415088Sab196087 elfedit_modified_phdr(obj_state);
6425088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SETPHINTERP),
6435088Sab196087 EC_WORD(interp.phndx), EC_XWORD(interp.phdr->p_offset),
6445088Sab196087 EC_XWORD(interp.phdr->p_filesz));
6455088Sab196087
6465088Sab196087 return (ELFEDIT_CMDRET_MOD);
6475088Sab196087 }
6485088Sab196087
6495088Sab196087
6505088Sab196087 /*
6515088Sab196087 * Common body for the phdr: module commands. These commands
6525088Sab196087 * share a large amount of common behavior, so it is convenient
6535088Sab196087 * to centralize things and use the cmd argument to handle the
6545088Sab196087 * small differences.
6555088Sab196087 *
6565088Sab196087 * entry:
6575088Sab196087 * cmd - One of the PHDR_CMD_T_* constants listed above, specifying
6585088Sab196087 * which command to implement.
6595088Sab196087 * obj_state, argc, argv - Standard command arguments
6605088Sab196087 */
6615088Sab196087 static elfedit_cmdret_t
cmd_body(PHDR_CMD_T cmd,elfedit_obj_state_t * obj_state,int argc,const char * argv[])6625088Sab196087 cmd_body(PHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,
6635088Sab196087 int argc, const char *argv[])
6645088Sab196087 {
6655088Sab196087 ARGSTATE argstate;
6665088Sab196087 Phdr *phdr;
6675088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE;
6685088Sab196087 int do_autoprint = 1;
6695088Sab196087
6705088Sab196087 process_args(obj_state, argc, argv, cmd, &argstate);
6715088Sab196087
6725088Sab196087 /* If this is a printing request, print and return */
6735088Sab196087 if (argstate.print_req) {
6745088Sab196087 print_phdr(cmd, 0, &argstate);
6755088Sab196087 return (ELFEDIT_CMDRET_NONE);
6765088Sab196087 }
6775088Sab196087
6785088Sab196087
6795088Sab196087 if (argstate.ndx_set)
6805088Sab196087 phdr = &argstate.obj_state->os_phdr[argstate.ndx];
6815088Sab196087
6825088Sab196087 switch (cmd) {
6835088Sab196087 /*
6845088Sab196087 * PHDR_CMD_T_DUMP can't get here: It never has more than
6855088Sab196087 * one argument, and is handled above.
6865088Sab196087 */
6875088Sab196087
6885088Sab196087 case PHDR_CMD_T_P_TYPE:
6895088Sab196087 {
690*9273SAli.Bahrami@Sun.COM Ehdr *ehdr = obj_state->os_ehdr;
691*9273SAli.Bahrami@Sun.COM uchar_t osabi = ehdr->e_ident[EI_OSABI];
692*9273SAli.Bahrami@Sun.COM Half mach = ehdr->e_machine;
6935088Sab196087 Word p_type = elfedit_atoconst(argstate.argv[1],
6945088Sab196087 ELFEDIT_CONST_PT);
6955088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
6965088Sab196087
6975088Sab196087 if (phdr->p_type == p_type) {
6985088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
6995088Sab196087 MSG_INTL(MSG_DEBUG_S_OK),
7005088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE),
701*9273SAli.Bahrami@Sun.COM conv_phdr_type(osabi, mach, phdr->p_type,
7025088Sab196087 0, &inv_buf1));
7035088Sab196087 } else {
7045088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7055088Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
7065088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE),
707*9273SAli.Bahrami@Sun.COM conv_phdr_type(osabi, mach,
708*9273SAli.Bahrami@Sun.COM phdr->p_type, 0, &inv_buf1),
709*9273SAli.Bahrami@Sun.COM conv_phdr_type(osabi, mach,
710*9273SAli.Bahrami@Sun.COM p_type, 0, &inv_buf2));
7115088Sab196087 ret = ELFEDIT_CMDRET_MOD;
7125088Sab196087 phdr->p_type = p_type;
7135088Sab196087 }
7145088Sab196087 }
7155088Sab196087 break;
7165088Sab196087
7175088Sab196087 case PHDR_CMD_T_P_OFFSET:
7185088Sab196087 {
7195088Sab196087 Off p_offset;
7205088Sab196087
7215088Sab196087 p_offset = elfedit_atoui(argstate.argv[1], NULL);
7225088Sab196087 if (phdr->p_offset == p_offset) {
7235088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7245088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
7255088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET),
7265088Sab196087 EC_XWORD(phdr->p_offset));
7275088Sab196087 } else {
7285088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7295088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
7305088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET),
7315088Sab196087 EC_XWORD(phdr->p_offset),
7325088Sab196087 EC_XWORD(p_offset));
7335088Sab196087 ret = ELFEDIT_CMDRET_MOD;
7345088Sab196087 phdr->p_offset = p_offset;
7355088Sab196087 }
7365088Sab196087 }
7375088Sab196087 break;
7385088Sab196087
7395088Sab196087 case PHDR_CMD_T_P_VADDR:
7405088Sab196087 {
7415088Sab196087 Addr p_vaddr = elfedit_atoui(argstate.argv[1], NULL);
7425088Sab196087
7435088Sab196087 if (phdr->p_vaddr == p_vaddr) {
7445088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7455088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
7465088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR),
7475088Sab196087 EC_ADDR(phdr->p_vaddr));
7485088Sab196087 } else {
7495088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7505088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
7515088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR),
7525088Sab196087 EC_ADDR(phdr->p_vaddr), EC_ADDR(p_vaddr));
7535088Sab196087 ret = ELFEDIT_CMDRET_MOD;
7545088Sab196087 phdr->p_vaddr = p_vaddr;
7555088Sab196087 }
7565088Sab196087 }
7575088Sab196087 break;
7585088Sab196087
7595088Sab196087 case PHDR_CMD_T_P_PADDR:
7605088Sab196087 {
7615088Sab196087 Addr p_paddr = elfedit_atoui(argstate.argv[1], NULL);
7625088Sab196087
7635088Sab196087 if (phdr->p_paddr == p_paddr) {
7645088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7655088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
7665088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR),
7675088Sab196087 EC_ADDR(phdr->p_paddr));
7685088Sab196087 } else {
7695088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7705088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
7715088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR),
7725088Sab196087 EC_ADDR(phdr->p_paddr), EC_ADDR(p_paddr));
7735088Sab196087 ret = ELFEDIT_CMDRET_MOD;
7745088Sab196087 phdr->p_paddr = p_paddr;
7755088Sab196087 }
7765088Sab196087 }
7775088Sab196087 break;
7785088Sab196087
7795088Sab196087 case PHDR_CMD_T_P_FILESZ:
7805088Sab196087 {
7815088Sab196087 Xword p_filesz = elfedit_atoui(argstate.argv[1], NULL);
7825088Sab196087
7835088Sab196087 if (phdr->p_filesz == p_filesz) {
7845088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7855088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
7865088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ),
7875088Sab196087 EC_XWORD(phdr->p_filesz));
7885088Sab196087 } else {
7895088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
7905088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
7915088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ),
7925088Sab196087 EC_XWORD(phdr->p_filesz),
7935088Sab196087 EC_XWORD(p_filesz));
7945088Sab196087 ret = ELFEDIT_CMDRET_MOD;
7955088Sab196087 phdr->p_filesz = p_filesz;
7965088Sab196087 }
7975088Sab196087 }
7985088Sab196087 break;
7995088Sab196087
8005088Sab196087 case PHDR_CMD_T_P_MEMSZ:
8015088Sab196087 {
8025088Sab196087 Xword p_memsz = elfedit_atoui(argstate.argv[1], NULL);
8035088Sab196087
8045088Sab196087 if (phdr->p_memsz == p_memsz) {
8055088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8065088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
8075088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ),
8085088Sab196087 EC_XWORD(phdr->p_memsz));
8095088Sab196087 } else {
8105088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8115088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
8125088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ),
8135088Sab196087 EC_XWORD(phdr->p_memsz),
8145088Sab196087 EC_XWORD(p_memsz));
8155088Sab196087 ret = ELFEDIT_CMDRET_MOD;
8165088Sab196087 phdr->p_memsz = p_memsz;
8175088Sab196087 }
8185088Sab196087 }
8195088Sab196087 break;
8205088Sab196087
8215088Sab196087 case PHDR_CMD_T_P_FLAGS:
8225088Sab196087 {
823*9273SAli.Bahrami@Sun.COM Ehdr *ehdr = obj_state->os_ehdr;
824*9273SAli.Bahrami@Sun.COM uchar_t osabi = ehdr->e_ident[EI_OSABI];
8255088Sab196087 Conv_phdr_flags_buf_t buf1, buf2;
8265088Sab196087 Word p_flags = 0;
8275088Sab196087 int i;
8285088Sab196087
8295088Sab196087 /* Collect the flag arguments */
8305088Sab196087 for (i = 1; i < argstate.argc; i++)
8315088Sab196087 p_flags |=
8325088Sab196087 (Word) elfedit_atoconst(argstate.argv[i],
8335088Sab196087 ELFEDIT_CONST_PF);
8345088Sab196087
8355088Sab196087 /* Complement the value? */
8365088Sab196087 if (argstate.optmask & PHDR_OPT_F_CMP)
8375088Sab196087 p_flags = ~p_flags;
8385088Sab196087
8395088Sab196087 /* Perform any requested bit operations */
8405088Sab196087 if (argstate.optmask & PHDR_OPT_F_AND)
8415088Sab196087 p_flags &= phdr->p_flags;
8425088Sab196087 else if (argstate.optmask & PHDR_OPT_F_OR)
8435088Sab196087 p_flags |= phdr->p_flags;
8445088Sab196087
8455088Sab196087 /* Set the value */
8465088Sab196087 if (phdr->p_flags == p_flags) {
8475088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8485088Sab196087 MSG_INTL(MSG_DEBUG_S_OK),
8495088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS),
850*9273SAli.Bahrami@Sun.COM conv_phdr_flags(osabi, phdr->p_flags,
851*9273SAli.Bahrami@Sun.COM 0, &buf1));
8525088Sab196087 } else {
8535088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8545088Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
8555088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS),
856*9273SAli.Bahrami@Sun.COM conv_phdr_flags(osabi, phdr->p_flags,
857*9273SAli.Bahrami@Sun.COM 0, &buf1),
858*9273SAli.Bahrami@Sun.COM conv_phdr_flags(osabi, p_flags, 0, &buf2));
8595088Sab196087 ret = ELFEDIT_CMDRET_MOD;
8605088Sab196087 phdr->p_flags = p_flags;
8615088Sab196087 }
8625088Sab196087 }
8635088Sab196087 break;
8645088Sab196087
8655088Sab196087 case PHDR_CMD_T_P_ALIGN:
8665088Sab196087 {
8675088Sab196087 Xword p_align = elfedit_atoui(argstate.argv[1], NULL);
8685088Sab196087
8695088Sab196087 if (phdr->p_align == p_align) {
8705088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8715088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK),
8725088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN),
8735088Sab196087 EC_XWORD(phdr->p_align));
8745088Sab196087 } else {
8755088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
8765088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG),
8775088Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN),
8785088Sab196087 EC_XWORD(phdr->p_align),
8795088Sab196087 EC_XWORD(p_align));
8805088Sab196087 ret = ELFEDIT_CMDRET_MOD;
8815088Sab196087 phdr->p_align = p_align;
8825088Sab196087 }
8835088Sab196087 }
8845088Sab196087 break;
8855088Sab196087
8865088Sab196087 case PHDR_CMD_T_INTERP:
8875088Sab196087 ret = cmd_body_set_interp(&argstate);
8885088Sab196087 break;
8895088Sab196087
8905088Sab196087 case PHDR_CMD_T_DELETE:
8915088Sab196087 {
8925088Sab196087 Word cnt = (argstate.argc == 1) ? 1 :
8935088Sab196087 (Word) elfedit_atoui_range(argstate.argv[1],
8945088Sab196087 MSG_ORIG(MSG_STR_COUNT), 1,
8955088Sab196087 obj_state->os_phnum - argstate.ndx, NULL);
8965088Sab196087
8975088Sab196087 elfedit_array_elts_delete(MSG_ORIG(MSG_MOD_NAME),
8985088Sab196087 obj_state->os_phdr, sizeof (Phdr),
8995088Sab196087 obj_state->os_phnum, argstate.ndx, cnt);
9005088Sab196087 do_autoprint = 0;
9015088Sab196087 ret = ELFEDIT_CMDRET_MOD;
9025088Sab196087 }
9035088Sab196087 break;
9045088Sab196087
9055088Sab196087 case PHDR_CMD_T_MOVE:
9065088Sab196087 {
9075088Sab196087 Phdr save;
9085088Sab196087 Word cnt;
9095088Sab196087 Word dstndx;
9105088Sab196087
9115088Sab196087 do_autoprint = 0;
9125088Sab196087 dstndx = (Word)
9135088Sab196087 elfedit_atoui_range(argstate.argv[1],
9145088Sab196087 MSG_ORIG(MSG_STR_DST_INDEX), 0,
9155088Sab196087 obj_state->os_phnum - 1, NULL);
9165088Sab196087 if (argstate.argc == 2) {
9175088Sab196087 cnt = 1;
9185088Sab196087 } else {
9195088Sab196087 cnt = (Word) elfedit_atoui_range(
9205088Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT),
9215088Sab196087 1, obj_state->os_phnum, NULL);
9225088Sab196087 }
9235088Sab196087 elfedit_array_elts_move(MSG_ORIG(MSG_MOD_NAME),
9245088Sab196087 obj_state->os_phdr, sizeof (save),
9255088Sab196087 obj_state->os_phnum, argstate.ndx, dstndx,
9265088Sab196087 cnt, &save);
9275088Sab196087 ret = ELFEDIT_CMDRET_MOD;
9285088Sab196087 }
9295088Sab196087 break;
9305088Sab196087 }
9315088Sab196087
9325088Sab196087 /*
9335088Sab196087 * If we modified the section header array, tell libelf.
9345088Sab196087 */
9355088Sab196087 if (ret == ELFEDIT_CMDRET_MOD)
9365088Sab196087 elfedit_modified_phdr(obj_state);
9375088Sab196087
9385088Sab196087 /* Do autoprint */
9395088Sab196087 if (do_autoprint)
9405088Sab196087 print_phdr(cmd, 1, &argstate);
9415088Sab196087
9425088Sab196087 return (ret);
9435088Sab196087 }
9445088Sab196087
9455088Sab196087
9465088Sab196087
9475088Sab196087 /*
9485088Sab196087 * Command completion functions for the various commands
9495088Sab196087 */
9505088Sab196087
9515088Sab196087 /*
9525088Sab196087 * A number of the commands accept a PT_ constant as their first
9535088Sab196087 * argument as long as the -phndx option is not used.
9545088Sab196087 */
9555088Sab196087 /*ARGSUSED*/
9565088Sab196087 static void
cpl_1starg_pt(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)9575088Sab196087 cpl_1starg_pt(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
9585088Sab196087 const char *argv[], int num_opt)
9595088Sab196087 {
9605088Sab196087 int i;
9615088Sab196087
9625088Sab196087 for (i = 0; i < num_opt; i++)
9635088Sab196087 if (strcmp(MSG_ORIG(MSG_STR_MINUS_PHNDX), argv[i]) == 0)
9645088Sab196087 return;
9655088Sab196087
9665088Sab196087 if (argc == (num_opt + 1))
9675088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT);
9685088Sab196087 }
9695088Sab196087
9705088Sab196087 /*ARGSUSED*/
9715088Sab196087 static void
cpl_p_type(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)9725088Sab196087 cpl_p_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
9735088Sab196087 const char *argv[], int num_opt)
9745088Sab196087 {
9755088Sab196087 /* The first argument follows the standard rules */
9765088Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt);
9775088Sab196087
9785088Sab196087 /* The second argument can be a PT_ value */
9795088Sab196087 if (argc == (num_opt + 2))
9805088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT);
9815088Sab196087 }
9825088Sab196087
9835088Sab196087
9845088Sab196087 /*ARGSUSED*/
9855088Sab196087 static void
cpl_p_flags(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)9865088Sab196087 cpl_p_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
9875088Sab196087 const char *argv[], int num_opt)
9885088Sab196087 {
9895088Sab196087 /* The first argument follows the standard rules */
9905088Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt);
9915088Sab196087
9925088Sab196087 /* The second and following arguments can be an PF_ value */
9935088Sab196087 if (argc >= (num_opt + 2))
9945088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PF);
9955088Sab196087 }
9965088Sab196087
9975088Sab196087
9985088Sab196087
9995088Sab196087 /*
10005088Sab196087 * Implementation functions for the commands
10015088Sab196087 */
10025088Sab196087 static elfedit_cmdret_t
cmd_dump(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10035088Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10045088Sab196087 {
10055088Sab196087 return (cmd_body(PHDR_CMD_T_DUMP, obj_state, argc, argv));
10065088Sab196087 }
10075088Sab196087
10085088Sab196087 static elfedit_cmdret_t
cmd_p_type(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10095088Sab196087 cmd_p_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10105088Sab196087 {
10115088Sab196087 return (cmd_body(PHDR_CMD_T_P_TYPE, obj_state, argc, argv));
10125088Sab196087 }
10135088Sab196087
10145088Sab196087 static elfedit_cmdret_t
cmd_p_offset(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10155088Sab196087 cmd_p_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10165088Sab196087 {
10175088Sab196087 return (cmd_body(PHDR_CMD_T_P_OFFSET, obj_state, argc, argv));
10185088Sab196087 }
10195088Sab196087
10205088Sab196087 static elfedit_cmdret_t
cmd_p_vaddr(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10215088Sab196087 cmd_p_vaddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10225088Sab196087 {
10235088Sab196087 return (cmd_body(PHDR_CMD_T_P_VADDR, obj_state, argc, argv));
10245088Sab196087 }
10255088Sab196087
10265088Sab196087 static elfedit_cmdret_t
cmd_p_paddr(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10275088Sab196087 cmd_p_paddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10285088Sab196087 {
10295088Sab196087 return (cmd_body(PHDR_CMD_T_P_PADDR, obj_state, argc, argv));
10305088Sab196087 }
10315088Sab196087
10325088Sab196087 static elfedit_cmdret_t
cmd_p_filesz(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10335088Sab196087 cmd_p_filesz(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10345088Sab196087 {
10355088Sab196087 return (cmd_body(PHDR_CMD_T_P_FILESZ, obj_state, argc, argv));
10365088Sab196087 }
10375088Sab196087
10385088Sab196087 static elfedit_cmdret_t
cmd_p_memsz(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10395088Sab196087 cmd_p_memsz(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10405088Sab196087 {
10415088Sab196087 return (cmd_body(PHDR_CMD_T_P_MEMSZ, obj_state, argc, argv));
10425088Sab196087 }
10435088Sab196087
10445088Sab196087 static elfedit_cmdret_t
cmd_p_flags(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10455088Sab196087 cmd_p_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10465088Sab196087 {
10475088Sab196087 return (cmd_body(PHDR_CMD_T_P_FLAGS, obj_state, argc, argv));
10485088Sab196087 }
10495088Sab196087
10505088Sab196087 static elfedit_cmdret_t
cmd_p_align(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10515088Sab196087 cmd_p_align(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10525088Sab196087 {
10535088Sab196087 return (cmd_body(PHDR_CMD_T_P_ALIGN, obj_state, argc, argv));
10545088Sab196087 }
10555088Sab196087
10565088Sab196087 static elfedit_cmdret_t
cmd_interp(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10575088Sab196087 cmd_interp(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10585088Sab196087 {
10595088Sab196087 return (cmd_body(PHDR_CMD_T_INTERP, obj_state, argc, argv));
10605088Sab196087 }
10615088Sab196087
10625088Sab196087 static elfedit_cmdret_t
cmd_delete(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10635088Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10645088Sab196087 {
10655088Sab196087 return (cmd_body(PHDR_CMD_T_DELETE, obj_state, argc, argv));
10665088Sab196087 }
10675088Sab196087
10685088Sab196087 static elfedit_cmdret_t
cmd_move(elfedit_obj_state_t * obj_state,int argc,const char * argv[])10695088Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
10705088Sab196087 {
10715088Sab196087 return (cmd_body(PHDR_CMD_T_MOVE, obj_state, argc, argv));
10725088Sab196087 }
10735088Sab196087
10745088Sab196087
10755088Sab196087 /*ARGSUSED*/
10765088Sab196087 elfedit_module_t *
elfedit_init(elfedit_module_version_t version)10775088Sab196087 elfedit_init(elfedit_module_version_t version)
10785088Sab196087 {
10795088Sab196087 /* Multiple commands accept a standard set of options */
10805088Sab196087 static elfedit_cmd_optarg_t opt_std[] = {
10815088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
10825088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
10835088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX),
10845088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */
10855088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0,
10865088Sab196087 PHDR_OPT_F_PHNDX, 0 },
10875088Sab196087 { NULL }
10885088Sab196087 };
10895088Sab196087
10905088Sab196087 /* For commands that only accept -phndx */
10915088Sab196087 static elfedit_cmd_optarg_t opt_minus_phndx[] = {
10925088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX),
10935088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */
10945088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0,
10955088Sab196087 PHDR_OPT_F_PHNDX, 0 },
10965088Sab196087 { NULL }
10975088Sab196087 };
10985088Sab196087
10995088Sab196087
11005088Sab196087 /* phdr:dump */
11015088Sab196087 static const char *name_dump[] = {
11025088Sab196087 MSG_ORIG(MSG_CMD_DUMP),
11035088Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */
11045088Sab196087 NULL
11055088Sab196087 };
11065088Sab196087 static elfedit_cmd_optarg_t arg_dump[] = {
11075088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11085088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11095088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11105088Sab196087 ELFEDIT_CMDOA_F_OPT },
11115088Sab196087 { NULL }
11125088Sab196087 };
11135088Sab196087
11145088Sab196087 /* phdr:p_type */
11155088Sab196087 static const char *name_p_type[] = { MSG_ORIG(MSG_CMD_P_TYPE), NULL };
11165088Sab196087 static elfedit_cmd_optarg_t arg_p_type[] = {
11175088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11185088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11195088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11205088Sab196087 ELFEDIT_CMDOA_F_OPT },
11215088Sab196087 { MSG_ORIG(MSG_STR_TYPE),
11225088Sab196087 /* MSG_INTL(MSG_A2_P_TYPE_TYPE) */
11235088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_TYPE_TYPE),
11245088Sab196087 ELFEDIT_CMDOA_F_OPT },
11255088Sab196087 { NULL }
11265088Sab196087 };
11275088Sab196087
11285088Sab196087 /* phdr:p_offset */
11295088Sab196087 static const char *name_p_offset[] = { MSG_ORIG(MSG_CMD_P_OFFSET),
11305088Sab196087 NULL };
11315088Sab196087 static elfedit_cmd_optarg_t arg_p_offset[] = {
11325088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11335088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11345088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11355088Sab196087 ELFEDIT_CMDOA_F_OPT },
11365088Sab196087 { MSG_ORIG(MSG_STR_VALUE),
11375088Sab196087 /* MSG_INTL(MSG_A2_P_OFFSET_VALUE) */
11385088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_OFFSET_VALUE),
11395088Sab196087 ELFEDIT_CMDOA_F_OPT },
11405088Sab196087 { NULL }
11415088Sab196087 };
11425088Sab196087
11435088Sab196087 /* phdr:p_vaddr */
11445088Sab196087 static const char *name_p_vaddr[] = { MSG_ORIG(MSG_CMD_P_VADDR),
11455088Sab196087 NULL };
11465088Sab196087 static elfedit_cmd_optarg_t arg_p_vaddr[] = {
11475088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11485088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11495088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11505088Sab196087 ELFEDIT_CMDOA_F_OPT },
11515088Sab196087 { MSG_ORIG(MSG_STR_ADDR),
11525088Sab196087 /* MSG_INTL(MSG_A2_P_VADDR_ADDR) */
11535088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_VADDR_ADDR),
11545088Sab196087 ELFEDIT_CMDOA_F_OPT },
11555088Sab196087 { NULL }
11565088Sab196087 };
11575088Sab196087
11585088Sab196087 /* phdr:p_paddr */
11595088Sab196087 static const char *name_p_paddr[] = { MSG_ORIG(MSG_CMD_P_PADDR),
11605088Sab196087 NULL };
11615088Sab196087 static elfedit_cmd_optarg_t arg_p_paddr[] = {
11625088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11635088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11645088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11655088Sab196087 ELFEDIT_CMDOA_F_OPT },
11665088Sab196087 { MSG_ORIG(MSG_STR_ADDR),
11675088Sab196087 /* MSG_INTL(MSG_A2_P_PADDR_ADDR) */
11685088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_PADDR_ADDR),
11695088Sab196087 ELFEDIT_CMDOA_F_OPT },
11705088Sab196087 { NULL }
11715088Sab196087 };
11725088Sab196087
11735088Sab196087 /* phdr:p_filesz */
11745088Sab196087 static const char *name_p_filesz[] = { MSG_ORIG(MSG_CMD_P_FILESZ),
11755088Sab196087 NULL };
11765088Sab196087 static elfedit_cmd_optarg_t arg_p_filesz[] = {
11775088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11785088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11795088Sab196087 ELFEDIT_CMDOA_F_OPT },
11805088Sab196087 { MSG_ORIG(MSG_STR_SIZE),
11815088Sab196087 /* MSG_INTL(MSG_A2_P_FILESZ_SIZE) */
11825088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FILESZ_SIZE),
11835088Sab196087 ELFEDIT_CMDOA_F_OPT },
11845088Sab196087 { NULL }
11855088Sab196087 };
11865088Sab196087
11875088Sab196087 /* phdr:p_memsz */
11885088Sab196087 static const char *name_p_memsz[] = { MSG_ORIG(MSG_CMD_P_MEMSZ),
11895088Sab196087 NULL };
11905088Sab196087 static elfedit_cmd_optarg_t arg_p_memsz[] = {
11915088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
11925088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
11935088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
11945088Sab196087 ELFEDIT_CMDOA_F_OPT },
11955088Sab196087 { MSG_ORIG(MSG_STR_SIZE),
11965088Sab196087 /* MSG_INTL(MSG_A2_P_MEMSZ_SIZE) */
11975088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_MEMSZ_SIZE),
11985088Sab196087 ELFEDIT_CMDOA_F_OPT },
11995088Sab196087 { NULL }
12005088Sab196087 };
12015088Sab196087
12025088Sab196087 /* shdr:p_flags */
12035088Sab196087 static const char *name_p_flags[] = {
12045088Sab196087 MSG_ORIG(MSG_CMD_P_FLAGS), NULL };
12055088Sab196087 static elfedit_cmd_optarg_t opt_p_flags[] = {
12065088Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL,
12075088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_AND, PHDR_OPT_F_OR },
12085088Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL,
12095088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_CMP, 0 },
12105088Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX),
12115088Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */
12125088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0,
12135088Sab196087 PHDR_OPT_F_PHNDX, 0 },
12145088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
12155088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
12165088Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL,
12175088Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_OR, PHDR_OPT_F_AND },
12185088Sab196087 { NULL }
12195088Sab196087 };
12205088Sab196087 static elfedit_cmd_optarg_t arg_p_flags[] = {
12215088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
12225088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
12235088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
12245088Sab196087 ELFEDIT_CMDOA_F_OPT },
12255088Sab196087 { MSG_ORIG(MSG_STR_VALUE),
12265088Sab196087 /* MSG_INTL(MSG_A2_P_FLAGS_VALUE) */
12275088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FLAGS_VALUE),
12285088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
12295088Sab196087 { NULL }
12305088Sab196087 };
12315088Sab196087
12325088Sab196087 /* phdr:p_align */
12335088Sab196087 static const char *name_p_align[] = { MSG_ORIG(MSG_CMD_P_ALIGN),
12345088Sab196087 NULL };
12355088Sab196087 static elfedit_cmd_optarg_t arg_p_align[] = {
12365088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
12375088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
12385088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
12395088Sab196087 ELFEDIT_CMDOA_F_OPT },
12405088Sab196087 { MSG_ORIG(MSG_STR_ALIGN),
12415088Sab196087 /* MSG_INTL(MSG_A2_P_ALIGN_ALIGN) */
12425088Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_ALIGN_ALIGN),
12435088Sab196087 ELFEDIT_CMDOA_F_OPT },
12445088Sab196087 { NULL }
12455088Sab196087 };
12465088Sab196087
12475088Sab196087 /* phdr:interp */
12485088Sab196087 static const char *name_interp[] = { MSG_ORIG(MSG_CMD_INTERP), NULL };
12495088Sab196087 static elfedit_cmd_optarg_t opt_interp[] = {
12505088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
12515088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
12525088Sab196087 { NULL }
12535088Sab196087 };
12545088Sab196087 static elfedit_cmd_optarg_t arg_interp[] = {
12555088Sab196087 { MSG_ORIG(MSG_STR_NEWPATH),
12565088Sab196087 /* MSG_INTL(MSG_A1_INTERP_NEWPATH) */
12575088Sab196087 ELFEDIT_I18NHDL(MSG_A1_INTERP_NEWPATH),
12585088Sab196087 ELFEDIT_CMDOA_F_OPT },
12595088Sab196087 { NULL }
12605088Sab196087 };
12615088Sab196087
12625088Sab196087 /* phdr:delete */
12635088Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL };
12645088Sab196087 static elfedit_cmd_optarg_t arg_delete[] = {
12655088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
12665088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
12675088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
1268*9273SAli.Bahrami@Sun.COM 0 },
12695088Sab196087 { MSG_ORIG(MSG_STR_COUNT),
12705088Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */
12715088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT),
12725088Sab196087 ELFEDIT_CMDOA_F_OPT },
12735088Sab196087 { NULL }
12745088Sab196087 };
12755088Sab196087
12765088Sab196087 /* phdr:move */
12775088Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL };
12785088Sab196087 static elfedit_cmd_optarg_t arg_move[] = {
12795088Sab196087 { MSG_ORIG(MSG_STR_ELEMENT),
12805088Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */
12815088Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT),
12825088Sab196087 ELFEDIT_CMDOA_F_OPT },
12835088Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX),
12845088Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */
12855088Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX),
12865088Sab196087 0 },
12875088Sab196087 { MSG_ORIG(MSG_STR_COUNT),
12885088Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */
12895088Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT),
12905088Sab196087 ELFEDIT_CMDOA_F_OPT },
12915088Sab196087 { NULL }
12925088Sab196087 };
12935088Sab196087
12945088Sab196087 static elfedit_cmd_t cmds[] = {
12955088Sab196087 /* phdr:dump */
12965088Sab196087 { cmd_dump, cpl_1starg_pt, name_dump,
12975088Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */
12985088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP),
12995088Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */
13005088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP),
13015088Sab196087 opt_minus_phndx, arg_dump },
13025088Sab196087
13035088Sab196087 /* phdr:p_type */
13045088Sab196087 { cmd_p_type, cpl_p_type, name_p_type,
13055088Sab196087 /* MSG_INTL(MSG_DESC_P_TYPE) */
13065088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_TYPE),
13075088Sab196087 /* MSG_INTL(MSG_HELP_P_TYPE) */
13085088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_TYPE),
13095088Sab196087 opt_std, arg_p_type },
13105088Sab196087
13115088Sab196087 /* phdr:p_offset */
13125088Sab196087 { cmd_p_offset, cpl_1starg_pt, name_p_offset,
13135088Sab196087 /* MSG_INTL(MSG_DESC_P_OFFSET) */
13145088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_OFFSET),
13155088Sab196087 /* MSG_INTL(MSG_HELP_P_OFFSET) */
13165088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_OFFSET),
13175088Sab196087 opt_std, arg_p_offset },
13185088Sab196087
13195088Sab196087 /* phdr:p_vaddr */
13205088Sab196087 { cmd_p_vaddr, cpl_1starg_pt, name_p_vaddr,
13215088Sab196087 /* MSG_INTL(MSG_DESC_P_VADDR) */
13225088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_VADDR),
13235088Sab196087 /* MSG_INTL(MSG_HELP_P_VADDR) */
13245088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_VADDR),
13255088Sab196087 opt_std, arg_p_vaddr },
13265088Sab196087
13275088Sab196087 /* phdr:p_paddr */
13285088Sab196087 { cmd_p_paddr, cpl_1starg_pt, name_p_paddr,
13295088Sab196087 /* MSG_INTL(MSG_DESC_P_PADDR) */
13305088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_PADDR),
13315088Sab196087 /* MSG_INTL(MSG_HELP_P_PADDR) */
13325088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_PADDR),
13335088Sab196087 opt_std, arg_p_paddr },
13345088Sab196087
13355088Sab196087 /* phdr:p_filesz */
13365088Sab196087 { cmd_p_filesz, cpl_1starg_pt, name_p_filesz,
13375088Sab196087 /* MSG_INTL(MSG_DESC_P_FILESZ) */
13385088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FILESZ),
13395088Sab196087 /* MSG_INTL(MSG_HELP_P_FILESZ) */
13405088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FILESZ),
13415088Sab196087 opt_std, arg_p_filesz },
13425088Sab196087
13435088Sab196087 /* phdr:p_memsz */
13445088Sab196087 { cmd_p_memsz, cpl_1starg_pt, name_p_memsz,
13455088Sab196087 /* MSG_INTL(MSG_DESC_P_MEMSZ) */
13465088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_MEMSZ),
13475088Sab196087 /* MSG_INTL(MSG_HELP_P_MEMSZ) */
13485088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_MEMSZ),
13495088Sab196087 opt_std, arg_p_memsz },
13505088Sab196087
13515088Sab196087 /* phdr:p_flags */
13525088Sab196087 { cmd_p_flags, cpl_p_flags, name_p_flags,
13535088Sab196087 /* MSG_INTL(MSG_DESC_P_FLAGS) */
13545088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FLAGS),
13555088Sab196087 /* MSG_INTL(MSG_HELP_P_FLAGS) */
13565088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FLAGS),
13575088Sab196087 opt_p_flags, arg_p_flags },
13585088Sab196087
13595088Sab196087 /* phdr:p_align */
13605088Sab196087 { cmd_p_align, cpl_1starg_pt, name_p_align,
13615088Sab196087 /* MSG_INTL(MSG_DESC_P_ALIGN) */
13625088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_ALIGN),
13635088Sab196087 /* MSG_INTL(MSG_HELP_P_ALIGN) */
13645088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_ALIGN),
13655088Sab196087 opt_std, arg_p_align },
13665088Sab196087
13675088Sab196087 /* phdr:interp */
13685088Sab196087 { cmd_interp, NULL, name_interp,
13695088Sab196087 /* MSG_INTL(MSG_DESC_INTERP) */
13705088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_INTERP),
13715088Sab196087 /* MSG_INTL(MSG_HELP_INTERP) */
13725088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_INTERP),
13735088Sab196087 opt_interp, arg_interp },
13745088Sab196087
13755088Sab196087 /* phdr:delete */
13765088Sab196087 { cmd_delete, cpl_1starg_pt, name_delete,
13775088Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */
13785088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE),
13795088Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */
13805088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE),
13815088Sab196087 opt_minus_phndx, arg_delete },
13825088Sab196087
13835088Sab196087 /* phdr:move */
13845088Sab196087 { cmd_move, cpl_1starg_pt, name_move,
13855088Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */
13865088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE),
13875088Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */
13885088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE),
13895088Sab196087 opt_minus_phndx, arg_move },
13905088Sab196087
13915088Sab196087 { NULL }
13925088Sab196087 };
13935088Sab196087
13945088Sab196087 static elfedit_module_t module = {
13955088Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
13965088Sab196087 /* MSG_INTL(MSG_MOD_DESC) */
13975088Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC),
13985088Sab196087 cmds, mod_i18nhdl_to_str };
13995088Sab196087
14005088Sab196087 return (&module);
14015088Sab196087 }
1402