/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include /* * This module handles changes to the ELF header */ /* * This module uses shared code for several of the commands. * It is sometimes necessary to know which specific command * is active. */ typedef enum { /* Dump command, used as module default to display ELF header */ EHDR_CMD_T_DUMP = 0, /* ehdr:dump */ /* Commands that correspond directly to ELF header fields */ EHDR_CMD_T_E_IDENT = 1, /* ehdr:e_ident */ EHDR_CMD_T_E_TYPE = 2, /* ehdr:e_type */ EHDR_CMD_T_E_MACHINE = 3, /* ehdr:e_machine */ EHDR_CMD_T_E_VERSION = 4, /* ehdr:e_version */ EHDR_CMD_T_E_ENTRY = 5, /* ehdr:e_entry */ EHDR_CMD_T_E_PHOFF = 6, /* ehdr:e_phoff */ EHDR_CMD_T_E_SHOFF = 7, /* ehdr:e_shoff */ EHDR_CMD_T_E_FLAGS = 8, /* ehdr:e_flags */ EHDR_CMD_T_E_EHSIZE = 9, /* ehdr:e_ehsize */ EHDR_CMD_T_E_PHENTSIZE = 10, /* ehdr:e_phentsize */ EHDR_CMD_T_E_PHNUM = 11, /* ehdr:e_phnum */ EHDR_CMD_T_E_SHENTSIZE = 12, /* ehdr:e_shentsize */ EHDR_CMD_T_E_SHNUM = 13, /* ehdr:e_shnum */ EHDR_CMD_T_E_SHSTRNDX = 14, /* ehdr:e_shstrndx */ /* Commands that correspond to the e_ident[] array in ELF hdr */ EHDR_CMD_T_EI_MAG0 = 15, /* ehdr:ei_mag0 */ EHDR_CMD_T_EI_MAG1 = 16, /* ehdr:ei_mag1 */ EHDR_CMD_T_EI_MAG2 = 17, /* ehdr:ei_mag2 */ EHDR_CMD_T_EI_MAG3 = 18, /* ehdr:ei_mag3 */ EHDR_CMD_T_EI_CLASS = 19, /* ehdr:ei_class */ EHDR_CMD_T_EI_DATA = 20, /* ehdr:ei_data */ EHDR_CMD_T_EI_VERSION = 21, /* ehdr:ei_version */ EHDR_CMD_T_EI_OSABI = 22, /* ehdr:ei_osabi */ EHDR_CMD_T_EI_ABIVERSION = 23 /* ehdr:ei_abiversion */ } EHDR_CMD_T; #ifndef _ELF64 /* * We supply this function for the msg module */ const char * _ehdr_msg(Msg mid) { return (gettext(MSG_ORIG(mid))); } #endif /* * This function is supplied to elfedit through our elfedit_module_t * definition. It translates the opaque elfedit_i18nhdl_t handles * in our module interface into the actual strings for elfedit to * use. * * note: * This module uses Msg codes for its i18n handle type. * So the translation is simply to use MSG_INTL() to turn * it into a string and return it. */ static const char * mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) { Msg msg = (Msg)hdl; return (MSG_INTL(msg)); } /* * The ehdr_opt_t enum specifies a bit value for every optional * argument allowed by a command in this module. */ typedef enum { EHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */ EHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */ EHDR_OPT_F_OR = 4, /* -or: OR (|) values to dest */ EHDR_OPT_F_SHNDX = 8, /* -shndx: sec argument is index of */ /* section, not name */ EHDR_OPT_F_SHTYP = 16 /* -shtyp: sec argument is type of */ /* section, not name */ } ehdr_opt_t; /* * A variable of type ARGSTATE is used by each command to maintain * information about the arguments and related things. It is * initialized by process_args(), and used by the other routines. */ typedef struct { elfedit_obj_state_t *obj_state; ehdr_opt_t optmask; /* Mask of options used */ int argc; /* # of plain arguments */ const char **argv; /* Plain arguments */ } ARGSTATE; /* * Standard argument processing for ehdr module * * entry * obj_state, argc, argv - Standard command arguments * argstate - Address of ARGSTATE block to be initialized * * exit: * On success, *argstate is initialized. On error, * an error is issued and this routine does not return. */ static void process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], ARGSTATE *argstate) { elfedit_getopt_state_t getopt_state; elfedit_getopt_ret_t *getopt_ret; bzero(argstate, sizeof (*argstate)); argstate->obj_state = obj_state; elfedit_getopt_init(&getopt_state, &argc, &argv); /* Add each new option to the options mask */ while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) argstate->optmask |= getopt_ret->gor_idmask; /* If there may be an arbitrary amount of output, use a pager */ if (argc == 0) elfedit_pager_init(); /* Return the updated values of argc/argv */ argstate->argc = argc; argstate->argv = argv; } /* * Format the given magic number byte into a buffer * * entry: * value - Value of the magic value byte given by * ehdr->ei_ident[EI_MAG?] */ static const char * conv_magic_value(int value) { /* * This routine can be called twice within a single C statement, * so we use alternating buffers on each call to allow this * without requiring the caller to supply a buffer (the size of * which they don't know). */ static char buf1[20]; static char buf2[20]; static char *buf; /* Switch buffers */ buf = (buf == buf1) ? buf2 : buf1; if (isprint(value)) (void) snprintf(buf, sizeof (buf1), MSG_ORIG(MSG_FMT_HEXNUM_QCHR), value, value); else (void) snprintf(buf, sizeof (buf1), MSG_ORIG(MSG_FMT_HEXNUM), value); return (buf); } /* * Print ELF header values, taking the calling command, and output style * into account. * * entry: * cmd - EHDR_CMD_T_* value giving identify of caller * e_ident_ndx - Ignored unless cmd is EHDR_CMD_T_E_IDENT. In IDENT * case, index of item in e_ident[] array to display, or * -1 to display the entire array. * autoprint - If True, output is only produced if the elfedit * autoprint flag is set. If False, output is always produced. * argstate - Argument state block */ static void print_ehdr(EHDR_CMD_T cmd, int e_ident_ndx, int autoprint, ARGSTATE *argstate) { elfedit_outstyle_t outstyle; Conv_fmt_flags_t flags_fmt_flags = 0; Ehdr *ehdr; int c; Conv_inv_buf_t inv_buf; if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0)) return; /* * Pick an output style. ehdr:dump is required to use the default * style. The other commands use the current output style. */ if (cmd == EHDR_CMD_T_DUMP) { outstyle = ELFEDIT_OUTSTYLE_DEFAULT; } else { outstyle = elfedit_outstyle(); /* * When the caller specifies the simple output style, * omit the brackets from around the values. */ if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) flags_fmt_flags = CONV_FMT_NOBKT; /* * For things that show a single header item, switch * from default to simple mode. */ if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) && ((cmd != EHDR_CMD_T_E_IDENT) || (e_ident_ndx != -1))) outstyle = ELFEDIT_OUTSTYLE_SIMPLE; } ehdr = argstate->obj_state->os_ehdr; /* * If doing default output, use elfdump style where we * show the full ELF header. In this case, the command * that called us doesn't matter. This can only happen * from ehdr:dump or ehdr:e_ident/ */ if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { const char *ndx, *value; char ndx_buf[64], value_buf[20]; int i; if (cmd == EHDR_CMD_T_DUMP) { Elf_ehdr(NULL, ehdr, argstate->obj_state->os_secarr[0].sec_shdr); elfedit_printf(MSG_ORIG(MSG_STR_NL)); } /* * Elf_ehdr() does not display all of e_ident[], so we * augment by displaying the entire array separately. */ elfedit_printf(MSG_ORIG(MSG_STR_EIDENT_HDR)); for (i = 0; i < EI_NIDENT; i++) { ndx = value = NULL; switch (i) { case EI_MAG0: case EI_MAG1: case EI_MAG2: case EI_MAG3: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, i, 1); value = conv_magic_value(ehdr->e_ident[i]); break; case EI_CLASS: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_CLASS, 1); value = conv_ehdr_class(ehdr->e_ident[EI_CLASS], 0, &inv_buf); break; case EI_DATA: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_DATA, 1); value = conv_ehdr_data(ehdr->e_ident[EI_DATA], 0, &inv_buf); break; case EI_VERSION: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_VERSION, 1); value = conv_ehdr_vers( ehdr->e_ident[EI_VERSION], 0, &inv_buf); break; case EI_OSABI: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_OSABI, 1); value = conv_ehdr_osabi(ehdr->e_ident[EI_OSABI], 0, &inv_buf); break; case EI_ABIVERSION: ndx = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_ABIVERSION, 1); value = conv_ehdr_abivers( ehdr->e_ident[EI_OSABI], ehdr->e_ident[EI_ABIVERSION], CONV_FMT_DECIMAL, &inv_buf); break; default: value = value_buf; (void) snprintf(value_buf, sizeof (value_buf), MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]); break; } if (ndx == NULL) (void) snprintf(ndx_buf, sizeof (ndx_buf), MSG_ORIG(MSG_FMT_BKTINT), i); else (void) snprintf(ndx_buf, sizeof (ndx_buf), MSG_ORIG(MSG_FMT_BKTSTR), ndx); elfedit_printf(MSG_ORIG(MSG_FMT_EI_ELT), ndx_buf, value); } return; } switch (cmd) { case EHDR_CMD_T_E_IDENT: { int i, cnt; /* Show one element, or the entire thing? */ if (e_ident_ndx == -1) { i = 0; cnt = EI_NIDENT; } else { i = e_ident_ndx; cnt = 1; } for (; cnt-- > 0; i++) { /* * If using numeric style, or there is * no conversion routine for this item, * print a simple hex value. */ if ((outstyle == ELFEDIT_OUTSTYLE_NUM) || (i > EI_ABIVERSION)) { elfedit_printf( MSG_ORIG(MSG_FMT_HEXNUMNL), ehdr->e_ident[i]); continue; } /* Handle special cases in simple mode */ switch (i) { case EI_MAG0: case EI_MAG1: case EI_MAG2: case EI_MAG3: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_magic_value(ehdr->e_ident[i])); continue; case EI_CLASS: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_class( ehdr->e_ident[EI_CLASS], 0, &inv_buf)); continue; case EI_DATA: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_data( ehdr->e_ident[EI_DATA], 0, &inv_buf)); continue; case EI_VERSION: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_vers( ehdr->e_ident[EI_VERSION], 0, &inv_buf)); continue; case EI_OSABI: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_osabi( ehdr->e_ident[EI_OSABI], 0, &inv_buf)); continue; case EI_ABIVERSION: elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_abivers( ehdr->e_ident[EI_OSABI], ehdr->e_ident[EI_ABIVERSION], CONV_FMT_DECIMAL, &inv_buf)); continue; } } } return; case EHDR_CMD_T_E_TYPE: if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_type(ehdr->e_ident[EI_OSABI], ehdr->e_type, 0, &inv_buf)); else elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), ehdr->e_type); return; case EHDR_CMD_T_E_MACHINE: if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf)); } else { elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(ehdr->e_machine)); } return; case EHDR_CMD_T_E_VERSION: if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_vers(ehdr->e_version, 0, &inv_buf)); else elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), ehdr->e_version); return; case EHDR_CMD_T_E_ENTRY: elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), EC_WORD(ehdr->e_entry)); return; case EHDR_CMD_T_E_PHOFF: elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), EC_WORD(ehdr->e_phoff)); return; case EHDR_CMD_T_E_SHOFF: elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), EC_WORD(ehdr->e_shoff)); return; case EHDR_CMD_T_E_FLAGS: if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { Conv_ehdr_flags_buf_t flags_buf; elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags, flags_fmt_flags, &flags_buf)); } else { elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), ehdr->e_flags); } return; case EHDR_CMD_T_E_EHSIZE: elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(ehdr->e_ehsize)); return; case EHDR_CMD_T_E_PHENTSIZE: elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(ehdr->e_phentsize)); return; case EHDR_CMD_T_E_PHNUM: { Word num = ehdr->e_phnum; /* * If using extended indexes, fetch the real * value from shdr[0].sh_info */ if (num == PN_XNUM) num = argstate->obj_state-> os_secarr[0].sec_shdr->sh_info; elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(num)); } return; case EHDR_CMD_T_E_SHENTSIZE: elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(ehdr->e_shentsize)); return; case EHDR_CMD_T_E_SHNUM: { Word num = ehdr->e_shnum; /* * If using extended indexes, fetch the real * value from shdr[0].sh_size */ if (num == 0) num = argstate->obj_state-> os_secarr[0].sec_shdr->sh_size; elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(num)); } return; case EHDR_CMD_T_E_SHSTRNDX: { Word num = ehdr->e_shstrndx; /* * If using extended indexes, fetch the real * value from shdr[0].sh_link */ if (num == SHN_XINDEX) num = argstate->obj_state-> os_secarr[0].sec_shdr->sh_link; elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL), EC_WORD(num)); } return; case EHDR_CMD_T_EI_MAG0: case EHDR_CMD_T_EI_MAG1: case EHDR_CMD_T_EI_MAG2: case EHDR_CMD_T_EI_MAG3: /* This depends on EHDR_CMD_T_EI_MAG[0-3] being contiguous */ c = ehdr->e_ident[cmd - EHDR_CMD_T_EI_MAG0]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_magic_value(c)); else elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); return; case EHDR_CMD_T_EI_CLASS: c = ehdr->e_ident[EI_CLASS]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_class(c, 0, &inv_buf)); else elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); return; case EHDR_CMD_T_EI_DATA: c = ehdr->e_ident[EI_DATA]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_data(c, 0, &inv_buf)); else elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); return; case EHDR_CMD_T_EI_VERSION: c = ehdr->e_ident[EI_VERSION]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_vers(c, 0, &inv_buf)); else elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c); return; case EHDR_CMD_T_EI_OSABI: c = ehdr->e_ident[EI_OSABI]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_osabi(c, 0, &inv_buf)); } else { elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), EC_WORD(c)); } return; case EHDR_CMD_T_EI_ABIVERSION: c = ehdr->e_ident[EI_ABIVERSION]; if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), conv_ehdr_abivers(ehdr->e_ident[EI_OSABI], c, CONV_FMT_DECIMAL, &inv_buf)); } else { elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), EC_WORD(c)); } return; } } /* * Common body for the ehdr: module commands. These commands * share a large amount of common behavior, so it is convenient * to centralize things and use the cmd argument to handle the * small differences. * * entry: * cmd - One of the EHDR_CMD_T_* constants listed above, specifying * which command to implement. * obj_state, argc, argv - Standard command arguments */ static elfedit_cmdret_t cmd_body(EHDR_CMD_T cmd, elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { /* * When a call comes in for ehdr:e_ident[ndx], and the * specified element is one that we have a special command * for, then we revector to that special command instead * of using the generic ehdr:e_ident processing. This array, * which is indexed by the e_ident[] index value is used * to decide if that is the case. If the resulting value * is EHDR_CMD_T_E_IDENT, then the generic processing is * used. Otherwise, we revector to the specified command. */ static const int e_ident_revector[16] = { EHDR_CMD_T_EI_MAG0, /* 0: EI_MAG0 */ EHDR_CMD_T_EI_MAG1, /* 1: EI_MAG1 */ EHDR_CMD_T_EI_MAG2, /* 2: EI_MAG2 */ EHDR_CMD_T_EI_MAG3, /* 3: EI_MAG3 */ EHDR_CMD_T_EI_CLASS, /* 4: EI_CLASS */ EHDR_CMD_T_EI_DATA, /* 5: EI_DATA */ EHDR_CMD_T_EI_VERSION, /* 6: EI_VERSION */ EHDR_CMD_T_EI_OSABI, /* 7: EI_OSABI */ EHDR_CMD_T_EI_ABIVERSION, /* 8: EI_ABIVERSION */ EHDR_CMD_T_E_IDENT, /* 9: generic */ EHDR_CMD_T_E_IDENT, /* 10: generic */ EHDR_CMD_T_E_IDENT, /* 11: generic */ EHDR_CMD_T_E_IDENT, /* 12: generic */ EHDR_CMD_T_E_IDENT, /* 13: generic */ EHDR_CMD_T_E_IDENT, /* 14: generic */ EHDR_CMD_T_E_IDENT, /* 15: generic */ }; ARGSTATE argstate; Ehdr *ehdr; elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; int e_ident_ndx = -1; Conv_inv_buf_t inv_buf1, inv_buf2; /* Process the optional arguments */ process_args(obj_state, argc, argv, &argstate); /* Check number of arguments */ switch (cmd) { case EHDR_CMD_T_DUMP: /* ehdr:dump does not accept arguments */ if (argstate.argc > 0) elfedit_command_usage(); break; case EHDR_CMD_T_E_IDENT: /* * ehdr:e_ident accepts 1 or 2 arguments, the first * being the index into the array, and the second being * the value. If there are arguments, then process the * index, and remove it from the argument list. */ if (argstate.argc > 0) { if (argstate.argc > 2) elfedit_command_usage(); e_ident_ndx = (int) elfedit_atoconst_range(argstate.argv[0], MSG_ORIG(MSG_STR_INDEX), 0, EI_NIDENT - 1, ELFEDIT_CONST_EI); argstate.argc--; argstate.argv++; /* * If the index is for one of the e_ident elements * that we have a special command for, then switch * to that command. e_ident_revector[] returns * EHDR_CMD_T_E_IDENT in the cases where such a command * does not exist, in which case we'll continue with the * generic code. */ cmd = e_ident_revector[e_ident_ndx]; } break; case EHDR_CMD_T_E_FLAGS: /* ehdr:e_flags accepts an arbitrary number of arguments */ break; default: /* The remaining commands accept a single optional argument */ if (argstate.argc > 1) elfedit_command_usage(); break; } /* If there are no arguments, dump the ELF header and return */ if (argstate.argc == 0) { print_ehdr(cmd, e_ident_ndx, 0, &argstate); return (ELFEDIT_CMDRET_NONE); } ehdr = obj_state->os_ehdr; switch (cmd) { /* * EHDR_CMD_T_DUMP can't get here: It never has an * argument, and is handled above. */ case EHDR_CMD_T_E_IDENT: { /* * Only those e_ident[] elements for which we * don't have a specialized command come here. * The argument is a value to be set in * e_ident[e_ident_ndx]. */ uchar_t value = (uchar_t) elfedit_atoui_range(argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL); if (ehdr->e_ident[e_ident_ndx] == value) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_D_X_OK), e_ident_ndx, EC_WORD(value)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_D_X_CHG), e_ident_ndx, ehdr->e_ident[e_ident_ndx], value); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[e_ident_ndx] = value; } } break; case EHDR_CMD_T_E_TYPE: { /* The argument gives the object type */ Half type = (Half) elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_ET); const char *name = MSG_ORIG(MSG_CMD_E_TYPE); if (ehdr->e_type == type) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_OK), name, conv_ehdr_type(ehdr->e_ident[EI_OSABI], ehdr->e_type, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_CHG), name, conv_ehdr_type(ehdr->e_ident[EI_OSABI], ehdr->e_type, 0, &inv_buf1), conv_ehdr_type(ehdr->e_ident[EI_OSABI], type, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_type = type; } } break; case EHDR_CMD_T_E_MACHINE: { /* The argument gives the machine code */ Half mach = (Half) elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_EM); const char *name = MSG_ORIG(MSG_CMD_E_MACHINE); if (ehdr->e_machine == mach) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_OK), name, conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_CHG), name, conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf1), conv_ehdr_mach(mach, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD_OS_MACH; ehdr->e_machine = mach; } } break; case EHDR_CMD_T_E_VERSION: { /* The argument gives the version */ Word ver = (Word) elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_EV); const char *name = MSG_ORIG(MSG_CMD_E_VERSION); if (ehdr->e_version == ver) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_OK), name, conv_ehdr_vers(ehdr->e_version, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_CHG), name, conv_ehdr_vers(ehdr->e_version, 0, &inv_buf1), conv_ehdr_vers(ver, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_version = ver; } } break; case EHDR_CMD_T_E_ENTRY: { /* The argument gives the entry address */ Addr entry = (Addr) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_ENTRY); if (ehdr->e_entry == entry) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_OK), name, EC_ADDR(ehdr->e_entry)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, EC_ADDR(ehdr->e_entry), EC_ADDR(entry)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_entry = entry; } } break; case EHDR_CMD_T_E_PHOFF: { /* The argument gives the program header offset */ Off off = (Off) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_PHOFF); if (ehdr->e_phoff == off) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_OK), name, EC_OFF(ehdr->e_phoff)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, EC_OFF(ehdr->e_phoff), EC_OFF(off)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_phoff = off; } } break; case EHDR_CMD_T_E_SHOFF: { /* The argument gives the section header offset */ Off off = (Off) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_SHOFF); if (ehdr->e_shoff == off) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_OK), name, EC_OFF(ehdr->e_shoff)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_LLX_CHG), name, EC_OFF(ehdr->e_shoff), EC_OFF(off)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_shoff = off; } } break; case EHDR_CMD_T_E_FLAGS: { Conv_ehdr_flags_buf_t flags_buf1, flags_buf2; const char *name = MSG_ORIG(MSG_CMD_E_FLAGS); Word flags = 0; int i; /* Collect the arguments */ for (i = 0; i < argstate.argc; i++) flags |= (Word) elfedit_atoconst(argstate.argv[i], ELFEDIT_CONST_EF); /* Complement the value? */ if (argstate.optmask & EHDR_OPT_F_CMP) flags = ~flags; /* Perform any requested bit operations */ if (argstate.optmask & EHDR_OPT_F_AND) flags &= ehdr->e_flags; else if (argstate.optmask & EHDR_OPT_F_OR) flags |= ehdr->e_flags; /* Set the value */ if (ehdr->e_flags == flags) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_OK), name, conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags, 0, &flags_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_S_CHG), name, conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags, 0, &flags_buf1), conv_ehdr_flags(ehdr->e_machine, flags, 0, &flags_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_flags = flags; } } break; case EHDR_CMD_T_E_EHSIZE: { /* The argument gives the ELF header size */ Half ehsize = (Half) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_EHSIZE); if (ehdr->e_ehsize == ehsize) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_ehsize)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_ehsize), EC_WORD(ehsize)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ehsize = ehsize; } } break; case EHDR_CMD_T_E_PHENTSIZE: { /* * The argument gives the size of a program * header element. */ Half phentsize = (Half) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_PHENTSIZE); if (ehdr->e_phentsize == phentsize) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_phentsize)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_phentsize), EC_WORD(phentsize)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_phentsize = phentsize; } } break; case EHDR_CMD_T_E_PHNUM: { /* The argument gives the number of program headers */ Word phnum = (Word) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_PHNUM); elfedit_section_t *sec0 = &obj_state->os_secarr[0]; Shdr *shdr0 = sec0->sec_shdr; Half e_phnum; Word sh_info; if (phnum >= PN_XNUM) { e_phnum = PN_XNUM; sh_info = phnum; } else { e_phnum = phnum; sh_info = 0; } if (ehdr->e_phnum == e_phnum) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_phnum)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_phnum), e_phnum); ret = ELFEDIT_CMDRET_MOD; ehdr->e_phnum = e_phnum; } if (shdr0->sh_info == sh_info) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_OK), MSG_ORIG(MSG_STR_SH_INFO), EC_WORD(shdr0->sh_info)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), MSG_ORIG(MSG_STR_SH_INFO), EC_WORD(shdr0->sh_info), sh_info); ret = ELFEDIT_CMDRET_MOD; shdr0->sh_info = sh_info; elfedit_modified_shdr(sec0); } } break; case EHDR_CMD_T_E_SHENTSIZE: { /* * The argument gives the size of a program * header element. */ Half shentsize = (Half) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_SHENTSIZE); if (ehdr->e_shentsize == shentsize) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_shentsize)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_shentsize), EC_WORD(shentsize)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_shentsize = shentsize; } } break; case EHDR_CMD_T_E_SHNUM: { /* The argument gives the number of section headers */ Word shnum = (Word) elfedit_atoui(argstate.argv[0], NULL); const char *name = MSG_ORIG(MSG_CMD_E_SHNUM); elfedit_section_t *sec0 = &obj_state->os_secarr[0]; Shdr *shdr0 = sec0->sec_shdr; Half e_shnum; Word sh_size; if (shnum >= SHN_LORESERVE) { e_shnum = 0; sh_size = shnum; } else { e_shnum = shnum; sh_size = 0; } if (ehdr->e_shnum == e_shnum) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_shnum)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_shnum), e_shnum); ret = ELFEDIT_CMDRET_MOD; ehdr->e_shnum = e_shnum; } if (shdr0->sh_size == sh_size) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_OK), MSG_ORIG(MSG_STR_SH_SIZE), EC_WORD(shdr0->sh_size)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), MSG_ORIG(MSG_STR_SH_SIZE), EC_WORD(shdr0->sh_size), sh_size); ret = ELFEDIT_CMDRET_MOD; shdr0->sh_size = sh_size; elfedit_modified_shdr(sec0); } } break; case EHDR_CMD_T_E_SHSTRNDX: { const char *name = MSG_ORIG(MSG_CMD_E_SHSTRNDX); Word shstrndx; elfedit_section_t *sec0 = &obj_state->os_secarr[0]; Shdr *shdr0 = sec0->sec_shdr; Half e_shstrndx; Word sh_link; /* * By default, sec argument is name of section. * If -shndx is used, it is a numeric index, and * if -shtyp is used, it is a section type. */ if (argstate.optmask & EHDR_OPT_F_SHNDX) shstrndx = elfedit_atoshndx(argstate.argv[0], obj_state->os_shnum); else if (argstate.optmask & EHDR_OPT_F_SHTYP) shstrndx = elfedit_type_to_shndx(obj_state, elfedit_atoconst(argstate.argv[0], ELFEDIT_CONST_SHT)); else shstrndx = elfedit_name_to_shndx(obj_state, argstate.argv[0]); /* Warn if the section isn't a string table */ if ((shstrndx >= obj_state->os_shnum) || ((shstrndx >= SHN_LORESERVE) && (shstrndx <= SHN_HIRESERVE)) || (obj_state->os_secarr[shstrndx].sec_shdr->sh_type != SHT_STRTAB)) elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_NOTSTRTAB), name, EC_WORD(shstrndx)); if (shstrndx >= SHN_LORESERVE) { e_shstrndx = SHN_XINDEX; sh_link = shstrndx; } else { e_shstrndx = shstrndx; sh_link = 0; } if (ehdr->e_shstrndx == e_shstrndx) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_OK), name, EC_WORD(ehdr->e_shstrndx)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_E_D_CHG), name, EC_WORD(ehdr->e_shstrndx), e_shstrndx); ret = ELFEDIT_CMDRET_MOD; ehdr->e_shstrndx = e_shstrndx; } if (shdr0->sh_link == sh_link) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_OK), MSG_ORIG(MSG_STR_SH_LINK), EC_WORD(shdr0->sh_link)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_SHDR0_D_CHG), MSG_ORIG(MSG_STR_SH_LINK), EC_WORD(shdr0->sh_link), sh_link); ret = ELFEDIT_CMDRET_MOD; shdr0->sh_link = sh_link; elfedit_modified_shdr(sec0); } } break; case EHDR_CMD_T_EI_MAG0: case EHDR_CMD_T_EI_MAG1: case EHDR_CMD_T_EI_MAG2: case EHDR_CMD_T_EI_MAG3: { /* * This depends on EHDR_CMD_T_EI_MAG[0-3] * being contiguous */ int ei_ndx = (cmd - EHDR_CMD_T_EI_MAG0) + EI_MAG0; /* The argument gives the magic number byte */ int mag = (int)elfedit_atoui_range(argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL); if (ehdr->e_ident[ei_ndx] == mag) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, ei_ndx, 1), conv_magic_value(ehdr->e_ident[ei_ndx])); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, ei_ndx, 1), conv_magic_value(ehdr->e_ident[ei_ndx]), conv_magic_value(mag)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[ei_ndx] = mag; } } break; case EHDR_CMD_T_EI_CLASS: { /* The argument gives the ELFCLASS value */ int class = (int)elfedit_atoconst_range( argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_ELFCLASS); const char *name = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_CLASS, 1); if (ehdr->e_ident[EI_CLASS] == class) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, conv_ehdr_class(class, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, conv_ehdr_class(ehdr->e_ident[EI_CLASS], 0, &inv_buf1), conv_ehdr_class(class, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[EI_CLASS] = class; } } break; case EHDR_CMD_T_EI_DATA: { /* The argument gives the ELFDATA value */ int data = (int)elfedit_atoconst_range(argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_ELFDATA); const char *name = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_DATA, 1); if (ehdr->e_ident[EI_DATA] == data) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, conv_ehdr_data(data, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, conv_ehdr_data(ehdr->e_ident[EI_DATA], 0, &inv_buf1), conv_ehdr_data(data, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[EI_DATA] = data; } } break; case EHDR_CMD_T_EI_VERSION: { /* The argument gives the version */ int ver = (int)elfedit_atoconst_range(argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_EV); const char *name = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_VERSION, 1); if (ehdr->e_ident[EI_VERSION] == ver) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, conv_ehdr_vers(ver, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, conv_ehdr_vers(ehdr->e_ident[EI_VERSION], 0, &inv_buf1), conv_ehdr_vers(ver, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[EI_VERSION] = ver; } } break; case EHDR_CMD_T_EI_OSABI: { /* The argument gives the ABI code */ int osabi = (int)elfedit_atoconst_range( argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_ELFOSABI); const char *name = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_OSABI, 1); if (ehdr->e_ident[EI_OSABI] == osabi) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, conv_ehdr_osabi(osabi, 0, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, conv_ehdr_osabi(ehdr->e_ident[EI_OSABI], 0, &inv_buf1), conv_ehdr_osabi(osabi, 0, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD_OS_MACH; ehdr->e_ident[EI_OSABI] = osabi; } } break; case EHDR_CMD_T_EI_ABIVERSION: { /* The argument gives the ABI version */ int abiver = (int)elfedit_atoconst_range( argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_EAV); const char *name = elfedit_atoconst_value_to_str( ELFEDIT_CONST_EI, EI_ABIVERSION, 1); if (ehdr->e_ident[EI_ABIVERSION] == abiver) { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_OK), name, conv_ehdr_abivers(ehdr->e_ident[EI_OSABI], abiver, CONV_FMT_DECIMAL, &inv_buf1)); } else { elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name, conv_ehdr_abivers(ehdr->e_ident[EI_OSABI], ehdr->e_ident[EI_ABIVERSION], CONV_FMT_DECIMAL, &inv_buf1), conv_ehdr_abivers(ehdr->e_ident[EI_OSABI], abiver, CONV_FMT_DECIMAL, &inv_buf2)); ret = ELFEDIT_CMDRET_MOD; ehdr->e_ident[EI_ABIVERSION] = abiver; } } break; } /* * If we modified the ELF header, tell libelf. */ if (ret == ELFEDIT_CMDRET_MOD) elfedit_modified_ehdr(obj_state); /* Do autoprint */ print_ehdr(cmd, e_ident_ndx, 1, &argstate); return (ret); } /* * Command completion functions for the various commands */ /*ARGSUSED*/ static void cpl_e_ident(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { elfedit_atoui_t ndx; /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) { elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EI); return; } if (argc != 2) return; /* * In order to offer up the right completion strings for * the value, we need to know what index was given for * the first argument. If we don't recognize the index, * we want to return quietly without issuing an error, * so we use elfedit_atoui_range2(), which returns * a success/failure result and does not throw any errors. */ if (elfedit_atoconst_range2(argv[0], 0, EI_NIDENT - 1, ELFEDIT_CONST_EI, &ndx) == 0) return; switch (ndx) { case EI_CLASS: elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS); break; case EI_DATA: elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA); break; case EI_VERSION: elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV); break; case EI_OSABI: elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI); break; } } /*ARGSUSED*/ static void cpl_e_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ET); } /*ARGSUSED*/ static void cpl_e_machine(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM); } /*ARGSUSED*/ static void cpl_e_version(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV); } /*ARGSUSED*/ static void cpl_e_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* This routine allows multiple flags to be specified */ elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EF); } /*ARGSUSED*/ static void cpl_e_shstrndx(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { enum { NAME, INDEX, TYPE } op; Word ndx; /* * The plainargument can be a section name, index, or * type, based on the options used. All have completions. */ if (argc != (num_opt + 1)) return; op = NAME; for (ndx = 0; ndx < num_opt; ndx++) { if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0) op = INDEX; else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0) op = TYPE; } if (obj_state == NULL) { /* No object available */ if (op == TYPE) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); return; } /* * Loop over the sections and supply command completion * for the string tables in the file. */ for (ndx = 0; ndx < obj_state->os_shnum; ndx++) { elfedit_section_t *sec = &obj_state->os_secarr[ndx]; if (sec->sec_shdr->sh_type != SHT_STRTAB) continue; switch (op) { case NAME: elfedit_cpl_match(cpldata, sec->sec_name, 0); break; case INDEX: elfedit_cpl_ndx(cpldata, ndx); break; case TYPE: elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT_STRTAB); break; } } } /*ARGSUSED*/ static void cpl_ei_class(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS); } /*ARGSUSED*/ static void cpl_ei_data(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA); } /*ARGSUSED*/ static void cpl_ei_osabi(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI); } /*ARGSUSED*/ static void cpl_ei_abiversion(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { /* * This command doesn't accept options, so num_opt should be * 0. This is a defensive measure, in case that should change. */ argc -= num_opt; argv += num_opt; if (argc == 1) elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EAV); } /* * Implementation functions for the commands */ static elfedit_cmdret_t cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_DUMP, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_ident(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_IDENT, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_TYPE, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_machine(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_MACHINE, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_VERSION, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_entry(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_ENTRY, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_phoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_PHOFF, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_shoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_SHOFF, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_FLAGS, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_ehsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_EHSIZE, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_phentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_PHENTSIZE, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_phnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_PHNUM, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_shentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_SHENTSIZE, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_shnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_SHNUM, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_e_shstrndx(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_E_SHSTRNDX, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_mag0(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_MAG0, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_mag1(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_MAG1, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_mag2(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_MAG2, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_mag3(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_MAG3, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_class(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_CLASS, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_data(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_DATA, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_VERSION, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_osabi(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_OSABI, obj_state, argc, argv)); } static elfedit_cmdret_t cmd_ei_abiversion(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) { return (cmd_body(EHDR_CMD_T_EI_ABIVERSION, obj_state, argc, argv)); } /*ARGSUSED*/ elfedit_module_t * elfedit_init(elfedit_module_version_t version) { /* Many of the commands only accept -o */ static elfedit_cmd_optarg_t opt_std[] = { { ELFEDIT_STDOA_OPT_O, NULL, ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, { NULL } }; /* ehdr:dump */ static const char *name_dump[] = { MSG_ORIG(MSG_CMD_DUMP), MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ NULL }; /* ehdr:e_ident */ static const char *name_e_ident[] = { MSG_ORIG(MSG_CMD_E_IDENT), NULL }; static elfedit_cmd_optarg_t arg_e_ident[] = { { MSG_ORIG(MSG_STR_INDEX), /* MSG_INTL(MSG_ARGDESC_E_IDENT_NDX) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_NDX), ELFEDIT_CMDOA_F_OPT, 0 }, { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_IDENT_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_type */ static const char *name_e_type[] = { MSG_ORIG(MSG_CMD_E_TYPE), NULL }; static elfedit_cmd_optarg_t arg_e_type[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_TYPE_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_TYPE_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_machine */ static const char *name_e_machine[] = { MSG_ORIG(MSG_CMD_E_MACHINE), NULL }; static elfedit_cmd_optarg_t arg_e_machine[] = { { MSG_ORIG(MSG_STR_TYPE), /* MSG_INTL(MSG_ARGDESC_E_MACHINE_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_MACHINE_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_version */ static const char *name_e_version[] = { MSG_ORIG(MSG_CMD_E_VERSION), NULL }; static elfedit_cmd_optarg_t arg_e_version[] = { { MSG_ORIG(MSG_STR_VERSION), /* MSG_INTL(MSG_ARGDESC_E_VERSION_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_VERSION_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_entry */ static const char *name_e_entry[] = { MSG_ORIG(MSG_CMD_E_ENTRY), NULL }; static elfedit_cmd_optarg_t arg_e_entry[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_ENTRY_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_ENTRY_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_phoff */ static const char *name_e_phoff[] = { MSG_ORIG(MSG_CMD_E_PHOFF), NULL }; static elfedit_cmd_optarg_t arg_e_phoff[] = { { MSG_ORIG(MSG_STR_OFFSET), /* MSG_INTL(MSG_ARGDESC_E_PHOFF_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHOFF_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_shoff */ static const char *name_e_shoff[] = { MSG_ORIG(MSG_CMD_E_SHOFF), NULL }; static elfedit_cmd_optarg_t arg_e_shoff[] = { { MSG_ORIG(MSG_STR_OFFSET), /* MSG_INTL(MSG_ARGDESC_E_SHOFF_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHOFF_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_flags */ static const char *name_e_flags[] = { MSG_ORIG(MSG_CMD_E_FLAGS), NULL }; static elfedit_cmd_optarg_t opt_e_flags[] = { { ELFEDIT_STDOA_OPT_AND, NULL, ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_AND, EHDR_OPT_F_OR }, { ELFEDIT_STDOA_OPT_CMP, NULL, ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_CMP, 0 }, { ELFEDIT_STDOA_OPT_O, NULL, ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, { ELFEDIT_STDOA_OPT_OR, NULL, ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_OR, EHDR_OPT_F_AND }, { NULL } }; static elfedit_cmd_optarg_t arg_e_flags[] = { { MSG_ORIG(MSG_STR_FLAGVALUE), /* MSG_INTL(MSG_ARGDESC_E_FLAGS_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_FLAGS_VALUE), ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT, 0 }, { NULL } }; /* ehdr:e_ehsize */ static const char *name_e_ehsize[] = { MSG_ORIG(MSG_CMD_E_EHSIZE), NULL }; static elfedit_cmd_optarg_t arg_e_ehsize[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_EHSIZE_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_EHSIZE_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_phentsize */ static const char *name_e_phentsize[] = { MSG_ORIG(MSG_CMD_E_PHENTSIZE), NULL }; static elfedit_cmd_optarg_t arg_e_phentsize[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_PHENTSIZE_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHENTSIZE_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_phnum */ static const char *name_e_phnum[] = { MSG_ORIG(MSG_CMD_E_PHNUM), NULL }; static elfedit_cmd_optarg_t arg_e_phnum[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_PHNUM_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHNUM_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_shentsize */ static const char *name_e_shentsize[] = { MSG_ORIG(MSG_CMD_E_SHENTSIZE), NULL }; static elfedit_cmd_optarg_t arg_e_shentsize[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_SHENTSIZE_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHENTSIZE_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_shnum */ static const char *name_e_shnum[] = { MSG_ORIG(MSG_CMD_E_SHNUM), NULL }; static elfedit_cmd_optarg_t arg_e_shnum[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_E_SHNUM_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHNUM_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:e_shstrndx */ static const char *name_e_shstrndx[] = { MSG_ORIG(MSG_CMD_E_SHSTRNDX), NULL }; static elfedit_cmd_optarg_t opt_e_shstrndx[] = { { ELFEDIT_STDOA_OPT_O, NULL, ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, { MSG_ORIG(MSG_STR_MINUS_SHNDX), /* MSG_INTL(MSG_OPTDESC_SHNDX) */ ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0, EHDR_OPT_F_SHNDX, EHDR_OPT_F_SHTYP }, { MSG_ORIG(MSG_STR_MINUS_SHTYP), /* MSG_INTL(MSG_OPTDESC_SHTYP) */ ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0, EHDR_OPT_F_SHTYP, EHDR_OPT_F_SHNDX, }, { NULL } }; static elfedit_cmd_optarg_t arg_e_shstrndx[] = { { MSG_ORIG(MSG_STR_SEC), /* MSG_INTL(MSG_ARGDESC_E_SHSTRNDX_SEC) */ ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHSTRNDX_SEC), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_mag0 */ static const char *name_ei_mag0[] = { MSG_ORIG(MSG_CMD_EI_MAG0), NULL }; static elfedit_cmd_optarg_t arg_ei_mag0[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_MAG0_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG0_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_mag1 */ static const char *name_ei_mag1[] = { MSG_ORIG(MSG_CMD_EI_MAG1), NULL }; static elfedit_cmd_optarg_t arg_ei_mag1[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_MAG1_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG1_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_mag2 */ static const char *name_ei_mag2[] = { MSG_ORIG(MSG_CMD_EI_MAG2), NULL }; static elfedit_cmd_optarg_t arg_ei_mag2[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_MAG2_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG2_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_mag3 */ static const char *name_ei_mag3[] = { MSG_ORIG(MSG_CMD_EI_MAG3), NULL }; static elfedit_cmd_optarg_t arg_ei_mag3[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_MAG3_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG3_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_class */ static const char *name_ei_class[] = { MSG_ORIG(MSG_CMD_EI_CLASS), NULL }; static elfedit_cmd_optarg_t arg_ei_class[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_CLASS_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_CLASS_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_data */ static const char *name_ei_data[] = { MSG_ORIG(MSG_CMD_EI_DATA), NULL }; static elfedit_cmd_optarg_t arg_ei_data[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_DATA_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_DATA_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_version */ static const char *name_ei_version[] = { MSG_ORIG(MSG_CMD_EI_VERSION), NULL }; /* Note: arg_e_version is also used for this command */ /* ehdr:ei_osabi */ static const char *name_ei_osabi[] = { MSG_ORIG(MSG_CMD_EI_OSABI), NULL }; static elfedit_cmd_optarg_t arg_ei_osabi[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_OSABI_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_OSABI_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; /* ehdr:ei_abiversion */ static const char *name_ei_abiversion[] = { MSG_ORIG(MSG_CMD_EI_ABIVERSION), NULL }; static elfedit_cmd_optarg_t arg_ei_abiversion[] = { { MSG_ORIG(MSG_STR_VALUE), /* MSG_INTL(MSG_ARGDESC_EI_ABIVERSION_VALUE) */ ELFEDIT_I18NHDL(MSG_ARGDESC_EI_ABIVERSION_VALUE), ELFEDIT_CMDOA_F_OPT, 0 }, { NULL } }; static elfedit_cmd_t cmds[] = { /* ehdr:dump */ { cmd_dump, NULL, name_dump, /* MSG_INTL(MSG_DESC_DUMP) */ ELFEDIT_I18NHDL(MSG_DESC_DUMP), /* MSG_INTL(MSG_HELP_DUMP) */ ELFEDIT_I18NHDL(MSG_HELP_DUMP), NULL, NULL }, /* ehdr:e_ident */ { cmd_e_ident, cpl_e_ident, name_e_ident, /* MSG_INTL(MSG_DESC_E_IDENT) */ ELFEDIT_I18NHDL(MSG_DESC_E_IDENT), /* MSG_INTL(MSG_HELP_E_IDENT) */ ELFEDIT_I18NHDL(MSG_HELP_E_IDENT), opt_std, arg_e_ident }, /* ehdr:e_type */ { cmd_e_type, cpl_e_type, name_e_type, /* MSG_INTL(MSG_DESC_E_TYPE) */ ELFEDIT_I18NHDL(MSG_DESC_E_TYPE), /* MSG_INTL(MSG_HELP_E_TYPE) */ ELFEDIT_I18NHDL(MSG_HELP_E_TYPE), opt_std, arg_e_type }, /* ehdr:e_machine */ { cmd_e_machine, cpl_e_machine, name_e_machine, /* MSG_INTL(MSG_DESC_E_MACHINE) */ ELFEDIT_I18NHDL(MSG_DESC_E_MACHINE), /* MSG_INTL(MSG_HELP_E_MACHINE) */ ELFEDIT_I18NHDL(MSG_HELP_E_MACHINE), opt_std, arg_e_machine }, /* ehdr:e_version */ { cmd_e_version, cpl_e_version, name_e_version, /* MSG_INTL(MSG_DESC_E_VERSION) */ ELFEDIT_I18NHDL(MSG_DESC_E_VERSION), /* MSG_INTL(MSG_HELP_E_VERSION) */ ELFEDIT_I18NHDL(MSG_HELP_E_VERSION), opt_std, arg_e_version }, /* ehdr:e_entry */ { cmd_e_entry, NULL, name_e_entry, /* MSG_INTL(MSG_DESC_E_ENTRY) */ ELFEDIT_I18NHDL(MSG_DESC_E_ENTRY), /* MSG_INTL(MSG_HELP_E_ENTRY) */ ELFEDIT_I18NHDL(MSG_HELP_E_ENTRY), opt_std, arg_e_entry }, /* ehdr:e_phoff */ { cmd_e_phoff, NULL, name_e_phoff, /* MSG_INTL(MSG_DESC_E_PHOFF) */ ELFEDIT_I18NHDL(MSG_DESC_E_PHOFF), /* MSG_INTL(MSG_HELP_E_PHOFF) */ ELFEDIT_I18NHDL(MSG_HELP_E_PHOFF), opt_std, arg_e_phoff }, /* ehdr:e_shoff */ { cmd_e_shoff, NULL, name_e_shoff, /* MSG_INTL(MSG_DESC_E_SHOFF) */ ELFEDIT_I18NHDL(MSG_DESC_E_SHOFF), /* MSG_INTL(MSG_HELP_E_SHOFF) */ ELFEDIT_I18NHDL(MSG_HELP_E_SHOFF), opt_std, arg_e_shoff }, /* ehdr:e_flags */ { cmd_e_flags, cpl_e_flags, name_e_flags, /* MSG_INTL(MSG_DESC_E_FLAGS) */ ELFEDIT_I18NHDL(MSG_DESC_E_FLAGS), /* MSG_INTL(MSG_HELP_E_FLAGS) */ ELFEDIT_I18NHDL(MSG_HELP_E_FLAGS), opt_e_flags, arg_e_flags }, /* ehdr:e_ehsize */ { cmd_e_ehsize, NULL, name_e_ehsize, /* MSG_INTL(MSG_DESC_E_EHSIZE) */ ELFEDIT_I18NHDL(MSG_DESC_E_EHSIZE), /* MSG_INTL(MSG_HELP_E_EHSIZE) */ ELFEDIT_I18NHDL(MSG_HELP_E_EHSIZE), opt_std, arg_e_ehsize }, /* ehdr:e_phentsize */ { cmd_e_phentsize, NULL, name_e_phentsize, /* MSG_INTL(MSG_DESC_E_PHENTSIZE) */ ELFEDIT_I18NHDL(MSG_DESC_E_PHENTSIZE), /* MSG_INTL(MSG_HELP_E_PHENTSIZE) */ ELFEDIT_I18NHDL(MSG_HELP_E_PHENTSIZE), opt_std, arg_e_phentsize }, /* ehdr:e_phnum */ { cmd_e_phnum, NULL, name_e_phnum, /* MSG_INTL(MSG_DESC_E_PHNUM) */ ELFEDIT_I18NHDL(MSG_DESC_E_PHNUM), /* MSG_INTL(MSG_HELP_E_PHNUM) */ ELFEDIT_I18NHDL(MSG_HELP_E_PHNUM), opt_std, arg_e_phnum }, /* ehdr:e_shentsize */ { cmd_e_shentsize, NULL, name_e_shentsize, /* MSG_INTL(MSG_DESC_E_SHENTSIZE) */ ELFEDIT_I18NHDL(MSG_DESC_E_SHENTSIZE), /* MSG_INTL(MSG_HELP_E_SHENTSIZE) */ ELFEDIT_I18NHDL(MSG_HELP_E_SHENTSIZE), opt_std, arg_e_shentsize }, /* ehdr:e_shnum */ { cmd_e_shnum, NULL, name_e_shnum, /* MSG_INTL(MSG_DESC_E_SHNUM) */ ELFEDIT_I18NHDL(MSG_DESC_E_SHNUM), /* MSG_INTL(MSG_HELP_E_SHNUM) */ ELFEDIT_I18NHDL(MSG_HELP_E_SHNUM), opt_std, arg_e_shnum }, /* ehdr:e_shstrndx */ { cmd_e_shstrndx, cpl_e_shstrndx, name_e_shstrndx, /* MSG_INTL(MSG_DESC_E_SHSTRNDX) */ ELFEDIT_I18NHDL(MSG_DESC_E_SHSTRNDX), /* MSG_INTL(MSG_HELP_E_SHSTRNDX) */ ELFEDIT_I18NHDL(MSG_HELP_E_SHSTRNDX), opt_e_shstrndx, arg_e_shstrndx }, /* ehdr:ei_mag0 */ { cmd_ei_mag0, NULL, name_ei_mag0, /* MSG_INTL(MSG_DESC_EI_MAG0) */ ELFEDIT_I18NHDL(MSG_DESC_EI_MAG0), /* MSG_INTL(MSG_HELP_EI_MAG0) */ ELFEDIT_I18NHDL(MSG_HELP_EI_MAG0), opt_std, arg_ei_mag0 }, /* ehdr:ei_mag1 */ { cmd_ei_mag1, NULL, name_ei_mag1, /* MSG_INTL(MSG_DESC_EI_MAG1) */ ELFEDIT_I18NHDL(MSG_DESC_EI_MAG1), /* MSG_INTL(MSG_HELP_EI_MAG1) */ ELFEDIT_I18NHDL(MSG_HELP_EI_MAG1), opt_std, arg_ei_mag1 }, /* ehdr:ei_mag2 */ { cmd_ei_mag2, NULL, name_ei_mag2, /* MSG_INTL(MSG_DESC_EI_MAG2) */ ELFEDIT_I18NHDL(MSG_DESC_EI_MAG2), /* MSG_INTL(MSG_HELP_EI_MAG2) */ ELFEDIT_I18NHDL(MSG_HELP_EI_MAG2), opt_std, arg_ei_mag2 }, /* ehdr:ei_mag3 */ { cmd_ei_mag3, NULL, name_ei_mag3, /* MSG_INTL(MSG_DESC_EI_MAG3) */ ELFEDIT_I18NHDL(MSG_DESC_EI_MAG3), /* MSG_INTL(MSG_HELP_EI_MAG3) */ ELFEDIT_I18NHDL(MSG_HELP_EI_MAG3), opt_std, arg_ei_mag3 }, /* ehdr:ei_class */ { cmd_ei_class, cpl_ei_class, name_ei_class, /* MSG_INTL(MSG_DESC_EI_CLASS) */ ELFEDIT_I18NHDL(MSG_DESC_EI_CLASS), /* MSG_INTL(MSG_HELP_EI_CLASS) */ ELFEDIT_I18NHDL(MSG_HELP_EI_CLASS), opt_std, arg_ei_class }, /* ehdr:ei_data */ { cmd_ei_data, cpl_ei_data, name_ei_data, /* MSG_INTL(MSG_DESC_EI_DATA) */ ELFEDIT_I18NHDL(MSG_DESC_EI_DATA), /* MSG_INTL(MSG_HELP_EI_DATA) */ ELFEDIT_I18NHDL(MSG_HELP_EI_DATA), opt_std, arg_ei_data }, /* ehdr:ei_version */ { cmd_ei_version, cpl_e_version, name_ei_version, /* MSG_INTL(MSG_DESC_EI_VERSION) */ ELFEDIT_I18NHDL(MSG_DESC_EI_VERSION), /* MSG_INTL(MSG_HELP_EI_VERSION) */ ELFEDIT_I18NHDL(MSG_HELP_EI_VERSION), opt_std, arg_e_version }, /* ehdr:ei_osabi */ { cmd_ei_osabi, cpl_ei_osabi, name_ei_osabi, /* MSG_INTL(MSG_DESC_EI_OSABI) */ ELFEDIT_I18NHDL(MSG_DESC_EI_OSABI), /* MSG_INTL(MSG_HELP_EI_OSABI) */ ELFEDIT_I18NHDL(MSG_HELP_EI_OSABI), opt_std, arg_ei_osabi }, /* ehdr:ei_abiversion */ { cmd_ei_abiversion, cpl_ei_abiversion, name_ei_abiversion, /* MSG_INTL(MSG_DESC_EI_ABIVERSION) */ ELFEDIT_I18NHDL(MSG_DESC_EI_ABIVERSION), /* MSG_INTL(MSG_HELP_EI_ABIVERSION) */ ELFEDIT_I18NHDL(MSG_HELP_EI_ABIVERSION), opt_std, arg_ei_abiversion }, { NULL } }; static elfedit_module_t module = { ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), /* MSG_INTL(MSG_MOD_DESC) */ ELFEDIT_I18NHDL(MSG_MOD_DESC), cmds, mod_i18nhdl_to_str }; return (&module); }