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