ehdr.c revision ba2be53024c0b999e74ba9adcd7d80fec5df8c57
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <ctype.h>
#include <elfedit.h>
#include <sys/elf_SPARC.h>
#include <sys/elf_amd64.h>
#include <strings.h>
#include <conv.h>
#include <debug.h>
#include <ehdr_msg.h>
#define MAXNDXSIZE 10
/*
* 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 = value_buf;
(void) snprintf(value_buf, sizeof (value_buf),
MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]);
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;
}
}
}
return;
case EHDR_CMD_T_E_TYPE:
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_ehdr_type(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:
elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
EC_WORD(ehdr->e_ident[EI_ABIVERSION]));
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_type, 0, &inv_buf1));
} else {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_E_S_CHG), name,
conv_ehdr_type(ehdr->e_type, 0, &inv_buf1),
conv_ehdr_type(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;
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;
ehdr->e_ident[EI_OSABI] = osabi;
}
}
break;
case EHDR_CMD_T_EI_ABIVERSION:
{
/* The argument gives the ABI version */
int abiver = (int)elfedit_atoui_range(argstate.argv[0],
MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL);
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_X_OK), name,
EC_WORD(abiver));
} else {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_EI_S_X_CHG), name,
EC_WORD(ehdr->e_ident[EI_ABIVERSION]),
EC_WORD(abiver));
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:
{
char index[MAXNDXSIZE];
(void) snprintf(index, sizeof (index),
MSG_ORIG(MSG_FMT_WORDVAL),
ndx);
elfedit_cpl_match(cpldata, index, 1);
}
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);
}
/*
* 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, NULL, 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);
}