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