sym.c revision d29b2c4438482eb00488be49a1f5d6835f455546
/*
* 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
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#define ELF_TARGET_AMD64 /* SHN_AMD64_LCOMMON */
#include <stdio.h>
#include <unistd.h>
#include <machdep.h>
#include <elfedit.h>
#include <strings.h>
#include <debug.h>
#include <conv.h>
#include <sym_msg.h>
#define MAXNDXSIZE 10
/*
* This module uses shared code for several of the commands.
* It is sometimes necessary to know which specific command
* is active.
*/
typedef enum {
SYM_CMD_T_DUMP = 0, /* sym:dump */
} SYM_CMD_T;
/*
* ELFCLASS-specific definitions
*/
#ifdef _ELF64
#else
/*
* We supply this function for the msg module. Only one copy is needed.
*/
const char *
{
}
#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 *
{
}
/*
* The sym_opt_t enum specifies a bit value for every optional
* argument allowed by a command in this module.
*/
typedef enum {
/* index section */
/* is numeric offset */
/* rather than ASCII string */
/* section index, not name */
/* section type, not name */
} sym_opt_t;
/*
* A variable of type ARGSTATE is used by each command to maintain
* the overall state for a given set of arguments and the symbol tables
* being managed.
*
* The state for each symbol table and the auxiliary sections that are
* related to it are kept in a SYMSTATE sub-struct.
*
* One benefit of ARGSTATE is that it helps us to ensure that we only
* fetch each section a single time:
* - More efficient
* - Prevents multiple ELFEDIT_MSG_DEBUG messages from
* being produced for a given section.
*
* note: The symstate array in ARGSTATE is defined as having one
* element, but in reality, we allocate enough room for
* the number of elements defined in the numsymstate field.
*/
typedef struct {
struct { /* Symbol table */
Word n;
} sym;
struct { /* String table */
} str;
struct { /* Versym */
Word n;
} versym;
struct { /* Extended section indices */
Word n;
} xshndx;
} SYMSTATE;
typedef struct {
int argc; /* # of plain arguments */
const char **argv; /* Plain arguments */
int numsymstate; /* # of items in symstate[] */
} ARGSTATE;
/*
* We maintain the state of each symbol table and related associated
* sections in a SYMSTATE structure . We don't look those auxiliary
* things up unless we actually need them, both to be efficient,
* and to prevent duplicate ELFEDIT_MSG_DEBUG messages from being
* issued as they are located. Hence, process_args() is used to
* initialize the state block with just the symbol table, and then one
* of the argstate_add_XXX() functions is used as needed
* to fetch the additional sections.
*
* entry:
* argstate - Overall state block
* symstate - State block for current symbol table.
*
* exit:
* If the needed auxiliary section is not found, an error is
* issued and the argstate_add_XXX() routine does not return.
* Otherwise, the fields in argstate have been filled in, ready
* for use.
*
*/
static void
{
return;
}
static void
{
return;
}
static void
{
return;
}
/*
* Display symbol table entries in the style used by elfdump.
*
* entry:
* argstate - Overall state block
* symstate - State block for current symbol table.
* ndx - Index of first symbol to display
* cnt - Number of symbols to display
*/
static void
{
char index[MAXNDXSIZE];
const char *shndx_name;
const char *symname;
/* If there is a versym index section, fetch it */
/* If there is an extended index section, fetch it */
ELFEDIT_MSG_DEBUG, 0);
}
}
/*
* Called by print_sym() to determine if a given symbol has the same
* display value for the current command in every symbol table.
*
* entry:
* cmd - SYM_CMD_T_* value giving identify of caller
* argstate - Overall state block
* outstyle - Output style to use
*/
static int
{
switch (cmd) {
case SYM_CMD_T_DUMP:
/* sym:dump should always show everything */
return (0);
case SYM_CMD_T_ST_BIND:
return (0);
break;
case SYM_CMD_T_ST_INFO:
return (0);
break;
case SYM_CMD_T_ST_NAME:
/*
* In simple output mode, we show the string. In
* numeric mode, we show the string table offset.
*/
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
return (0);
} else {
return (0);
}
break;
case SYM_CMD_T_ST_OTHER:
return (0);
break;
case SYM_CMD_T_ST_SHNDX:
{
if ((ndx1 == SHN_XINDEX) &&
}
if ((ndx2 == SHN_XINDEX) &&
}
return (0);
}
break;
case SYM_CMD_T_ST_SIZE:
return (0);
break;
case SYM_CMD_T_ST_TYPE:
return (0);
break;
case SYM_CMD_T_ST_VALUE:
return (0);
break;
case SYM_CMD_T_ST_VISIBILITY:
return (0);
break;
}
}
/* If we got here, there are no differences (or maybe only 1 table */
return (1);
}
/*
* Called by print_sym() to display values for a single symbol table.
*
* entry:
* autoprint - If True, output is only produced if the elfedit
* autoprint flag is set. If False, output is always produced.
* cmd - SYM_CMD_T_* value giving identify of caller
* argstate - Overall state block
* symstate - State block for current symbol table.
* ndx - Index of first symbol to display
* cnt - Number of symbols to display
*/
static void
{
/*
* If doing default output, use elfdump style where we
* show all symbol attributes. In this case, the command
* that called us doesn't matter
*/
if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
return;
}
switch (cmd) {
case SYM_CMD_T_ST_BIND:
{
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
} else {
}
}
}
return;
case SYM_CMD_T_ST_INFO:
return;
case SYM_CMD_T_ST_NAME:
/*
* In simple output mode, we show the string. In numeric
* mode, we show the string table offset.
*/
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
}
} else {
}
return;
case SYM_CMD_T_ST_OTHER:
return;
case SYM_CMD_T_ST_SHNDX:
/* If there is an extended index section, fetch it */
if ((value == SHN_XINDEX) &&
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
value));
} else {
}
}
return;
case SYM_CMD_T_ST_SIZE:
/*
* machine word width integers displayed in fixed width
* 0-filled hex format.
*/
return;
case SYM_CMD_T_ST_TYPE:
{
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
} else {
}
}
}
return;
case SYM_CMD_T_ST_VALUE:
/*
* machine word width integers displayed in fixed width
* 0-filled hex format.
*/
return;
case SYM_CMD_T_ST_VISIBILITY:
{
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
} else {
}
}
}
return;
}
}
/*
* Print symbol values, taking the calling command, and output style
* into account.
*
* entry:
* autoprint - If True, output is only produced if the elfedit
* autoprint flag is set. If False, output is always produced.
* cmd - SYM_CMD_T_* value giving identify of caller
* argstate - Overall state block
* symstate - State block for current symbol table.
* ndx - Index of first symbol to display
* cnt - Number of symbols to display
*/
static void
{
int only_one;
return;
/*
* Pick an output style. sym:dump is required to use the default
* style. The other commands use the current output style.
*/
/*
* This is a nicity: Force any needed auxiliary sections to be
* fetched here before any output is produced. This will put all
* of the debug messages right at the top in a single cluster.
*/
if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
continue;
}
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
switch (cmd) {
case SYM_CMD_T_ST_NAME:
break;
case SYM_CMD_T_ST_SHNDX:
break;
}
}
}
/*
* If there is more than one table, we are displaying a single
* item, we are not using the default "elfdump" style, and all
* the symbols have the same value for the thing we intend to
* display, then we only want to display it once.
*/
(outstyle != ELFEDIT_OUTSTYLE_DEFAULT) &&
/* Run through the tables and display from each one */
ndx = 0;
} else {
cnt = 1;
}
(outstyle == ELFEDIT_OUTSTYLE_DEFAULT)))
if (only_one)
break;
}
}
/*
* The cmd_body_set_st_XXX() functions are for use by cmd_body().
* They handle the case where the second plain argument is
* a value to be stored in the symbol.
*
* entry:
* argstate - Overall state block
* symstate - State block for current symbol table.
*/
static elfedit_cmdret_t
{
/*
* Use the ELF_ST_BIND() macro to access the defined bits
* of the st_info field related to symbol binding.
* Accepts STB_ symbolic names as well as integers.
*/
} else {
/*
* The sh_info field of the symbol table section header
* gives the index of the first non-local symbol in
* the table. Issue warnings if the binding we set
* contradicts this.
*/
&inv_buf1),
}
return (ret);
}
static elfedit_cmdret_t
{
/*
* If -n was specified, this is an offset into the string
* table. Otherwise it is a string we need to turn into
* an offset
*/
/* Warn if the offset is out of range */
} else {
}
} else {
/*
* Warn the user: Changing the name of a symbol in the dynsym
* will break the hash table in this object.
*/
}
return (ret);
}
static elfedit_cmdret_t
{
int use_xshndx;
int shndx_chg, xshndx_chg;
/*
* By default, the sec argument is a section name. If -secshndx was
* specified, it is a section index, and if -secshtyp is specified,
* it is a section type.
*/
else
/*
* We want to use an extended index section if the index is too
* large to be represented otherwise, or if the caller specified
* the -e option to make us do it anyway. However, we cannot
* do this if the index is in the special reserved range between
* SHN_LORESERVE and SHN_HIRESERVE.
*/
((shndx < SHN_LORESERVE) &&
/*
* There are two cases where we have to touch the extended
* index section:
*
* 1) We have determined that we need to, as determined above.
* 2) We do not require it, but the file has an extended
* index section, in which case we should set the slot
* in that extended section to SHN_UNDEF (0).
*
* Fetch the extended section as required, and determine the values
* for st_shndx and the extended section slot.
*/
if (use_xshndx) {
/* We must have an extended index section, or error out */
/* Set symbol to SHN_XINDEX, put index in the extended sec. */
} else {
use_xshndx = 1;
}
if (use_xshndx)
xshndx_chg = use_xshndx &&
/* If anything is going to change, issue appropiate warnings */
if (shndx_chg || xshndx_chg) {
/*
* Setting the first symbol to anything other than SHN_UNDEF
* produces a bad ELF file.
*/
/*
* Setting SHN_XINDEX directly, instead of providing
* an extended index and letting us decide to use
* SHN_XINDEX to implement it, is probably a mistake.
* Issue a warning, but go ahead and follow the directions
* we've been given.
*/
if (shndx == SHN_XINDEX)
/*
* If the section index can fit in the symbol, but
* -e is being used to force it into the extended
* index section, issue a warning.
*/
(st_shndx == SHN_XINDEX))
}
if (shndx_chg) {
} else {
}
if (use_xshndx) {
if (xshndx_chg) {
} else {
}
}
return (ret);
}
static elfedit_cmdret_t
{
/*
* Use the ELF_ST_TYPE() macro to access the defined bits
* of the st_info field related to symbol type.
* Accepts STT_ symbolic names as well as integers.
*/
&inv_buf1));
} else {
&inv_buf1),
&inv_buf2));
}
return (ret);
}
static elfedit_cmdret_t
{
/*
* Use the ELF_ST_VISIBILITY() macro to access the
* defined bits of the st_other field related to symbol
* visibility. Accepts STV_ symbolic names as well as integers.
*/
&inv_buf1));
} else {
&inv_buf1),
}
return (ret);
}
/*
* Standard argument processing for sym module
*
* entry
* obj_state, argc, argv - Standard command arguments
* optmask - Mask of allowed optional arguments.
* symstate - State block for current symbol table.
* 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.
*
* note:
* Only the basic symbol table is initially referenced by
* argstate. Use the argstate_add_XXX() routines below to
* access any auxiliary sections needed.
*/
static ARGSTATE *
{
/*
* We reuse this same argstate, resizing it to the required
* number of symbol tables on the first call, and as necessary.
*/
static int argstate_size = 0;
int explicit = 0;
int got_sym = 0;
/* If there are no symbol tables, we can't do a thing */
if (obj_state->os_symtabnum == 0)
/* Calulate required size of argstate and realloc as necessary */
if (argstate_size != size) {
}
switch (getopt_ret->gor_idmask) {
case SYM_OPT_F_SHNAME: /* -shnam name */
explicit = 1;
break;
case SYM_OPT_F_SHNDX: /* -shndx index */
explicit = 1;
break;
case SYM_OPT_F_SHTYP: /* -shtyp type */
explicit = 1;
break;
}
}
/*
* Usage error if there are too many plain arguments. sym:dump accepts
* a single argument, while the others accept 2.
*/
/*
* If the -symndx option was specified, the sym arg is an index
* into the symbol table. In this case, the symbol table must be
* explicitly specified (-shnam, -shndx, or -shtype).
*/
/*
* If a section was explicitly specified, it needs
* be a symbol table.
*/
if (explicit)
1, NULL);
/* If there may be an arbitrary amount of output, use a pager */
if (argc == 0)
/*
* Decide which symbol table(s) to use. Set up the symstate
* array to contain them:
* - If a symbol table was explicitly specified, we use
* it, and only it.
* - If no symbol table is explicitly specified, and the symbol
* is given by name, we use all symbol tables that
* contain a symbol with that name, throwing an error
* if there isn't at least 1 such table.
* - If no symbol table is specified, and no symbol is specified,
* we use all the tables.
*/
/* If explicit table specified, only that table is considered */
continue;
if (argc > 0) {
} else {
/*
* arg is a symbol name. Use the index of
* the first symbol that matches
*/
/*
* We will use debug messages for failure up
* until we run out of symbol tables. If we
* don't find a table with the desired symbol
* before the last table, we switch to error
* messages. Hence, we will jump with an error
* if no table will work.
*/
/*
* If the symbol table doesn't have this
* symbol, then forget it.
*/
continue;
}
}
}
argstate->numsymstate++;
symstate++;
/*
* If the symbol table was given explicitly, and
* we've just taken it, then there is no reason to
* continue searching.
*/
if (explicit)
break;
}
return (argstate);
}
/*
* Called by cmd_body() to handle the value change for a single
* symbol table.
*
* entry:
* cmd - One of the SYM_CMD_T_* constants listed above, specifying
* which command to implement.
* argstate - Overall state block
* symstate - State block for current symbol table.
*/
static elfedit_cmdret_t
{
/* You're not supposed to change the value of symbol [0] */
/* The second value is an integer giving a new value */
switch (cmd) {
/*
* SYM_CMD_T_DUMP can't get here: It never has more than
* one argument, and is handled above.
*/
case SYM_CMD_T_ST_BIND:
break;
case SYM_CMD_T_ST_INFO:
{
/* Treat st_info as a raw integer field */
} else {
}
}
break;
case SYM_CMD_T_ST_NAME:
break;
case SYM_CMD_T_ST_OTHER:
{
/* Treat st_other as a raw integer field */
} else {
}
}
break;
case SYM_CMD_T_ST_SHNDX:
break;
case SYM_CMD_T_ST_SIZE:
{
} else {
}
}
break;
case SYM_CMD_T_ST_TYPE:
break;
case SYM_CMD_T_ST_VALUE:
{
} else {
}
}
break;
case SYM_CMD_T_ST_VISIBILITY:
break;
}
/*
* If we modified the symbol table, tell libelf.
* Any other modified sections are the responsibility
* of the cmd_body_set_st_*() function that did it, but
* everyone modifies the table itself, so we handle that here.
*/
if (ret == ELFEDIT_CMDRET_MOD)
return (ret);
}
/*
* Common body for the sym: 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 SYM_CMD_T_* constants listed above, specifying
* which command to implement.
* obj_state, argc, argv - Standard command arguments
*/
static elfedit_cmdret_t
{
/*
* If there are not 2 arguments, then this is a display request.
* If no arguments are present, the full table (or tables) is
* dumped. If there is one argument, then the specified item is shown.
*/
return (ELFEDIT_CMDRET_NONE);
}
/*
* When processing multiple symbol tables, it is important that
* any failure happen before anything is changed. Otherwise, you
* can end up in a situation where things are left in an inconsistent
* half done state. sym:st_name has that issue when the -name_offset
* option is used, because the string may be insertable into some
* (dynstr) string tables, but not all of them. So, do the tests
* up front, and refuse to continue if any string insertions would
* fail.
*/
}
/* Loop over the table(s) and make the specified value change */
/* Do autoprint */
return (ret);
}
/*
* Command completion functions for the various commands
*/
/*
* Handle filling in the values for -shnam, -shndx, and -shtyp options.
*/
/*ARGSUSED*/
static void
{
return;
} else {
return;
}
return;
/*
* Loop over the symbol tables and supply command completion
* for the items in the file.
*/
switch (op) {
case NAME:
break;
case INDEX:
{
char index[MAXNDXSIZE];
symtab->symt_shndx);
}
break;
case TYPE:
{
}
break;
}
}
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/* The second argument can be an STB_ value */
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/*
* The second argument can be a section name, a section
* index (-secshndx), or a section type (-secshtyp). We
* can do completions for each of these.
*/
return;
MSG_ORIG(MSG_STR_MINUS_SECSHTYP)) == 0)
}
switch (op) {
case NAME:
break;
break;
case INDEX:
break;
case TYPE:
break;
}
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/* The second argument can be an STT_ value */
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/* The second argument can be an STV_ value */
}
/*
* Implementation functions for the commands
*/
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
static elfedit_cmdret_t
{
}
/*ARGSUSED*/
{
/* Multiple commands accept only the standard set of options */
static elfedit_cmd_optarg_t opt_std[] = {
/* MSG_INTL(MSG_OPTDESC_SHNAM) */
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
/* MSG_INTL(MSG_OPTDESC_SYMNDX) */
ELFEDIT_CMDOA_F_INHERIT, 0 },
{ NULL }
};
/* sym:dump */
static const char *name_dump[] = {
};
static elfedit_cmd_optarg_t opt_dump[] = {
/* MSG_INTL(MSG_OPTDESC_SHNAM) */
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
/* MSG_INTL(MSG_OPTDESC_SYMNDX) */
{ NULL }
};
static elfedit_cmd_optarg_t arg_dump[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
{ NULL }
};
/* sym:st_bind */
static const char *name_st_bind[] = {
static elfedit_cmd_optarg_t arg_st_bind[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_BIND) */
{ NULL }
};
/* sym:st_info */
static const char *name_st_info[] = {
static elfedit_cmd_optarg_t arg_st_info[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_INFO) */
{ NULL }
};
/* sym:st_name */
static const char *name_st_name[] = {
static elfedit_cmd_optarg_t opt_st_name[] = {
/* MSG_INTL(MSG_OPTDESC_SHNAM) */
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
/* MSG_INTL(MSG_OPTDESC_SYMNDX) */
SYM_OPT_F_SYMNDX, 0 },
/* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */
SYM_OPT_F_NAMOFFSET, 0 },
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
{ NULL }
};
static elfedit_cmd_optarg_t arg_st_name[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
{ MSG_ORIG(MSG_STR_NAME),
/* MSG_INTL(MSG_A2_DESC_ST_NAME) */
{ NULL }
};
/* sym:st_other */
static const char *name_st_other[] = {
static elfedit_cmd_optarg_t arg_st_other[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_OTHER) */
{ NULL }
};
/* sym:st_shndx */
static const char *name_st_shndx[] = {
static elfedit_cmd_optarg_t opt_st_shndx[] = {
/* MSG_INTL(MSG_OPTDESC_E) */
/* MSG_INTL(MSG_OPTDESC_SHNAM) */
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
/* MSG_INTL(MSG_OPTDESC_SYMNDX) */
SYM_OPT_F_SYMNDX, 0 },
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
/* MSG_INTL(MSG_OPTDESC_SECSHNDX) */
/* MSG_INTL(MSG_OPTDESC_SECSHTYP) */
{ NULL }
};
static elfedit_cmd_optarg_t arg_st_shndx[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A2_DESC_ST_SEC) */
{ NULL }
};
/* sym:st_size */
static const char *name_st_size[] = {
static elfedit_cmd_optarg_t arg_st_size[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_SIZE) */
{ NULL }
};
/* sym:st_type */
static const char *name_st_type[] = {
static elfedit_cmd_optarg_t arg_st_type[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_TYPE) */
{ NULL }
};
/* sym:st_value */
static const char *name_st_value[] = {
static elfedit_cmd_optarg_t arg_st_value[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_VALUE) */
{ NULL }
};
/* sym:st_visibility */
static const char *name_st_visibility[] = {
static elfedit_cmd_optarg_t arg_st_visibility[] = {
{ MSG_ORIG(MSG_STR_SYM),
/* MSG_INTL(MSG_A1_SYM) */
/* MSG_INTL(MSG_A2_DESC_ST_VISIBILITY) */
{ NULL }
};
static elfedit_cmd_t cmds[] = {
/* sym:dump */
/* MSG_INTL(MSG_DESC_DUMP) */
/* MSG_INTL(MSG_HELP_DUMP) */
/* sym:st_bind */
/* MSG_INTL(MSG_DESC_ST_BIND) */
/* MSG_INTL(MSG_HELP_ST_BIND) */
opt_std, arg_st_bind },
/* sym:st_info */
/* MSG_INTL(MSG_DESC_ST_INFO) */
/* MSG_INTL(MSG_HELP_ST_INFO) */
opt_std, arg_st_info },
/* sym:st_name */
/* MSG_INTL(MSG_DESC_ST_NAME) */
/* MSG_INTL(MSG_HELP_ST_NAME) */
/* sym:st_other */
/* MSG_INTL(MSG_DESC_ST_OTHER) */
/* MSG_INTL(MSG_HELP_ST_OTHER) */
opt_std, arg_st_other },
/* sym:st_shndx */
/* MSG_INTL(MSG_DESC_ST_SHNDX) */
/* MSG_INTL(MSG_HELP_ST_SHNDX) */
/* sym:st_size */
/* MSG_INTL(MSG_DESC_ST_SIZE) */
/* MSG_INTL(MSG_HELP_ST_SIZE) */
opt_std, arg_st_size },
/* sym:st_type */
/* MSG_INTL(MSG_DESC_ST_TYPE) */
/* MSG_INTL(MSG_HELP_ST_TYPE) */
opt_std, arg_st_type },
/* sym:st_value */
/* MSG_INTL(MSG_DESC_ST_VALUE) */
/* MSG_INTL(MSG_HELP_ST_VALUE) */
opt_std, arg_st_value },
/* sym:st_visibility */
/* MSG_INTL(MSG_DESC_ST_VISIBILITY) */
/* MSG_INTL(MSG_HELP_ST_VISIBILITY) */
{ NULL }
};
static elfedit_module_t module = {
/* MSG_INTL(MSG_MOD_DESC) */
return (&module);
}