1*5088Sab196087 /* 2*5088Sab196087 * CDDL HEADER START 3*5088Sab196087 * 4*5088Sab196087 * The contents of this file are subject to the terms of the 5*5088Sab196087 * Common Development and Distribution License (the "License"). 6*5088Sab196087 * You may not use this file except in compliance with the License. 7*5088Sab196087 * 8*5088Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5088Sab196087 * or http://www.opensolaris.org/os/licensing. 10*5088Sab196087 * See the License for the specific language governing permissions 11*5088Sab196087 * and limitations under the License. 12*5088Sab196087 * 13*5088Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 14*5088Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5088Sab196087 * If applicable, add the following below this CDDL HEADER, with the 16*5088Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 17*5088Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 18*5088Sab196087 * 19*5088Sab196087 * CDDL HEADER END 20*5088Sab196087 */ 21*5088Sab196087 22*5088Sab196087 /* 23*5088Sab196087 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5088Sab196087 * Use is subject to license terms. 25*5088Sab196087 */ 26*5088Sab196087 #pragma ident "%Z%%M% %I% %E% SMI" 27*5088Sab196087 28*5088Sab196087 #define ELF_TARGET_AMD64 /* SHN_AMD64_LCOMMON */ 29*5088Sab196087 30*5088Sab196087 #include <stdio.h> 31*5088Sab196087 #include <unistd.h> 32*5088Sab196087 #include <machdep.h> 33*5088Sab196087 #include <elfedit.h> 34*5088Sab196087 #include <strings.h> 35*5088Sab196087 #include <debug.h> 36*5088Sab196087 #include <conv.h> 37*5088Sab196087 #include <sym_msg.h> 38*5088Sab196087 39*5088Sab196087 40*5088Sab196087 41*5088Sab196087 42*5088Sab196087 #define MAXNDXSIZE 10 43*5088Sab196087 44*5088Sab196087 45*5088Sab196087 46*5088Sab196087 /* 47*5088Sab196087 * This module uses shared code for several of the commands. 48*5088Sab196087 * It is sometimes necessary to know which specific command 49*5088Sab196087 * is active. 50*5088Sab196087 */ 51*5088Sab196087 typedef enum { 52*5088Sab196087 SYM_CMD_T_DUMP = 0, /* sym:dump */ 53*5088Sab196087 54*5088Sab196087 SYM_CMD_T_ST_BIND = 1, /* sym:st_bind */ 55*5088Sab196087 SYM_CMD_T_ST_INFO = 2, /* sym:st_info */ 56*5088Sab196087 SYM_CMD_T_ST_NAME = 3, /* sym:st_name */ 57*5088Sab196087 SYM_CMD_T_ST_OTHER = 4, /* sym:st_other */ 58*5088Sab196087 SYM_CMD_T_ST_SHNDX = 5, /* sym:st_shndx */ 59*5088Sab196087 SYM_CMD_T_ST_SIZE = 6, /* sym:st_size */ 60*5088Sab196087 SYM_CMD_T_ST_TYPE = 7, /* sym:st_type */ 61*5088Sab196087 SYM_CMD_T_ST_VALUE = 8, /* sym:st_value */ 62*5088Sab196087 SYM_CMD_T_ST_VISIBILITY = 9 /* sym:st_visibility */ 63*5088Sab196087 } SYM_CMD_T; 64*5088Sab196087 65*5088Sab196087 66*5088Sab196087 67*5088Sab196087 /* 68*5088Sab196087 * ELFCLASS-specific definitions 69*5088Sab196087 */ 70*5088Sab196087 #ifdef _ELF64 71*5088Sab196087 72*5088Sab196087 #define MSG_FMT_XWORDVALNL MSG_FMT_XWORDVALNL_64 73*5088Sab196087 74*5088Sab196087 #else 75*5088Sab196087 76*5088Sab196087 #define MSG_FMT_XWORDVALNL MSG_FMT_XWORDVALNL_32 77*5088Sab196087 78*5088Sab196087 /* 79*5088Sab196087 * We supply this function for the msg module. Only one copy is needed. 80*5088Sab196087 */ 81*5088Sab196087 const char * 82*5088Sab196087 _sym_msg(Msg mid) 83*5088Sab196087 { 84*5088Sab196087 return (gettext(MSG_ORIG(mid))); 85*5088Sab196087 } 86*5088Sab196087 87*5088Sab196087 #endif 88*5088Sab196087 89*5088Sab196087 90*5088Sab196087 91*5088Sab196087 /* 92*5088Sab196087 * This function is supplied to elfedit through our elfedit_module_t 93*5088Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles 94*5088Sab196087 * in our module interface into the actual strings for elfedit to 95*5088Sab196087 * use. 96*5088Sab196087 * 97*5088Sab196087 * note: 98*5088Sab196087 * This module uses Msg codes for its i18n handle type. 99*5088Sab196087 * So the translation is simply to use MSG_INTL() to turn 100*5088Sab196087 * it into a string and return it. 101*5088Sab196087 */ 102*5088Sab196087 static const char * 103*5088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 104*5088Sab196087 { 105*5088Sab196087 Msg msg = (Msg)hdl; 106*5088Sab196087 107*5088Sab196087 return (MSG_INTL(msg)); 108*5088Sab196087 } 109*5088Sab196087 110*5088Sab196087 111*5088Sab196087 112*5088Sab196087 /* 113*5088Sab196087 * The sym_opt_t enum specifies a bit value for every optional 114*5088Sab196087 * argument allowed by a command in this module. 115*5088Sab196087 */ 116*5088Sab196087 typedef enum { 117*5088Sab196087 SYM_OPT_F_XSHINDEX = 1, /* -e: Force shndx update to extended */ 118*5088Sab196087 /* index section */ 119*5088Sab196087 SYM_OPT_F_NAMOFFSET = 2, /* -name_offset: sym:st_name name arg */ 120*5088Sab196087 /* is numeric offset */ 121*5088Sab196087 /* rather than ASCII string */ 122*5088Sab196087 SYM_OPT_F_SECSHNDX = 4, /* -secshndx: Section arg is */ 123*5088Sab196087 /* section index, not name */ 124*5088Sab196087 SYM_OPT_F_SECSHTYP = 8, /* -secshtyp: Section arg is */ 125*5088Sab196087 /* section type, not name */ 126*5088Sab196087 SYM_OPT_F_SHNAME = 16, /* -shnam name: section spec. by name */ 127*5088Sab196087 SYM_OPT_F_SHNDX = 32, /* -shndx ndx: section spec. by index */ 128*5088Sab196087 SYM_OPT_F_SHTYP = 64, /* -shtyp type: section spec. by type */ 129*5088Sab196087 SYM_OPT_F_SYMNDX = 128 /* -symndx: Sym specified by index */ 130*5088Sab196087 } sym_opt_t; 131*5088Sab196087 132*5088Sab196087 133*5088Sab196087 /* 134*5088Sab196087 * A variable of type ARGSTATE is used by each command to maintain 135*5088Sab196087 * the overall state for a given set of arguments and the symbol tables 136*5088Sab196087 * being managed. 137*5088Sab196087 * 138*5088Sab196087 * The state for each symbol table and the auxiliary sections that are 139*5088Sab196087 * related to it are kept in a SYMSTATE sub-struct. 140*5088Sab196087 * 141*5088Sab196087 * One benefit of ARGSTATE is that it helps us to ensure that we only 142*5088Sab196087 * fetch each section a single time: 143*5088Sab196087 * - More efficient 144*5088Sab196087 * - Prevents multiple ELFEDIT_MSG_DEBUG messages from 145*5088Sab196087 * being produced for a given section. 146*5088Sab196087 * 147*5088Sab196087 * note: The symstate array in ARGSTATE is defined as having one 148*5088Sab196087 * element, but in reality, we allocate enough room for 149*5088Sab196087 * the number of elements defined in the numsymstate field. 150*5088Sab196087 */ 151*5088Sab196087 typedef struct { 152*5088Sab196087 Word ndx; /* If argstate.argc > 0, this is the table index */ 153*5088Sab196087 struct { /* Symbol table */ 154*5088Sab196087 elfedit_section_t *sec; 155*5088Sab196087 Sym *data; 156*5088Sab196087 Word n; 157*5088Sab196087 } sym; 158*5088Sab196087 struct { /* String table */ 159*5088Sab196087 elfedit_section_t *sec; 160*5088Sab196087 } str; 161*5088Sab196087 struct { /* Versym */ 162*5088Sab196087 Word shndx; 163*5088Sab196087 elfedit_section_t *sec; 164*5088Sab196087 Versym *data; 165*5088Sab196087 Word n; 166*5088Sab196087 } versym; 167*5088Sab196087 struct { /* Extended section indices */ 168*5088Sab196087 Word shndx; 169*5088Sab196087 elfedit_section_t *sec; 170*5088Sab196087 Word *data; 171*5088Sab196087 Word n; 172*5088Sab196087 } xshndx; 173*5088Sab196087 } SYMSTATE; 174*5088Sab196087 typedef struct { 175*5088Sab196087 elfedit_obj_state_t *obj_state; 176*5088Sab196087 sym_opt_t optmask; /* Mask of options used */ 177*5088Sab196087 int argc; /* # of plain arguments */ 178*5088Sab196087 const char **argv; /* Plain arguments */ 179*5088Sab196087 int numsymstate; /* # of items in symstate[] */ 180*5088Sab196087 SYMSTATE symstate[1]; /* Symbol tables to process */ 181*5088Sab196087 } ARGSTATE; 182*5088Sab196087 183*5088Sab196087 184*5088Sab196087 /* 185*5088Sab196087 * We maintain the state of each symbol table and related associated 186*5088Sab196087 * sections in a SYMSTATE structure . We don't look those auxiliary 187*5088Sab196087 * things up unless we actually need them, both to be efficient, 188*5088Sab196087 * and to prevent duplicate ELFEDIT_MSG_DEBUG messages from being 189*5088Sab196087 * issued as they are located. Hence, process_args() is used to 190*5088Sab196087 * initialize the state block with just the symbol table, and then one 191*5088Sab196087 * of the argstate_add_XXX() functions is used as needed 192*5088Sab196087 * to fetch the additional sections. 193*5088Sab196087 * 194*5088Sab196087 * entry: 195*5088Sab196087 * argstate - Overall state block 196*5088Sab196087 * symstate - State block for current symbol table. 197*5088Sab196087 * 198*5088Sab196087 * exit: 199*5088Sab196087 * If the needed auxiliary section is not found, an error is 200*5088Sab196087 * issued and the argstate_add_XXX() routine does not return. 201*5088Sab196087 * Otherwise, the fields in argstate have been filled in, ready 202*5088Sab196087 * for use. 203*5088Sab196087 * 204*5088Sab196087 */ 205*5088Sab196087 static void 206*5088Sab196087 symstate_add_str(ARGSTATE *argstate, SYMSTATE *symstate) 207*5088Sab196087 { 208*5088Sab196087 if (symstate->str.sec != NULL) 209*5088Sab196087 return; 210*5088Sab196087 211*5088Sab196087 symstate->str.sec = elfedit_sec_getstr(argstate->obj_state, 212*5088Sab196087 symstate->sym.sec->sec_shdr->sh_link); 213*5088Sab196087 } 214*5088Sab196087 static void 215*5088Sab196087 symstate_add_versym(ARGSTATE *argstate, SYMSTATE *symstate) 216*5088Sab196087 { 217*5088Sab196087 if (symstate->versym.sec != NULL) 218*5088Sab196087 return; 219*5088Sab196087 220*5088Sab196087 symstate->versym.sec = elfedit_sec_getversym(argstate->obj_state, 221*5088Sab196087 symstate->sym.sec, &symstate->versym.data, &symstate->versym.n); 222*5088Sab196087 } 223*5088Sab196087 static void 224*5088Sab196087 symstate_add_xshndx(ARGSTATE *argstate, SYMSTATE *symstate) 225*5088Sab196087 { 226*5088Sab196087 if (symstate->xshndx.sec != NULL) 227*5088Sab196087 return; 228*5088Sab196087 229*5088Sab196087 symstate->xshndx.sec = elfedit_sec_getxshndx(argstate->obj_state, 230*5088Sab196087 symstate->sym.sec, &symstate->xshndx.data, &symstate->xshndx.n); 231*5088Sab196087 } 232*5088Sab196087 233*5088Sab196087 234*5088Sab196087 235*5088Sab196087 /* 236*5088Sab196087 * Display symbol table entries in the style used by elfdump. 237*5088Sab196087 * 238*5088Sab196087 * entry: 239*5088Sab196087 * argstate - Overall state block 240*5088Sab196087 * symstate - State block for current symbol table. 241*5088Sab196087 * ndx - Index of first symbol to display 242*5088Sab196087 * cnt - Number of symbols to display 243*5088Sab196087 */ 244*5088Sab196087 static void 245*5088Sab196087 dump_symtab(ARGSTATE *argstate, SYMSTATE *symstate, Word ndx, Word cnt) 246*5088Sab196087 { 247*5088Sab196087 char index[MAXNDXSIZE]; 248*5088Sab196087 Word shndx; 249*5088Sab196087 const char *shndx_name; 250*5088Sab196087 elfedit_section_t *symsec; 251*5088Sab196087 elfedit_section_t *strsec; 252*5088Sab196087 Sym *sym; 253*5088Sab196087 elfedit_obj_state_t *obj_state = argstate->obj_state; 254*5088Sab196087 Half mach = obj_state->os_ehdr->e_machine; 255*5088Sab196087 const char *symname; 256*5088Sab196087 Versym versym; 257*5088Sab196087 258*5088Sab196087 symsec = symstate->sym.sec; 259*5088Sab196087 sym = symstate->sym.data + ndx; 260*5088Sab196087 261*5088Sab196087 symstate_add_str(argstate, symstate); 262*5088Sab196087 strsec = symstate->str.sec; 263*5088Sab196087 264*5088Sab196087 /* If there is a versym index section, fetch it */ 265*5088Sab196087 if (symstate->versym.shndx != SHN_UNDEF) 266*5088Sab196087 symstate_add_versym(argstate, symstate); 267*5088Sab196087 268*5088Sab196087 /* If there is an extended index section, fetch it */ 269*5088Sab196087 if (symstate->xshndx.shndx != SHN_UNDEF) 270*5088Sab196087 symstate_add_xshndx(argstate, symstate); 271*5088Sab196087 272*5088Sab196087 elfedit_printf(MSG_INTL(MSG_FMT_SYMTAB), symsec->sec_name); 273*5088Sab196087 Elf_syms_table_title(0, ELF_DBG_ELFDUMP); 274*5088Sab196087 for (; cnt-- > 0; ndx++, sym++) { 275*5088Sab196087 (void) snprintf(index, MAXNDXSIZE, 276*5088Sab196087 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(ndx)); 277*5088Sab196087 versym = (symstate->versym.sec == NULL) ? 0 : 278*5088Sab196087 symstate->versym.data[ndx]; 279*5088Sab196087 symname = elfedit_offset_to_str(strsec, sym->st_name, 280*5088Sab196087 ELFEDIT_MSG_DEBUG, 0); 281*5088Sab196087 shndx = sym->st_shndx; 282*5088Sab196087 if ((shndx == SHN_XINDEX) && (symstate->xshndx.sec != NULL)) 283*5088Sab196087 shndx = symstate->xshndx.data[ndx]; 284*5088Sab196087 shndx_name = elfedit_shndx_to_name(obj_state, shndx); 285*5088Sab196087 Elf_syms_table_entry(NULL, ELF_DBG_ELFDUMP, index, mach, 286*5088Sab196087 sym, versym, 0, shndx_name, symname); 287*5088Sab196087 } 288*5088Sab196087 } 289*5088Sab196087 290*5088Sab196087 291*5088Sab196087 292*5088Sab196087 /* 293*5088Sab196087 * Called by print_sym() to determine if a given symbol has the same 294*5088Sab196087 * display value for the current command in every symbol table. 295*5088Sab196087 * 296*5088Sab196087 * entry: 297*5088Sab196087 * cmd - SYM_CMD_T_* value giving identify of caller 298*5088Sab196087 * argstate - Overall state block 299*5088Sab196087 * outstyle - Output style to use 300*5088Sab196087 */ 301*5088Sab196087 static int 302*5088Sab196087 all_same(SYM_CMD_T cmd, ARGSTATE *argstate, elfedit_outstyle_t outstyle) 303*5088Sab196087 { 304*5088Sab196087 Word tblndx; 305*5088Sab196087 SYMSTATE *symstate1, *symstate2; 306*5088Sab196087 Sym *sym1, *sym2; 307*5088Sab196087 308*5088Sab196087 symstate1 = argstate->symstate; 309*5088Sab196087 for (tblndx = 0; tblndx < (argstate->numsymstate - 1); 310*5088Sab196087 tblndx++, symstate1++) { 311*5088Sab196087 symstate2 = symstate1 + 1; 312*5088Sab196087 sym1 = &symstate1->sym.data[symstate1->ndx]; 313*5088Sab196087 sym2 = &symstate2->sym.data[symstate2->ndx]; 314*5088Sab196087 315*5088Sab196087 switch (cmd) { 316*5088Sab196087 case SYM_CMD_T_DUMP: 317*5088Sab196087 /* sym:dump should always show everything */ 318*5088Sab196087 return (0); 319*5088Sab196087 320*5088Sab196087 case SYM_CMD_T_ST_BIND: 321*5088Sab196087 if (ELF_ST_BIND(sym1->st_info) != 322*5088Sab196087 ELF_ST_BIND(sym2->st_info)) 323*5088Sab196087 return (0); 324*5088Sab196087 break; 325*5088Sab196087 326*5088Sab196087 case SYM_CMD_T_ST_INFO: 327*5088Sab196087 if (sym1->st_info != sym2->st_info) 328*5088Sab196087 return (0); 329*5088Sab196087 break; 330*5088Sab196087 331*5088Sab196087 case SYM_CMD_T_ST_NAME: 332*5088Sab196087 /* 333*5088Sab196087 * In simple output mode, we show the string. In 334*5088Sab196087 * numeric mode, we show the string table offset. 335*5088Sab196087 */ 336*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 337*5088Sab196087 const char *n1, *n2; 338*5088Sab196087 339*5088Sab196087 symstate_add_str(argstate, symstate1); 340*5088Sab196087 symstate_add_str(argstate, symstate2); 341*5088Sab196087 n1 = elfedit_offset_to_str(symstate1->str.sec, 342*5088Sab196087 sym1->st_name, ELFEDIT_MSG_DEBUG, 0); 343*5088Sab196087 n2 = elfedit_offset_to_str(symstate2->str.sec, 344*5088Sab196087 sym2->st_name, ELFEDIT_MSG_DEBUG, 0); 345*5088Sab196087 if (strcmp(n1, n2) != 0) 346*5088Sab196087 return (0); 347*5088Sab196087 } else { 348*5088Sab196087 if (sym1->st_name != sym2->st_name) 349*5088Sab196087 return (0); 350*5088Sab196087 } 351*5088Sab196087 break; 352*5088Sab196087 353*5088Sab196087 case SYM_CMD_T_ST_OTHER: 354*5088Sab196087 if (sym1->st_other != sym2->st_other) 355*5088Sab196087 return (0); 356*5088Sab196087 break; 357*5088Sab196087 358*5088Sab196087 case SYM_CMD_T_ST_SHNDX: 359*5088Sab196087 { 360*5088Sab196087 Word ndx1, ndx2; 361*5088Sab196087 362*5088Sab196087 ndx1 = sym1->st_shndx; 363*5088Sab196087 if ((ndx1 == SHN_XINDEX) && 364*5088Sab196087 (symstate1->xshndx.shndx != SHN_UNDEF)) { 365*5088Sab196087 symstate_add_xshndx(argstate, 366*5088Sab196087 symstate1); 367*5088Sab196087 ndx1 = symstate1->xshndx. 368*5088Sab196087 data[symstate1->ndx]; 369*5088Sab196087 } 370*5088Sab196087 ndx2 = sym2->st_shndx; 371*5088Sab196087 if ((ndx2 == SHN_XINDEX) && 372*5088Sab196087 (symstate2->xshndx.shndx != SHN_UNDEF)) { 373*5088Sab196087 symstate_add_xshndx(argstate, 374*5088Sab196087 symstate2); 375*5088Sab196087 ndx2 = symstate2->xshndx. 376*5088Sab196087 data[symstate2->ndx]; 377*5088Sab196087 } 378*5088Sab196087 if (ndx1 != ndx2) 379*5088Sab196087 return (0); 380*5088Sab196087 } 381*5088Sab196087 break; 382*5088Sab196087 383*5088Sab196087 case SYM_CMD_T_ST_SIZE: 384*5088Sab196087 if (sym1->st_size != sym2->st_size) 385*5088Sab196087 return (0); 386*5088Sab196087 break; 387*5088Sab196087 388*5088Sab196087 case SYM_CMD_T_ST_TYPE: 389*5088Sab196087 if (ELF_ST_TYPE(sym1->st_info) != 390*5088Sab196087 ELF_ST_TYPE(sym2->st_info)) 391*5088Sab196087 return (0); 392*5088Sab196087 break; 393*5088Sab196087 394*5088Sab196087 case SYM_CMD_T_ST_VALUE: 395*5088Sab196087 if (sym1->st_value != sym2->st_value) 396*5088Sab196087 return (0); 397*5088Sab196087 break; 398*5088Sab196087 399*5088Sab196087 case SYM_CMD_T_ST_VISIBILITY: 400*5088Sab196087 if (ELF_ST_VISIBILITY(sym1->st_info) != 401*5088Sab196087 ELF_ST_VISIBILITY(sym2->st_info)) 402*5088Sab196087 return (0); 403*5088Sab196087 break; 404*5088Sab196087 } 405*5088Sab196087 } 406*5088Sab196087 407*5088Sab196087 /* If we got here, there are no differences (or maybe only 1 table */ 408*5088Sab196087 return (1); 409*5088Sab196087 } 410*5088Sab196087 411*5088Sab196087 412*5088Sab196087 /* 413*5088Sab196087 * Called by print_sym() to display values for a single symbol table. 414*5088Sab196087 * 415*5088Sab196087 * entry: 416*5088Sab196087 * autoprint - If True, output is only produced if the elfedit 417*5088Sab196087 * autoprint flag is set. If False, output is always produced. 418*5088Sab196087 * cmd - SYM_CMD_T_* value giving identify of caller 419*5088Sab196087 * argstate - Overall state block 420*5088Sab196087 * symstate - State block for current symbol table. 421*5088Sab196087 * ndx - Index of first symbol to display 422*5088Sab196087 * cnt - Number of symbols to display 423*5088Sab196087 */ 424*5088Sab196087 static void 425*5088Sab196087 print_symstate(SYM_CMD_T cmd, ARGSTATE *argstate, SYMSTATE *symstate, 426*5088Sab196087 elfedit_outstyle_t outstyle, Word ndx, Word cnt) 427*5088Sab196087 { 428*5088Sab196087 Word value; 429*5088Sab196087 Sym *sym; 430*5088Sab196087 431*5088Sab196087 /* 432*5088Sab196087 * If doing default output, use elfdump style where we 433*5088Sab196087 * show all symbol attributes. In this case, the command 434*5088Sab196087 * that called us doesn't matter 435*5088Sab196087 */ 436*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { 437*5088Sab196087 dump_symtab(argstate, symstate, ndx, cnt); 438*5088Sab196087 return; 439*5088Sab196087 } 440*5088Sab196087 441*5088Sab196087 sym = symstate->sym.data; 442*5088Sab196087 443*5088Sab196087 switch (cmd) { 444*5088Sab196087 case SYM_CMD_T_ST_BIND: 445*5088Sab196087 { 446*5088Sab196087 Conv_inv_buf_t inv_buf; 447*5088Sab196087 448*5088Sab196087 for (sym += ndx; cnt--; sym++) { 449*5088Sab196087 value = ELF_ST_BIND(sym->st_info); 450*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 451*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 452*5088Sab196087 conv_sym_info_bind(value, 453*5088Sab196087 CONV_FMT_ALT_FULLNAME, &inv_buf)); 454*5088Sab196087 } else { 455*5088Sab196087 elfedit_printf( 456*5088Sab196087 MSG_ORIG(MSG_FMT_WORDVALNL), 457*5088Sab196087 EC_WORD(value)); 458*5088Sab196087 } 459*5088Sab196087 } 460*5088Sab196087 } 461*5088Sab196087 return; 462*5088Sab196087 463*5088Sab196087 case SYM_CMD_T_ST_INFO: 464*5088Sab196087 for (sym += ndx; cnt-- > 0; sym++) 465*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 466*5088Sab196087 EC_WORD(sym->st_info)); 467*5088Sab196087 return; 468*5088Sab196087 469*5088Sab196087 case SYM_CMD_T_ST_NAME: 470*5088Sab196087 /* 471*5088Sab196087 * In simple output mode, we show the string. In numeric 472*5088Sab196087 * mode, we show the string table offset. 473*5088Sab196087 */ 474*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 475*5088Sab196087 symstate_add_str(argstate, symstate); 476*5088Sab196087 for (sym += ndx; cnt--; sym++) { 477*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 478*5088Sab196087 elfedit_offset_to_str(symstate->str.sec, 479*5088Sab196087 sym->st_name, ELFEDIT_MSG_ERR, 0)); 480*5088Sab196087 } 481*5088Sab196087 } else { 482*5088Sab196087 for (; cnt--; sym++) 483*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 484*5088Sab196087 EC_WORD(sym->st_name)); 485*5088Sab196087 } 486*5088Sab196087 return; 487*5088Sab196087 488*5088Sab196087 case SYM_CMD_T_ST_OTHER: 489*5088Sab196087 for (sym += ndx; cnt-- > 0; sym++) 490*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 491*5088Sab196087 EC_WORD(sym->st_other)); 492*5088Sab196087 return; 493*5088Sab196087 494*5088Sab196087 case SYM_CMD_T_ST_SHNDX: 495*5088Sab196087 /* If there is an extended index section, fetch it */ 496*5088Sab196087 if (symstate->xshndx.shndx != SHN_UNDEF) 497*5088Sab196087 symstate_add_xshndx(argstate, symstate); 498*5088Sab196087 499*5088Sab196087 for (; cnt--; ndx++) { 500*5088Sab196087 value = sym[ndx].st_shndx; 501*5088Sab196087 if ((value == SHN_XINDEX) && 502*5088Sab196087 (symstate->xshndx.sec != NULL)) 503*5088Sab196087 value = symstate->xshndx.data[ndx]; 504*5088Sab196087 505*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 506*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 507*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, 508*5088Sab196087 value)); 509*5088Sab196087 } else { 510*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_WORDVALNL), 511*5088Sab196087 EC_WORD(value)); 512*5088Sab196087 } 513*5088Sab196087 } 514*5088Sab196087 return; 515*5088Sab196087 516*5088Sab196087 case SYM_CMD_T_ST_SIZE: 517*5088Sab196087 /* 518*5088Sab196087 * machine word width integers displayed in fixed width 519*5088Sab196087 * 0-filled hex format. 520*5088Sab196087 */ 521*5088Sab196087 for (sym += ndx; cnt--; sym++) 522*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDVALNL), 523*5088Sab196087 sym->st_size); 524*5088Sab196087 return; 525*5088Sab196087 526*5088Sab196087 case SYM_CMD_T_ST_TYPE: 527*5088Sab196087 { 528*5088Sab196087 Half mach = argstate->obj_state->os_ehdr->e_machine; 529*5088Sab196087 Conv_inv_buf_t inv_buf; 530*5088Sab196087 531*5088Sab196087 for (sym += ndx; cnt--; sym++) { 532*5088Sab196087 value = ELF_ST_TYPE(sym->st_info); 533*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 534*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 535*5088Sab196087 conv_sym_info_type(mach, value, 536*5088Sab196087 CONV_FMT_ALT_FULLNAME, &inv_buf)); 537*5088Sab196087 } else { 538*5088Sab196087 elfedit_printf( 539*5088Sab196087 MSG_ORIG(MSG_FMT_WORDVALNL), 540*5088Sab196087 EC_WORD(value)); 541*5088Sab196087 } 542*5088Sab196087 } 543*5088Sab196087 } 544*5088Sab196087 return; 545*5088Sab196087 546*5088Sab196087 case SYM_CMD_T_ST_VALUE: 547*5088Sab196087 /* 548*5088Sab196087 * machine word width integers displayed in fixed width 549*5088Sab196087 * 0-filled hex format. 550*5088Sab196087 */ 551*5088Sab196087 for (sym += ndx; cnt--; sym++) 552*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_XWORDVALNL), 553*5088Sab196087 sym->st_value); 554*5088Sab196087 return; 555*5088Sab196087 556*5088Sab196087 case SYM_CMD_T_ST_VISIBILITY: 557*5088Sab196087 { 558*5088Sab196087 Conv_inv_buf_t inv_buf; 559*5088Sab196087 560*5088Sab196087 for (sym += ndx; cnt--; sym++) { 561*5088Sab196087 value = ELF_ST_VISIBILITY(sym->st_other); 562*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 563*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), 564*5088Sab196087 conv_sym_other_vis(value, 565*5088Sab196087 CONV_FMT_ALT_FULLNAME, &inv_buf)); 566*5088Sab196087 } else { 567*5088Sab196087 elfedit_printf( 568*5088Sab196087 MSG_ORIG(MSG_FMT_WORDVALNL), 569*5088Sab196087 EC_WORD(value)); 570*5088Sab196087 } 571*5088Sab196087 } 572*5088Sab196087 } 573*5088Sab196087 return; 574*5088Sab196087 575*5088Sab196087 } 576*5088Sab196087 } 577*5088Sab196087 578*5088Sab196087 579*5088Sab196087 /* 580*5088Sab196087 * Print symbol values, taking the calling command, and output style 581*5088Sab196087 * into account. 582*5088Sab196087 * 583*5088Sab196087 * entry: 584*5088Sab196087 * autoprint - If True, output is only produced if the elfedit 585*5088Sab196087 * autoprint flag is set. If False, output is always produced. 586*5088Sab196087 * cmd - SYM_CMD_T_* value giving identify of caller 587*5088Sab196087 * argstate - Overall state block 588*5088Sab196087 * symstate - State block for current symbol table. 589*5088Sab196087 * ndx - Index of first symbol to display 590*5088Sab196087 * cnt - Number of symbols to display 591*5088Sab196087 */ 592*5088Sab196087 static void 593*5088Sab196087 print_sym(SYM_CMD_T cmd, int autoprint, ARGSTATE *argstate) 594*5088Sab196087 { 595*5088Sab196087 Word ndx, tblndx; 596*5088Sab196087 Word cnt; 597*5088Sab196087 elfedit_outstyle_t outstyle; 598*5088Sab196087 SYMSTATE *symstate; 599*5088Sab196087 int only_one; 600*5088Sab196087 601*5088Sab196087 if ((autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))) 602*5088Sab196087 return; 603*5088Sab196087 604*5088Sab196087 /* 605*5088Sab196087 * Pick an output style. sym:dump is required to use the default 606*5088Sab196087 * style. The other commands use the current output style. 607*5088Sab196087 */ 608*5088Sab196087 outstyle = (cmd == SYM_CMD_T_DUMP) ? 609*5088Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle(); 610*5088Sab196087 611*5088Sab196087 /* 612*5088Sab196087 * This is a nicity: Force any needed auxiliary sections to be 613*5088Sab196087 * fetched here before any output is produced. This will put all 614*5088Sab196087 * of the debug messages right at the top in a single cluster. 615*5088Sab196087 */ 616*5088Sab196087 symstate = argstate->symstate; 617*5088Sab196087 for (tblndx = 0; tblndx < argstate->numsymstate; tblndx++, symstate++) { 618*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) { 619*5088Sab196087 symstate_add_str(argstate, symstate); 620*5088Sab196087 if (symstate->versym.shndx != SHN_UNDEF) 621*5088Sab196087 symstate_add_versym(argstate, symstate); 622*5088Sab196087 if (symstate->xshndx.shndx != SHN_UNDEF) 623*5088Sab196087 symstate_add_xshndx(argstate, symstate); 624*5088Sab196087 continue; 625*5088Sab196087 } 626*5088Sab196087 627*5088Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) { 628*5088Sab196087 switch (cmd) { 629*5088Sab196087 case SYM_CMD_T_ST_NAME: 630*5088Sab196087 symstate_add_str(argstate, symstate); 631*5088Sab196087 break; 632*5088Sab196087 633*5088Sab196087 case SYM_CMD_T_ST_SHNDX: 634*5088Sab196087 if (symstate->xshndx.shndx != SHN_UNDEF) 635*5088Sab196087 symstate_add_xshndx(argstate, symstate); 636*5088Sab196087 break; 637*5088Sab196087 } 638*5088Sab196087 } 639*5088Sab196087 } 640*5088Sab196087 641*5088Sab196087 /* 642*5088Sab196087 * If there is more than one table, we are displaying a single 643*5088Sab196087 * item, we are not using the default "elfdump" style, and all 644*5088Sab196087 * the symbols have the same value for the thing we intend to 645*5088Sab196087 * display, then we only want to display it once. 646*5088Sab196087 */ 647*5088Sab196087 only_one = (argstate->numsymstate > 1) && (argstate->argc > 0) && 648*5088Sab196087 (outstyle != ELFEDIT_OUTSTYLE_DEFAULT) && 649*5088Sab196087 all_same(cmd, argstate, outstyle); 650*5088Sab196087 651*5088Sab196087 /* Run through the tables and display from each one */ 652*5088Sab196087 symstate = argstate->symstate; 653*5088Sab196087 for (tblndx = 0; tblndx < argstate->numsymstate; tblndx++, symstate++) { 654*5088Sab196087 if (argstate->argc == 0) { 655*5088Sab196087 ndx = 0; 656*5088Sab196087 cnt = symstate->sym.n; 657*5088Sab196087 } else { 658*5088Sab196087 ndx = symstate->ndx; 659*5088Sab196087 cnt = 1; 660*5088Sab196087 } 661*5088Sab196087 662*5088Sab196087 if ((tblndx > 0) && ((argstate->argc == 0) || 663*5088Sab196087 (outstyle == ELFEDIT_OUTSTYLE_DEFAULT))) 664*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 665*5088Sab196087 666*5088Sab196087 print_symstate(cmd, argstate, symstate, outstyle, ndx, cnt); 667*5088Sab196087 if (only_one) 668*5088Sab196087 break; 669*5088Sab196087 } 670*5088Sab196087 } 671*5088Sab196087 672*5088Sab196087 673*5088Sab196087 /* 674*5088Sab196087 * The cmd_body_set_st_XXX() functions are for use by cmd_body(). 675*5088Sab196087 * They handle the case where the second plain argument is 676*5088Sab196087 * a value to be stored in the symbol. 677*5088Sab196087 * 678*5088Sab196087 * entry: 679*5088Sab196087 * argstate - Overall state block 680*5088Sab196087 * symstate - State block for current symbol table. 681*5088Sab196087 */ 682*5088Sab196087 static elfedit_cmdret_t 683*5088Sab196087 cmd_body_set_st_bind(ARGSTATE *argstate, SYMSTATE *symstate) 684*5088Sab196087 { 685*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 686*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 687*5088Sab196087 Word gbl_ndx; 688*5088Sab196087 uchar_t bind, type, old_bind; 689*5088Sab196087 Word symndx; 690*5088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 691*5088Sab196087 692*5088Sab196087 /* 693*5088Sab196087 * Use the ELF_ST_BIND() macro to access the defined bits 694*5088Sab196087 * of the st_info field related to symbol binding. 695*5088Sab196087 * Accepts STB_ symbolic names as well as integers. 696*5088Sab196087 */ 697*5088Sab196087 bind = elfedit_atoconst_range(argstate->argv[1], 698*5088Sab196087 MSG_INTL(MSG_ARG_SYMBIND), 0, 15, ELFEDIT_CONST_STB); 699*5088Sab196087 old_bind = ELF_ST_BIND(sym->st_info); 700*5088Sab196087 type = ELF_ST_TYPE(sym->st_info); 701*5088Sab196087 702*5088Sab196087 if (old_bind == bind) { 703*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_OK), 704*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 705*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_BIND), 706*5088Sab196087 conv_sym_info_bind(bind, CONV_FMT_ALT_FULLNAME, &inv_buf1)); 707*5088Sab196087 } else { 708*5088Sab196087 /* 709*5088Sab196087 * The sh_info field of the symbol table section header 710*5088Sab196087 * gives the index of the first non-local symbol in 711*5088Sab196087 * the table. Issue warnings if the binding we set 712*5088Sab196087 * contradicts this. 713*5088Sab196087 */ 714*5088Sab196087 gbl_ndx = symstate->sym.sec->sec_shdr->sh_info; 715*5088Sab196087 symndx = symstate->sym.sec->sec_shndx; 716*5088Sab196087 if ((bind == STB_LOCAL) && (symstate->ndx >= gbl_ndx)) 717*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 718*5088Sab196087 MSG_INTL(MSG_DEBUG_LBINDGSYM), 719*5088Sab196087 EC_WORD(symndx), symstate->sym.sec->sec_name, 720*5088Sab196087 symstate->ndx, EC_WORD(symndx), gbl_ndx); 721*5088Sab196087 if ((bind != STB_LOCAL) && (symstate->ndx < gbl_ndx)) 722*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 723*5088Sab196087 MSG_INTL(MSG_DEBUG_GBINDLSYM), 724*5088Sab196087 EC_WORD(symndx), symstate->sym.sec->sec_name, 725*5088Sab196087 symstate->ndx, EC_WORD(symndx), gbl_ndx); 726*5088Sab196087 727*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_CHG), 728*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 729*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_BIND), 730*5088Sab196087 conv_sym_info_bind(old_bind, CONV_FMT_ALT_FULLNAME, 731*5088Sab196087 &inv_buf1), 732*5088Sab196087 conv_sym_info_bind(bind, CONV_FMT_ALT_FULLNAME, &inv_buf2)); 733*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 734*5088Sab196087 sym->st_info = ELF_ST_INFO(bind, type); 735*5088Sab196087 } 736*5088Sab196087 737*5088Sab196087 return (ret); 738*5088Sab196087 } 739*5088Sab196087 740*5088Sab196087 static elfedit_cmdret_t 741*5088Sab196087 cmd_body_set_st_name(ARGSTATE *argstate, SYMSTATE *symstate) 742*5088Sab196087 { 743*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 744*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 745*5088Sab196087 Word str_offset; 746*5088Sab196087 747*5088Sab196087 /* 748*5088Sab196087 * If -n was specified, this is an offset into the string 749*5088Sab196087 * table. Otherwise it is a string we need to turn into 750*5088Sab196087 * an offset 751*5088Sab196087 */ 752*5088Sab196087 symstate_add_str(argstate, symstate); 753*5088Sab196087 if (argstate->optmask & SYM_OPT_F_NAMOFFSET) { 754*5088Sab196087 str_offset = elfedit_atoui(argstate->argv[1], NULL); 755*5088Sab196087 /* Warn if the offset is out of range */ 756*5088Sab196087 (void) elfedit_offset_to_str(symstate->str.sec, 757*5088Sab196087 str_offset, ELFEDIT_MSG_DEBUG, 1); 758*5088Sab196087 } else { 759*5088Sab196087 str_offset = elfedit_strtab_insert(argstate->obj_state, 760*5088Sab196087 symstate->str.sec, NULL, argstate->argv[1]); 761*5088Sab196087 } 762*5088Sab196087 763*5088Sab196087 if (sym->st_name == str_offset) { 764*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_D_OK), 765*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 766*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_NAME), 767*5088Sab196087 EC_WORD(sym->st_name)); 768*5088Sab196087 } else { 769*5088Sab196087 /* 770*5088Sab196087 * Warn the user: Changing the name of a symbol in the dynsym 771*5088Sab196087 * will break the hash table in this object. 772*5088Sab196087 */ 773*5088Sab196087 if (symstate->sym.sec->sec_shdr->sh_type == SHT_DYNSYM) 774*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 775*5088Sab196087 MSG_INTL(MSG_DEBUG_DYNSYMNAMCHG), 776*5088Sab196087 EC_WORD(symstate->sym.sec->sec_shndx), 777*5088Sab196087 symstate->sym.sec->sec_name, 778*5088Sab196087 EC_WORD(symstate->ndx)); 779*5088Sab196087 780*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_D_CHG), 781*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 782*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_NAME), 783*5088Sab196087 EC_WORD(sym->st_name), 784*5088Sab196087 EC_WORD(str_offset)); 785*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 786*5088Sab196087 sym->st_name = str_offset; 787*5088Sab196087 } 788*5088Sab196087 789*5088Sab196087 return (ret); 790*5088Sab196087 } 791*5088Sab196087 792*5088Sab196087 static elfedit_cmdret_t 793*5088Sab196087 cmd_body_set_st_shndx(ARGSTATE *argstate, SYMSTATE *symstate) 794*5088Sab196087 { 795*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 796*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 797*5088Sab196087 Word shndx, st_shndx, xshndx; 798*5088Sab196087 int use_xshndx; 799*5088Sab196087 int shndx_chg, xshndx_chg; 800*5088Sab196087 801*5088Sab196087 802*5088Sab196087 /* 803*5088Sab196087 * By default, the sec argument is a section name. If -secshndx was 804*5088Sab196087 * specified, it is a section index, and if -secshtyp is specified, 805*5088Sab196087 * it is a section type. 806*5088Sab196087 */ 807*5088Sab196087 if (argstate->optmask & SYM_OPT_F_SECSHNDX) 808*5088Sab196087 shndx = elfedit_atoshndx(argstate->argv[1], 809*5088Sab196087 argstate->obj_state->os_shnum); 810*5088Sab196087 else if (argstate->optmask & SYM_OPT_F_SECSHTYP) 811*5088Sab196087 shndx = elfedit_type_to_shndx(argstate->obj_state, 812*5088Sab196087 elfedit_atoconst(argstate->argv[1], ELFEDIT_CONST_SHT)); 813*5088Sab196087 else 814*5088Sab196087 shndx = elfedit_name_to_shndx(argstate->obj_state, 815*5088Sab196087 argstate->argv[1]); 816*5088Sab196087 817*5088Sab196087 /* 818*5088Sab196087 * We want to use an extended index section if the index is too 819*5088Sab196087 * large to be represented otherwise, or if the caller specified 820*5088Sab196087 * the -e option to make us do it anyway. However, we cannot 821*5088Sab196087 * do this if the index is in the special reserved range between 822*5088Sab196087 * SHN_LORESERVE and SHN_HIRESERVE. 823*5088Sab196087 */ 824*5088Sab196087 use_xshndx = (shndx > SHN_HIRESERVE) || 825*5088Sab196087 ((shndx < SHN_LORESERVE) && 826*5088Sab196087 (argstate->optmask & SYM_OPT_F_XSHINDEX)); 827*5088Sab196087 828*5088Sab196087 /* 829*5088Sab196087 * There are two cases where we have to touch the extended 830*5088Sab196087 * index section: 831*5088Sab196087 * 832*5088Sab196087 * 1) We have determined that we need to, as determined above. 833*5088Sab196087 * 2) We do not require it, but the file has an extended 834*5088Sab196087 * index section, in which case we should set the slot 835*5088Sab196087 * in that extended section to SHN_UNDEF (0). 836*5088Sab196087 * 837*5088Sab196087 * Fetch the extended section as required, and determine the values 838*5088Sab196087 * for st_shndx and the extended section slot. 839*5088Sab196087 */ 840*5088Sab196087 if (use_xshndx) { 841*5088Sab196087 /* We must have an extended index section, or error out */ 842*5088Sab196087 symstate_add_xshndx(argstate, symstate); 843*5088Sab196087 844*5088Sab196087 /* Set symbol to SHN_XINDEX, put index in the extended sec. */ 845*5088Sab196087 st_shndx = SHN_XINDEX; 846*5088Sab196087 xshndx = shndx; 847*5088Sab196087 } else { 848*5088Sab196087 st_shndx = shndx; 849*5088Sab196087 xshndx = SHN_UNDEF; 850*5088Sab196087 if (symstate->xshndx.shndx != SHN_UNDEF) 851*5088Sab196087 use_xshndx = 1; 852*5088Sab196087 } 853*5088Sab196087 if (use_xshndx) 854*5088Sab196087 symstate_add_xshndx(argstate, symstate); 855*5088Sab196087 shndx_chg = (sym->st_shndx != st_shndx); 856*5088Sab196087 xshndx_chg = use_xshndx && 857*5088Sab196087 (symstate->xshndx.data[symstate->ndx] != xshndx); 858*5088Sab196087 859*5088Sab196087 860*5088Sab196087 /* If anything is going to change, issue appropiate warnings */ 861*5088Sab196087 if (shndx_chg || xshndx_chg) { 862*5088Sab196087 /* 863*5088Sab196087 * Setting the first symbol to anything other than SHN_UNDEF 864*5088Sab196087 * produces a bad ELF file. 865*5088Sab196087 */ 866*5088Sab196087 if ((symstate->ndx == 0) && (shndx != SHN_UNDEF)) 867*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 868*5088Sab196087 MSG_INTL(MSG_DEBUG_SHNDX_UNDEF0)); 869*5088Sab196087 870*5088Sab196087 /* 871*5088Sab196087 * Setting SHN_XINDEX directly, instead of providing 872*5088Sab196087 * an extended index and letting us decide to use 873*5088Sab196087 * SHN_XINDEX to implement it, is probably a mistake. 874*5088Sab196087 * Issue a warning, but go ahead and follow the directions 875*5088Sab196087 * we've been given. 876*5088Sab196087 */ 877*5088Sab196087 if (shndx == SHN_XINDEX) 878*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 879*5088Sab196087 MSG_INTL(MSG_DEBUG_SHNDX_XINDEX)); 880*5088Sab196087 881*5088Sab196087 /* 882*5088Sab196087 * If the section index can fit in the symbol, but 883*5088Sab196087 * -e is being used to force it into the extended 884*5088Sab196087 * index section, issue a warning. 885*5088Sab196087 */ 886*5088Sab196087 if (use_xshndx && (shndx < SHN_LORESERVE) && 887*5088Sab196087 (st_shndx == SHN_XINDEX)) 888*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 889*5088Sab196087 MSG_INTL(MSG_DEBUG_SHNDX_EFORCE), 890*5088Sab196087 EC_WORD(symstate->sym.sec->sec_shndx), 891*5088Sab196087 symstate->sym.sec->sec_name, EC_WORD(symstate->ndx), 892*5088Sab196087 EC_WORD(shndx)); 893*5088Sab196087 } 894*5088Sab196087 895*5088Sab196087 if (shndx_chg) { 896*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_CHG), 897*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 898*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_SHNDX), 899*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, 900*5088Sab196087 sym->st_shndx), 901*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, st_shndx)); 902*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 903*5088Sab196087 sym->st_shndx = st_shndx; 904*5088Sab196087 } else { 905*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_OK), 906*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 907*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_SHNDX), 908*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, st_shndx)); 909*5088Sab196087 } 910*5088Sab196087 911*5088Sab196087 if (use_xshndx) { 912*5088Sab196087 if (xshndx_chg) { 913*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 914*5088Sab196087 MSG_INTL(MSG_DEBUG_EXT_S_CHG), 915*5088Sab196087 symstate->xshndx.sec->sec_shndx, 916*5088Sab196087 symstate->xshndx.sec->sec_name, 917*5088Sab196087 EC_WORD(symstate->ndx), 918*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, 919*5088Sab196087 symstate->xshndx.data[symstate->ndx]), 920*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, xshndx)); 921*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 922*5088Sab196087 symstate->xshndx.data[symstate->ndx] = xshndx; 923*5088Sab196087 elfedit_modified_data(symstate->xshndx.sec); 924*5088Sab196087 } else { 925*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 926*5088Sab196087 MSG_INTL(MSG_DEBUG_EXT_S_OK), 927*5088Sab196087 symstate->xshndx.sec->sec_shndx, 928*5088Sab196087 symstate->xshndx.sec->sec_name, 929*5088Sab196087 EC_WORD(symstate->ndx), 930*5088Sab196087 elfedit_shndx_to_name(argstate->obj_state, xshndx)); 931*5088Sab196087 } 932*5088Sab196087 } 933*5088Sab196087 934*5088Sab196087 return (ret); 935*5088Sab196087 } 936*5088Sab196087 937*5088Sab196087 static elfedit_cmdret_t 938*5088Sab196087 cmd_body_set_st_type(ARGSTATE *argstate, SYMSTATE *symstate) 939*5088Sab196087 { 940*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 941*5088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 942*5088Sab196087 Half mach = argstate->obj_state->os_ehdr->e_machine; 943*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 944*5088Sab196087 uchar_t bind, type, old_type; 945*5088Sab196087 946*5088Sab196087 /* 947*5088Sab196087 * Use the ELF_ST_TYPE() macro to access the defined bits 948*5088Sab196087 * of the st_info field related to symbol type. 949*5088Sab196087 * Accepts STT_ symbolic names as well as integers. 950*5088Sab196087 */ 951*5088Sab196087 bind = ELF_ST_BIND(sym->st_info); 952*5088Sab196087 type = elfedit_atoconst_range(argstate->argv[1], 953*5088Sab196087 MSG_INTL(MSG_ARG_SYMBIND), 0, 15, ELFEDIT_CONST_STT); 954*5088Sab196087 old_type = ELF_ST_TYPE(sym->st_info); 955*5088Sab196087 956*5088Sab196087 if (old_type == type) { 957*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_OK), 958*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 959*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_TYPE), 960*5088Sab196087 conv_sym_info_type(mach, type, CONV_FMT_ALT_FULLNAME, 961*5088Sab196087 &inv_buf1)); 962*5088Sab196087 } else { 963*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_CHG), 964*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 965*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_TYPE), 966*5088Sab196087 conv_sym_info_type(mach, old_type, CONV_FMT_ALT_FULLNAME, 967*5088Sab196087 &inv_buf1), 968*5088Sab196087 conv_sym_info_type(mach, type, CONV_FMT_ALT_FULLNAME, 969*5088Sab196087 &inv_buf2)); 970*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 971*5088Sab196087 sym->st_info = ELF_ST_INFO(bind, type); 972*5088Sab196087 } 973*5088Sab196087 974*5088Sab196087 return (ret); 975*5088Sab196087 } 976*5088Sab196087 977*5088Sab196087 static elfedit_cmdret_t 978*5088Sab196087 cmd_body_set_st_visibility(ARGSTATE *argstate, SYMSTATE *symstate) 979*5088Sab196087 { 980*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 981*5088Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 982*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 983*5088Sab196087 uchar_t st_other = sym->st_other; 984*5088Sab196087 uchar_t vis, old_vis; 985*5088Sab196087 986*5088Sab196087 /* 987*5088Sab196087 * Use the ELF_ST_VISIBILITY() macro to access the 988*5088Sab196087 * defined bits of the st_other field related to symbol 989*5088Sab196087 * visibility. Accepts STV_ symbolic names as well as integers. 990*5088Sab196087 */ 991*5088Sab196087 vis = elfedit_atoconst_range(argstate->argv[1], 992*5088Sab196087 MSG_INTL(MSG_ARG_SYMVIS), 0, STV_PROTECTED, ELFEDIT_CONST_STV); 993*5088Sab196087 old_vis = st_other & MSK_SYM_VISIBILITY; 994*5088Sab196087 995*5088Sab196087 if (old_vis == vis) { 996*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_OK), 997*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 998*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_VISIBILITY), 999*5088Sab196087 conv_sym_other_vis(old_vis, CONV_FMT_ALT_FULLNAME, 1000*5088Sab196087 &inv_buf1)); 1001*5088Sab196087 } else { 1002*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_S_CHG), 1003*5088Sab196087 symstate->sym.sec->sec_shndx, symstate->sym.sec->sec_name, 1004*5088Sab196087 EC_WORD(symstate->ndx), MSG_ORIG(MSG_CMD_ST_VISIBILITY), 1005*5088Sab196087 conv_sym_other_vis(old_vis, CONV_FMT_ALT_FULLNAME, 1006*5088Sab196087 &inv_buf1), 1007*5088Sab196087 conv_sym_other_vis(vis, CONV_FMT_ALT_FULLNAME, &inv_buf2)); 1008*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1009*5088Sab196087 st_other = (st_other & ~MSK_SYM_VISIBILITY) | 1010*5088Sab196087 ELF_ST_VISIBILITY(vis); 1011*5088Sab196087 sym->st_other = st_other; 1012*5088Sab196087 } 1013*5088Sab196087 1014*5088Sab196087 return (ret); 1015*5088Sab196087 } 1016*5088Sab196087 1017*5088Sab196087 1018*5088Sab196087 /* 1019*5088Sab196087 * Standard argument processing for sym module 1020*5088Sab196087 * 1021*5088Sab196087 * entry 1022*5088Sab196087 * obj_state, argc, argv - Standard command arguments 1023*5088Sab196087 * optmask - Mask of allowed optional arguments. 1024*5088Sab196087 * symstate - State block for current symbol table. 1025*5088Sab196087 * argstate - Address of ARGSTATE block to be initialized 1026*5088Sab196087 * 1027*5088Sab196087 * exit: 1028*5088Sab196087 * On success, *argstate is initialized. On error, 1029*5088Sab196087 * an error is issued and this routine does not return. 1030*5088Sab196087 * 1031*5088Sab196087 * note: 1032*5088Sab196087 * Only the basic symbol table is initially referenced by 1033*5088Sab196087 * argstate. Use the argstate_add_XXX() routines below to 1034*5088Sab196087 * access any auxiliary sections needed. 1035*5088Sab196087 */ 1036*5088Sab196087 static ARGSTATE * 1037*5088Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[], 1038*5088Sab196087 SYM_CMD_T cmd) 1039*5088Sab196087 { 1040*5088Sab196087 /* 1041*5088Sab196087 * We reuse this same argstate, resizing it to the required 1042*5088Sab196087 * number of symbol tables on the first call, and as necessary. 1043*5088Sab196087 */ 1044*5088Sab196087 static ARGSTATE *argstate; 1045*5088Sab196087 static int argstate_size = 0; 1046*5088Sab196087 1047*5088Sab196087 elfedit_getopt_state_t getopt_state; 1048*5088Sab196087 elfedit_getopt_ret_t *getopt_ret; 1049*5088Sab196087 elfedit_symtab_t *symtab; 1050*5088Sab196087 int explicit = 0; 1051*5088Sab196087 int got_sym = 0; 1052*5088Sab196087 Word index; 1053*5088Sab196087 Word tblndx; 1054*5088Sab196087 size_t size; 1055*5088Sab196087 SYMSTATE *symstate; 1056*5088Sab196087 1057*5088Sab196087 /* If there are no symbol tables, we can't do a thing */ 1058*5088Sab196087 if (obj_state->os_symtabnum == 0) 1059*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOSYMTAB)); 1060*5088Sab196087 1061*5088Sab196087 /* Calulate required size of argstate and realloc as necessary */ 1062*5088Sab196087 size = sizeof (ARGSTATE) + 1063*5088Sab196087 ((obj_state->os_symtabnum - 1) * sizeof (SYMSTATE)); 1064*5088Sab196087 if (argstate_size != size) { 1065*5088Sab196087 argstate = elfedit_realloc(MSG_INTL(MSG_ALLOC_ARGSTATE), 1066*5088Sab196087 argstate, size); 1067*5088Sab196087 argstate_size = size; 1068*5088Sab196087 } 1069*5088Sab196087 bzero(argstate, argstate_size); 1070*5088Sab196087 argstate->obj_state = obj_state; 1071*5088Sab196087 1072*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 1073*5088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) { 1074*5088Sab196087 argstate->optmask |= getopt_ret->gor_idmask; 1075*5088Sab196087 switch (getopt_ret->gor_idmask) { 1076*5088Sab196087 case SYM_OPT_F_SHNAME: /* -shnam name */ 1077*5088Sab196087 index = elfedit_name_to_shndx(obj_state, 1078*5088Sab196087 getopt_ret->gor_value); 1079*5088Sab196087 explicit = 1; 1080*5088Sab196087 break; 1081*5088Sab196087 1082*5088Sab196087 case SYM_OPT_F_SHNDX: /* -shndx index */ 1083*5088Sab196087 index = elfedit_atoui_range(getopt_ret->gor_value, 1084*5088Sab196087 MSG_INTL(MSG_ARG_SECNDX), 1, 1085*5088Sab196087 obj_state->os_shnum - 1, NULL); 1086*5088Sab196087 explicit = 1; 1087*5088Sab196087 break; 1088*5088Sab196087 1089*5088Sab196087 case SYM_OPT_F_SHTYP: /* -shtyp type */ 1090*5088Sab196087 index = elfedit_type_to_shndx(obj_state, 1091*5088Sab196087 elfedit_atoconst(getopt_ret->gor_value, 1092*5088Sab196087 ELFEDIT_CONST_SHT)); 1093*5088Sab196087 explicit = 1; 1094*5088Sab196087 break; 1095*5088Sab196087 } 1096*5088Sab196087 } 1097*5088Sab196087 1098*5088Sab196087 /* 1099*5088Sab196087 * Usage error if there are too many plain arguments. sym:dump accepts 1100*5088Sab196087 * a single argument, while the others accept 2. 1101*5088Sab196087 */ 1102*5088Sab196087 if (((cmd == SYM_CMD_T_DUMP) && (argc > 1)) || (argc > 2)) 1103*5088Sab196087 elfedit_command_usage(); 1104*5088Sab196087 1105*5088Sab196087 /* 1106*5088Sab196087 * If the -symndx option was specified, the sym arg is an index 1107*5088Sab196087 * into the symbol table. In this case, the symbol table must be 1108*5088Sab196087 * explicitly specified (-shnam, -shndx, or -shtype). 1109*5088Sab196087 */ 1110*5088Sab196087 if ((argstate->optmask & SYM_OPT_F_SYMNDX) && !explicit) 1111*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NEEDEXPSYMTAB)); 1112*5088Sab196087 1113*5088Sab196087 /* 1114*5088Sab196087 * If a section was explicitly specified, it needs 1115*5088Sab196087 * be a symbol table. 1116*5088Sab196087 */ 1117*5088Sab196087 if (explicit) 1118*5088Sab196087 (void) elfedit_sec_issymtab(&obj_state->os_secarr[index], 1119*5088Sab196087 1, NULL); 1120*5088Sab196087 1121*5088Sab196087 /* If there may be an arbitrary amount of output, use a pager */ 1122*5088Sab196087 if (argc == 0) 1123*5088Sab196087 elfedit_pager_init(); 1124*5088Sab196087 1125*5088Sab196087 /* Return the updated values of argc/argv */ 1126*5088Sab196087 argstate->argc = argc; 1127*5088Sab196087 argstate->argv = argv; 1128*5088Sab196087 1129*5088Sab196087 /* 1130*5088Sab196087 * Decide which symbol table(s) to use. Set up the symstate 1131*5088Sab196087 * array to contain them: 1132*5088Sab196087 * - If a symbol table was explicitly specified, we use 1133*5088Sab196087 * it, and only it. 1134*5088Sab196087 * - If no symbol table is explicitly specified, and the symbol 1135*5088Sab196087 * is given by name, we use all symbol tables that 1136*5088Sab196087 * contain a symbol with that name, throwing an error 1137*5088Sab196087 * if there isn't at least 1 such table. 1138*5088Sab196087 * - If no symbol table is specified, and no symbol is specified, 1139*5088Sab196087 * we use all the tables. 1140*5088Sab196087 */ 1141*5088Sab196087 symtab = obj_state->os_symtab; 1142*5088Sab196087 symstate = argstate->symstate; 1143*5088Sab196087 for (tblndx = 0; tblndx < obj_state->os_symtabnum; 1144*5088Sab196087 tblndx++, symtab++) { 1145*5088Sab196087 /* If explicit table specified, only that table is considered */ 1146*5088Sab196087 if (explicit && (symtab->symt_shndx != index)) 1147*5088Sab196087 continue; 1148*5088Sab196087 1149*5088Sab196087 symstate->sym.sec = elfedit_sec_getsymtab(obj_state, 1, 1150*5088Sab196087 symtab->symt_shndx, NULL, &symstate->sym.data, 1151*5088Sab196087 &symstate->sym.n, &symtab); 1152*5088Sab196087 symstate->versym.shndx = symtab->symt_versym; 1153*5088Sab196087 symstate->xshndx.shndx = symtab->symt_xshndx; 1154*5088Sab196087 if (argc > 0) { 1155*5088Sab196087 if (argstate->optmask & SYM_OPT_F_SYMNDX) { 1156*5088Sab196087 symstate->ndx = elfedit_atoui_range( 1157*5088Sab196087 argstate->argv[0], MSG_INTL(MSG_ARG_SYM), 0, 1158*5088Sab196087 symstate->sym.n - 1, NULL); 1159*5088Sab196087 } else { 1160*5088Sab196087 /* 1161*5088Sab196087 * arg is a symbol name. Use the index of 1162*5088Sab196087 * the first symbol that matches 1163*5088Sab196087 */ 1164*5088Sab196087 1165*5088Sab196087 /* 1166*5088Sab196087 * We will use debug messages for failure up 1167*5088Sab196087 * until we run out of symbol tables. If we 1168*5088Sab196087 * don't find a table with the desired symbol 1169*5088Sab196087 * before the last table, we switch to error 1170*5088Sab196087 * messages. Hence, we will jump with an error 1171*5088Sab196087 * if no table will work. 1172*5088Sab196087 */ 1173*5088Sab196087 int err_type = (!got_sym && 1174*5088Sab196087 ((tblndx + 1) == obj_state->os_symtabnum)) ? 1175*5088Sab196087 ELFEDIT_MSG_ERR : ELFEDIT_MSG_DEBUG; 1176*5088Sab196087 1177*5088Sab196087 symstate_add_str(argstate, symstate); 1178*5088Sab196087 1179*5088Sab196087 /* 1180*5088Sab196087 * If the symbol table doesn't have this 1181*5088Sab196087 * symbol, then forget it. 1182*5088Sab196087 */ 1183*5088Sab196087 if (elfedit_name_to_symndx(symstate->sym.sec, 1184*5088Sab196087 symstate->str.sec, argstate->argv[0], 1185*5088Sab196087 err_type, &symstate->ndx) == 0) { 1186*5088Sab196087 bzero(symstate, sizeof (*symstate)); 1187*5088Sab196087 continue; 1188*5088Sab196087 } 1189*5088Sab196087 } 1190*5088Sab196087 } 1191*5088Sab196087 argstate->numsymstate++; 1192*5088Sab196087 symstate++; 1193*5088Sab196087 /* 1194*5088Sab196087 * If the symbol table was given explicitly, and 1195*5088Sab196087 * we've just taken it, then there is no reason to 1196*5088Sab196087 * continue searching. 1197*5088Sab196087 */ 1198*5088Sab196087 if (explicit) 1199*5088Sab196087 break; 1200*5088Sab196087 } 1201*5088Sab196087 1202*5088Sab196087 return (argstate); 1203*5088Sab196087 } 1204*5088Sab196087 1205*5088Sab196087 1206*5088Sab196087 1207*5088Sab196087 /* 1208*5088Sab196087 * Called by cmd_body() to handle the value change for a single 1209*5088Sab196087 * symbol table. 1210*5088Sab196087 * 1211*5088Sab196087 * entry: 1212*5088Sab196087 * cmd - One of the SYM_CMD_T_* constants listed above, specifying 1213*5088Sab196087 * which command to implement. 1214*5088Sab196087 * argstate - Overall state block 1215*5088Sab196087 * symstate - State block for current symbol table. 1216*5088Sab196087 */ 1217*5088Sab196087 static elfedit_cmdret_t 1218*5088Sab196087 symstate_cmd_body(SYM_CMD_T cmd, ARGSTATE *argstate, SYMSTATE *symstate) 1219*5088Sab196087 { 1220*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 1221*5088Sab196087 Sym *sym = &symstate->sym.data[symstate->ndx]; 1222*5088Sab196087 1223*5088Sab196087 /* You're not supposed to change the value of symbol [0] */ 1224*5088Sab196087 if (symstate->ndx == 0) 1225*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CHGSYMELT0), 1226*5088Sab196087 EC_WORD(symstate->sym.sec->sec_shndx), 1227*5088Sab196087 symstate->sym.sec->sec_name, EC_WORD(symstate->ndx)); 1228*5088Sab196087 1229*5088Sab196087 /* The second value is an integer giving a new value */ 1230*5088Sab196087 switch (cmd) { 1231*5088Sab196087 /* 1232*5088Sab196087 * SYM_CMD_T_DUMP can't get here: It never has more than 1233*5088Sab196087 * one argument, and is handled above. 1234*5088Sab196087 */ 1235*5088Sab196087 1236*5088Sab196087 case SYM_CMD_T_ST_BIND: 1237*5088Sab196087 ret = cmd_body_set_st_bind(argstate, symstate); 1238*5088Sab196087 break; 1239*5088Sab196087 1240*5088Sab196087 case SYM_CMD_T_ST_INFO: 1241*5088Sab196087 { 1242*5088Sab196087 /* Treat st_info as a raw integer field */ 1243*5088Sab196087 uchar_t st_info = 1244*5088Sab196087 elfedit_atoui(argstate->argv[1], NULL); 1245*5088Sab196087 1246*5088Sab196087 if (sym->st_info == st_info) { 1247*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1248*5088Sab196087 MSG_INTL(MSG_DEBUG_D_OK), 1249*5088Sab196087 symstate->sym.sec->sec_shndx, 1250*5088Sab196087 symstate->sym.sec->sec_name, 1251*5088Sab196087 EC_WORD(symstate->ndx), 1252*5088Sab196087 MSG_ORIG(MSG_CMD_ST_INFO), 1253*5088Sab196087 EC_WORD(sym->st_info)); 1254*5088Sab196087 } else { 1255*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1256*5088Sab196087 MSG_INTL(MSG_DEBUG_D_CHG), 1257*5088Sab196087 symstate->sym.sec->sec_shndx, 1258*5088Sab196087 symstate->sym.sec->sec_name, 1259*5088Sab196087 EC_WORD(symstate->ndx), 1260*5088Sab196087 MSG_ORIG(MSG_CMD_ST_INFO), 1261*5088Sab196087 EC_WORD(sym->st_info), EC_WORD(st_info)); 1262*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1263*5088Sab196087 sym->st_info = st_info; 1264*5088Sab196087 } 1265*5088Sab196087 } 1266*5088Sab196087 break; 1267*5088Sab196087 1268*5088Sab196087 case SYM_CMD_T_ST_NAME: 1269*5088Sab196087 ret = cmd_body_set_st_name(argstate, symstate); 1270*5088Sab196087 break; 1271*5088Sab196087 1272*5088Sab196087 case SYM_CMD_T_ST_OTHER: 1273*5088Sab196087 { 1274*5088Sab196087 /* Treat st_other as a raw integer field */ 1275*5088Sab196087 uchar_t st_other = 1276*5088Sab196087 elfedit_atoui(argstate->argv[1], NULL); 1277*5088Sab196087 1278*5088Sab196087 if (sym->st_other == st_other) { 1279*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1280*5088Sab196087 MSG_INTL(MSG_DEBUG_D_OK), 1281*5088Sab196087 symstate->sym.sec->sec_shndx, 1282*5088Sab196087 symstate->sym.sec->sec_name, 1283*5088Sab196087 EC_WORD(symstate->ndx), 1284*5088Sab196087 MSG_ORIG(MSG_CMD_ST_OTHER), 1285*5088Sab196087 EC_WORD(sym->st_other)); 1286*5088Sab196087 } else { 1287*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1288*5088Sab196087 MSG_INTL(MSG_DEBUG_D_CHG), 1289*5088Sab196087 symstate->sym.sec->sec_shndx, 1290*5088Sab196087 symstate->sym.sec->sec_name, 1291*5088Sab196087 EC_WORD(symstate->ndx), 1292*5088Sab196087 MSG_ORIG(MSG_CMD_ST_OTHER), 1293*5088Sab196087 EC_WORD(sym->st_other), EC_WORD(st_other)); 1294*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1295*5088Sab196087 sym->st_other = st_other; 1296*5088Sab196087 } 1297*5088Sab196087 } 1298*5088Sab196087 break; 1299*5088Sab196087 1300*5088Sab196087 case SYM_CMD_T_ST_SHNDX: 1301*5088Sab196087 ret = cmd_body_set_st_shndx(argstate, symstate); 1302*5088Sab196087 break; 1303*5088Sab196087 1304*5088Sab196087 case SYM_CMD_T_ST_SIZE: 1305*5088Sab196087 { 1306*5088Sab196087 Xword st_size = elfedit_atoui(argstate->argv[1], NULL); 1307*5088Sab196087 1308*5088Sab196087 if (sym->st_size == st_size) { 1309*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1310*5088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 1311*5088Sab196087 symstate->sym.sec->sec_shndx, 1312*5088Sab196087 symstate->sym.sec->sec_name, 1313*5088Sab196087 EC_WORD(symstate->ndx), 1314*5088Sab196087 MSG_ORIG(MSG_CMD_ST_SIZE), 1315*5088Sab196087 EC_XWORD(sym->st_size)); 1316*5088Sab196087 } else { 1317*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1318*5088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 1319*5088Sab196087 symstate->sym.sec->sec_shndx, 1320*5088Sab196087 symstate->sym.sec->sec_name, 1321*5088Sab196087 EC_WORD(symstate->ndx), 1322*5088Sab196087 MSG_ORIG(MSG_CMD_ST_SIZE), 1323*5088Sab196087 EC_XWORD(sym->st_size), EC_XWORD(st_size)); 1324*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1325*5088Sab196087 sym->st_size = st_size; 1326*5088Sab196087 } 1327*5088Sab196087 } 1328*5088Sab196087 break; 1329*5088Sab196087 1330*5088Sab196087 case SYM_CMD_T_ST_TYPE: 1331*5088Sab196087 ret = cmd_body_set_st_type(argstate, symstate); 1332*5088Sab196087 break; 1333*5088Sab196087 1334*5088Sab196087 case SYM_CMD_T_ST_VALUE: 1335*5088Sab196087 { 1336*5088Sab196087 Addr st_value = elfedit_atoui(argstate->argv[1], NULL); 1337*5088Sab196087 1338*5088Sab196087 if (sym->st_value == st_value) { 1339*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1340*5088Sab196087 MSG_INTL(MSG_DEBUG_LLX_OK), 1341*5088Sab196087 symstate->sym.sec->sec_shndx, 1342*5088Sab196087 symstate->sym.sec->sec_name, 1343*5088Sab196087 EC_WORD(symstate->ndx), 1344*5088Sab196087 MSG_ORIG(MSG_CMD_ST_VALUE), 1345*5088Sab196087 EC_ADDR(sym->st_value)); 1346*5088Sab196087 } else { 1347*5088Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, 1348*5088Sab196087 MSG_INTL(MSG_DEBUG_LLX_CHG), 1349*5088Sab196087 symstate->sym.sec->sec_shndx, 1350*5088Sab196087 symstate->sym.sec->sec_name, 1351*5088Sab196087 EC_WORD(symstate->ndx), 1352*5088Sab196087 MSG_ORIG(MSG_CMD_ST_VALUE), 1353*5088Sab196087 EC_ADDR(sym->st_value), 1354*5088Sab196087 EC_ADDR(st_value)); 1355*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1356*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1357*5088Sab196087 sym->st_value = st_value; 1358*5088Sab196087 } 1359*5088Sab196087 } 1360*5088Sab196087 break; 1361*5088Sab196087 1362*5088Sab196087 case SYM_CMD_T_ST_VISIBILITY: 1363*5088Sab196087 ret = cmd_body_set_st_visibility(argstate, symstate); 1364*5088Sab196087 break; 1365*5088Sab196087 } 1366*5088Sab196087 1367*5088Sab196087 /* 1368*5088Sab196087 * If we modified the symbol table, tell libelf. 1369*5088Sab196087 * Any other modified sections are the responsibility 1370*5088Sab196087 * of the cmd_body_set_st_*() function that did it, but 1371*5088Sab196087 * everyone modifies the table itself, so we handle that here. 1372*5088Sab196087 */ 1373*5088Sab196087 if (ret == ELFEDIT_CMDRET_MOD) 1374*5088Sab196087 elfedit_modified_data(symstate->sym.sec); 1375*5088Sab196087 1376*5088Sab196087 return (ret); 1377*5088Sab196087 } 1378*5088Sab196087 1379*5088Sab196087 1380*5088Sab196087 1381*5088Sab196087 1382*5088Sab196087 /* 1383*5088Sab196087 * Common body for the sym: module commands. These commands 1384*5088Sab196087 * share a large amount of common behavior, so it is convenient 1385*5088Sab196087 * to centralize things and use the cmd argument to handle the 1386*5088Sab196087 * small differences. 1387*5088Sab196087 * 1388*5088Sab196087 * entry: 1389*5088Sab196087 * cmd - One of the SYM_CMD_T_* constants listed above, specifying 1390*5088Sab196087 * which command to implement. 1391*5088Sab196087 * obj_state, argc, argv - Standard command arguments 1392*5088Sab196087 */ 1393*5088Sab196087 static elfedit_cmdret_t 1394*5088Sab196087 cmd_body(SYM_CMD_T cmd, elfedit_obj_state_t *obj_state, 1395*5088Sab196087 int argc, const char *argv[]) 1396*5088Sab196087 { 1397*5088Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE; 1398*5088Sab196087 ARGSTATE *argstate; 1399*5088Sab196087 SYMSTATE *symstate; 1400*5088Sab196087 Word tblndx; 1401*5088Sab196087 1402*5088Sab196087 argstate = process_args(obj_state, argc, argv, cmd); 1403*5088Sab196087 1404*5088Sab196087 /* 1405*5088Sab196087 * If there are not 2 arguments, then this is a display request. 1406*5088Sab196087 * If no arguments are present, the full table (or tables) is 1407*5088Sab196087 * dumped. If there is one argument, then the specified item is shown. 1408*5088Sab196087 */ 1409*5088Sab196087 if (argstate->argc < 2) { 1410*5088Sab196087 print_sym(cmd, 0, argstate); 1411*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 1412*5088Sab196087 } 1413*5088Sab196087 1414*5088Sab196087 /* 1415*5088Sab196087 * When processing multiple symbol tables, it is important that 1416*5088Sab196087 * any failure happen before anything is changed. Otherwise, you 1417*5088Sab196087 * can end up in a situation where things are left in an inconsistent 1418*5088Sab196087 * half done state. sym:st_name has that issue when the -name_offset 1419*5088Sab196087 * option is used, because the string may be insertable into some 1420*5088Sab196087 * (dynstr) string tables, but not all of them. So, do the tests 1421*5088Sab196087 * up front, and refuse to continue if any string insertions would 1422*5088Sab196087 * fail. 1423*5088Sab196087 */ 1424*5088Sab196087 if ((cmd == SYM_CMD_T_ST_NAME) && (argstate->numsymstate > 1) && 1425*5088Sab196087 ((argstate->optmask & SYM_OPT_F_NAMOFFSET) == 0)) { 1426*5088Sab196087 symstate = argstate->symstate; 1427*5088Sab196087 for (tblndx = 0; tblndx < argstate->numsymstate; 1428*5088Sab196087 tblndx++, symstate++) 1429*5088Sab196087 elfedit_strtab_insert_test(obj_state, symstate->str.sec, 1430*5088Sab196087 NULL, argstate->argv[1]); 1431*5088Sab196087 } 1432*5088Sab196087 1433*5088Sab196087 1434*5088Sab196087 /* Loop over the table(s) and make the specified value change */ 1435*5088Sab196087 symstate = argstate->symstate; 1436*5088Sab196087 for (tblndx = 0; tblndx < argstate->numsymstate; tblndx++, symstate++) 1437*5088Sab196087 if (symstate_cmd_body(cmd, argstate, symstate) == 1438*5088Sab196087 ELFEDIT_CMDRET_MOD) 1439*5088Sab196087 ret = ELFEDIT_CMDRET_MOD; 1440*5088Sab196087 1441*5088Sab196087 /* Do autoprint */ 1442*5088Sab196087 print_sym(cmd, 1, argstate); 1443*5088Sab196087 1444*5088Sab196087 return (ret); 1445*5088Sab196087 } 1446*5088Sab196087 1447*5088Sab196087 1448*5088Sab196087 1449*5088Sab196087 1450*5088Sab196087 /* 1451*5088Sab196087 * Command completion functions for the various commands 1452*5088Sab196087 */ 1453*5088Sab196087 1454*5088Sab196087 /* 1455*5088Sab196087 * Handle filling in the values for -shnam, -shndx, and -shtyp options. 1456*5088Sab196087 */ 1457*5088Sab196087 /*ARGSUSED*/ 1458*5088Sab196087 static void 1459*5088Sab196087 cpl_sh_opt(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1460*5088Sab196087 const char *argv[], int num_opt) 1461*5088Sab196087 { 1462*5088Sab196087 enum { NAME, INDEX, TYPE } op; 1463*5088Sab196087 elfedit_symtab_t *symtab; 1464*5088Sab196087 Word tblndx; 1465*5088Sab196087 1466*5088Sab196087 if ((argc != num_opt) || (argc < 2)) 1467*5088Sab196087 return; 1468*5088Sab196087 1469*5088Sab196087 if (strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_SHNAM)) == 0) { 1470*5088Sab196087 op = NAME; 1471*5088Sab196087 } else if (strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0) { 1472*5088Sab196087 op = INDEX; 1473*5088Sab196087 1474*5088Sab196087 } else if (strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0) { 1475*5088Sab196087 op = TYPE; 1476*5088Sab196087 if (obj_state == NULL) /* No object available */ 1477*5088Sab196087 elfedit_cpl_atoconst(cpldata, 1478*5088Sab196087 ELFEDIT_CONST_SHT_ALLSYMTAB); 1479*5088Sab196087 } else { 1480*5088Sab196087 return; 1481*5088Sab196087 } 1482*5088Sab196087 1483*5088Sab196087 if (obj_state == NULL) /* No object available */ 1484*5088Sab196087 return; 1485*5088Sab196087 1486*5088Sab196087 /* 1487*5088Sab196087 * Loop over the symbol tables and supply command completion 1488*5088Sab196087 * for the items in the file. 1489*5088Sab196087 */ 1490*5088Sab196087 symtab = obj_state->os_symtab; 1491*5088Sab196087 for (tblndx = 0; tblndx < obj_state->os_symtabnum; 1492*5088Sab196087 tblndx++, symtab++) { 1493*5088Sab196087 elfedit_section_t *sec = 1494*5088Sab196087 &obj_state->os_secarr[symtab->symt_shndx]; 1495*5088Sab196087 1496*5088Sab196087 switch (op) { 1497*5088Sab196087 case NAME: 1498*5088Sab196087 elfedit_cpl_match(cpldata, sec->sec_name, 0); 1499*5088Sab196087 break; 1500*5088Sab196087 case INDEX: 1501*5088Sab196087 { 1502*5088Sab196087 char index[MAXNDXSIZE]; 1503*5088Sab196087 1504*5088Sab196087 (void) snprintf(index, sizeof (index), 1505*5088Sab196087 MSG_ORIG(MSG_FMT_WORDVAL), 1506*5088Sab196087 symtab->symt_shndx); 1507*5088Sab196087 elfedit_cpl_match(cpldata, index, 1); 1508*5088Sab196087 } 1509*5088Sab196087 break; 1510*5088Sab196087 case TYPE: 1511*5088Sab196087 { 1512*5088Sab196087 elfedit_atoui_sym_t *cpl_list; 1513*5088Sab196087 1514*5088Sab196087 (void) elfedit_sec_issymtab(sec, 1, &cpl_list); 1515*5088Sab196087 elfedit_cpl_atoui(cpldata, cpl_list); 1516*5088Sab196087 } 1517*5088Sab196087 break; 1518*5088Sab196087 } 1519*5088Sab196087 } 1520*5088Sab196087 } 1521*5088Sab196087 1522*5088Sab196087 /*ARGSUSED*/ 1523*5088Sab196087 static void 1524*5088Sab196087 cpl_st_bind(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1525*5088Sab196087 const char *argv[], int num_opt) 1526*5088Sab196087 { 1527*5088Sab196087 /* Handle -shXXX options */ 1528*5088Sab196087 cpl_sh_opt(obj_state, cpldata, argc, argv, num_opt); 1529*5088Sab196087 1530*5088Sab196087 /* The second argument can be an STB_ value */ 1531*5088Sab196087 if (argc == (num_opt + 2)) 1532*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_STB); 1533*5088Sab196087 } 1534*5088Sab196087 1535*5088Sab196087 /*ARGSUSED*/ 1536*5088Sab196087 static void 1537*5088Sab196087 cpl_st_shndx(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1538*5088Sab196087 const char *argv[], int num_opt) 1539*5088Sab196087 { 1540*5088Sab196087 elfedit_section_t *sec; 1541*5088Sab196087 enum { NAME, INDEX, TYPE } op; 1542*5088Sab196087 Word ndx; 1543*5088Sab196087 1544*5088Sab196087 /* Handle -shXXX options */ 1545*5088Sab196087 cpl_sh_opt(obj_state, cpldata, argc, argv, num_opt); 1546*5088Sab196087 1547*5088Sab196087 /* 1548*5088Sab196087 * The second argument can be a section name, a section 1549*5088Sab196087 * index (-secshndx), or a section type (-secshtyp). We 1550*5088Sab196087 * can do completions for each of these. 1551*5088Sab196087 */ 1552*5088Sab196087 if (argc != (num_opt + 2)) 1553*5088Sab196087 return; 1554*5088Sab196087 1555*5088Sab196087 op = NAME; 1556*5088Sab196087 for (ndx = 0; ndx < num_opt; ndx++) { 1557*5088Sab196087 if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SECSHNDX)) == 0) 1558*5088Sab196087 op = INDEX; 1559*5088Sab196087 else if (strcmp(argv[ndx], 1560*5088Sab196087 MSG_ORIG(MSG_STR_MINUS_SECSHTYP)) == 0) 1561*5088Sab196087 op = TYPE; 1562*5088Sab196087 } 1563*5088Sab196087 1564*5088Sab196087 switch (op) { 1565*5088Sab196087 case NAME: 1566*5088Sab196087 if (obj_state == NULL) 1567*5088Sab196087 break; 1568*5088Sab196087 sec = obj_state->os_secarr; 1569*5088Sab196087 for (ndx = 0; ndx < obj_state->os_shnum; ndx++, sec++) 1570*5088Sab196087 elfedit_cpl_match(cpldata, sec->sec_name, 0); 1571*5088Sab196087 break; 1572*5088Sab196087 1573*5088Sab196087 case INDEX: 1574*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHN); 1575*5088Sab196087 break; 1576*5088Sab196087 1577*5088Sab196087 case TYPE: 1578*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT); 1579*5088Sab196087 break; 1580*5088Sab196087 } 1581*5088Sab196087 } 1582*5088Sab196087 1583*5088Sab196087 /*ARGSUSED*/ 1584*5088Sab196087 static void 1585*5088Sab196087 cpl_st_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1586*5088Sab196087 const char *argv[], int num_opt) 1587*5088Sab196087 { 1588*5088Sab196087 /* Handle -shXXX options */ 1589*5088Sab196087 cpl_sh_opt(obj_state, cpldata, argc, argv, num_opt); 1590*5088Sab196087 1591*5088Sab196087 /* The second argument can be an STT_ value */ 1592*5088Sab196087 if (argc == (num_opt + 2)) 1593*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_STT); 1594*5088Sab196087 } 1595*5088Sab196087 1596*5088Sab196087 /*ARGSUSED*/ 1597*5088Sab196087 static void 1598*5088Sab196087 cpl_st_visibility(elfedit_obj_state_t *obj_state, void *cpldata, int argc, 1599*5088Sab196087 const char *argv[], int num_opt) 1600*5088Sab196087 { 1601*5088Sab196087 /* Handle -shXXX options */ 1602*5088Sab196087 cpl_sh_opt(obj_state, cpldata, argc, argv, num_opt); 1603*5088Sab196087 1604*5088Sab196087 /* The second argument can be an STV_ value */ 1605*5088Sab196087 if (argc == (num_opt + 2)) 1606*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_STV); 1607*5088Sab196087 } 1608*5088Sab196087 1609*5088Sab196087 1610*5088Sab196087 1611*5088Sab196087 /* 1612*5088Sab196087 * Implementation functions for the commands 1613*5088Sab196087 */ 1614*5088Sab196087 static elfedit_cmdret_t 1615*5088Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1616*5088Sab196087 { 1617*5088Sab196087 return (cmd_body(SYM_CMD_T_DUMP, obj_state, argc, argv)); 1618*5088Sab196087 } 1619*5088Sab196087 1620*5088Sab196087 1621*5088Sab196087 static elfedit_cmdret_t 1622*5088Sab196087 cmd_st_bind(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1623*5088Sab196087 { 1624*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_BIND, obj_state, argc, argv)); 1625*5088Sab196087 } 1626*5088Sab196087 1627*5088Sab196087 1628*5088Sab196087 static elfedit_cmdret_t 1629*5088Sab196087 cmd_st_info(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1630*5088Sab196087 { 1631*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_INFO, obj_state, argc, argv)); 1632*5088Sab196087 } 1633*5088Sab196087 1634*5088Sab196087 static elfedit_cmdret_t 1635*5088Sab196087 cmd_st_name(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1636*5088Sab196087 { 1637*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_NAME, obj_state, argc, argv)); 1638*5088Sab196087 } 1639*5088Sab196087 1640*5088Sab196087 static elfedit_cmdret_t 1641*5088Sab196087 cmd_st_other(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1642*5088Sab196087 { 1643*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_OTHER, obj_state, argc, argv)); 1644*5088Sab196087 } 1645*5088Sab196087 1646*5088Sab196087 static elfedit_cmdret_t 1647*5088Sab196087 cmd_st_shndx(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1648*5088Sab196087 { 1649*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_SHNDX, obj_state, argc, argv)); 1650*5088Sab196087 } 1651*5088Sab196087 1652*5088Sab196087 static elfedit_cmdret_t 1653*5088Sab196087 cmd_st_size(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1654*5088Sab196087 { 1655*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_SIZE, obj_state, argc, argv)); 1656*5088Sab196087 } 1657*5088Sab196087 1658*5088Sab196087 static elfedit_cmdret_t 1659*5088Sab196087 cmd_st_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1660*5088Sab196087 { 1661*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_TYPE, obj_state, argc, argv)); 1662*5088Sab196087 } 1663*5088Sab196087 1664*5088Sab196087 static elfedit_cmdret_t 1665*5088Sab196087 cmd_st_value(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1666*5088Sab196087 { 1667*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_VALUE, obj_state, argc, argv)); 1668*5088Sab196087 } 1669*5088Sab196087 1670*5088Sab196087 static elfedit_cmdret_t 1671*5088Sab196087 cmd_st_visibility(elfedit_obj_state_t *obj_state, int argc, const char *argv[]) 1672*5088Sab196087 { 1673*5088Sab196087 return (cmd_body(SYM_CMD_T_ST_VISIBILITY, obj_state, argc, argv)); 1674*5088Sab196087 } 1675*5088Sab196087 1676*5088Sab196087 1677*5088Sab196087 1678*5088Sab196087 /*ARGSUSED*/ 1679*5088Sab196087 elfedit_module_t * 1680*5088Sab196087 elfedit_init(elfedit_module_version_t version) 1681*5088Sab196087 { 1682*5088Sab196087 /* Multiple commands accept only the standard set of options */ 1683*5088Sab196087 static elfedit_cmd_optarg_t opt_std[] = { 1684*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNAM), 1685*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNAM) */ 1686*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNAM), ELFEDIT_CMDOA_F_VALUE, 1687*5088Sab196087 SYM_OPT_F_SHNAME, SYM_OPT_F_SHNDX | SYM_OPT_F_SHTYP }, 1688*5088Sab196087 { MSG_ORIG(MSG_STR_NAME), NULL, 0 }, 1689*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1690*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1691*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), ELFEDIT_CMDOA_F_VALUE, 1692*5088Sab196087 SYM_OPT_F_SHNDX, SYM_OPT_F_SHNAME | SYM_OPT_F_SHTYP }, 1693*5088Sab196087 { MSG_ORIG(MSG_STR_INDEX), NULL, 0 }, 1694*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1695*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1696*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), ELFEDIT_CMDOA_F_VALUE, 1697*5088Sab196087 SYM_OPT_F_SHTYP, SYM_OPT_F_SHNAME | SYM_OPT_F_SHNDX }, 1698*5088Sab196087 { MSG_ORIG(MSG_STR_TYPE), NULL, 0 }, 1699*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SYMNDX), 1700*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SYMNDX) */ 1701*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SYMNDX), 0, SYM_OPT_F_SYMNDX }, 1702*5088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1703*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0 }, 1704*5088Sab196087 { NULL } 1705*5088Sab196087 }; 1706*5088Sab196087 1707*5088Sab196087 /* sym:dump */ 1708*5088Sab196087 static const char *name_dump[] = { 1709*5088Sab196087 MSG_ORIG(MSG_CMD_DUMP), 1710*5088Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */ 1711*5088Sab196087 NULL 1712*5088Sab196087 }; 1713*5088Sab196087 static elfedit_cmd_optarg_t opt_dump[] = { 1714*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNAM), 1715*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNAM) */ 1716*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNAM), ELFEDIT_CMDOA_F_VALUE, 1717*5088Sab196087 SYM_OPT_F_SHNAME, SYM_OPT_F_SHNDX | SYM_OPT_F_SHTYP }, 1718*5088Sab196087 { MSG_ORIG(MSG_STR_NAME), NULL, 0 }, 1719*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1720*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1721*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), ELFEDIT_CMDOA_F_VALUE, 1722*5088Sab196087 SYM_OPT_F_SHNDX, SYM_OPT_F_SHNAME | SYM_OPT_F_SHTYP }, 1723*5088Sab196087 { MSG_ORIG(MSG_STR_INDEX), NULL, 0 }, 1724*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1725*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1726*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), ELFEDIT_CMDOA_F_VALUE, 1727*5088Sab196087 SYM_OPT_F_SHTYP, SYM_OPT_F_SHNAME | SYM_OPT_F_SHNDX }, 1728*5088Sab196087 { MSG_ORIG(MSG_STR_TYPE), NULL, 0 }, 1729*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SYMNDX), 1730*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SYMNDX) */ 1731*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SYMNDX), 0, SYM_OPT_F_SYMNDX }, 1732*5088Sab196087 { NULL } 1733*5088Sab196087 }; 1734*5088Sab196087 static elfedit_cmd_optarg_t arg_dump[] = { 1735*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1736*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1737*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1738*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1739*5088Sab196087 { NULL } 1740*5088Sab196087 }; 1741*5088Sab196087 1742*5088Sab196087 /* sym:st_bind */ 1743*5088Sab196087 static const char *name_st_bind[] = { 1744*5088Sab196087 MSG_ORIG(MSG_CMD_ST_BIND), NULL }; 1745*5088Sab196087 static elfedit_cmd_optarg_t arg_st_bind[] = { 1746*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1747*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1748*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1749*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1750*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1751*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_BIND) */ 1752*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_BIND), 1753*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1754*5088Sab196087 { NULL } 1755*5088Sab196087 }; 1756*5088Sab196087 1757*5088Sab196087 /* sym:st_info */ 1758*5088Sab196087 static const char *name_st_info[] = { 1759*5088Sab196087 MSG_ORIG(MSG_CMD_ST_INFO), NULL }; 1760*5088Sab196087 static elfedit_cmd_optarg_t arg_st_info[] = { 1761*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1762*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1763*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1764*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1765*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1766*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_INFO) */ 1767*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_INFO), 1768*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1769*5088Sab196087 { NULL } 1770*5088Sab196087 }; 1771*5088Sab196087 1772*5088Sab196087 /* sym:st_name */ 1773*5088Sab196087 static const char *name_st_name[] = { 1774*5088Sab196087 MSG_ORIG(MSG_CMD_ST_NAME), NULL }; 1775*5088Sab196087 static elfedit_cmd_optarg_t opt_st_name[] = { 1776*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNAM), 1777*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNAM) */ 1778*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNAM), ELFEDIT_CMDOA_F_VALUE, 1779*5088Sab196087 SYM_OPT_F_SHNAME, SYM_OPT_F_SHNDX | SYM_OPT_F_SHTYP }, 1780*5088Sab196087 { MSG_ORIG(MSG_STR_NAME), NULL, 0, 0 }, 1781*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1782*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1783*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), ELFEDIT_CMDOA_F_VALUE, 1784*5088Sab196087 SYM_OPT_F_SHNDX, SYM_OPT_F_SHNAME | SYM_OPT_F_SHTYP }, 1785*5088Sab196087 { MSG_ORIG(MSG_STR_INDEX), NULL, 0, 0 }, 1786*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1787*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1788*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), ELFEDIT_CMDOA_F_VALUE, 1789*5088Sab196087 SYM_OPT_F_SHTYP, SYM_OPT_F_SHNAME | SYM_OPT_F_SHNDX }, 1790*5088Sab196087 { MSG_ORIG(MSG_STR_TYPE), NULL, 0, 0 }, 1791*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SYMNDX), 1792*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SYMNDX) */ 1793*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SYMNDX), 0, 1794*5088Sab196087 SYM_OPT_F_SYMNDX, 0 }, 1795*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_NAME_OFFSET), 1796*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_NAME_OFFSET) */ 1797*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_NAME_OFFSET), 0, 1798*5088Sab196087 SYM_OPT_F_NAMOFFSET, 0 }, 1799*5088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1800*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1801*5088Sab196087 { NULL } 1802*5088Sab196087 }; 1803*5088Sab196087 static elfedit_cmd_optarg_t arg_st_name[] = { 1804*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1805*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1806*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1807*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1808*5088Sab196087 { MSG_ORIG(MSG_STR_NAME), 1809*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_NAME) */ 1810*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_NAME), 1811*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1812*5088Sab196087 { NULL } 1813*5088Sab196087 }; 1814*5088Sab196087 1815*5088Sab196087 /* sym:st_other */ 1816*5088Sab196087 static const char *name_st_other[] = { 1817*5088Sab196087 MSG_ORIG(MSG_CMD_ST_OTHER), NULL }; 1818*5088Sab196087 static elfedit_cmd_optarg_t arg_st_other[] = { 1819*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1820*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1821*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1822*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1823*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1824*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_OTHER) */ 1825*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_OTHER), 1826*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1827*5088Sab196087 { NULL } 1828*5088Sab196087 }; 1829*5088Sab196087 1830*5088Sab196087 /* sym:st_shndx */ 1831*5088Sab196087 static const char *name_st_shndx[] = { 1832*5088Sab196087 MSG_ORIG(MSG_CMD_ST_SHNDX), NULL }; 1833*5088Sab196087 static elfedit_cmd_optarg_t opt_st_shndx[] = { 1834*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_E), 1835*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_E) */ 1836*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_E), 0, SYM_OPT_F_XSHINDEX, 0 }, 1837*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNAM), 1838*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNAM) */ 1839*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNAM), ELFEDIT_CMDOA_F_VALUE, 1840*5088Sab196087 SYM_OPT_F_SHNAME, SYM_OPT_F_SHNDX | SYM_OPT_F_SHTYP }, 1841*5088Sab196087 { MSG_ORIG(MSG_STR_NAME), NULL, 0, 0 }, 1842*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHNDX), 1843*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHNDX) */ 1844*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), ELFEDIT_CMDOA_F_VALUE, 1845*5088Sab196087 SYM_OPT_F_SHNDX, SYM_OPT_F_SHNAME | SYM_OPT_F_SHTYP }, 1846*5088Sab196087 { MSG_ORIG(MSG_STR_INDEX), NULL, 0, 0 }, 1847*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SHTYP), 1848*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SHTYP) */ 1849*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), ELFEDIT_CMDOA_F_VALUE, 1850*5088Sab196087 SYM_OPT_F_SHTYP, SYM_OPT_F_SHNAME | SYM_OPT_F_SHNDX }, 1851*5088Sab196087 { MSG_ORIG(MSG_STR_TYPE), NULL, 0, 0 }, 1852*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SYMNDX), 1853*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SYMNDX) */ 1854*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SYMNDX), 0, 1855*5088Sab196087 SYM_OPT_F_SYMNDX, 0 }, 1856*5088Sab196087 { ELFEDIT_STDOA_OPT_O, NULL, 1857*5088Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 }, 1858*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SECSHNDX), 1859*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SECSHNDX) */ 1860*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SECSHNDX), 1861*5088Sab196087 0, SYM_OPT_F_SECSHNDX, SYM_OPT_F_SECSHTYP }, 1862*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_SECSHTYP), 1863*5088Sab196087 /* MSG_INTL(MSG_OPTDESC_SECSHTYP) */ 1864*5088Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_SECSHTYP), 1865*5088Sab196087 0, SYM_OPT_F_SECSHTYP, SYM_OPT_F_SECSHNDX }, 1866*5088Sab196087 { NULL } 1867*5088Sab196087 }; 1868*5088Sab196087 static elfedit_cmd_optarg_t arg_st_shndx[] = { 1869*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1870*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1871*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1872*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1873*5088Sab196087 { MSG_ORIG(MSG_STR_SEC), 1874*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_SEC) */ 1875*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_SEC), 1876*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1877*5088Sab196087 { NULL } 1878*5088Sab196087 }; 1879*5088Sab196087 1880*5088Sab196087 /* sym:st_size */ 1881*5088Sab196087 static const char *name_st_size[] = { 1882*5088Sab196087 MSG_ORIG(MSG_CMD_ST_SIZE), NULL }; 1883*5088Sab196087 static elfedit_cmd_optarg_t arg_st_size[] = { 1884*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1885*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1886*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1887*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1888*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1889*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_SIZE) */ 1890*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_SIZE), 1891*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1892*5088Sab196087 { NULL } 1893*5088Sab196087 }; 1894*5088Sab196087 1895*5088Sab196087 /* sym:st_type */ 1896*5088Sab196087 static const char *name_st_type[] = { 1897*5088Sab196087 MSG_ORIG(MSG_CMD_ST_TYPE), NULL }; 1898*5088Sab196087 static elfedit_cmd_optarg_t arg_st_type[] = { 1899*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1900*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1901*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1902*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1903*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1904*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_TYPE) */ 1905*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_TYPE), 1906*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1907*5088Sab196087 { NULL } 1908*5088Sab196087 }; 1909*5088Sab196087 1910*5088Sab196087 /* sym:st_value */ 1911*5088Sab196087 static const char *name_st_value[] = { 1912*5088Sab196087 MSG_ORIG(MSG_CMD_ST_VALUE), NULL }; 1913*5088Sab196087 static elfedit_cmd_optarg_t arg_st_value[] = { 1914*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1915*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1916*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1917*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1918*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1919*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_VALUE) */ 1920*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_VALUE), 1921*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1922*5088Sab196087 { NULL } 1923*5088Sab196087 }; 1924*5088Sab196087 1925*5088Sab196087 /* sym:st_visibility */ 1926*5088Sab196087 static const char *name_st_visibility[] = { 1927*5088Sab196087 MSG_ORIG(MSG_CMD_ST_VISIBILITY), NULL }; 1928*5088Sab196087 static elfedit_cmd_optarg_t arg_st_visibility[] = { 1929*5088Sab196087 { MSG_ORIG(MSG_STR_SYM), 1930*5088Sab196087 /* MSG_INTL(MSG_A1_SYM) */ 1931*5088Sab196087 ELFEDIT_I18NHDL(MSG_A1_SYM), 1932*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1933*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 1934*5088Sab196087 /* MSG_INTL(MSG_A2_DESC_ST_VISIBILITY) */ 1935*5088Sab196087 ELFEDIT_I18NHDL(MSG_A2_DESC_ST_VISIBILITY), 1936*5088Sab196087 ELFEDIT_CMDOA_F_OPT }, 1937*5088Sab196087 { NULL } 1938*5088Sab196087 }; 1939*5088Sab196087 1940*5088Sab196087 static elfedit_cmd_t cmds[] = { 1941*5088Sab196087 /* sym:dump */ 1942*5088Sab196087 { cmd_dump, cpl_sh_opt, name_dump, 1943*5088Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */ 1944*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP), 1945*5088Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */ 1946*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP), 1947*5088Sab196087 opt_dump, arg_dump }, 1948*5088Sab196087 1949*5088Sab196087 /* sym:st_bind */ 1950*5088Sab196087 { cmd_st_bind, cpl_st_bind, name_st_bind, 1951*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_BIND) */ 1952*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_BIND), 1953*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_BIND) */ 1954*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_BIND), 1955*5088Sab196087 opt_std, arg_st_bind }, 1956*5088Sab196087 1957*5088Sab196087 /* sym:st_info */ 1958*5088Sab196087 { cmd_st_info, cpl_sh_opt, name_st_info, 1959*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_INFO) */ 1960*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_INFO), 1961*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_INFO) */ 1962*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_INFO), 1963*5088Sab196087 opt_std, arg_st_info }, 1964*5088Sab196087 1965*5088Sab196087 /* sym:st_name */ 1966*5088Sab196087 { cmd_st_name, cpl_sh_opt, name_st_name, 1967*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_NAME) */ 1968*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_NAME), 1969*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_NAME) */ 1970*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_NAME), 1971*5088Sab196087 opt_st_name, arg_st_name }, 1972*5088Sab196087 1973*5088Sab196087 /* sym:st_other */ 1974*5088Sab196087 { cmd_st_other, cpl_sh_opt, name_st_other, 1975*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_OTHER) */ 1976*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_OTHER), 1977*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_OTHER) */ 1978*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_OTHER), 1979*5088Sab196087 opt_std, arg_st_other }, 1980*5088Sab196087 1981*5088Sab196087 /* sym:st_shndx */ 1982*5088Sab196087 { cmd_st_shndx, cpl_st_shndx, name_st_shndx, 1983*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_SHNDX) */ 1984*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_SHNDX), 1985*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_SHNDX) */ 1986*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_SHNDX), 1987*5088Sab196087 opt_st_shndx, arg_st_shndx }, 1988*5088Sab196087 1989*5088Sab196087 /* sym:st_size */ 1990*5088Sab196087 { cmd_st_size, cpl_sh_opt, name_st_size, 1991*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_SIZE) */ 1992*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_SIZE), 1993*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_SIZE) */ 1994*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_SIZE), 1995*5088Sab196087 opt_std, arg_st_size }, 1996*5088Sab196087 1997*5088Sab196087 /* sym:st_type */ 1998*5088Sab196087 { cmd_st_type, cpl_st_type, name_st_type, 1999*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_TYPE) */ 2000*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_TYPE), 2001*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_TYPE) */ 2002*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_TYPE), 2003*5088Sab196087 opt_std, arg_st_type }, 2004*5088Sab196087 2005*5088Sab196087 /* sym:st_value */ 2006*5088Sab196087 { cmd_st_value, cpl_sh_opt, name_st_value, 2007*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_VALUE) */ 2008*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_VALUE), 2009*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_VALUE) */ 2010*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_VALUE), 2011*5088Sab196087 opt_std, arg_st_value }, 2012*5088Sab196087 2013*5088Sab196087 /* sym:st_visibility */ 2014*5088Sab196087 { cmd_st_visibility, cpl_st_visibility, name_st_visibility, 2015*5088Sab196087 /* MSG_INTL(MSG_DESC_ST_VISIBILITY) */ 2016*5088Sab196087 ELFEDIT_I18NHDL(MSG_DESC_ST_VISIBILITY), 2017*5088Sab196087 /* MSG_INTL(MSG_HELP_ST_VISIBILITY) */ 2018*5088Sab196087 ELFEDIT_I18NHDL(MSG_HELP_ST_VISIBILITY), 2019*5088Sab196087 opt_std, arg_st_visibility }, 2020*5088Sab196087 2021*5088Sab196087 { NULL } 2022*5088Sab196087 }; 2023*5088Sab196087 2024*5088Sab196087 static elfedit_module_t module = { 2025*5088Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME), 2026*5088Sab196087 /* MSG_INTL(MSG_MOD_DESC) */ 2027*5088Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC), 2028*5088Sab196087 cmds, mod_i18nhdl_to_str }; 2029*5088Sab196087 2030*5088Sab196087 return (&module); 2031*5088Sab196087 } 2032