1d29b2c44Sab196087 /* 2d29b2c44Sab196087 * CDDL HEADER START 3d29b2c44Sab196087 * 4d29b2c44Sab196087 * The contents of this file are subject to the terms of the 5d29b2c44Sab196087 * Common Development and Distribution License (the "License"). 6d29b2c44Sab196087 * You may not use this file except in compliance with the License. 7d29b2c44Sab196087 * 8d29b2c44Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9d29b2c44Sab196087 * or http://www.opensolaris.org/os/licensing. 10d29b2c44Sab196087 * See the License for the specific language governing permissions 11d29b2c44Sab196087 * and limitations under the License. 12d29b2c44Sab196087 * 13d29b2c44Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 14d29b2c44Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15d29b2c44Sab196087 * If applicable, add the following below this CDDL HEADER, with the 16d29b2c44Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 17d29b2c44Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 18d29b2c44Sab196087 * 19d29b2c44Sab196087 * CDDL HEADER END 20d29b2c44Sab196087 */ 21d29b2c44Sab196087 22d29b2c44Sab196087 /* 23*4f680cc6SAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24d29b2c44Sab196087 * Use is subject to license terms. 25d29b2c44Sab196087 */ 26d29b2c44Sab196087 27d29b2c44Sab196087 #include <elfedit.h> 28d29b2c44Sab196087 #include <strings.h> 29d29b2c44Sab196087 #include <conv.h> 30d29b2c44Sab196087 #include <debug.h> 31d29b2c44Sab196087 #include <phdr_msg.h> 32d29b2c44Sab196087 33d29b2c44Sab196087 34d29b2c44Sab196087 /* 35d29b2c44Sab196087 * Program headers 36d29b2c44Sab196087 */ 37d29b2c44Sab196087 38d29b2c44Sab196087 39d29b2c44Sab196087 40d29b2c44Sab196087 /* 41d29b2c44Sab196087 * This module uses shared code for several of the commands. 42d29b2c44Sab196087 * It is sometimes necessary to know which specific command 43d29b2c44Sab196087 * is active. 44d29b2c44Sab196087 */ 45d29b2c44Sab196087 typedef enum { 46d29b2c44Sab196087 /* Dump command, used as module default to display dynamic section */ 47d29b2c44Sab196087 PHDR_CMD_T_DUMP = 0, /* phdr:dump */ 48d29b2c44Sab196087 49d29b2c44Sab196087 /* Commands that correspond directly to program header fields */ 50d29b2c44Sab196087 PHDR_CMD_T_P_TYPE = 1, /* phdr:p_type */ 51d29b2c44Sab196087 PHDR_CMD_T_P_OFFSET = 2, /* phdr:p_offset */ 52d29b2c44Sab196087 PHDR_CMD_T_P_VADDR = 3, /* phdr:p_vaddr */ 53d29b2c44Sab196087 PHDR_CMD_T_P_PADDR = 4, /* phdr:p_paddr */ 54d29b2c44Sab196087 PHDR_CMD_T_P_FILESZ = 5, /* phdr:p_filesz */ 55d29b2c44Sab196087 PHDR_CMD_T_P_MEMSZ = 6, /* phdr:p_memsz */ 56d29b2c44Sab196087 PHDR_CMD_T_P_FLAGS = 7, /* phdr:p_flags */ 57d29b2c44Sab196087 PHDR_CMD_T_P_ALIGN = 8, /* phdr:p_align */ 58d29b2c44Sab196087 59d29b2c44Sab196087 /* Commands that do not correspond directly to a specific phdr tag */ 60d29b2c44Sab196087 PHDR_CMD_T_INTERP = 9, /* phdr:interp */ 61d29b2c44Sab196087 PHDR_CMD_T_DELETE = 10, /* phdr:delete */ 62d29b2c44Sab196087 PHDR_CMD_T_MOVE = 11 /* phdr:move */ 63d29b2c44Sab196087 } PHDR_CMD_T; 64d29b2c44Sab196087 65d29b2c44Sab196087 66d29b2c44Sab196087 67d29b2c44Sab196087 /* 68d29b2c44Sab196087 * The following type is ued by locate_interp() to return 69d29b2c44Sab196087 * information about the interpreter program header. 70d29b2c44Sab196087 */ 71d29b2c44Sab196087 typedef struct { 72d29b2c44Sab196087 Word phndx; /* Index of PT_INTERP header */ 73d29b2c44Sab196087 Phdr *phdr; /* PT_INTERP header */ 74d29b2c44Sab196087 elfedit_section_t *sec; /* Section containing string */ 75d29b2c44Sab196087 Word stroff; /* Offset into string section */ 76d29b2c44Sab196087 const char *str; /* Interpreter string */ 77d29b2c44Sab196087 } INTERP_STATE; 78d29b2c44Sab196087 79d29b2c44Sab196087 80d29b2c44Sab196087 #ifndef _ELF64 81d29b2c44Sab196087 /* 82d29b2c44Sab196087 * We supply this function for the msg module 83d29b2c44Sab196087 */ 84d29b2c44Sab196087 const char * 85d29b2c44Sab196087 _phdr_msg(Msg mid) 86d29b2c44Sab196087 { 87d29b2c44Sab196087 return (gettext(MSG_ORIG(mid))); 88d29b2c44Sab196087 } 89d29b2c44Sab196087 #endif 90d29b2c44Sab196087 91d29b2c44Sab196087 92d29b2c44Sab196087 /* 93d29b2c44Sab196087 * This function is supplied to elfedit through our elfedit_module_t 94d29b2c44Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles 95d29b2c44Sab196087 * in our module interface into the actual strings for elfedit to 96d29b2c44Sab196087 * use. 97d29b2c44Sab196087 * 98d29b2c44Sab196087 * note: 99d29b2c44Sab196087 * This module uses Msg codes for its i18n handle type. 100d29b2c44Sab196087 * So the translation is simply to use MSG_INTL() to turn 101d29b2c44Sab196087 * it into a string and return it. 102d29b2c44Sab196087 */ 103d29b2c44Sab196087 static const char * 104d29b2c44Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 105d29b2c44Sab196087 { 106d29b2c44Sab196087 Msg msg = (Msg)hdl; 107d29b2c44Sab196087 108d29b2c44Sab196087 return (MSG_INTL(msg)); 109d29b2c44Sab196087 } 110d29b2c44Sab196087 111d29b2c44Sab196087 112d29b2c44Sab196087 113d29b2c44Sab196087 /* 114d29b2c44Sab196087 * The phdr_opt_t enum specifies a bit value for every optional 115d29b2c44Sab196087 * argument allowed by a command in this module. 116d29b2c44Sab196087 */ 117d29b2c44Sab196087 typedef enum { 118d29b2c44Sab196087 PHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */ 119d29b2c44Sab196087 PHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ 120d29b2c44Sab196087 PHDR_OPT_F_PHNDX = 4, /* -phndx: Program header by index, */ 121d29b2c44Sab196087 /* not by name */ 122d29b2c44Sab196087 PHDR_OPT_F_OR = 8 /* -or: OR (|) values to dest */ 123d29b2c44Sab196087 } phdr_opt_t; 124d29b2c44Sab196087 125d29b2c44Sab196087 126d29b2c44Sab196087 /* 127d29b2c44Sab196087 * A variable of type ARGSTATE is used by each command to maintain 128d29b2c44Sab196087 * information about the section headers and related things. It is 129d29b2c44Sab196087 * initialized by process_args(), and used by the other routines. 130d29b2c44Sab196087 */ 131d29b2c44Sab196087 typedef struct { 132d29b2c44Sab196087 elfedit_obj_state_t *obj_state; 133d29b2c44Sab196087 phdr_opt_t optmask; /* Mask of options used */ 134d29b2c44Sab196087 int argc; /* # of plain arguments */ 135d29b2c44Sab196087 const char **argv; /* Plain arguments */ 136d29b2c44Sab196087 int ndx_set; /* True if ndx is valid */ 137d29b2c44Sab196087 Word ndx; /* Index of header if cmd */ 138d29b2c44Sab196087 /* accepts it */ 139d29b2c44Sab196087 int print_req; /* Call is a print request */ 140d29b2c44Sab196087 } ARGSTATE; 141d29b2c44Sab196087 142d29b2c44Sab196087 143d29b2c44Sab196087 /* 144d29b2c44Sab196087 * Standard argument processing for phdr module 145d29b2c44Sab196087 * 146d29b2c44Sab196087 * entry 147d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments 148d29b2c44Sab196087 * optmask - Mask of allowed optional arguments. 149d29b2c44Sab196087 * cmd - PHDR_CMD_T_* value giving identify of caller 150d29b2c44Sab196087 * argstate - Address of ARGSTATE block to be initialized 151d29b2c44Sab196087 * 152d29b2c44Sab196087 * exit: 153d29b2c44Sab196087 * On success, *argstate is initialized. On error, 154d29b2c44Sab196087 * an error is issued and this routine does not return. 155d29b2c44Sab196087 */ 156d29b2c44Sab196087 static void 157d29b2c44Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 158d29b2c44Sab196087 PHDR_CMD_T cmd, ARGSTATE *argstate) 159d29b2c44Sab196087 { 160d29b2c44Sab196087 elfedit_getopt_state_t getopt_state; 161d29b2c44Sab196087 elfedit_getopt_ret_t *getopt_ret; 162d29b2c44Sab196087 163d29b2c44Sab196087 bzero(argstate, sizeof (*argstate)); 164d29b2c44Sab196087 argstate->obj_state = obj_state; 165d29b2c44Sab196087 166d29b2c44Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 167d29b2c44Sab196087 168d29b2c44Sab196087 /* Add each new option to the options mask */ 169d29b2c44Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) 170d29b2c44Sab196087 argstate->optmask |= getopt_ret->gor_idmask; 171d29b2c44Sab196087 172d29b2c44Sab196087 /* Are the right number of plain arguments present? */ 173d29b2c44Sab196087 switch (cmd) { 174d29b2c44Sab196087 case PHDR_CMD_T_DUMP: 175d29b2c44Sab196087 if (argc > 1) 176d29b2c44Sab196087 elfedit_command_usage(); 177d29b2c44Sab196087 argstate->print_req = 1; 178d29b2c44Sab196087 break; 179d29b2c44Sab196087 case PHDR_CMD_T_P_FLAGS: 180d29b2c44Sab196087 /* phdr:sh_flags allows an arbitrary number of arguments */ 181d29b2c44Sab196087 argstate->print_req = (argc < 2); 182d29b2c44Sab196087 break; 183d29b2c44Sab196087 case PHDR_CMD_T_INTERP: 184d29b2c44Sab196087 if (argc > 1) 185d29b2c44Sab196087 elfedit_command_usage(); 186d29b2c44Sab196087 argstate->print_req = (argc == 0); 187d29b2c44Sab196087 break; 188d29b2c44Sab196087 case PHDR_CMD_T_DELETE: 189d29b2c44Sab196087 if ((argc < 1) || (argc > 2)) 190d29b2c44Sab196087 elfedit_command_usage(); 191d29b2c44Sab196087 argstate->print_req = 0; 192d29b2c44Sab196087 break; 193d29b2c44Sab196087 case PHDR_CMD_T_MOVE: 194d29b2c44Sab196087 if ((argc < 2) || (argc > 3)) 195d29b2c44Sab196087 elfedit_command_usage(); 196d29b2c44Sab196087 argstate->print_req = 0; 197d29b2c44Sab196087 break; 198d29b2c44Sab196087 199d29b2c44Sab196087 default: 200d29b2c44Sab196087 /* The remaining commands accept 2 plain arguments */ 201d29b2c44Sab196087 if (argc > 2) 202d29b2c44Sab196087 elfedit_command_usage(); 203d29b2c44Sab196087 argstate->print_req = (argc < 2); 204d29b2c44Sab196087 break; 205d29b2c44Sab196087 } 206d29b2c44Sab196087 207d29b2c44Sab196087 /* Return the updated values of argc/argv */ 208d29b2c44Sab196087 argstate->argc = argc; 209d29b2c44Sab196087 argstate->argv = argv; 210d29b2c44Sab196087 211d29b2c44Sab196087 argstate->ndx_set = 0; 212d29b2c44Sab196087 if ((argc > 0) && (cmd != PHDR_CMD_T_INTERP)) { 213d29b2c44Sab196087 /* 214d29b2c44Sab196087 * If the -phndx option is present, the first argument is 215d29b2c44Sab196087 * the index of the header to use. Otherwise, it is a 216d29b2c44Sab196087 * name corresponding to its type, similar to the way 217d29b2c44Sab196087 * elfdump works with its -N option. 218d29b2c44Sab196087 */ 219d29b2c44Sab196087 if (argstate->optmask & PHDR_OPT_F_PHNDX) { 220d29b2c44Sab196087 argstate->ndx = (Word) elfedit_atoui_range( 221d29b2c44Sab196087 argstate->argv[0], MSG_ORIG(MSG_STR_ELEMENT), 0, 222d29b2c44Sab196087 argstate->obj_state->os_phnum - 1, NULL); 223d29b2c44Sab196087 argstate->ndx_set = 1; 224d29b2c44Sab196087 } else { 225d29b2c44Sab196087 Conv_inv_buf_t inv_buf; 226*4f680cc6SAli Bahrami Ehdr *ehdr = obj_state->os_ehdr; 227*4f680cc6SAli Bahrami Half mach = ehdr->e_machine; 228*4f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI]; 229d29b2c44Sab196087 Word i; 230d29b2c44Sab196087 Phdr *phdr; 231d29b2c44Sab196087 232d29b2c44Sab196087 argstate->ndx = (Word) elfedit_atoconst( 233d29b2c44Sab196087 argstate->argv[0], ELFEDIT_CONST_PT); 234d29b2c44Sab196087 phdr = obj_state->os_phdr; 235d29b2c44Sab196087 for (i = 0; i < obj_state->os_phnum; i++, phdr++) { 236d29b2c44Sab196087 if (phdr->p_type == argstate->ndx) { 237d29b2c44Sab196087 argstate->ndx = i; 238d29b2c44Sab196087 argstate->ndx_set = 1; 239d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 240d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_PHDR), 241*4f680cc6SAli Bahrami EC_WORD(i), conv_phdr_type(osabi, 242*4f680cc6SAli Bahrami mach, phdr->p_type, 0, &inv_buf)); 243d29b2c44Sab196087 break; 244d29b2c44Sab196087 } 245d29b2c44Sab196087 } 246d29b2c44Sab196087 if (i == argstate->obj_state->os_phnum) 247d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, 248d29b2c44Sab196087 MSG_INTL(MSG_ERR_NOPHDR), conv_phdr_type( 249*4f680cc6SAli Bahrami osabi, mach, argstate->ndx, 0, &inv_buf)); 250d29b2c44Sab196087 } 251d29b2c44Sab196087 } 252d29b2c44Sab196087 253d29b2c44Sab196087 /* If there may be an arbitrary amount of output, use a pager */ 254d29b2c44Sab196087 if (argc == 0) 255d29b2c44Sab196087 elfedit_pager_init(); 256d29b2c44Sab196087 257d29b2c44Sab196087 } 258d29b2c44Sab196087 259d29b2c44Sab196087 260d29b2c44Sab196087 261d29b2c44Sab196087 /* 262d29b2c44Sab196087 * Locate the interpreter string for the object and related information 263d29b2c44Sab196087 * 264d29b2c44Sab196087 * entry: 265d29b2c44Sab196087 * obj_state - Object state 266d29b2c44Sab196087 * interp - NULL, or variable to be filled in with information 267d29b2c44Sab196087 * about the interpteter string. 268d29b2c44Sab196087 */ 269d29b2c44Sab196087 static const char * 270d29b2c44Sab196087 locate_interp(elfedit_obj_state_t *obj_state, INTERP_STATE *interp) 271d29b2c44Sab196087 { 272d29b2c44Sab196087 INTERP_STATE local_interp; 273d29b2c44Sab196087 elfedit_section_t *strsec; /* String table */ 274d29b2c44Sab196087 size_t phnum; /* # of program headers */ 275d29b2c44Sab196087 int phndx; /* Index of PT_INTERP program header */ 276d29b2c44Sab196087 Phdr *phdr; /* Program header array */ 277d29b2c44Sab196087 Word i; 278d29b2c44Sab196087 279d29b2c44Sab196087 if (interp == NULL) 280d29b2c44Sab196087 interp = &local_interp; 281d29b2c44Sab196087 282d29b2c44Sab196087 /* Locate the PT_INTERP program header */ 283d29b2c44Sab196087 phnum = obj_state->os_phnum; 284d29b2c44Sab196087 phdr = obj_state->os_phdr; 285d29b2c44Sab196087 286d29b2c44Sab196087 for (phndx = 0; phndx < phnum; phndx++) { 287d29b2c44Sab196087 if (phdr[phndx].p_type == PT_INTERP) { 288d29b2c44Sab196087 interp->phndx = phndx; 289d29b2c44Sab196087 interp->phdr = phdr + phndx; 290d29b2c44Sab196087 break; 291d29b2c44Sab196087 } 292d29b2c44Sab196087 } 293d29b2c44Sab196087 /* If no PT_INTERP program header found, we cannot proceed */ 294d29b2c44Sab196087 if (phndx == phnum) 295d29b2c44Sab196087 elfedit_elferr(obj_state->os_file, 296d29b2c44Sab196087 MSG_INTL(MSG_ERR_NOINTERPPHDR)); 297d29b2c44Sab196087 298d29b2c44Sab196087 /* 299d29b2c44Sab196087 * Locate the section containing the interpteter string as well 300d29b2c44Sab196087 * as the string itself. 301d29b2c44Sab196087 * 302d29b2c44Sab196087 * The program header contains a direct offset to the string, so 303d29b2c44Sab196087 * we find the section by walking through the them looking for 304d29b2c44Sab196087 * the one with a base and size that would contain the string. 305d29b2c44Sab196087 * Note that this target section cannot be in a NOBITS section. 306d29b2c44Sab196087 */ 307d29b2c44Sab196087 for (i = 1; i < obj_state->os_shnum; i++) { 308d29b2c44Sab196087 strsec = &obj_state->os_secarr[i]; 309d29b2c44Sab196087 310d29b2c44Sab196087 if ((strsec->sec_shdr->sh_type != SHT_NOBITS) && 311d29b2c44Sab196087 (interp->phdr->p_offset >= strsec->sec_shdr->sh_offset) && 312d29b2c44Sab196087 ((interp->phdr->p_offset + interp->phdr->p_filesz) <= 313d29b2c44Sab196087 (strsec->sec_shdr->sh_offset + 314d29b2c44Sab196087 strsec->sec_shdr->sh_size))) { 315d29b2c44Sab196087 interp->sec = strsec; 316d29b2c44Sab196087 317d29b2c44Sab196087 interp->stroff = interp->phdr->p_offset - 318d29b2c44Sab196087 strsec->sec_shdr->sh_offset; 319d29b2c44Sab196087 interp->str = ((char *)strsec->sec_data->d_buf) + 320d29b2c44Sab196087 interp->stroff; 321d29b2c44Sab196087 return (interp->str); 322d29b2c44Sab196087 } 323d29b2c44Sab196087 } 324d29b2c44Sab196087 325d29b2c44Sab196087 /* 326d29b2c44Sab196087 * We don't expect to get here: If there is a PT_INTERP header, 327d29b2c44Sab196087 * we fully expect the string to exist. 328d29b2c44Sab196087 */ 329d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOINTERPSEC)); 330d29b2c44Sab196087 /*NOTREACHED*/ 331d29b2c44Sab196087 332d29b2c44Sab196087 return (NULL); /* For lint */ 333d29b2c44Sab196087 } 334d29b2c44Sab196087 335d29b2c44Sab196087 /* 336d29b2c44Sab196087 * Print program header values, taking the calling command, and output style 337d29b2c44Sab196087 * into account. 338d29b2c44Sab196087 * 339d29b2c44Sab196087 * entry: 340d29b2c44Sab196087 * autoprint - If True, output is only produced if the elfedit 341d29b2c44Sab196087 * autoprint flag is set. If False, output is always produced. 342d29b2c44Sab196087 * cmd - PHDR_CMD_T_* value giving identify of caller 343*4f680cc6SAli Bahrami * argstate - State block for section header array. The following 344*4f680cc6SAli Bahrami * fields are examined in order to determine the form 345*4f680cc6SAli Bahrami * of output: ndx_set, ndx, print_req. 346d29b2c44Sab196087 */ 347d29b2c44Sab196087 static void 348d29b2c44Sab196087 print_phdr(PHDR_CMD_T cmd, int autoprint, ARGSTATE *argstate) 349d29b2c44Sab196087 { 350d29b2c44Sab196087 elfedit_outstyle_t outstyle; 351*4f680cc6SAli Bahrami Ehdr *ehdr = argstate->obj_state->os_ehdr; 352*4f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI]; 353*4f680cc6SAli Bahrami Half mach = ehdr->e_machine; 354*4f680cc6SAli Bahrami Word ndx, cnt, by_type, type; 355*4f680cc6SAli Bahrami Phdr *phdr; 356d29b2c44Sab196087 357d29b2c44Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) 358d29b2c44Sab196087 return; 359d29b2c44Sab196087 360*4f680cc6SAli Bahrami /* 361*4f680cc6SAli Bahrami * Determine which indexes to display: 362*4f680cc6SAli Bahrami * 363*4f680cc6SAli Bahrami * - If the user specified an index, the display starts 364*4f680cc6SAli Bahrami * with that item. If it was a print_request, and the 365*4f680cc6SAli Bahrami * index was specified by type, then all items of the 366*4f680cc6SAli Bahrami * same type are shown. If not a print request, or the index 367*4f680cc6SAli Bahrami * was given numerically, then just the single item is shown. 368*4f680cc6SAli Bahrami * 369*4f680cc6SAli Bahrami * - If no index is specified, every program header is shown. 370*4f680cc6SAli Bahrami */ 371*4f680cc6SAli Bahrami by_type = 0; 372d29b2c44Sab196087 if (argstate->ndx_set) { 373d29b2c44Sab196087 ndx = argstate->ndx; 374*4f680cc6SAli Bahrami if (argstate->print_req && 375*4f680cc6SAli Bahrami ((argstate->optmask & PHDR_OPT_F_PHNDX) == 0)) { 376*4f680cc6SAli Bahrami by_type = 1; 377*4f680cc6SAli Bahrami type = argstate->obj_state->os_phdr[ndx].p_type; 378*4f680cc6SAli Bahrami cnt = argstate->obj_state->os_phnum - ndx; 379*4f680cc6SAli Bahrami } else { 380d29b2c44Sab196087 cnt = 1; 381*4f680cc6SAli Bahrami } 382d29b2c44Sab196087 } else { 383d29b2c44Sab196087 ndx = 0; 384d29b2c44Sab196087 cnt = argstate->obj_state->os_phnum; 385d29b2c44Sab196087 } 386*4f680cc6SAli Bahrami phdr = argstate->obj_state->os_phdr + ndx; 387d29b2c44Sab196087 388d29b2c44Sab196087 /* 389d29b2c44Sab196087 * Pick an output style. phdr:dump is required to use the default 390d29b2c44Sab196087 * style. The other commands use the current output style. 391d29b2c44Sab196087 */ 392d29b2c44Sab196087 outstyle = (cmd == PHDR_CMD_T_DUMP) ? 393d29b2c44Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle(); 394d29b2c44Sab196087 395d29b2c44Sab196087 /* 396d29b2c44Sab196087 * If doing default output, use elfdump style where we 397d29b2c44Sab196087 * show all program header attributes. In this case, the 398d29b2c44Sab196087 * command that called us doesn't matter. 399d29b2c44Sab196087 * 400*4f680cc6SAli Bahrami * Exclude PHDR_CMD_T_INTERP from this: It isn't per-phdr like 401d29b2c44Sab196087 * the other commands. 402d29b2c44Sab196087 */ 403d29b2c44Sab196087 if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) && 404d29b2c44Sab196087 (cmd != PHDR_CMD_T_INTERP)) { 405d29b2c44Sab196087 for (; cnt--; ndx++, phdr++) { 406*4f680cc6SAli Bahrami if (by_type && (type != phdr->p_type)) 407*4f680cc6SAli Bahrami continue; 408*4f680cc6SAli Bahrami 409d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 410d29b2c44Sab196087 elfedit_printf(MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx)); 411*4f680cc6SAli Bahrami Elf_phdr(0, osabi, mach, phdr); 412d29b2c44Sab196087 } 413d29b2c44Sab196087 return; 414d29b2c44Sab196087 } 415d29b2c44Sab196087 416*4f680cc6SAli Bahrami if (cmd == PHDR_CMD_T_INTERP) { 417d29b2c44Sab196087 INTERP_STATE interp; 418d29b2c44Sab196087 419d29b2c44Sab196087 (void) locate_interp(argstate->obj_state, &interp); 420d29b2c44Sab196087 switch (outstyle) { 421d29b2c44Sab196087 case ELFEDIT_OUTSTYLE_DEFAULT: 422d29b2c44Sab196087 elfedit_printf(MSG_INTL(MSG_FMT_ELF_INTERP), 423d29b2c44Sab196087 interp.sec->sec_name, interp.str); 424d29b2c44Sab196087 break; 425d29b2c44Sab196087 case ELFEDIT_OUTSTYLE_SIMPLE: 426*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), interp.str); 427d29b2c44Sab196087 break; 428d29b2c44Sab196087 case ELFEDIT_OUTSTYLE_NUM: 429d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_U_NL), 430d29b2c44Sab196087 EC_WORD(interp.stroff)); 431d29b2c44Sab196087 break; 432d29b2c44Sab196087 } 433d29b2c44Sab196087 return; 434d29b2c44Sab196087 } 435*4f680cc6SAli Bahrami 436*4f680cc6SAli Bahrami /* Handle the remaining commands */ 437*4f680cc6SAli Bahrami for (; cnt--; ndx++, phdr++) { 438*4f680cc6SAli Bahrami if (by_type && (type != phdr->p_type)) 439*4f680cc6SAli Bahrami continue; 440*4f680cc6SAli Bahrami 441*4f680cc6SAli Bahrami switch (cmd) { 442*4f680cc6SAli Bahrami case PHDR_CMD_T_P_TYPE: 443*4f680cc6SAli Bahrami if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 444*4f680cc6SAli Bahrami Conv_inv_buf_t inv_buf; 445*4f680cc6SAli Bahrami 446*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 447*4f680cc6SAli Bahrami conv_phdr_type(osabi, 448*4f680cc6SAli Bahrami argstate->obj_state->os_ehdr->e_machine, 449*4f680cc6SAli Bahrami phdr->p_type, 0, &inv_buf)); 450*4f680cc6SAli Bahrami } else { 451*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_X_NL), 452*4f680cc6SAli Bahrami EC_WORD(phdr->p_type)); 453*4f680cc6SAli Bahrami } 454*4f680cc6SAli Bahrami break; 455*4f680cc6SAli Bahrami 456*4f680cc6SAli Bahrami case PHDR_CMD_T_P_OFFSET: 457*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 458*4f680cc6SAli Bahrami EC_OFF(phdr->p_offset)); 459*4f680cc6SAli Bahrami break; 460*4f680cc6SAli Bahrami 461*4f680cc6SAli Bahrami case PHDR_CMD_T_P_VADDR: 462*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 463*4f680cc6SAli Bahrami EC_ADDR(phdr->p_vaddr)); 464*4f680cc6SAli Bahrami break; 465*4f680cc6SAli Bahrami 466*4f680cc6SAli Bahrami case PHDR_CMD_T_P_PADDR: 467*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 468*4f680cc6SAli Bahrami EC_ADDR(phdr->p_paddr)); 469*4f680cc6SAli Bahrami break; 470*4f680cc6SAli Bahrami 471*4f680cc6SAli Bahrami case PHDR_CMD_T_P_FILESZ: 472*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 473*4f680cc6SAli Bahrami EC_XWORD(phdr->p_filesz)); 474*4f680cc6SAli Bahrami break; 475*4f680cc6SAli Bahrami 476*4f680cc6SAli Bahrami case PHDR_CMD_T_P_MEMSZ: 477*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 478*4f680cc6SAli Bahrami EC_XWORD(phdr->p_memsz)); 479*4f680cc6SAli Bahrami break; 480*4f680cc6SAli Bahrami 481*4f680cc6SAli Bahrami case PHDR_CMD_T_P_FLAGS: 482*4f680cc6SAli Bahrami if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 483*4f680cc6SAli Bahrami Conv_phdr_flags_buf_t phdr_flags_buf; 484*4f680cc6SAli Bahrami 485*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 486*4f680cc6SAli Bahrami conv_phdr_flags(osabi, phdr->p_flags, 487*4f680cc6SAli Bahrami CONV_FMT_NOBKT, &phdr_flags_buf)); 488*4f680cc6SAli Bahrami } else { 489*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_X_NL), 490*4f680cc6SAli Bahrami EC_WORD(phdr->p_flags)); 491*4f680cc6SAli Bahrami } 492*4f680cc6SAli Bahrami break; 493*4f680cc6SAli Bahrami 494*4f680cc6SAli Bahrami case PHDR_CMD_T_P_ALIGN: 495*4f680cc6SAli Bahrami elfedit_printf(MSG_ORIG(MSG_FMT_LLX_NL), 496*4f680cc6SAli Bahrami EC_XWORD(phdr->p_align)); 497*4f680cc6SAli Bahrami break; 498*4f680cc6SAli Bahrami } 499*4f680cc6SAli Bahrami } 500d29b2c44Sab196087 } 501d29b2c44Sab196087 502d29b2c44Sab196087 503d29b2c44Sab196087 /* 504d29b2c44Sab196087 * Called from cmd_body() in the case where a plain argument 505d29b2c44Sab196087 * is given to phdr:interp to change the interpreter. 506d29b2c44Sab196087 */ 507d29b2c44Sab196087 static elfedit_cmdret_t 508d29b2c44Sab196087 cmd_body_set_interp(ARGSTATE *argstate) 509d29b2c44Sab196087 { 510d29b2c44Sab196087 elfedit_obj_state_t *obj_state = argstate->obj_state; 511d29b2c44Sab196087 elfedit_section_t *strsec; /* String table */ 512d29b2c44Sab196087 INTERP_STATE interp; 513d29b2c44Sab196087 Word numdyn; /* # of elements in dyn arr */ 514d29b2c44Sab196087 size_t phnum; /* # of program headers */ 515d29b2c44Sab196087 Phdr *phdr; /* Program header array */ 516d29b2c44Sab196087 Word i, j; 517d29b2c44Sab196087 Word str_offset; /* Offset in strsec to new interp str */ 518d29b2c44Sab196087 int str_found = 0; /* True when we have new interp str */ 519d29b2c44Sab196087 Word str_size; /* Size of new interp string + NULL */ 520d29b2c44Sab196087 521d29b2c44Sab196087 phnum = obj_state->os_phnum; 522d29b2c44Sab196087 phdr = obj_state->os_phdr; 523d29b2c44Sab196087 524d29b2c44Sab196087 /* Locate the PT_INTERP program header */ 525d29b2c44Sab196087 (void) locate_interp(obj_state, &interp); 526d29b2c44Sab196087 strsec = interp.sec; 527d29b2c44Sab196087 str_offset = interp.stroff; 528d29b2c44Sab196087 529d29b2c44Sab196087 /* 530d29b2c44Sab196087 * If the given string is the same as the existing interpreter 531d29b2c44Sab196087 * string, say so and return. 532d29b2c44Sab196087 */ 533d29b2c44Sab196087 if (strcmp(interp.str, argstate->argv[0]) == 0) { 534d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_OLDINTERPOK), 535d29b2c44Sab196087 EC_WORD(strsec->sec_shndx), strsec->sec_name, 536d29b2c44Sab196087 EC_WORD(str_offset), interp.str); 537d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE); 538d29b2c44Sab196087 } 539d29b2c44Sab196087 540d29b2c44Sab196087 /* 541d29b2c44Sab196087 * An ELF PT_INTERP usually references its own special section 542d29b2c44Sab196087 * instead of some other string table. The ELF ABI says that this 543d29b2c44Sab196087 * section must be named ".interp". Hence, this is a rare case 544d29b2c44Sab196087 * in which the name of a section can be taken as an indication 545d29b2c44Sab196087 * of its contents. .interp is typically sized to just fit 546d29b2c44Sab196087 * the original string, including its NULL termination. You can 547d29b2c44Sab196087 * treat it as a string table with one string. 548d29b2c44Sab196087 * 549d29b2c44Sab196087 * Thanks to 'elfedit', it may be that we encounter a file where 550d29b2c44Sab196087 * PT_INTERP does not reference the .interp section. This will happen 551d29b2c44Sab196087 * if elfedit is used to change the interpreter to a string that is 552d29b2c44Sab196087 * too big to fit in .interp, in which case we will use the 553d29b2c44Sab196087 * .dynstr string table (That code is below, in this function). 554d29b2c44Sab196087 * 555d29b2c44Sab196087 * Given the above facts, our next step is to locate the .interp 556d29b2c44Sab196087 * section and see if our new string will fit in it. Since we can't 557d29b2c44Sab196087 * depend on PT_INTERP, we search the section headers to find a 558d29b2c44Sab196087 * section whith the following characteristics: 559d29b2c44Sab196087 * - The name is ".interp". 560d29b2c44Sab196087 * - Section is allocable (SHF_ALLOC) and SHT_PROGBITS. 561d29b2c44Sab196087 * - It is not part of a writable segment. 562d29b2c44Sab196087 * If we find such a section, and the new string fits, we will 563d29b2c44Sab196087 * write it there. 564d29b2c44Sab196087 */ 565d29b2c44Sab196087 str_size = strlen(argstate->argv[0]) + 1; 566d29b2c44Sab196087 for (i = 1; i < obj_state->os_shnum; i++) { 567d29b2c44Sab196087 strsec = &obj_state->os_secarr[i]; 568d29b2c44Sab196087 if ((strcmp(strsec->sec_name, MSG_ORIG(MSG_SEC_INTERP)) == 0) && 569d29b2c44Sab196087 (strsec->sec_shdr->sh_flags & SHF_ALLOC) && 570d29b2c44Sab196087 (strsec->sec_shdr->sh_type & SHT_PROGBITS)) { 571d29b2c44Sab196087 for (j = 0; j < phnum; j++) { 572d29b2c44Sab196087 Phdr *tphdr = &phdr[j]; 573d29b2c44Sab196087 if ((strsec->sec_shdr->sh_offset >= 574d29b2c44Sab196087 tphdr->p_offset) && 575d29b2c44Sab196087 ((strsec->sec_shdr->sh_offset + 576d29b2c44Sab196087 strsec->sec_shdr->sh_size) <= 577d29b2c44Sab196087 (tphdr->p_offset + tphdr->p_filesz)) && 578d29b2c44Sab196087 (tphdr->p_flags & PF_W)) { 579d29b2c44Sab196087 break; 580d29b2c44Sab196087 } 581d29b2c44Sab196087 } 582d29b2c44Sab196087 if ((j == phnum) && 583d29b2c44Sab196087 (str_size <= strsec->sec_shdr->sh_size)) { 584d29b2c44Sab196087 /* .interp section found, and has room */ 585d29b2c44Sab196087 str_found = 1; 586d29b2c44Sab196087 str_offset = 0; 587d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 588d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_NEWISTR), EC_WORD(j), 589d29b2c44Sab196087 strsec->sec_name, EC_WORD(str_offset), 590d29b2c44Sab196087 argstate->argv[0]); 591d29b2c44Sab196087 /* Put new value in section */ 592d29b2c44Sab196087 (void) strncpy((char *)strsec->sec_data->d_buf, 593d29b2c44Sab196087 argstate->argv[0], 594d29b2c44Sab196087 strsec->sec_shdr->sh_size); 595d29b2c44Sab196087 /* Set libelf dirty bit so change is flushed */ 596d29b2c44Sab196087 elfedit_modified_data(strsec); 597d29b2c44Sab196087 break; 598d29b2c44Sab196087 } else { 599d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 600d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LNGISTR), EC_WORD(j), 601d29b2c44Sab196087 strsec->sec_name, EC_WORD(str_offset), 602d29b2c44Sab196087 EC_WORD(str_size), 603d29b2c44Sab196087 EC_WORD(strsec->sec_shdr->sh_size), 604d29b2c44Sab196087 argstate->argv[0]); 605d29b2c44Sab196087 } 606d29b2c44Sab196087 } 607d29b2c44Sab196087 } 608d29b2c44Sab196087 609d29b2c44Sab196087 /* 610d29b2c44Sab196087 * If the above did not find a string within the .interp section, 611d29b2c44Sab196087 * then we have a second option. If this ELF object has a dynamic 612d29b2c44Sab196087 * section, then we are willing to use strings from within the 613d29b2c44Sab196087 * associated .dynstr string table. And if there is reserved space 614d29b2c44Sab196087 * in .dynstr (as reported by the DT_SUNW_STRPAD dynamic entry), 615d29b2c44Sab196087 * then we are even willing to add a new string to .dynstr. 616d29b2c44Sab196087 */ 617d29b2c44Sab196087 if (!str_found) { 618d29b2c44Sab196087 elfedit_section_t *dynsec; 619d29b2c44Sab196087 Dyn *dyn; 620d29b2c44Sab196087 621d29b2c44Sab196087 dynsec = elfedit_sec_getdyn(obj_state, &dyn, &numdyn); 622d29b2c44Sab196087 strsec = elfedit_sec_getstr(obj_state, 62355ef6355Sab196087 dynsec->sec_shdr->sh_link, 0); 624d29b2c44Sab196087 625d29b2c44Sab196087 /* Does string exist in the table already, or can we add it? */ 626d29b2c44Sab196087 str_offset = elfedit_strtab_insert(obj_state, strsec, 627d29b2c44Sab196087 dynsec, argstate->argv[0]); 628d29b2c44Sab196087 } 629d29b2c44Sab196087 630d29b2c44Sab196087 631d29b2c44Sab196087 /* 632d29b2c44Sab196087 * If we are here, we know we have a replacement string, because 633d29b2c44Sab196087 * the errors from checking .dynamic/.dynstr will not allow 634d29b2c44Sab196087 * things to get here otherwise. 635d29b2c44Sab196087 * 636d29b2c44Sab196087 * The PT_INTERP program header references the string directly, 637d29b2c44Sab196087 * so we add the section offset to the string offset. 638d29b2c44Sab196087 */ 639d29b2c44Sab196087 interp.phdr->p_offset = strsec->sec_shdr->sh_offset + str_offset; 640d29b2c44Sab196087 interp.phdr->p_filesz = str_size; 641d29b2c44Sab196087 elfedit_modified_phdr(obj_state); 642d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SETPHINTERP), 643d29b2c44Sab196087 EC_WORD(interp.phndx), EC_XWORD(interp.phdr->p_offset), 644d29b2c44Sab196087 EC_XWORD(interp.phdr->p_filesz)); 645d29b2c44Sab196087 646d29b2c44Sab196087 return (ELFEDIT_CMDRET_MOD); 647d29b2c44Sab196087 } 648d29b2c44Sab196087 649d29b2c44Sab196087 650d29b2c44Sab196087 /* 651d29b2c44Sab196087 * Common body for the phdr: module commands. These commands 652d29b2c44Sab196087 * share a large amount of common behavior, so it is convenient 653d29b2c44Sab196087 * to centralize things and use the cmd argument to handle the 654d29b2c44Sab196087 * small differences. 655d29b2c44Sab196087 * 656d29b2c44Sab196087 * entry: 657d29b2c44Sab196087 * cmd - One of the PHDR_CMD_T_* constants listed above, specifying 658d29b2c44Sab196087 * which command to implement. 659d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments 660d29b2c44Sab196087 */ 661d29b2c44Sab196087 static elfedit_cmdret_t 662d29b2c44Sab196087 cmd_body(PHDR_CMD_T cmd, elfedit_obj_state_t *obj_state, 663d29b2c44Sab196087 int argc, const char *argv[]) 664d29b2c44Sab196087 { 665d29b2c44Sab196087 ARGSTATE argstate; 666d29b2c44Sab196087 Phdr *phdr; 667d29b2c44Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 668d29b2c44Sab196087 int do_autoprint = 1; 669d29b2c44Sab196087 670d29b2c44Sab196087 process_args(obj_state, argc, argv, cmd, &argstate); 671d29b2c44Sab196087 672d29b2c44Sab196087 /* If this is a printing request, print and return */ 673d29b2c44Sab196087 if (argstate.print_req) { 674d29b2c44Sab196087 print_phdr(cmd, 0, &argstate); 675d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE); 676d29b2c44Sab196087 } 677d29b2c44Sab196087 678d29b2c44Sab196087 679d29b2c44Sab196087 if (argstate.ndx_set) 680d29b2c44Sab196087 phdr = &argstate.obj_state->os_phdr[argstate.ndx]; 681d29b2c44Sab196087 682d29b2c44Sab196087 switch (cmd) { 683d29b2c44Sab196087 /* 684d29b2c44Sab196087 * PHDR_CMD_T_DUMP can't get here: It never has more than 685d29b2c44Sab196087 * one argument, and is handled above. 686d29b2c44Sab196087 */ 687d29b2c44Sab196087 688d29b2c44Sab196087 case PHDR_CMD_T_P_TYPE: 689d29b2c44Sab196087 { 690*4f680cc6SAli Bahrami Ehdr *ehdr = obj_state->os_ehdr; 691*4f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI]; 692*4f680cc6SAli Bahrami Half mach = ehdr->e_machine; 693d29b2c44Sab196087 Word p_type = elfedit_atoconst(argstate.argv[1], 694d29b2c44Sab196087 ELFEDIT_CONST_PT); 695d29b2c44Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 696d29b2c44Sab196087 697d29b2c44Sab196087 if (phdr->p_type == p_type) { 698d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 699d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), 700d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE), 701*4f680cc6SAli Bahrami conv_phdr_type(osabi, mach, phdr->p_type, 702d29b2c44Sab196087 0, &inv_buf1)); 703d29b2c44Sab196087 } else { 704d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 705d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG), 706d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_TYPE), 707*4f680cc6SAli Bahrami conv_phdr_type(osabi, mach, 708*4f680cc6SAli Bahrami phdr->p_type, 0, &inv_buf1), 709*4f680cc6SAli Bahrami conv_phdr_type(osabi, mach, 710*4f680cc6SAli Bahrami p_type, 0, &inv_buf2)); 711d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 712d29b2c44Sab196087 phdr->p_type = p_type; 713d29b2c44Sab196087 } 714d29b2c44Sab196087 } 715d29b2c44Sab196087 break; 716d29b2c44Sab196087 717d29b2c44Sab196087 case PHDR_CMD_T_P_OFFSET: 718d29b2c44Sab196087 { 719d29b2c44Sab196087 Off p_offset; 720d29b2c44Sab196087 721d29b2c44Sab196087 p_offset = elfedit_atoui(argstate.argv[1], NULL); 722d29b2c44Sab196087 if (phdr->p_offset == p_offset) { 723d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 724d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 725d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET), 726d29b2c44Sab196087 EC_XWORD(phdr->p_offset)); 727d29b2c44Sab196087 } else { 728d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 729d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 730d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_OFFSET), 731d29b2c44Sab196087 EC_XWORD(phdr->p_offset), 732d29b2c44Sab196087 EC_XWORD(p_offset)); 733d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 734d29b2c44Sab196087 phdr->p_offset = p_offset; 735d29b2c44Sab196087 } 736d29b2c44Sab196087 } 737d29b2c44Sab196087 break; 738d29b2c44Sab196087 739d29b2c44Sab196087 case PHDR_CMD_T_P_VADDR: 740d29b2c44Sab196087 { 741d29b2c44Sab196087 Addr p_vaddr = elfedit_atoui(argstate.argv[1], NULL); 742d29b2c44Sab196087 743d29b2c44Sab196087 if (phdr->p_vaddr == p_vaddr) { 744d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 745d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 746d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR), 747d29b2c44Sab196087 EC_ADDR(phdr->p_vaddr)); 748d29b2c44Sab196087 } else { 749d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 750d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 751d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_VADDR), 752d29b2c44Sab196087 EC_ADDR(phdr->p_vaddr), EC_ADDR(p_vaddr)); 753d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 754d29b2c44Sab196087 phdr->p_vaddr = p_vaddr; 755d29b2c44Sab196087 } 756d29b2c44Sab196087 } 757d29b2c44Sab196087 break; 758d29b2c44Sab196087 759d29b2c44Sab196087 case PHDR_CMD_T_P_PADDR: 760d29b2c44Sab196087 { 761d29b2c44Sab196087 Addr p_paddr = elfedit_atoui(argstate.argv[1], NULL); 762d29b2c44Sab196087 763d29b2c44Sab196087 if (phdr->p_paddr == p_paddr) { 764d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 765d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 766d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR), 767d29b2c44Sab196087 EC_ADDR(phdr->p_paddr)); 768d29b2c44Sab196087 } else { 769d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 770d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 771d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_PADDR), 772d29b2c44Sab196087 EC_ADDR(phdr->p_paddr), EC_ADDR(p_paddr)); 773d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 774d29b2c44Sab196087 phdr->p_paddr = p_paddr; 775d29b2c44Sab196087 } 776d29b2c44Sab196087 } 777d29b2c44Sab196087 break; 778d29b2c44Sab196087 779d29b2c44Sab196087 case PHDR_CMD_T_P_FILESZ: 780d29b2c44Sab196087 { 781d29b2c44Sab196087 Xword p_filesz = elfedit_atoui(argstate.argv[1], NULL); 782d29b2c44Sab196087 783d29b2c44Sab196087 if (phdr->p_filesz == p_filesz) { 784d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 785d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 786d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ), 787d29b2c44Sab196087 EC_XWORD(phdr->p_filesz)); 788d29b2c44Sab196087 } else { 789d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 790d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 791d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FILESZ), 792d29b2c44Sab196087 EC_XWORD(phdr->p_filesz), 793d29b2c44Sab196087 EC_XWORD(p_filesz)); 794d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 795d29b2c44Sab196087 phdr->p_filesz = p_filesz; 796d29b2c44Sab196087 } 797d29b2c44Sab196087 } 798d29b2c44Sab196087 break; 799d29b2c44Sab196087 800d29b2c44Sab196087 case PHDR_CMD_T_P_MEMSZ: 801d29b2c44Sab196087 { 802d29b2c44Sab196087 Xword p_memsz = elfedit_atoui(argstate.argv[1], NULL); 803d29b2c44Sab196087 804d29b2c44Sab196087 if (phdr->p_memsz == p_memsz) { 805d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 806d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 807d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ), 808d29b2c44Sab196087 EC_XWORD(phdr->p_memsz)); 809d29b2c44Sab196087 } else { 810d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 811d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 812d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_MEMSZ), 813d29b2c44Sab196087 EC_XWORD(phdr->p_memsz), 814d29b2c44Sab196087 EC_XWORD(p_memsz)); 815d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 816d29b2c44Sab196087 phdr->p_memsz = p_memsz; 817d29b2c44Sab196087 } 818d29b2c44Sab196087 } 819d29b2c44Sab196087 break; 820d29b2c44Sab196087 821d29b2c44Sab196087 case PHDR_CMD_T_P_FLAGS: 822d29b2c44Sab196087 { 823*4f680cc6SAli Bahrami Ehdr *ehdr = obj_state->os_ehdr; 824*4f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI]; 825d29b2c44Sab196087 Conv_phdr_flags_buf_t buf1, buf2; 826d29b2c44Sab196087 Word p_flags = 0; 827d29b2c44Sab196087 int i; 828d29b2c44Sab196087 829d29b2c44Sab196087 /* Collect the flag arguments */ 830d29b2c44Sab196087 for (i = 1; i < argstate.argc; i++) 831d29b2c44Sab196087 p_flags |= 832d29b2c44Sab196087 (Word) elfedit_atoconst(argstate.argv[i], 833d29b2c44Sab196087 ELFEDIT_CONST_PF); 834d29b2c44Sab196087 835d29b2c44Sab196087 /* Complement the value? */ 836d29b2c44Sab196087 if (argstate.optmask & PHDR_OPT_F_CMP) 837d29b2c44Sab196087 p_flags = ~p_flags; 838d29b2c44Sab196087 839d29b2c44Sab196087 /* Perform any requested bit operations */ 840d29b2c44Sab196087 if (argstate.optmask & PHDR_OPT_F_AND) 841d29b2c44Sab196087 p_flags &= phdr->p_flags; 842d29b2c44Sab196087 else if (argstate.optmask & PHDR_OPT_F_OR) 843d29b2c44Sab196087 p_flags |= phdr->p_flags; 844d29b2c44Sab196087 845d29b2c44Sab196087 /* Set the value */ 846d29b2c44Sab196087 if (phdr->p_flags == p_flags) { 847d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 848d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), 849d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS), 850*4f680cc6SAli Bahrami conv_phdr_flags(osabi, phdr->p_flags, 851*4f680cc6SAli Bahrami 0, &buf1)); 852d29b2c44Sab196087 } else { 853d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 854d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG), 855d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_FLAGS), 856*4f680cc6SAli Bahrami conv_phdr_flags(osabi, phdr->p_flags, 857*4f680cc6SAli Bahrami 0, &buf1), 858*4f680cc6SAli Bahrami conv_phdr_flags(osabi, p_flags, 0, &buf2)); 859d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 860d29b2c44Sab196087 phdr->p_flags = p_flags; 861d29b2c44Sab196087 } 862d29b2c44Sab196087 } 863d29b2c44Sab196087 break; 864d29b2c44Sab196087 865d29b2c44Sab196087 case PHDR_CMD_T_P_ALIGN: 866d29b2c44Sab196087 { 867d29b2c44Sab196087 Xword p_align = elfedit_atoui(argstate.argv[1], NULL); 868d29b2c44Sab196087 869d29b2c44Sab196087 if (phdr->p_align == p_align) { 870d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 871d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 872d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN), 873d29b2c44Sab196087 EC_XWORD(phdr->p_align)); 874d29b2c44Sab196087 } else { 875d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 876d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 877d29b2c44Sab196087 argstate.ndx, MSG_ORIG(MSG_CMD_P_ALIGN), 878d29b2c44Sab196087 EC_XWORD(phdr->p_align), 879d29b2c44Sab196087 EC_XWORD(p_align)); 880d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 881d29b2c44Sab196087 phdr->p_align = p_align; 882d29b2c44Sab196087 } 883d29b2c44Sab196087 } 884d29b2c44Sab196087 break; 885d29b2c44Sab196087 886d29b2c44Sab196087 case PHDR_CMD_T_INTERP: 887d29b2c44Sab196087 ret = cmd_body_set_interp(&argstate); 888d29b2c44Sab196087 break; 889d29b2c44Sab196087 890d29b2c44Sab196087 case PHDR_CMD_T_DELETE: 891d29b2c44Sab196087 { 892d29b2c44Sab196087 Word cnt = (argstate.argc == 1) ? 1 : 893d29b2c44Sab196087 (Word) elfedit_atoui_range(argstate.argv[1], 894d29b2c44Sab196087 MSG_ORIG(MSG_STR_COUNT), 1, 895d29b2c44Sab196087 obj_state->os_phnum - argstate.ndx, NULL); 896d29b2c44Sab196087 897d29b2c44Sab196087 elfedit_array_elts_delete(MSG_ORIG(MSG_MOD_NAME), 898d29b2c44Sab196087 obj_state->os_phdr, sizeof (Phdr), 899d29b2c44Sab196087 obj_state->os_phnum, argstate.ndx, cnt); 900d29b2c44Sab196087 do_autoprint = 0; 901d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 902d29b2c44Sab196087 } 903d29b2c44Sab196087 break; 904d29b2c44Sab196087 905d29b2c44Sab196087 case PHDR_CMD_T_MOVE: 906d29b2c44Sab196087 { 907d29b2c44Sab196087 Phdr save; 908d29b2c44Sab196087 Word cnt; 909d29b2c44Sab196087 Word dstndx; 910d29b2c44Sab196087 911d29b2c44Sab196087 do_autoprint = 0; 912d29b2c44Sab196087 dstndx = (Word) 913d29b2c44Sab196087 elfedit_atoui_range(argstate.argv[1], 914d29b2c44Sab196087 MSG_ORIG(MSG_STR_DST_INDEX), 0, 915d29b2c44Sab196087 obj_state->os_phnum - 1, NULL); 916d29b2c44Sab196087 if (argstate.argc == 2) { 917d29b2c44Sab196087 cnt = 1; 918d29b2c44Sab196087 } else { 919d29b2c44Sab196087 cnt = (Word) elfedit_atoui_range( 920d29b2c44Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT), 921d29b2c44Sab196087 1, obj_state->os_phnum, NULL); 922d29b2c44Sab196087 } 923d29b2c44Sab196087 elfedit_array_elts_move(MSG_ORIG(MSG_MOD_NAME), 924d29b2c44Sab196087 obj_state->os_phdr, sizeof (save), 925d29b2c44Sab196087 obj_state->os_phnum, argstate.ndx, dstndx, 926d29b2c44Sab196087 cnt, &save); 927d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD; 928d29b2c44Sab196087 } 929d29b2c44Sab196087 break; 930d29b2c44Sab196087 } 931d29b2c44Sab196087 932d29b2c44Sab196087 /* 933d29b2c44Sab196087 * If we modified the section header array, tell libelf. 934d29b2c44Sab196087 */ 935d29b2c44Sab196087 if (ret == ELFEDIT_CMDRET_MOD) 936d29b2c44Sab196087 elfedit_modified_phdr(obj_state); 937d29b2c44Sab196087 938d29b2c44Sab196087 /* Do autoprint */ 939d29b2c44Sab196087 if (do_autoprint) 940d29b2c44Sab196087 print_phdr(cmd, 1, &argstate); 941d29b2c44Sab196087 942d29b2c44Sab196087 return (ret); 943d29b2c44Sab196087 } 944d29b2c44Sab196087 945d29b2c44Sab196087 946d29b2c44Sab196087 947d29b2c44Sab196087 /* 948d29b2c44Sab196087 * Command completion functions for the various commands 949d29b2c44Sab196087 */ 950d29b2c44Sab196087 951d29b2c44Sab196087 /* 952d29b2c44Sab196087 * A number of the commands accept a PT_ constant as their first 953d29b2c44Sab196087 * argument as long as the -phndx option is not used. 954d29b2c44Sab196087 */ 955d29b2c44Sab196087 /*ARGSUSED*/ 956d29b2c44Sab196087 static void 957d29b2c44Sab196087 cpl_1starg_pt(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 958d29b2c44Sab196087 const char *argv[], int num_opt) 959d29b2c44Sab196087 { 960d29b2c44Sab196087 int i; 961d29b2c44Sab196087 962d29b2c44Sab196087 for (i = 0; i < num_opt; i++) 963d29b2c44Sab196087 if (strcmp(MSG_ORIG(MSG_STR_MINUS_PHNDX), argv[i]) == 0) 964d29b2c44Sab196087 return; 965d29b2c44Sab196087 966d29b2c44Sab196087 if (argc == (num_opt + 1)) 967d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT); 968d29b2c44Sab196087 } 969d29b2c44Sab196087 970d29b2c44Sab196087 /*ARGSUSED*/ 971d29b2c44Sab196087 static void 972d29b2c44Sab196087 cpl_p_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 973d29b2c44Sab196087 const char *argv[], int num_opt) 974d29b2c44Sab196087 { 975d29b2c44Sab196087 /* The first argument follows the standard rules */ 976d29b2c44Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt); 977d29b2c44Sab196087 978d29b2c44Sab196087 /* The second argument can be a PT_ value */ 979d29b2c44Sab196087 if (argc == (num_opt + 2)) 980d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PT); 981d29b2c44Sab196087 } 982d29b2c44Sab196087 983d29b2c44Sab196087 984d29b2c44Sab196087 /*ARGSUSED*/ 985d29b2c44Sab196087 static void 986d29b2c44Sab196087 cpl_p_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 987d29b2c44Sab196087 const char *argv[], int num_opt) 988d29b2c44Sab196087 { 989d29b2c44Sab196087 /* The first argument follows the standard rules */ 990d29b2c44Sab196087 cpl_1starg_pt(obj_state, cpldata, argc, argv, num_opt); 991d29b2c44Sab196087 992d29b2c44Sab196087 /* The second and following arguments can be an PF_ value */ 993d29b2c44Sab196087 if (argc >= (num_opt + 2)) 994d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_PF); 995d29b2c44Sab196087 } 996d29b2c44Sab196087 997d29b2c44Sab196087 998d29b2c44Sab196087 999d29b2c44Sab196087 /* 1000d29b2c44Sab196087 * Implementation functions for the commands 1001d29b2c44Sab196087 */ 1002d29b2c44Sab196087 static elfedit_cmdret_t 1003d29b2c44Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1004d29b2c44Sab196087 { 1005d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_DUMP, obj_state, argc, argv)); 1006d29b2c44Sab196087 } 1007d29b2c44Sab196087 1008d29b2c44Sab196087 static elfedit_cmdret_t 1009d29b2c44Sab196087 cmd_p_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1010d29b2c44Sab196087 { 1011d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_TYPE, obj_state, argc, argv)); 1012d29b2c44Sab196087 } 1013d29b2c44Sab196087 1014d29b2c44Sab196087 static elfedit_cmdret_t 1015d29b2c44Sab196087 cmd_p_offset(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1016d29b2c44Sab196087 { 1017d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_OFFSET, obj_state, argc, argv)); 1018d29b2c44Sab196087 } 1019d29b2c44Sab196087 1020d29b2c44Sab196087 static elfedit_cmdret_t 1021d29b2c44Sab196087 cmd_p_vaddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1022d29b2c44Sab196087 { 1023d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_VADDR, obj_state, argc, argv)); 1024d29b2c44Sab196087 } 1025d29b2c44Sab196087 1026d29b2c44Sab196087 static elfedit_cmdret_t 1027d29b2c44Sab196087 cmd_p_paddr(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1028d29b2c44Sab196087 { 1029d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_PADDR, obj_state, argc, argv)); 1030d29b2c44Sab196087 } 1031d29b2c44Sab196087 1032d29b2c44Sab196087 static elfedit_cmdret_t 1033d29b2c44Sab196087 cmd_p_filesz(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1034d29b2c44Sab196087 { 1035d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_FILESZ, obj_state, argc, argv)); 1036d29b2c44Sab196087 } 1037d29b2c44Sab196087 1038d29b2c44Sab196087 static elfedit_cmdret_t 1039d29b2c44Sab196087 cmd_p_memsz(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1040d29b2c44Sab196087 { 1041d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_MEMSZ, obj_state, argc, argv)); 1042d29b2c44Sab196087 } 1043d29b2c44Sab196087 1044d29b2c44Sab196087 static elfedit_cmdret_t 1045d29b2c44Sab196087 cmd_p_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1046d29b2c44Sab196087 { 1047d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_FLAGS, obj_state, argc, argv)); 1048d29b2c44Sab196087 } 1049d29b2c44Sab196087 1050d29b2c44Sab196087 static elfedit_cmdret_t 1051d29b2c44Sab196087 cmd_p_align(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1052d29b2c44Sab196087 { 1053d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_P_ALIGN, obj_state, argc, argv)); 1054d29b2c44Sab196087 } 1055d29b2c44Sab196087 1056d29b2c44Sab196087 static elfedit_cmdret_t 1057d29b2c44Sab196087 cmd_interp(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1058d29b2c44Sab196087 { 1059d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_INTERP, obj_state, argc, argv)); 1060d29b2c44Sab196087 } 1061d29b2c44Sab196087 1062d29b2c44Sab196087 static elfedit_cmdret_t 1063d29b2c44Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1064d29b2c44Sab196087 { 1065d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_DELETE, obj_state, argc, argv)); 1066d29b2c44Sab196087 } 1067d29b2c44Sab196087 1068d29b2c44Sab196087 static elfedit_cmdret_t 1069d29b2c44Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1070d29b2c44Sab196087 { 1071d29b2c44Sab196087 return (cmd_body(PHDR_CMD_T_MOVE, obj_state, argc, argv)); 1072d29b2c44Sab196087 } 1073d29b2c44Sab196087 1074d29b2c44Sab196087 1075d29b2c44Sab196087 /*ARGSUSED*/ 1076d29b2c44Sab196087 elfedit_module_t * 1077d29b2c44Sab196087 elfedit_init(elfedit_module_version_t version) 1078d29b2c44Sab196087 { 1079d29b2c44Sab196087 /* Multiple commands accept a standard set of options */ 1080d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_std[] = { 1081d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1082d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1083d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 1084d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 1085d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 1086d29b2c44Sab196087 PHDR_OPT_F_PHNDX, 0 }, 1087d29b2c44Sab196087 { NULL } 1088d29b2c44Sab196087 }; 1089d29b2c44Sab196087 1090d29b2c44Sab196087 /* For commands that only accept -phndx */ 1091d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_minus_phndx[] = { 1092d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 1093d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 1094d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 1095d29b2c44Sab196087 PHDR_OPT_F_PHNDX, 0 }, 1096d29b2c44Sab196087 { NULL } 1097d29b2c44Sab196087 }; 1098d29b2c44Sab196087 1099d29b2c44Sab196087 1100d29b2c44Sab196087 /* phdr:dump */ 1101d29b2c44Sab196087 static const char *name_dump[] = { 1102d29b2c44Sab196087 MSG_ORIG(MSG_CMD_DUMP), 1103d29b2c44Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 1104d29b2c44Sab196087 NULL 1105d29b2c44Sab196087 }; 1106d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_dump[] = { 1107d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1108d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1109d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1110d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1111d29b2c44Sab196087 { NULL } 1112d29b2c44Sab196087 }; 1113d29b2c44Sab196087 1114d29b2c44Sab196087 /* phdr:p_type */ 1115d29b2c44Sab196087 static const char *name_p_type[] = { MSG_ORIG(MSG_CMD_P_TYPE), NULL }; 1116d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_type[] = { 1117d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1118d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1119d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1120d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1121d29b2c44Sab196087 { MSG_ORIG(MSG_STR_TYPE), 1122d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_TYPE_TYPE) */ 1123d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_TYPE_TYPE), 1124d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1125d29b2c44Sab196087 { NULL } 1126d29b2c44Sab196087 }; 1127d29b2c44Sab196087 1128d29b2c44Sab196087 /* phdr:p_offset */ 1129d29b2c44Sab196087 static const char *name_p_offset[] = { MSG_ORIG(MSG_CMD_P_OFFSET), 1130d29b2c44Sab196087 NULL }; 1131d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_offset[] = { 1132d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1133d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1134d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1135d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1136d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1137d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_OFFSET_VALUE) */ 1138d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_OFFSET_VALUE), 1139d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1140d29b2c44Sab196087 { NULL } 1141d29b2c44Sab196087 }; 1142d29b2c44Sab196087 1143d29b2c44Sab196087 /* phdr:p_vaddr */ 1144d29b2c44Sab196087 static const char *name_p_vaddr[] = { MSG_ORIG(MSG_CMD_P_VADDR), 1145d29b2c44Sab196087 NULL }; 1146d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_vaddr[] = { 1147d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1148d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1149d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1150d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1151d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ADDR), 1152d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_VADDR_ADDR) */ 1153d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_VADDR_ADDR), 1154d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1155d29b2c44Sab196087 { NULL } 1156d29b2c44Sab196087 }; 1157d29b2c44Sab196087 1158d29b2c44Sab196087 /* phdr:p_paddr */ 1159d29b2c44Sab196087 static const char *name_p_paddr[] = { MSG_ORIG(MSG_CMD_P_PADDR), 1160d29b2c44Sab196087 NULL }; 1161d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_paddr[] = { 1162d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1163d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1164d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1165d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1166d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ADDR), 1167d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_PADDR_ADDR) */ 1168d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_PADDR_ADDR), 1169d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1170d29b2c44Sab196087 { NULL } 1171d29b2c44Sab196087 }; 1172d29b2c44Sab196087 1173d29b2c44Sab196087 /* phdr:p_filesz */ 1174d29b2c44Sab196087 static const char *name_p_filesz[] = { MSG_ORIG(MSG_CMD_P_FILESZ), 1175d29b2c44Sab196087 NULL }; 1176d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_filesz[] = { 1177d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1178d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1179d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1180d29b2c44Sab196087 { MSG_ORIG(MSG_STR_SIZE), 1181d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_FILESZ_SIZE) */ 1182d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FILESZ_SIZE), 1183d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1184d29b2c44Sab196087 { NULL } 1185d29b2c44Sab196087 }; 1186d29b2c44Sab196087 1187d29b2c44Sab196087 /* phdr:p_memsz */ 1188d29b2c44Sab196087 static const char *name_p_memsz[] = { MSG_ORIG(MSG_CMD_P_MEMSZ), 1189d29b2c44Sab196087 NULL }; 1190d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_memsz[] = { 1191d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1192d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1193d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1194d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1195d29b2c44Sab196087 { MSG_ORIG(MSG_STR_SIZE), 1196d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_MEMSZ_SIZE) */ 1197d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_MEMSZ_SIZE), 1198d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1199d29b2c44Sab196087 { NULL } 1200d29b2c44Sab196087 }; 1201d29b2c44Sab196087 1202d29b2c44Sab196087 /* shdr:p_flags */ 1203d29b2c44Sab196087 static const char *name_p_flags[] = { 1204d29b2c44Sab196087 MSG_ORIG(MSG_CMD_P_FLAGS), NULL }; 1205d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_p_flags[] = { 1206d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL, 1207d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_AND, PHDR_OPT_F_OR }, 1208d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL, 1209d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_CMP, 0 }, 1210d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_PHNDX), 1211d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_PHNDX) */ 1212d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_PHNDX), 0, 1213d29b2c44Sab196087 PHDR_OPT_F_PHNDX, 0 }, 1214d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1215d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1216d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL, 1217d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, PHDR_OPT_F_OR, PHDR_OPT_F_AND }, 1218d29b2c44Sab196087 { NULL } 1219d29b2c44Sab196087 }; 1220d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_flags[] = { 1221d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1222d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1223d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1224d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1225d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1226d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_FLAGS_VALUE) */ 1227d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_FLAGS_VALUE), 1228d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 1229d29b2c44Sab196087 { NULL } 1230d29b2c44Sab196087 }; 1231d29b2c44Sab196087 1232d29b2c44Sab196087 /* phdr:p_align */ 1233d29b2c44Sab196087 static const char *name_p_align[] = { MSG_ORIG(MSG_CMD_P_ALIGN), 1234d29b2c44Sab196087 NULL }; 1235d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_p_align[] = { 1236d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1237d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1238d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1239d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1240d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ALIGN), 1241d29b2c44Sab196087 /* MSG_INTL(MSG_A2_P_ALIGN_ALIGN) */ 1242d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_P_ALIGN_ALIGN), 1243d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1244d29b2c44Sab196087 { NULL } 1245d29b2c44Sab196087 }; 1246d29b2c44Sab196087 1247d29b2c44Sab196087 /* phdr:interp */ 1248d29b2c44Sab196087 static const char *name_interp[] = { MSG_ORIG(MSG_CMD_INTERP), NULL }; 1249d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_interp[] = { 1250d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1251d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1252d29b2c44Sab196087 { NULL } 1253d29b2c44Sab196087 }; 1254d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_interp[] = { 1255d29b2c44Sab196087 { MSG_ORIG(MSG_STR_NEWPATH), 1256d29b2c44Sab196087 /* MSG_INTL(MSG_A1_INTERP_NEWPATH) */ 1257d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_INTERP_NEWPATH), 1258d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1259d29b2c44Sab196087 { NULL } 1260d29b2c44Sab196087 }; 1261d29b2c44Sab196087 1262d29b2c44Sab196087 /* phdr:delete */ 1263d29b2c44Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL }; 1264d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_delete[] = { 1265d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1266d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1267d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1268*4f680cc6SAli Bahrami 0 }, 1269d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT), 1270d29b2c44Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */ 1271d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT), 1272d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1273d29b2c44Sab196087 { NULL } 1274d29b2c44Sab196087 }; 1275d29b2c44Sab196087 1276d29b2c44Sab196087 /* phdr:move */ 1277d29b2c44Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL }; 1278d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_move[] = { 1279d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELEMENT), 1280d29b2c44Sab196087 /* MSG_INTL(MSG_A1_ELEMENT) */ 1281d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_ELEMENT), 1282d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1283d29b2c44Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX), 1284d29b2c44Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */ 1285d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX), 1286d29b2c44Sab196087 0 }, 1287d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT), 1288d29b2c44Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */ 1289d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT), 1290d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT }, 1291d29b2c44Sab196087 { NULL } 1292d29b2c44Sab196087 }; 1293d29b2c44Sab196087 1294d29b2c44Sab196087 static elfedit_cmd_t cmds[] = { 1295d29b2c44Sab196087 /* phdr:dump */ 1296d29b2c44Sab196087 { cmd_dump, cpl_1starg_pt, name_dump, 1297d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */ 1298d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 1299d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */ 1300d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 1301d29b2c44Sab196087 opt_minus_phndx, arg_dump }, 1302d29b2c44Sab196087 1303d29b2c44Sab196087 /* phdr:p_type */ 1304d29b2c44Sab196087 { cmd_p_type, cpl_p_type, name_p_type, 1305d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_TYPE) */ 1306d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_TYPE), 1307d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_TYPE) */ 1308d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_TYPE), 1309d29b2c44Sab196087 opt_std, arg_p_type }, 1310d29b2c44Sab196087 1311d29b2c44Sab196087 /* phdr:p_offset */ 1312d29b2c44Sab196087 { cmd_p_offset, cpl_1starg_pt, name_p_offset, 1313d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_OFFSET) */ 1314d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_OFFSET), 1315d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_OFFSET) */ 1316d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_OFFSET), 1317d29b2c44Sab196087 opt_std, arg_p_offset }, 1318d29b2c44Sab196087 1319d29b2c44Sab196087 /* phdr:p_vaddr */ 1320d29b2c44Sab196087 { cmd_p_vaddr, cpl_1starg_pt, name_p_vaddr, 1321d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_VADDR) */ 1322d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_VADDR), 1323d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_VADDR) */ 1324d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_VADDR), 1325d29b2c44Sab196087 opt_std, arg_p_vaddr }, 1326d29b2c44Sab196087 1327d29b2c44Sab196087 /* phdr:p_paddr */ 1328d29b2c44Sab196087 { cmd_p_paddr, cpl_1starg_pt, name_p_paddr, 1329d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_PADDR) */ 1330d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_PADDR), 1331d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_PADDR) */ 1332d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_PADDR), 1333d29b2c44Sab196087 opt_std, arg_p_paddr }, 1334d29b2c44Sab196087 1335d29b2c44Sab196087 /* phdr:p_filesz */ 1336d29b2c44Sab196087 { cmd_p_filesz, cpl_1starg_pt, name_p_filesz, 1337d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_FILESZ) */ 1338d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FILESZ), 1339d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_FILESZ) */ 1340d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FILESZ), 1341d29b2c44Sab196087 opt_std, arg_p_filesz }, 1342d29b2c44Sab196087 1343d29b2c44Sab196087 /* phdr:p_memsz */ 1344d29b2c44Sab196087 { cmd_p_memsz, cpl_1starg_pt, name_p_memsz, 1345d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_MEMSZ) */ 1346d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_MEMSZ), 1347d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_MEMSZ) */ 1348d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_MEMSZ), 1349d29b2c44Sab196087 opt_std, arg_p_memsz }, 1350d29b2c44Sab196087 1351d29b2c44Sab196087 /* phdr:p_flags */ 1352d29b2c44Sab196087 { cmd_p_flags, cpl_p_flags, name_p_flags, 1353d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_FLAGS) */ 1354d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_FLAGS), 1355d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_FLAGS) */ 1356d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_FLAGS), 1357d29b2c44Sab196087 opt_p_flags, arg_p_flags }, 1358d29b2c44Sab196087 1359d29b2c44Sab196087 /* phdr:p_align */ 1360d29b2c44Sab196087 { cmd_p_align, cpl_1starg_pt, name_p_align, 1361d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_P_ALIGN) */ 1362d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_P_ALIGN), 1363d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_P_ALIGN) */ 1364d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_P_ALIGN), 1365d29b2c44Sab196087 opt_std, arg_p_align }, 1366d29b2c44Sab196087 1367d29b2c44Sab196087 /* phdr:interp */ 1368d29b2c44Sab196087 { cmd_interp, NULL, name_interp, 1369d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_INTERP) */ 1370d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_INTERP), 1371d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_INTERP) */ 1372d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_INTERP), 1373d29b2c44Sab196087 opt_interp, arg_interp }, 1374d29b2c44Sab196087 1375d29b2c44Sab196087 /* phdr:delete */ 1376d29b2c44Sab196087 { cmd_delete, cpl_1starg_pt, name_delete, 1377d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */ 1378d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE), 1379d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */ 1380d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE), 1381d29b2c44Sab196087 opt_minus_phndx, arg_delete }, 1382d29b2c44Sab196087 1383d29b2c44Sab196087 /* phdr:move */ 1384d29b2c44Sab196087 { cmd_move, cpl_1starg_pt, name_move, 1385d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */ 1386d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE), 1387d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */ 1388d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE), 1389d29b2c44Sab196087 opt_minus_phndx, arg_move }, 1390d29b2c44Sab196087 1391d29b2c44Sab196087 { NULL } 1392d29b2c44Sab196087 }; 1393d29b2c44Sab196087 1394d29b2c44Sab196087 static elfedit_module_t module = { 1395d29b2c44Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 1396d29b2c44Sab196087 /* MSG_INTL(MSG_MOD_DESC) */ 1397d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC), 1398d29b2c44Sab196087 cmds, mod_i18nhdl_to_str }; 1399d29b2c44Sab196087 1400d29b2c44Sab196087 return (&module); 1401d29b2c44Sab196087 } 1402