/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <unistd.h>
#include <elfedit.h>
#include <sys/elf_SPARC.h>
#include <sys/elf_amd64.h>
#include <strings.h>
#include <debug.h>
#include <conv.h>
#include <shdr_msg.h>
/*
* This module uses shared code for several of the commands.
* It is sometimes necessary to know which specific command
* is active.
*/
typedef enum {
} SHDR_CMD_T;
#ifndef _ELF64
/*
* 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 shdr_opt_t enum specifies a bit value for every optional
* argument allowed by a command in this module.
*/
typedef enum {
/* ofset rather than string */
/* sh_link given as section name */
/* sh_link given as section type */
} shdr_opt_t;
/*
* A variable of type ARGSTATE is used by each command to maintain
* information about the section headers and related things. It is
* initialized by process_args(), and used by the other routines.
*/
typedef struct {
} ARGSTATE;
/*
* Standard argument processing for shdr module
*
* entry
* obj_state, argc, argv - Standard command arguments
* optmask - Mask of allowed optional arguments.
* cmd - SHDR_CMD_T_* value giving identify of caller
* 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
{
/* Add each new option to the options mask */
/* Are the right number of plain arguments present? */
switch (cmd) {
case SHDR_CMD_T_DUMP:
if (argc > 1)
break;
case SHDR_CMD_T_SH_FLAGS:
/* shdr:sh_flags allows an arbitrary number of arguments */
break;
default:
/* The remaining commands accept 2 plain arguments */
if (argc > 2)
break;
}
/* If there may be an arbitrary amount of output, use a pager */
if (argc == 0)
}
/*
* Options for deciding which items print_shdr() displays.
*/
typedef enum {
/* of shdr[ndx] */
/* of shdr[ndx] */
} PRINT_SHDR_T;
/*
* Print section header 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 - SHDR_CMD_T_* value giving identify of caller
* argstate - State block for section header array
* ndx - Index of first section to display
* cnt - Number of sections to display
* print_type - Specifies which items are shown
*/
static void
{
(cnt == 0))
return;
/*
* Pick an output style. shdr:dump is required to use the default
* style. The other commands use the current output style.
*/
switch (print_type) {
case PRINT_SHDR_TYPE:
continue;
break;
case PRINT_SHDR_NAME:
continue;
break;
}
/*
* If doing default output, use elfdump style where we
* show all section header attributes. In this case, the
* command that called us doesn't matter
*/
if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
continue;
}
/* Non-default output is handled case by case */
switch (cmd) {
case SHDR_CMD_T_SH_ADDR:
break;
case SHDR_CMD_T_SH_ADDRALIGN:
break;
case SHDR_CMD_T_SH_ENTSIZE:
break;
case SHDR_CMD_T_SH_FLAGS:
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
} else {
}
break;
case SHDR_CMD_T_SH_INFO:
break;
case SHDR_CMD_T_SH_LINK:
break;
case SHDR_CMD_T_SH_NAME:
/*
* In simple output mode, we show the string. In
* numeric mode, we show the string table offset.
*/
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
} else {
}
break;
case SHDR_CMD_T_SH_OFFSET:
break;
case SHDR_CMD_T_SH_SIZE:
break;
case SHDR_CMD_T_SH_TYPE:
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
&inv_buf));
} else {
}
break;
}
}
}
/*
* Common body for the shdr: 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 SHDR_CMD_T_* constants listed above, specifying
* which command to implement.
* obj_state, argc, argv - Standard command arguments
*/
static elfedit_cmdret_t
{
/* If there are no arguments, dump the whole table and return */
return (ELFEDIT_CMDRET_NONE);
}
/*
* The first argument gives the section to use. This can be a
* name (default), section index, or section type, depending on
* the options used.
*/
} else {
}
/* If there is a single argument, display that item and return */
return (ELFEDIT_CMDRET_NONE);
}
/*
* Section [0] is supposed to be all zero unless extended sections
* are in force. Rather than setting extended values directly,
* it is expected to be handled by libelf. So, a direct change here
* is probably not what was intended.
*/
if (ndx == 0)
/* The second value is an integer giving a new value */
switch (cmd) {
/*
* SHDR_CMD_T_DUMP can't get here: It never has more than
* one argument, and is handled above.
*/
case SHDR_CMD_T_SH_ADDR:
{
} else {
}
}
break;
case SHDR_CMD_T_SH_ADDRALIGN:
{
sizeof (sh_addralign)) > 1)
} else {
}
}
break;
case SHDR_CMD_T_SH_ENTSIZE:
{
} else {
}
}
break;
case SHDR_CMD_T_SH_FLAGS:
{
int i;
/* Collect the flag arguments */
sh_flags |=
/* Complement the value? */
/* Perform any requested bit operations */
/* Set the value */
} else {
}
}
break;
case SHDR_CMD_T_SH_INFO:
{
else
} else {
}
}
break;
case SHDR_CMD_T_SH_LINK:
{
else
} else {
}
}
break;
case SHDR_CMD_T_SH_NAME:
{
/*
* If -name_offset was specified, this is an offset
* into the string table. Otherwise it is a string
* we need to turn into an offset.
*/
} else {
/*
* The section name is cached, so we must
* also update that value. This call will
* warn if the offset is out of range, and
* will supply a safe string in that case.
*/
}
}
break;
case SHDR_CMD_T_SH_OFFSET:
{
} else {
}
}
break;
case SHDR_CMD_T_SH_SIZE:
{
} else {
}
}
break;
case SHDR_CMD_T_SH_TYPE:
{
0, &inv_buf1));
} else {
0, &inv_buf1),
0, &inv_buf2));
}
}
break;
}
/*
* If we modified the section header array, tell libelf.
*/
if (ret == ELFEDIT_CMDRET_MOD)
/* Do autoprint */
return (ret);
}
/*
* Command completion functions for the various commands
*/
/*
* All of the commands accept the same first argument (sec) that
* specifies the section. This argument can be a section name
* (default), section index, or section type, depending on the
* options used. This routine determines which case is current,
* and then supplies completion for the first argument.
*/
static void
{
return;
}
switch (op) {
case NAME:
break;
break;
case INDEX:
break;
case TYPE:
break;
}
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/* The second and following arguments can be an SHF_ value */
}
/*
* For shdr:sh_info and shdr:sh_link: The value argument can be an
* integer, section name, or section type.
*/
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
return;
MSG_ORIG(MSG_STR_MINUS_VALUE_SHTYP)) == 0)
}
switch (op) {
case NAME:
break;
break;
case TYPE:
break;
}
}
/*ARGSUSED*/
static void
{
/* Handle -shXXX options */
/* The second argument can be an SHT_ 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
{
}
static elfedit_cmdret_t
{
}
/*ARGSUSED*/
{
/* Multiple commands accept only the standard set of options */
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
{ NULL }
};
/*
* sh_info and sh_link accept the standard options above,
* plus -value_shnam and -value_shtyp.
*/
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
/* MSG_INTL(MSG_OPTDESC_VALUE_SHNAM) */
/* MSG_INTL(MSG_OPTDESC_VALUE_SHTYP) */
{ NULL }
};
/* shdr:sh_addr */
static const char *name_sh_addr[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_ADDR) */
{ NULL }
};
/* shdr:dump */
static const char *name_dump[] = {
};
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
{ NULL }
};
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
{ NULL }
};
/* shdr:sh_addralign */
static const char *name_sh_addralign[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_ADDRALIGN) */
{ NULL }
};
/* shdr:sh_entsize */
static const char *name_sh_entsize[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_ENTSIZE) */
{ NULL }
};
/* shdr:sh_flags */
static const char *name_sh_flags[] = {
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
{ NULL }
};
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_FLAGS) */
{ NULL }
};
/* shdr:sh_info */
static const char *name_sh_info[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_INFO) */
{ NULL }
};
/* shdr:sh_link */
static const char *name_sh_link[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_LINK) */
{ NULL }
};
/* shdr:sh_name */
static const char *name_sh_name[] = {
/* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */
SHDR_OPT_F_NAMOFFSET, 0 },
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
/* MSG_INTL(MSG_OPTDESC_SHNDX) */
/* MSG_INTL(MSG_OPTDESC_SHTYP) */
{ NULL }
};
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
{ MSG_ORIG(MSG_STR_NAME),
/* MSG_INTL(MSG_A2_DESC_SH_NAME) */
{ NULL }
};
/* shdr:sh_offset */
static const char *name_sh_offset[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_OFFSET) */
{ NULL }
};
/* shdr:sh_size */
static const char *name_sh_size[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_SIZE) */
{ NULL }
};
/* shdr:sh_type */
static const char *name_sh_type[] = {
{ MSG_ORIG(MSG_STR_SEC),
/* MSG_INTL(MSG_A1_SEC) */
/* MSG_INTL(MSG_A2_DESC_SH_TYPE) */
{ NULL }
};
/* shdr:dump */
/* MSG_INTL(MSG_DESC_DUMP) */
/* MSG_INTL(MSG_HELP_DUMP) */
/* shdr:sh_addr */
/* MSG_INTL(MSG_DESC_SH_ADDR) */
/* MSG_INTL(MSG_HELP_SH_ADDR) */
opt_std, arg_sh_addr },
/* shdr:sh_addralign */
/* MSG_INTL(MSG_DESC_SH_ADDRALIGN) */
/* MSG_INTL(MSG_HELP_SH_ADDRALIGN) */
/* shdr:sh_entsize */
/* MSG_INTL(MSG_DESC_SH_ENTSIZE) */
/* MSG_INTL(MSG_HELP_SH_ENTSIZE) */
/* shdr:sh_flags */
/* MSG_INTL(MSG_DESC_SH_FLAGS) */
/* MSG_INTL(MSG_HELP_SH_FLAGS) */
/* shdr:sh_info */
/* MSG_INTL(MSG_DESC_SH_INFO) */
/* MSG_INTL(MSG_HELP_SH_INFO) */
/* shdr:sh_link */
/* MSG_INTL(MSG_DESC_SH_LINK) */
/* MSG_INTL(MSG_HELP_SH_LINK) */
/* shdr:sh_name */
/* MSG_INTL(MSG_DESC_SH_NAME) */
/* MSG_INTL(MSG_HELP_SH_NAME) */
/* shdr:sh_offset */
/* MSG_INTL(MSG_DESC_SH_OFFSET) */
/* MSG_INTL(MSG_HELP_SH_OFFSET) */
opt_std, arg_sh_offset },
/* shdr:sh_size */
/* MSG_INTL(MSG_DESC_SH_SIZE) */
/* MSG_INTL(MSG_HELP_SH_SIZE) */
opt_std, arg_sh_size },
/* shdr:sh_type */
/* MSG_INTL(MSG_DESC_SH_TYPE) */
/* MSG_INTL(MSG_HELP_SH_TYPE) */
opt_std, arg_sh_type },
{ NULL }
};
/* MSG_INTL(MSG_MOD_DESC) */
return (&module);
}