#include <ctype.h>
#include <elfedit.h>
#include <sys/elf_SPARC.h>
#include <strings.h>
#include <debug.h>
#include <conv.h>
#include <cap_msg.h>
typedef enum {
CAP_CMD_T_DUMP = 0,
CAP_CMD_T_TAG = 1,
CAP_CMD_T_VALUE = 2,
CAP_CMD_T_DELETE = 3,
CAP_CMD_T_MOVE = 4,
CAP_CMD_T_HW1 = 5,
CAP_CMD_T_SF1 = 6,
CAP_CMD_T_HW2 = 7,
CAP_CMD_T_HW3 = 8,
} CAP_CMD_T;
#ifndef _ELF64
const char *
_cap_msg(Msg mid)
{
return (gettext(MSG_ORIG(mid)));
}
#endif
static const char *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
{
Msg msg = (Msg)hdl;
return (MSG_INTL(msg));
}
typedef enum {
CAP_OPT_F_AND = 1,
CAP_OPT_F_CMP = 2,
CAP_OPT_F_CAPID = 4,
CAP_OPT_F_CAPNDX = 8,
CAP_OPT_F_OR = 16,
CAP_OPT_F_STRVAL = 32
} cap_opt_t;
typedef struct {
elfedit_obj_state_t *obj_state;
struct {
elfedit_section_t *sec;
Cap *data;
Word num;
Boolean grp_set;
Word grp_start_ndx;
Word grp_end_ndx;
} cap;
struct {
elfedit_section_t *sec;
} str;
cap_opt_t optmask;
int argc;
const char **argv;
} ARGSTATE;
static void
argstate_add_str(ARGSTATE *argstate, Boolean required)
{
if (argstate->str.sec != NULL)
return;
if (argstate->cap.sec->sec_shdr->sh_info == 0) {
if (required)
elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSTRTAB),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name);
return;
}
argstate->str.sec = elfedit_sec_getstr(argstate->obj_state,
argstate->cap.sec->sec_shdr->sh_info, 0);
}
static void
cap_group_extents(ARGSTATE *argstate, Word ndx, Word *ret_start_ndx,
Word *ret_end_ndx)
{
*ret_end_ndx = ndx;
while ((ndx > 0) && (argstate->cap.data[ndx].c_tag == CA_SUNW_NULL))
ndx--;
while ((ndx > 0) && (argstate->cap.data[ndx - 1].c_tag != CA_SUNW_NULL))
ndx--;
*ret_start_ndx = ndx;
ndx = *ret_end_ndx;
while (((ndx + 1) < argstate->cap.num) &&
(argstate->cap.data[ndx].c_tag != CA_SUNW_NULL))
ndx++;
while (((ndx + 1) < argstate->cap.num) &&
(argstate->cap.data[ndx + 1].c_tag == CA_SUNW_NULL))
ndx++;
*ret_end_ndx = ndx;
}
static const char *
cap_group_id(ARGSTATE *argstate)
{
Word ndx = argstate->cap.grp_start_ndx;
Cap *cap = argstate->cap.data + ndx;
for (; ndx <= argstate->cap.grp_end_ndx; ndx++, cap++) {
if (cap->c_tag == CA_SUNW_ID) {
argstate_add_str(argstate, TRUE);
return (elfedit_offset_to_str(argstate->str.sec,
cap->c_un.c_val, ELFEDIT_MSG_ERR, 0));
}
if (cap->c_tag == CA_SUNW_NULL)
break;
}
return ((argstate->cap.grp_start_ndx == 0) ?
MSG_INTL(MSG_STR_OBJECT) : MSG_INTL(MSG_STR_NONAME));
}
static void
argstate_cap_group(ARGSTATE *argstate, Word ndx)
{
if (argstate->cap.grp_set == TRUE)
return;
cap_group_extents(argstate, ndx, &argstate->cap.grp_start_ndx,
&argstate->cap.grp_end_ndx);
argstate->cap.grp_set = TRUE;
elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CAPGRP),
EC_WORD(argstate->cap.sec->sec_shndx), argstate->cap.sec->sec_name,
EC_WORD(argstate->cap.grp_start_ndx),
EC_WORD(argstate->cap.grp_end_ndx), cap_group_id(argstate));
}
static void
group_title(ARGSTATE *argstate, Word ndx)
{
ARGSTATE loc_argstate;
loc_argstate = *argstate;
cap_group_extents(argstate, ndx, &loc_argstate.cap.grp_start_ndx,
&loc_argstate.cap.grp_end_ndx);
elfedit_printf(MSG_INTL(MSG_FMT_CAPGRP),
EC_WORD(loc_argstate.cap.grp_start_ndx),
EC_WORD(loc_argstate.cap.grp_end_ndx), cap_group_id(&loc_argstate));
}
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;
const char *capid = NULL;
bzero(argstate, sizeof (*argstate));
argstate->obj_state = obj_state;
elfedit_getopt_init(&getopt_state, &argc, &argv);
while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) {
argstate->optmask |= getopt_ret->gor_idmask;
if (getopt_ret->gor_idmask == CAP_OPT_F_CAPID)
capid = getopt_ret->gor_value;
}
if (argc == 0)
elfedit_pager_init();
argstate->argc = argc;
argstate->argv = argv;
argstate->cap.sec = elfedit_sec_getcap(obj_state, &argstate->cap.data,
&argstate->cap.num);
if (capid != NULL) {
Word i;
Cap *cap = argstate->cap.data;
argstate_add_str(argstate, TRUE);
for (i = 0; i < argstate->cap.num; i++, cap++)
if ((cap->c_tag == CA_SUNW_ID) &&
(strcmp(capid, elfedit_offset_to_str(
argstate->str.sec, cap->c_un.c_val,
ELFEDIT_MSG_ERR, 0)) == 0))
break;
if (i == argstate->cap.num)
elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_BADCAPID),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name, capid);
argstate_cap_group(argstate, i);
} else {
argstate->cap.grp_start_ndx = 0;
argstate->cap.grp_end_ndx = argstate->cap.num - 1;
}
}
typedef enum {
PRINT_CAP_T_ALL = 0,
PRINT_CAP_T_NDX = 1,
PRINT_CAP_T_TAG = 2
} PRINT_CAP_T;
static void
print_cap(CAP_CMD_T cmd, int autoprint, ARGSTATE *argstate,
PRINT_CAP_T print_type, Word arg)
{
elfedit_outstyle_t outstyle;
Word cnt, ndx, printed = 0;
Cap *cap;
Boolean header_done = FALSE, null_seen = FALSE;
const char *str;
size_t str_size;
if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
return;
outstyle = (cmd == CAP_CMD_T_DUMP) ?
ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
if (print_type == PRINT_CAP_T_NDX) {
if (arg >= argstate->cap.num)
return;
ndx = arg;
cnt = 1;
} else {
ndx = argstate->cap.grp_start_ndx;
cnt = argstate->cap.grp_end_ndx - ndx + 1;
}
argstate_add_str(argstate, FALSE);
if (argstate->str.sec == NULL) {
str = NULL;
str_size = 0;
} else {
str = (const char *)argstate->str.sec->sec_data->d_buf;
str_size = argstate->str.sec->sec_data->d_size;
}
cap = &argstate->cap.data[ndx];
for (; cnt--; cap++, ndx++) {
if ((print_type == PRINT_CAP_T_TAG) && (cap->c_tag != arg)) {
if (cap->c_tag == CA_SUNW_NULL)
null_seen = TRUE;
continue;
}
switch (cap->c_tag) {
case CA_SUNW_PLAT:
case CA_SUNW_MACH:
case CA_SUNW_ID:
if (argstate->str.sec == NULL)
argstate_add_str(argstate, TRUE);
break;
}
if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
if (null_seen && (cap->c_tag != CA_SUNW_NULL)) {
null_seen = FALSE;
if (header_done) {
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
MSG_ORIG(MSG_STR_EMPTY));
header_done = FALSE;
}
}
if (header_done == FALSE) {
header_done = TRUE;
group_title(argstate, ndx);
Elf_cap_title(0);
}
Elf_cap_entry(NULL, cap, ndx, str, str_size,
argstate->obj_state->os_ehdr->e_machine);
} else {
if (cmd == CAP_CMD_T_TAG) {
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
Conv_inv_buf_t inv_buf;
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_tag(cap->c_tag, 0,
&inv_buf));
} else {
elfedit_printf(
MSG_ORIG(MSG_FMT_WORDVALNL),
EC_WORD(cap->c_tag));
}
printed = 1;
continue;
}
if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
Conv_cap_val_buf_t cap_val_buf;
if (print_type == PRINT_CAP_T_TAG) {
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_val_hw1(cap->c_un.c_val,
argstate->obj_state->os_ehdr->
e_machine, CONV_FMT_NOBKT,
&cap_val_buf.cap_val_hw1_buf));
printed = 1;
continue;
}
switch (cap->c_tag) {
case CA_SUNW_HW_1:
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_val_hw1(cap->c_un.c_val,
argstate->obj_state->os_ehdr->
e_machine, CONV_FMT_NOBKT,
&cap_val_buf.cap_val_hw1_buf));
printed = 1;
continue;
case CA_SUNW_SF_1:
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_val_sf1(cap->c_un.c_val,
argstate->obj_state->os_ehdr->
e_machine, CONV_FMT_NOBKT,
&cap_val_buf.cap_val_sf1_buf));
printed = 1;
continue;
case CA_SUNW_HW_2:
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_val_hw2(cap->c_un.c_val,
argstate->obj_state->os_ehdr->
e_machine, CONV_FMT_NOBKT,
&cap_val_buf.cap_val_hw2_buf));
printed = 1;
continue;
case CA_SUNW_PLAT:
case CA_SUNW_MACH:
case CA_SUNW_ID:
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
elfedit_offset_to_str(
argstate->str.sec, cap->c_un.c_val,
ELFEDIT_MSG_ERR, 0));
printed = 1;
continue;
case CA_SUNW_HW_3:
elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
conv_cap_val_hw3(cap->c_un.c_val,
argstate->obj_state->os_ehdr->
e_machine, CONV_FMT_NOBKT,
&cap_val_buf.cap_val_hw3_buf));
printed = 1;
continue;
}
}
elfedit_printf(MSG_ORIG(MSG_FMT_HEXXWORDNL),
EC_XWORD(cap->c_un.c_val));
}
printed = 1;
if (cap->c_tag == CA_SUNW_NULL)
null_seen = TRUE;
}
if (!printed && (print_type == PRINT_CAP_T_TAG)) {
Conv_inv_buf_t inv_buf;
elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name, argstate->cap.grp_start_ndx,
argstate->cap.grp_end_ndx, cap_group_id(argstate),
conv_cap_tag(arg, 0, &inv_buf));
}
}
static Word
arg_to_index(ARGSTATE *argstate, const char *arg, const char *argname,
int print_request, PRINT_CAP_T *print_type)
{
Word ndx, ca_value;
*print_type = PRINT_CAP_T_NDX;
if ((argstate->optmask & CAP_OPT_F_CAPNDX) != 0) {
ndx = (Word) elfedit_atoui_range(arg, argname, 0,
argstate->cap.num - 1, NULL);
argstate_cap_group(argstate, ndx);
return (ndx);
}
ca_value = (Word) elfedit_atoconst(arg, ELFEDIT_CONST_CA);
if (print_request) {
*print_type = PRINT_CAP_T_TAG;
return (ca_value);
}
if (!argstate->cap.grp_set)
argstate_cap_group(argstate, 0);
for (ndx = argstate->cap.grp_start_ndx;
ndx <= argstate->cap.grp_end_ndx; ndx++) {
if (argstate->cap.data[ndx].c_tag == ca_value) {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_CA2NDX),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name, EC_WORD(ndx), arg);
return (ndx);
}
if (argstate->cap.data[ndx].c_tag == CA_SUNW_NULL) {
if (ndx < argstate->cap.grp_end_ndx) {
Conv_inv_buf_t inv_buf;
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_CONVNULL),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name, EC_WORD(ndx),
conv_cap_tag(ca_value, 0, &inv_buf));
argstate->cap.data[ndx].c_tag = ca_value;
bzero(&argstate->cap.data[ndx].c_un,
sizeof (argstate->cap.data[ndx].c_un));
return (ndx);
}
break;
}
}
elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOCAELT),
EC_WORD(argstate->cap.sec->sec_shndx),
argstate->cap.sec->sec_name, argstate->cap.grp_start_ndx,
argstate->cap.grp_end_ndx, cap_group_id(argstate), arg);
return (0);
}
static Word
flag_bitop(ARGSTATE *argstate, Word orig, const elfedit_atoui_sym_t *const_sym)
{
Word flags = 0;
int i;
for (i = 0; i < argstate->argc; i++)
flags |= (Word) elfedit_atoui(argstate->argv[i], const_sym);
if (argstate->optmask & CAP_OPT_F_CMP)
flags = ~flags;
if (argstate->optmask & CAP_OPT_F_AND)
flags &= orig;
else if (argstate->optmask & CAP_OPT_F_OR)
flags |= orig;
return (flags);
}
static elfedit_cmdret_t
cap_set(ARGSTATE *argstate, Cap *cap, Word ndx, Word cap_ndx,
const char *cap_name, Xword cap_tag, elfedit_const_t const_type)
{
Conv_cap_val_buf_t buf1, buf2;
Half mach = argstate->obj_state->os_ehdr->e_machine;
Xword ncap, ocap;
ncap = flag_bitop(argstate, cap[ndx].c_un.c_val,
elfedit_const_to_atoui(const_type));
if ((ocap = cap[ndx].c_un.c_val) == ncap) {
elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_BSB_OK),
cap_ndx, cap_name, EC_WORD(ndx),
conv_cap_val(cap_tag, ocap, mach, CONV_FMT_NOBKT, &buf1));
return (ELFEDIT_CMDRET_NONE);
} else {
elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_BSB_CHG),
cap_ndx, cap_name, EC_WORD(ndx),
conv_cap_val(cap_tag, ocap, mach, CONV_FMT_NOBKT, &buf1),
conv_cap_val(cap_tag, ncap, mach, CONV_FMT_NOBKT, &buf2));
cap[ndx].c_un.c_val = ncap;
return (ELFEDIT_CMDRET_MOD);
}
}
static elfedit_cmdret_t
cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state,
int argc, const char *argv[])
{
ARGSTATE argstate;
Cap *cap;
const char *cap_name;
Word cap_ndx;
elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE;
PRINT_CAP_T print_type = PRINT_CAP_T_ALL;
Word ndx;
int print_only = 0;
int do_autoprint = 1;
process_args(obj_state, argc, argv, &argstate);
cap = argstate.cap.data;
cap_name = argstate.cap.sec->sec_name;
cap_ndx = argstate.cap.sec->sec_shndx;
switch (cmd) {
case CAP_CMD_T_DUMP:
if (argstate.argc > 1)
elfedit_command_usage();
print_only = 1;
if (argstate.argc == 1)
ndx = arg_to_index(&argstate, argstate.argv[0],
MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
break;
case CAP_CMD_T_TAG:
case CAP_CMD_T_VALUE:
print_only = (argstate.argc != 2);
if (argstate.argc > 0) {
if (argstate.argc > 2)
elfedit_command_usage();
ndx = arg_to_index(&argstate, argstate.argv[0],
MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
}
break;
case CAP_CMD_T_DELETE:
if ((argstate.argc < 1) || (argstate.argc > 2))
elfedit_command_usage();
ndx = arg_to_index(&argstate, argstate.argv[0],
MSG_ORIG(MSG_STR_ELT),
0, &print_type);
do_autoprint = 0;
break;
case CAP_CMD_T_MOVE:
if ((argstate.argc < 2) || (argstate.argc > 3))
elfedit_command_usage();
ndx = arg_to_index(&argstate, argstate.argv[0],
MSG_ORIG(MSG_STR_ELT), 0, &print_type);
do_autoprint = 0;
break;
case CAP_CMD_T_HW1:
print_only = (argstate.argc == 0);
ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
ELFEDIT_CONST_CA, CA_SUNW_HW_1, 1),
MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
break;
case CAP_CMD_T_SF1:
print_only = (argstate.argc == 0);
ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
ELFEDIT_CONST_CA, CA_SUNW_SF_1, 1),
MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
break;
case CAP_CMD_T_HW2:
print_only = (argstate.argc == 0);
ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
ELFEDIT_CONST_CA, CA_SUNW_HW_2, 1),
MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
break;
case CAP_CMD_T_HW3:
print_only = (argstate.argc == 0);
ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
ELFEDIT_CONST_CA, CA_SUNW_HW_3, 1),
MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
break;
default:
elfedit_command_usage();
break;
}
if (print_only) {
print_cap(cmd, 0, &argstate, print_type, ndx);
return (ELFEDIT_CMDRET_NONE);
}
switch (cmd) {
case CAP_CMD_T_TAG:
{
Conv_inv_buf_t inv_buf1, inv_buf2;
Word c_tag = (Word) elfedit_atoconst(argstate.argv[1],
ELFEDIT_CONST_CA);
if (cap[ndx].c_tag == c_tag) {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_S_OK),
cap_ndx, cap_name, EC_WORD(ndx),
conv_cap_tag(c_tag, 0, &inv_buf1));
} else {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_S_CHG),
cap_ndx, cap_name, EC_WORD(ndx),
conv_cap_tag(cap[ndx].c_tag, 0, &inv_buf1),
conv_cap_tag(c_tag, 0, &inv_buf2));
cap[ndx].c_tag = c_tag;
ret = ELFEDIT_CMDRET_MOD;
}
}
break;
case CAP_CMD_T_VALUE:
{
Xword c_val;
if (argstate.optmask & CAP_OPT_F_STRVAL) {
argstate_add_str(&argstate, TRUE);
c_val = elfedit_strtab_insert(obj_state,
argstate.str.sec, NULL, argstate.argv[1]);
} else {
c_val = (Xword)
elfedit_atoui(argstate.argv[1], NULL);
}
if (cap[ndx].c_un.c_val == c_val) {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_X_OK),
argstate.cap.sec->sec_shndx,
argstate.cap.sec->sec_name,
EC_WORD(ndx), EC_XWORD(c_val));
} else {
elfedit_msg(ELFEDIT_MSG_DEBUG,
MSG_INTL(MSG_DEBUG_X_CHG),
argstate.cap.sec->sec_shndx,
argstate.cap.sec->sec_name,
EC_WORD(ndx), EC_XWORD(cap[ndx].c_un.c_val),
EC_XWORD(c_val));
cap[ndx].c_un.c_val = c_val;
ret = ELFEDIT_CMDRET_MOD;
}
}
break;
case CAP_CMD_T_DELETE:
{
Word cnt = (argstate.argc == 1) ? 1 :
(Word) elfedit_atoui_range(argstate.argv[1],
MSG_ORIG(MSG_STR_COUNT), 1,
argstate.cap.grp_end_ndx - ndx + 1, NULL);
const char *msg_prefix =
elfedit_sec_msgprefix(argstate.cap.sec);
if ((ndx + cnt - 1) > argstate.cap.grp_end_ndx)
elfedit_msg(ELFEDIT_MSG_ERR,
MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
argstate.cap.grp_start_ndx,
argstate.cap.grp_end_ndx,
cap_group_id(&argstate));
elfedit_array_elts_delete(msg_prefix, cap, sizeof (Cap),
argstate.cap.grp_end_ndx + 1, ndx, cnt);
ret = ELFEDIT_CMDRET_MOD;
}
break;
case CAP_CMD_T_MOVE:
{
Cap save;
Word cnt;
Word dstndx;
const char *msg_prefix =
elfedit_sec_msgprefix(argstate.cap.sec);
dstndx = (Word)
elfedit_atoui_range(argstate.argv[1],
MSG_ORIG(MSG_STR_DST_INDEX),
argstate.cap.grp_start_ndx,
argstate.cap.grp_end_ndx, NULL);
if (argstate.argc == 2) {
cnt = 1;
} else {
Word max;
max = argstate.cap.grp_end_ndx -
((ndx > dstndx) ? ndx : dstndx) + 1;
cnt = (Word) elfedit_atoui_range(
argstate.argv[2], MSG_ORIG(MSG_STR_COUNT),
1, max, NULL);
}
if ((ndx < argstate.cap.grp_start_ndx) ||
((ndx + cnt) > argstate.cap.grp_end_ndx) ||
(dstndx < argstate.cap.grp_start_ndx) ||
((dstndx + cnt) > argstate.cap.grp_end_ndx))
elfedit_msg(ELFEDIT_MSG_ERR,
MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
argstate.cap.grp_start_ndx,
argstate.cap.grp_end_ndx,
cap_group_id(&argstate));
elfedit_array_elts_move(msg_prefix, cap, sizeof (save),
argstate.cap.grp_end_ndx + 1, ndx, dstndx,
cnt, &save);
ret = ELFEDIT_CMDRET_MOD;
}
break;
case CAP_CMD_T_HW1:
{
ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
CA_SUNW_HW_1, ELFEDIT_CONST_HW1_SUNW);
}
break;
case CAP_CMD_T_SF1:
{
ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
CA_SUNW_SF_1, ELFEDIT_CONST_SF1_SUNW);
}
break;
case CAP_CMD_T_HW2:
{
ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
CA_SUNW_HW_2, ELFEDIT_CONST_HW2_SUNW);
}
break;
case CAP_CMD_T_HW3:
{
ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
CA_SUNW_HW_3, ELFEDIT_CONST_HW3_SUNW);
}
break;
}
if (ret == ELFEDIT_CMDRET_MOD)
elfedit_modified_data(argstate.cap.sec);
if (do_autoprint)
print_cap(cmd, 1, &argstate, print_type, ndx);
return (ret);
}
static void
cpl_capid_opt(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
elfedit_section_t *cap_sec, *str_sec;
Cap *cap;
Word num;
if (obj_state == NULL)
return;
if ((argc > num_opt) || (argc < 2) ||
(strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_CAPID)) != 0))
return;
cap_sec = elfedit_sec_getcap(obj_state, &cap, &num);
if (cap_sec->sec_shdr->sh_info == 0)
return;
str_sec = elfedit_sec_getstr(obj_state, cap_sec->sec_shdr->sh_info, 0);
for (; num--; cap++)
if (cap->c_tag == CA_SUNW_ID)
elfedit_cpl_match(cpldata, elfedit_offset_to_str(
str_sec, cap->c_un.c_val, ELFEDIT_MSG_ERR, 0), 0);
}
static void
cpl_eltarg(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
Word i;
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
if ((argc - num_opt) != 1)
return;
for (i = 0; i < num_opt; i++)
if (strcmp(argv[i], MSG_ORIG(MSG_STR_MINUS_CAPNDX)) == 0)
return;
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA);
}
static void
cpl_tag(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
if ((argc - num_opt) == 1) {
cpl_eltarg(obj_state, cpldata, argc, argv, num_opt);
return;
}
if ((argc - num_opt) == 2)
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA);
}
static void
cpl_hw1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW1_SUNW);
}
static void
cpl_sf1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SF1_SUNW);
}
static void
cpl_hw2(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW2_SUNW);
}
static void
cpl_hw3(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
const char *argv[], int num_opt)
{
if (argc <= num_opt) {
cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt);
return;
}
elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_HW3_SUNW);
}
static elfedit_cmdret_t
cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_DUMP, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_tag(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_TAG, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_value(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_VALUE, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_DELETE, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_MOVE, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_hw1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_HW1, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_sf1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_SF1, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_hw2(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_HW2, obj_state, argc, argv));
}
static elfedit_cmdret_t
cmd_hw3(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
{
return (cmd_body(CAP_CMD_T_HW3, obj_state, argc, argv));
}
elfedit_module_t *
elfedit_init(elfedit_module_version_t version)
{
static elfedit_cmd_optarg_t opt_ostyle_capid_bitop[] = {
{ ELFEDIT_STDOA_OPT_AND, 0,
ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_AND, CAP_OPT_F_OR },
{ MSG_ORIG(MSG_STR_MINUS_CAPID),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
{ MSG_ORIG(MSG_STR_IDNAME), 0, 0 },
{ ELFEDIT_STDOA_OPT_CMP, 0,
ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_CMP, 0 },
{ ELFEDIT_STDOA_OPT_O, 0,
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
{ ELFEDIT_STDOA_OPT_OR, 0,
ELFEDIT_CMDOA_F_INHERIT, CAP_OPT_F_OR, CAP_OPT_F_AND },
{ NULL }
};
static elfedit_cmd_optarg_t opt_capid_capndx[] = {
{ MSG_ORIG(MSG_STR_MINUS_CAPID),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
{ MSG_ORIG(MSG_STR_IDNAME), 0, 0 },
{ MSG_ORIG(MSG_STR_MINUS_CAPNDX),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
CAP_OPT_F_CAPNDX, CAP_OPT_F_CAPID },
{ NULL }
};
static const char *name_dump[] = {
MSG_ORIG(MSG_CMD_DUMP),
MSG_ORIG(MSG_STR_EMPTY),
NULL
};
static elfedit_cmd_optarg_t arg_dump[] = {
{ MSG_ORIG(MSG_STR_ELT),
ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
ELFEDIT_CMDOA_F_OPT },
{ NULL }
};
static const char *name_tag[] = { MSG_ORIG(MSG_CMD_TAG), NULL };
static elfedit_cmd_optarg_t opt_tag[] = {
{ MSG_ORIG(MSG_STR_MINUS_CAPID),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
{ MSG_ORIG(MSG_STR_IDNAME), 0, 0 },
{ MSG_ORIG(MSG_STR_MINUS_CAPNDX),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
CAP_OPT_F_CAPNDX, 0 },
{ ELFEDIT_STDOA_OPT_O, 0,
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
{ NULL }
};
static elfedit_cmd_optarg_t arg_tag[] = {
{ MSG_ORIG(MSG_STR_ELT),
ELFEDIT_I18NHDL(MSG_A1_TAG_ELT),
ELFEDIT_CMDOA_F_OPT },
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A2_TAG_VALUE),
ELFEDIT_CMDOA_F_OPT },
{ NULL }
};
static const char *name_value[] = { MSG_ORIG(MSG_CMD_VALUE), NULL };
static elfedit_cmd_optarg_t opt_value[] = {
{ MSG_ORIG(MSG_STR_MINUS_CAPID),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPID), ELFEDIT_CMDOA_F_VALUE,
CAP_OPT_F_CAPID, CAP_OPT_F_CAPNDX },
{ MSG_ORIG(MSG_STR_IDNAME), 0, 0 },
{ MSG_ORIG(MSG_STR_MINUS_CAPNDX),
ELFEDIT_I18NHDL(MSG_OPTDESC_CAPNDX), 0,
CAP_OPT_F_CAPNDX, 0 },
{ ELFEDIT_STDOA_OPT_O, 0,
ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
{ MSG_ORIG(MSG_STR_MINUS_S),
ELFEDIT_I18NHDL(MSG_OPTDESC_S), 0,
CAP_OPT_F_STRVAL, 0 },
{ NULL }
};
static elfedit_cmd_optarg_t arg_value[] = {
{ MSG_ORIG(MSG_STR_ELT),
ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
ELFEDIT_CMDOA_F_OPT },
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A2_VALUE_VALUE),
ELFEDIT_CMDOA_F_OPT },
{ NULL }
};
static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL };
static elfedit_cmd_optarg_t arg_delete[] = {
{ MSG_ORIG(MSG_STR_ELT),
ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
0 },
{ MSG_ORIG(MSG_STR_COUNT),
ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT),
ELFEDIT_CMDOA_F_OPT },
{ NULL }
};
static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL };
static elfedit_cmd_optarg_t arg_move[] = {
{ MSG_ORIG(MSG_STR_ELT),
ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
0 },
{ MSG_ORIG(MSG_STR_DST_INDEX),
ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX),
0 },
{ MSG_ORIG(MSG_STR_COUNT),
ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT),
ELFEDIT_CMDOA_F_OPT },
{ NULL }
};
static const char *name_hw1[] = { MSG_ORIG(MSG_CMD_HW1), NULL };
static elfedit_cmd_optarg_t arg_hw1[] = {
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A1_HW1_VALUE),
ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
{ NULL }
};
static const char *name_sf1[] = { MSG_ORIG(MSG_CMD_SF1), NULL };
static elfedit_cmd_optarg_t arg_sf1[] = {
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A1_SF1_VALUE),
ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
{ NULL }
};
static const char *name_hw2[] = { MSG_ORIG(MSG_CMD_HW2), NULL };
static elfedit_cmd_optarg_t arg_hw2[] = {
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A1_HW2_VALUE),
ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
{ NULL }
};
static const char *name_hw3[] = { MSG_ORIG(MSG_CMD_HW3), NULL };
static elfedit_cmd_optarg_t arg_hw3[] = {
{ MSG_ORIG(MSG_STR_VALUE),
ELFEDIT_I18NHDL(MSG_A1_HW3_VALUE),
ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
{ NULL }
};
static elfedit_cmd_t cmds[] = {
{ cmd_dump, cpl_eltarg, name_dump,
ELFEDIT_I18NHDL(MSG_DESC_DUMP),
ELFEDIT_I18NHDL(MSG_HELP_DUMP),
opt_capid_capndx, arg_dump },
{ cmd_tag, cpl_tag, name_tag,
ELFEDIT_I18NHDL(MSG_DESC_TAG),
ELFEDIT_I18NHDL(MSG_HELP_TAG),
opt_tag, arg_tag },
{ cmd_value, cpl_eltarg, name_value,
ELFEDIT_I18NHDL(MSG_DESC_VALUE),
ELFEDIT_I18NHDL(MSG_HELP_VALUE),
opt_value, arg_value },
{ cmd_delete, cpl_eltarg, name_delete,
ELFEDIT_I18NHDL(MSG_DESC_DELETE),
ELFEDIT_I18NHDL(MSG_HELP_DELETE),
opt_capid_capndx, arg_delete },
{ cmd_move, cpl_eltarg, name_move,
ELFEDIT_I18NHDL(MSG_DESC_MOVE),
ELFEDIT_I18NHDL(MSG_HELP_MOVE),
opt_capid_capndx, arg_move },
{ cmd_hw1, cpl_hw1, name_hw1,
ELFEDIT_I18NHDL(MSG_DESC_HW1),
ELFEDIT_I18NHDL(MSG_HELP_HW1),
opt_ostyle_capid_bitop, arg_hw1 },
{ cmd_sf1, cpl_sf1, name_sf1,
ELFEDIT_I18NHDL(MSG_DESC_SF1),
ELFEDIT_I18NHDL(MSG_HELP_SF1),
opt_ostyle_capid_bitop, arg_sf1 },
{ cmd_hw2, cpl_hw2, name_hw2,
ELFEDIT_I18NHDL(MSG_DESC_HW2),
ELFEDIT_I18NHDL(MSG_HELP_HW2),
opt_ostyle_capid_bitop, arg_hw2 },
{ cmd_hw3, cpl_hw3, name_hw3,
ELFEDIT_I18NHDL(MSG_DESC_HW3),
ELFEDIT_I18NHDL(MSG_HELP_HW3),
opt_ostyle_capid_bitop, arg_hw3 },
{ NULL }
};
static elfedit_module_t module = {
ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
ELFEDIT_I18NHDL(MSG_MOD_DESC),
cmds, mod_i18nhdl_to_str };
return (&module);
}