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