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 *
_sym_msg(Msg mid)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 *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)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
symstate_add_str(ARGSTATE * argstate,SYMSTATE * symstate)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
symstate_add_versym(ARGSTATE * argstate,SYMSTATE * symstate)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
symstate_add_xshndx(ARGSTATE * argstate,SYMSTATE * symstate)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
dump_symtab(ARGSTATE * argstate,SYMSTATE * symstate,Word ndx,Word cnt)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
all_same(SYM_CMD_T cmd,ARGSTATE * argstate,elfedit_outstyle_t outstyle)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
print_symstate(SYM_CMD_T cmd,ARGSTATE * argstate,SYMSTATE * symstate,elfedit_outstyle_t outstyle,Word ndx,Word cnt)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
print_sym(SYM_CMD_T cmd,int autoprint,ARGSTATE * argstate)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
cmd_body_set_st_bind(ARGSTATE * argstate,SYMSTATE * symstate)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
cmd_body_set_st_name(ARGSTATE * argstate,SYMSTATE * symstate)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
cmd_body_set_st_shndx(ARGSTATE * argstate,SYMSTATE * symstate)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
cmd_body_set_st_type(ARGSTATE * argstate,SYMSTATE * symstate)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
cmd_body_set_st_visibility(ARGSTATE * argstate,SYMSTATE * symstate)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 *
process_args(elfedit_obj_state_t * obj_state,int argc,const char * argv[],SYM_CMD_T cmd)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
symstate_cmd_body(SYM_CMD_T cmd,ARGSTATE * argstate,SYMSTATE * symstate)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
cmd_body(SYM_CMD_T cmd,elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cpl_sh_opt(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)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
cpl_st_bind(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)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
cpl_st_shndx(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)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
cpl_st_type(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)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
cpl_st_visibility(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)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
cmd_dump(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_bind(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_info(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_name(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_other(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_shndx(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_size(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_type(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_value(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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
cmd_st_visibility(elfedit_obj_state_t * obj_state,int argc,const char * argv[])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 *
elfedit_init(elfedit_module_version_t version)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