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*08278a5eSRod Evans * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24d29b2c44Sab196087 * Use is subject to license terms.
25d29b2c44Sab196087 */
26d29b2c44Sab196087
27d29b2c44Sab196087 #include <ctype.h>
28d29b2c44Sab196087 #include <elfedit.h>
29d29b2c44Sab196087 #include <sys/elf_SPARC.h>
30d29b2c44Sab196087 #include <strings.h>
31d29b2c44Sab196087 #include <debug.h>
32d29b2c44Sab196087 #include <conv.h>
33d29b2c44Sab196087 #include <dyn_msg.h>
34d29b2c44Sab196087
35d29b2c44Sab196087
36d29b2c44Sab196087 /*
37d29b2c44Sab196087 * Dynamic section
38d29b2c44Sab196087 */
39d29b2c44Sab196087
40d29b2c44Sab196087 /*
41d29b2c44Sab196087 * This module uses shared code for several of the commands.
42d29b2c44Sab196087 * It is sometimes necessary to know which specific command
43d29b2c44Sab196087 * is active.
44d29b2c44Sab196087 */
45d29b2c44Sab196087 typedef enum {
46d29b2c44Sab196087 /* Dump command, used as module default to display dynamic section */
47d29b2c44Sab196087 DYN_CMD_T_DUMP = 0, /* dyn:dump */
48d29b2c44Sab196087
49d29b2c44Sab196087 /* Commands that do not correspond directly to a specific DT tag */
50d29b2c44Sab196087 DYN_CMD_T_TAG = 1, /* dyn:tag */
51d29b2c44Sab196087 DYN_CMD_T_VALUE = 2, /* dyn:value */
52d29b2c44Sab196087 DYN_CMD_T_DELETE = 3, /* dyn:delete */
53d29b2c44Sab196087 DYN_CMD_T_MOVE = 4, /* dyn:shift */
54d29b2c44Sab196087
55d29b2c44Sab196087 /* Commands that embody tag specific knowledge */
56d29b2c44Sab196087 DYN_CMD_T_RUNPATH = 5, /* dyn:runpath/rpath */
57d29b2c44Sab196087 DYN_CMD_T_POSFLAG1 = 6, /* dyn:posflag1 */
58d29b2c44Sab196087 DYN_CMD_T_FLAGS = 7, /* dyn:flags */
59d29b2c44Sab196087 DYN_CMD_T_FLAGS1 = 8, /* dyn:flags1 */
60d29b2c44Sab196087 DYN_CMD_T_FEATURE1 = 9, /* dyn:feature1 */
61ba2be530Sab196087 DYN_CMD_T_CHECKSUM = 10, /* dyn:checksum */
62ba2be530Sab196087 DYN_CMD_T_SUNW_LDMACH = 11 /* dyn:sunw_ldmach */
63d29b2c44Sab196087 } DYN_CMD_T;
64d29b2c44Sab196087
65d29b2c44Sab196087
66d29b2c44Sab196087
67d29b2c44Sab196087 #ifndef _ELF64
68d29b2c44Sab196087 /*
69d29b2c44Sab196087 * We supply this function for the msg module
70d29b2c44Sab196087 */
71d29b2c44Sab196087 const char *
_dyn_msg(Msg mid)72d29b2c44Sab196087 _dyn_msg(Msg mid)
73d29b2c44Sab196087 {
74d29b2c44Sab196087 return (gettext(MSG_ORIG(mid)));
75d29b2c44Sab196087 }
76d29b2c44Sab196087 #endif
77d29b2c44Sab196087
78d29b2c44Sab196087
79d29b2c44Sab196087 /*
80d29b2c44Sab196087 * This function is supplied to elfedit through our elfedit_module_t
81d29b2c44Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles
82d29b2c44Sab196087 * in our module interface into the actual strings for elfedit to
83d29b2c44Sab196087 * use.
84d29b2c44Sab196087 *
85d29b2c44Sab196087 * note:
86d29b2c44Sab196087 * This module uses Msg codes for its i18n handle type.
87d29b2c44Sab196087 * So the translation is simply to use MSG_INTL() to turn
88d29b2c44Sab196087 * it into a string and return it.
89d29b2c44Sab196087 */
90d29b2c44Sab196087 static const char *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)91d29b2c44Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
92d29b2c44Sab196087 {
93d29b2c44Sab196087 Msg msg = (Msg)hdl;
94d29b2c44Sab196087
95d29b2c44Sab196087 return (MSG_INTL(msg));
96d29b2c44Sab196087 }
97d29b2c44Sab196087
98d29b2c44Sab196087
99d29b2c44Sab196087
100d29b2c44Sab196087 /*
101d29b2c44Sab196087 * The dyn_opt_t enum specifies a bit value for every optional
102d29b2c44Sab196087 * argument allowed by a command in this module.
103d29b2c44Sab196087 */
104d29b2c44Sab196087 typedef enum {
105d29b2c44Sab196087 DYN_OPT_F_ADD = 1, /* -add: Add new elt rather than */
106d29b2c44Sab196087 /* modifying an existing one */
107d29b2c44Sab196087 DYN_OPT_F_AND = 2, /* -and: AND (&) values to dest */
108d29b2c44Sab196087 DYN_OPT_F_CMP = 4, /* -cmp: Complement (~) values */
10955ef6355Sab196087 DYN_OPT_F_DYNNDX_ELT = 8, /* -dynndx: 1st plain arg is tag */
11055ef6355Sab196087 /* index, not name */
11155ef6355Sab196087 DYN_OPT_F_DYNNDX_VAL = 16, /* -dynndx ndx: Index is value to */
11255ef6355Sab196087 /* option rather than 1st plain */
11355ef6355Sab196087 /* arg. Used for dyn:posflag1 */
11455ef6355Sab196087 DYN_OPT_F_NEEDED = 32, /* -needed str: Locate DT_POSFLAG_1 */
11555ef6355Sab196087 /* relative to DT_NEEDED element */
11655ef6355Sab196087 DYN_OPT_F_OR = 64, /* -or: OR (|) values to dest */
11755ef6355Sab196087 DYN_OPT_F_STRVAL = 128 /* -s: value is string, not integer */
118d29b2c44Sab196087 } dyn_opt_t;
119d29b2c44Sab196087
120d29b2c44Sab196087
121d29b2c44Sab196087 /*
122d29b2c44Sab196087 * A variable of type ARGSTATE is used by each command to maintain
123d29b2c44Sab196087 * information about the arguments and related things. It is
124d29b2c44Sab196087 * initialized by process_args(), and used by the other routines.
125d29b2c44Sab196087 */
126d29b2c44Sab196087 typedef struct {
127d29b2c44Sab196087 elfedit_obj_state_t *obj_state;
128d29b2c44Sab196087 elfedit_section_t *strsec; /* Dynamic string table ref */
129d29b2c44Sab196087 struct {
130d29b2c44Sab196087 elfedit_section_t *sec; /* Dynamic section reference */
131d29b2c44Sab196087 Dyn *data; /* Start dynamic section data */
132d29b2c44Sab196087 Word num; /* # dynamic elts */
133d29b2c44Sab196087 Word null_ndx; /* Index of first DT_NULL */
134d29b2c44Sab196087 Word num_null_ndx; /* # of DT_NULL elements */
135d29b2c44Sab196087 } dyn;
136d29b2c44Sab196087 dyn_opt_t optmask; /* Mask of options used */
137d29b2c44Sab196087 int argc; /* # of plain arguments */
138d29b2c44Sab196087 const char **argv; /* Plain arguments */
13955ef6355Sab196087 const char *dyn_elt_str; /* Value string for */
14055ef6355Sab196087 /* DYN_OPT_F_DYNNDX_VAL */
14155ef6355Sab196087 /* or DYN_OPT_F_NEEDED */
142d29b2c44Sab196087 } ARGSTATE;
143d29b2c44Sab196087
144d29b2c44Sab196087
145d29b2c44Sab196087
146d29b2c44Sab196087 /*
147d29b2c44Sab196087 * Set argstate null_ndx field for current dynamic area
148d29b2c44Sab196087 */
149d29b2c44Sab196087 static void
set_null_ndx(ARGSTATE * argstate)150d29b2c44Sab196087 set_null_ndx(ARGSTATE *argstate)
151d29b2c44Sab196087 {
152d29b2c44Sab196087 Word num, null_ndx;
153d29b2c44Sab196087
154d29b2c44Sab196087 num = argstate->dyn.num;
155d29b2c44Sab196087 argstate->dyn.num_null_ndx = 0;
156d29b2c44Sab196087 for (null_ndx = 0; null_ndx < num; null_ndx++)
157d29b2c44Sab196087 if (argstate->dyn.data[null_ndx].d_tag == DT_NULL) {
158d29b2c44Sab196087 argstate->dyn.num_null_ndx++;
159d29b2c44Sab196087 break;
160d29b2c44Sab196087 }
161d29b2c44Sab196087 argstate->dyn.null_ndx = null_ndx;
162d29b2c44Sab196087
163d29b2c44Sab196087 /* Count the number of remaining DT_NULL items */
164d29b2c44Sab196087 for (; null_ndx < num; null_ndx++)
165d29b2c44Sab196087 if (argstate->dyn.data[null_ndx].d_tag == DT_NULL)
166d29b2c44Sab196087 argstate->dyn.num_null_ndx++;
167d29b2c44Sab196087 }
168d29b2c44Sab196087
169d29b2c44Sab196087
170d29b2c44Sab196087 /*
171d29b2c44Sab196087 * Convert the first available DT_NULL slot in the dynamic section
172d29b2c44Sab196087 * into something else.
173d29b2c44Sab196087 *
174d29b2c44Sab196087 * entry:
175d29b2c44Sab196087 * argstate - Argument state block
176d29b2c44Sab196087 * d_tag, d_val - Values to be set in new element
177d29b2c44Sab196087 *
178d29b2c44Sab196087 * exit:
179d29b2c44Sab196087 * If an extra DT_NULL slot is available, a debug message is
180d29b2c44Sab196087 * issued, the slot is converted to its new use, and the argstate
181d29b2c44Sab196087 * block state related to DT_NULL slots is updated.
182d29b2c44Sab196087 *
183d29b2c44Sab196087 * if no extra DT_NULL slot is present, an error is issued and
184d29b2c44Sab196087 * this routine does not return to the caller.
185d29b2c44Sab196087 */
186d29b2c44Sab196087 static Word
convert_dt_null(ARGSTATE * argstate,Xword d_tag,Xword d_val)1874f680cc6SAli Bahrami convert_dt_null(ARGSTATE *argstate, Xword d_tag, Xword d_val)
188d29b2c44Sab196087 {
189d29b2c44Sab196087 Conv_inv_buf_t inv_buf;
190d29b2c44Sab196087 Word ndx;
191d29b2c44Sab196087 Dyn *dyn;
1924f680cc6SAli Bahrami Ehdr *ehdr;
193d29b2c44Sab196087
194d29b2c44Sab196087 /* If we lack an extra element, we can't continue */
195d29b2c44Sab196087 if (argstate->dyn.num_null_ndx <= 1)
196d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOEXTRANULL),
197d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
198d29b2c44Sab196087 argstate->dyn.sec->sec_name);
199d29b2c44Sab196087
2004f680cc6SAli Bahrami ehdr = argstate->obj_state->os_ehdr;
201d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_CONVNULL),
202d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx), argstate->dyn.sec->sec_name,
203d29b2c44Sab196087 EC_WORD(argstate->dyn.null_ndx), conv_dyn_tag(d_tag,
2044f680cc6SAli Bahrami ehdr->e_ident[EI_OSABI], ehdr->e_machine, 0, &inv_buf));
205d29b2c44Sab196087
206d29b2c44Sab196087 ndx = argstate->dyn.null_ndx;
207d29b2c44Sab196087 dyn = &argstate->dyn.data[ndx];
208d29b2c44Sab196087 dyn->d_tag = d_tag;
209d29b2c44Sab196087 dyn->d_un.d_val = d_val;
210d29b2c44Sab196087
211d29b2c44Sab196087 /* Recompute the DT_NULL situation */
212d29b2c44Sab196087 set_null_ndx(argstate);
213d29b2c44Sab196087
214d29b2c44Sab196087 return (ndx);
215d29b2c44Sab196087 }
216d29b2c44Sab196087
217d29b2c44Sab196087
218d29b2c44Sab196087 /*
219d29b2c44Sab196087 * Standard argument processing for dyn module
220d29b2c44Sab196087 *
221d29b2c44Sab196087 * entry
222d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments
223d29b2c44Sab196087 * argstate - Address of ARGSTATE block to be initialized
224d29b2c44Sab196087 *
225d29b2c44Sab196087 * exit:
226d29b2c44Sab196087 * On success, *argstate is initialized. On error,
227d29b2c44Sab196087 * an error is issued and this routine does not return.
228d29b2c44Sab196087 */
229d29b2c44Sab196087 static void
process_args(elfedit_obj_state_t * obj_state,int argc,const char * argv[],ARGSTATE * argstate)230d29b2c44Sab196087 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
231d29b2c44Sab196087 ARGSTATE *argstate)
232d29b2c44Sab196087 {
233d29b2c44Sab196087 elfedit_getopt_state_t getopt_state;
234d29b2c44Sab196087 elfedit_getopt_ret_t *getopt_ret;
235d29b2c44Sab196087
236d29b2c44Sab196087 bzero(argstate, sizeof (*argstate));
237d29b2c44Sab196087 argstate->obj_state = obj_state;
238d29b2c44Sab196087
239d29b2c44Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv);
240d29b2c44Sab196087
241d29b2c44Sab196087 /* Add each new option to the options mask */
24255ef6355Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) {
243d29b2c44Sab196087 argstate->optmask |= getopt_ret->gor_idmask;
24455ef6355Sab196087 switch (getopt_ret->gor_idmask) {
24555ef6355Sab196087 case DYN_OPT_F_DYNNDX_VAL:
24655ef6355Sab196087 case DYN_OPT_F_NEEDED:
24755ef6355Sab196087 argstate->dyn_elt_str = getopt_ret->gor_value;
24855ef6355Sab196087 break;
24955ef6355Sab196087 }
25055ef6355Sab196087 }
251d29b2c44Sab196087
252d29b2c44Sab196087 /* If there may be an arbitrary amount of output, use a pager */
253d29b2c44Sab196087 if (argc == 0)
254d29b2c44Sab196087 elfedit_pager_init();
255d29b2c44Sab196087
256d29b2c44Sab196087 /* Return the updated values of argc/argv */
257d29b2c44Sab196087 argstate->argc = argc;
258d29b2c44Sab196087 argstate->argv = argv;
259d29b2c44Sab196087
260d29b2c44Sab196087 /* Locate the dynamic section, and the assocated string table */
261d29b2c44Sab196087 argstate->dyn.sec = elfedit_sec_getdyn(obj_state, &argstate->dyn.data,
262d29b2c44Sab196087 &argstate->dyn.num);
263d29b2c44Sab196087 argstate->strsec = elfedit_sec_getstr(obj_state,
26455ef6355Sab196087 argstate->dyn.sec->sec_shdr->sh_link, 0);
265d29b2c44Sab196087
266d29b2c44Sab196087 /* Index of first DT_NULL */
267d29b2c44Sab196087 set_null_ndx(argstate);
268d29b2c44Sab196087 }
269d29b2c44Sab196087
270d29b2c44Sab196087 /*
271d29b2c44Sab196087 * Print ELF header values, taking the calling command, and output style
272d29b2c44Sab196087 * into account.
273d29b2c44Sab196087 *
274d29b2c44Sab196087 * entry:
275d29b2c44Sab196087 * cmd - DYN_CMD_T_* value giving identify of caller
276d29b2c44Sab196087 * autoprint - If True, output is only produced if the elfedit
277d29b2c44Sab196087 * autoprint flag is set. If False, output is always produced.
278d29b2c44Sab196087 * argstate - Argument state block
279d29b2c44Sab196087 * print_type - Specifies which dynamic elements to display.
2804f680cc6SAli Bahrami * arg - If print_type is PRINT_DYN_T_NDX, displays the index specified.
281d29b2c44Sab196087 * Otherwise ignored.
282d29b2c44Sab196087 */
283d29b2c44Sab196087 typedef enum {
284d29b2c44Sab196087 PRINT_DYN_T_ALL = 0, /* Show all indexes */
285d29b2c44Sab196087 PRINT_DYN_T_NDX = 1, /* Show dynamic[arg] only */
286d29b2c44Sab196087 PRINT_DYN_T_TAG = 2, /* Show all elts with tag type */
287d29b2c44Sab196087 /* given by arg */
288d29b2c44Sab196087 PRINT_DYN_T_RUNPATH = 3 /* Show all runpath/rpath elts */
289d29b2c44Sab196087
290d29b2c44Sab196087 } PRINT_DYN_T;
291d29b2c44Sab196087
292d29b2c44Sab196087 static void
print_dyn(DYN_CMD_T cmd,int autoprint,ARGSTATE * argstate,PRINT_DYN_T print_type,Word arg)293d29b2c44Sab196087 print_dyn(DYN_CMD_T cmd, int autoprint, ARGSTATE *argstate,
294d29b2c44Sab196087 PRINT_DYN_T print_type, Word arg)
295d29b2c44Sab196087 {
296d29b2c44Sab196087 elfedit_outstyle_t outstyle;
297d29b2c44Sab196087 Conv_fmt_flags_t flags_fmt_flags;
298c6c9aed4Sab196087 Word end_ndx, ndx, printed = 0;
299d29b2c44Sab196087 Dyn *dyn;
300d29b2c44Sab196087 int header_done = 0;
301d29b2c44Sab196087 Xword last_d_val;
30255ef6355Sab196087 int one_shot;
3034f680cc6SAli Bahrami int osabi_solaris;
304d29b2c44Sab196087
305d29b2c44Sab196087 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
306d29b2c44Sab196087 return;
307d29b2c44Sab196087
3084f680cc6SAli Bahrami osabi_solaris =
3094f680cc6SAli Bahrami elfedit_test_osabi(argstate->obj_state, ELFOSABI_SOLARIS, 0);
3104f680cc6SAli Bahrami
311d29b2c44Sab196087 /*
312d29b2c44Sab196087 * Pick an output style. dyn:dump is required to use the default
313d29b2c44Sab196087 * style. The other commands use the current output style.
314d29b2c44Sab196087 */
315d29b2c44Sab196087 outstyle = (cmd == DYN_CMD_T_DUMP) ?
316d29b2c44Sab196087 ELFEDIT_OUTSTYLE_DEFAULT : elfedit_outstyle();
317d29b2c44Sab196087
318d29b2c44Sab196087 /*
319d29b2c44Sab196087 * When using the simple output style, omit the
320d29b2c44Sab196087 * brackets from around the values.
321d29b2c44Sab196087 */
322d29b2c44Sab196087 flags_fmt_flags = (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) ?
323d29b2c44Sab196087 CONV_FMT_NOBKT : 0;
324d29b2c44Sab196087
325c6c9aed4Sab196087 /* Starting index */
326d29b2c44Sab196087 if (print_type == PRINT_DYN_T_NDX) {
327d29b2c44Sab196087 if (arg >= argstate->dyn.num)
328d29b2c44Sab196087 return; /* Out of range */
329d29b2c44Sab196087 ndx = arg;
330d29b2c44Sab196087 } else {
331d29b2c44Sab196087 ndx = 0;
332d29b2c44Sab196087 }
333d29b2c44Sab196087
33455ef6355Sab196087 /*
33555ef6355Sab196087 * one_shot is used by positional elements (e.g. DT_POSFLAG_1)
33655ef6355Sab196087 * to get the item following them to be shown even if they
33755ef6355Sab196087 * are not of the desired tag type or the count of elements
33855ef6355Sab196087 * to be displayed is only 1.
33955ef6355Sab196087 */
34055ef6355Sab196087 one_shot = 0;
34155ef6355Sab196087
342d29b2c44Sab196087 dyn = &argstate->dyn.data[ndx];
343c6c9aed4Sab196087
344c6c9aed4Sab196087 /*
345c6c9aed4Sab196087 * Loop predicate explanation:
346c6c9aed4Sab196087 * Normally, we want to iterate from the starting index
347c6c9aed4Sab196087 * to the end. However, in the case of PRINT_DYN_T_NDX, we
348c6c9aed4Sab196087 * only want to display one item (ndx == arg) and then quit,
349c6c9aed4Sab196087 * with the exception that if we've been through the loop
350c6c9aed4Sab196087 * and encountered a one_shot situation, we want to continue
351c6c9aed4Sab196087 * iterating until the one-shot situation is cleared.
352c6c9aed4Sab196087 */
353c6c9aed4Sab196087 for (; (ndx < argstate->dyn.num) &&
354c6c9aed4Sab196087 ((print_type != PRINT_DYN_T_NDX) || ((ndx == arg) || one_shot));
355c6c9aed4Sab196087 dyn++, ndx++) {
356d29b2c44Sab196087 union {
357ba2be530Sab196087 Conv_inv_buf_t inv;
358d29b2c44Sab196087 Conv_dyn_flag_buf_t flag;
359d29b2c44Sab196087 Conv_dyn_flag1_buf_t flag1;
360d29b2c44Sab196087 Conv_dyn_posflag1_buf_t posflag1;
361d29b2c44Sab196087 Conv_dyn_feature1_buf_t feature1;
362d29b2c44Sab196087 } c_buf;
363d29b2c44Sab196087 const char *name;
364d29b2c44Sab196087
36555ef6355Sab196087 if (one_shot) {
36655ef6355Sab196087 one_shot = 0;
36755ef6355Sab196087 } else {
368d29b2c44Sab196087 /*
369d29b2c44Sab196087 * If we are only displaying certain tag types and
370d29b2c44Sab196087 * this isn't one of those, move on to next element.
371d29b2c44Sab196087 */
372d29b2c44Sab196087 switch (print_type) {
373d29b2c44Sab196087 case PRINT_DYN_T_TAG:
374d29b2c44Sab196087 if (dyn->d_tag != arg)
375d29b2c44Sab196087 continue;
376d29b2c44Sab196087 break;
377d29b2c44Sab196087 case PRINT_DYN_T_RUNPATH:
378d29b2c44Sab196087 if ((dyn->d_tag != DT_RPATH) &&
379d29b2c44Sab196087 (dyn->d_tag != DT_RUNPATH))
380d29b2c44Sab196087 continue;
381d29b2c44Sab196087 break;
382d29b2c44Sab196087 }
38355ef6355Sab196087 }
384d29b2c44Sab196087
385d29b2c44Sab196087 /*
386d29b2c44Sab196087 * Print the information numerically, and if possible
387d29b2c44Sab196087 * as a string.
388d29b2c44Sab196087 */
389d29b2c44Sab196087 name = NULL;
390d29b2c44Sab196087 switch (dyn->d_tag) {
391d29b2c44Sab196087 case DT_NULL:
392d29b2c44Sab196087 if (!((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) &&
393d29b2c44Sab196087 (print_type == PRINT_DYN_T_ALL) &&
394d29b2c44Sab196087 (dyn->d_un.d_val == 0)))
395d29b2c44Sab196087 break;
396d29b2c44Sab196087 end_ndx = ndx;
397d29b2c44Sab196087 /*
398d29b2c44Sab196087 * Special case: DT_NULLs can come in groups
399d29b2c44Sab196087 * that we prefer to reduce to a single line.
400d29b2c44Sab196087 */
401d29b2c44Sab196087 while ((end_ndx < (argstate->dyn.num - 1)) &&
402d29b2c44Sab196087 ((dyn + 1)->d_tag == DT_NULL) &&
403d29b2c44Sab196087 ((dyn + 1)->d_un.d_val == 0)) {
404d29b2c44Sab196087 dyn++;
405d29b2c44Sab196087 end_ndx++;
406d29b2c44Sab196087 }
407d29b2c44Sab196087 if (header_done == 0) {
408d29b2c44Sab196087 header_done = 1;
409d29b2c44Sab196087 Elf_dyn_title(0);
410d29b2c44Sab196087 }
411d29b2c44Sab196087 Elf_dyn_null_entry(0, dyn, ndx, end_ndx);
412d29b2c44Sab196087 ndx = end_ndx;
413d29b2c44Sab196087 printed = 1;
414d29b2c44Sab196087 last_d_val = dyn->d_un.d_val;
415d29b2c44Sab196087 continue;
416d29b2c44Sab196087
417d29b2c44Sab196087 /*
418d29b2c44Sab196087 * Print the information numerically, and if possible
419d29b2c44Sab196087 * as a string.
420d29b2c44Sab196087 */
421d29b2c44Sab196087 case DT_NEEDED:
422d29b2c44Sab196087 case DT_SONAME:
423d29b2c44Sab196087 case DT_FILTER:
424d29b2c44Sab196087 case DT_AUXILIARY:
425d29b2c44Sab196087 case DT_CONFIG:
426d29b2c44Sab196087 case DT_RPATH:
427d29b2c44Sab196087 case DT_RUNPATH:
428d29b2c44Sab196087 case DT_USED:
429d29b2c44Sab196087 case DT_DEPAUDIT:
430d29b2c44Sab196087 case DT_AUDIT:
4314f680cc6SAli Bahrami name = elfedit_offset_to_str(argstate->strsec,
4324f680cc6SAli Bahrami dyn->d_un.d_val, ELFEDIT_MSG_DEBUG, 0);
4334f680cc6SAli Bahrami break;
434d29b2c44Sab196087 case DT_SUNW_AUXILIARY:
435d29b2c44Sab196087 case DT_SUNW_FILTER:
4364f680cc6SAli Bahrami if (osabi_solaris)
437d29b2c44Sab196087 name = elfedit_offset_to_str(argstate->strsec,
438d29b2c44Sab196087 dyn->d_un.d_val, ELFEDIT_MSG_DEBUG, 0);
439d29b2c44Sab196087 break;
440d29b2c44Sab196087
441d29b2c44Sab196087 case DT_FLAGS:
442d29b2c44Sab196087 name = conv_dyn_flag(dyn->d_un.d_val,
443d29b2c44Sab196087 flags_fmt_flags, &c_buf.flag);
444d29b2c44Sab196087 break;
445d29b2c44Sab196087 case DT_FLAGS_1:
446d29b2c44Sab196087 name = conv_dyn_flag1(dyn->d_un.d_val,
447d29b2c44Sab196087 flags_fmt_flags, &c_buf.flag1);
448d29b2c44Sab196087 break;
449d29b2c44Sab196087 case DT_POSFLAG_1:
45055ef6355Sab196087 /*
45155ef6355Sab196087 * If this is dyn:posflag1, and the print_type
45255ef6355Sab196087 * is PRINT_DYN_T_TAG, and the -needed option is
45355ef6355Sab196087 * used, then don't show any DT_POSFLAG_1 elements
45455ef6355Sab196087 * that are not followed by a DT_NEEDED element
45555ef6355Sab196087 * that matches the -needed string.
45655ef6355Sab196087 */
45755ef6355Sab196087 if ((cmd == DYN_CMD_T_POSFLAG1) &&
45855ef6355Sab196087 (print_type == PRINT_DYN_T_TAG) &&
45955ef6355Sab196087 ((argstate->optmask & DYN_OPT_F_NEEDED) != 0) &&
46055ef6355Sab196087 ((ndx + 1) < argstate->dyn.num)) {
46155ef6355Sab196087 Dyn *dyn1 = &argstate->dyn.data[ndx + 1];
46255ef6355Sab196087
46355ef6355Sab196087 if (dyn1->d_tag != DT_NEEDED)
46455ef6355Sab196087 continue;
46555ef6355Sab196087 name = elfedit_offset_to_str(argstate->strsec,
46655ef6355Sab196087 dyn1->d_un.d_val, ELFEDIT_MSG_DEBUG, 0);
46755ef6355Sab196087 if (strncmp(name, argstate->dyn_elt_str,
46855ef6355Sab196087 strlen(argstate->dyn_elt_str)) != 0)
46955ef6355Sab196087 continue;
47055ef6355Sab196087 }
47155ef6355Sab196087
472d29b2c44Sab196087 name = conv_dyn_posflag1(dyn->d_un.d_val,
473d29b2c44Sab196087 flags_fmt_flags, &c_buf.posflag1);
47455ef6355Sab196087 /*
47555ef6355Sab196087 * DT_POSFLAG_1 is a positional element that affects
47655ef6355Sab196087 * the following item. If using the default output
47755ef6355Sab196087 * style, then show the following item as well.
47855ef6355Sab196087 */
47955ef6355Sab196087 one_shot = (outstyle == ELFEDIT_OUTSTYLE_DEFAULT);
480d29b2c44Sab196087 break;
481d29b2c44Sab196087 case DT_FEATURE_1:
482d29b2c44Sab196087 name = conv_dyn_feature1(dyn->d_un.d_val,
483d29b2c44Sab196087 flags_fmt_flags, &c_buf.feature1);
484d29b2c44Sab196087 break;
485d29b2c44Sab196087 case DT_DEPRECATED_SPARC_REGISTER:
486d29b2c44Sab196087 name = MSG_INTL(MSG_STR_DEPRECATED);
487d29b2c44Sab196087 break;
488ba2be530Sab196087 case DT_SUNW_LDMACH:
4894f680cc6SAli Bahrami if (osabi_solaris)
490ba2be530Sab196087 name = conv_ehdr_mach((Half)dyn->d_un.d_val, 0,
491ba2be530Sab196087 &c_buf.inv);
492ba2be530Sab196087 break;
493d29b2c44Sab196087 }
494d29b2c44Sab196087
495d29b2c44Sab196087 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
4964f680cc6SAli Bahrami Ehdr *ehdr;
4974f680cc6SAli Bahrami
498d29b2c44Sab196087 if (header_done == 0) {
499d29b2c44Sab196087 header_done = 1;
500d29b2c44Sab196087 Elf_dyn_title(0);
501d29b2c44Sab196087 }
502d29b2c44Sab196087 if (name == NULL)
503d29b2c44Sab196087 name = MSG_ORIG(MSG_STR_EMPTY);
5044f680cc6SAli Bahrami ehdr = argstate->obj_state->os_ehdr;
505d29b2c44Sab196087 Elf_dyn_entry(0, dyn, ndx, name,
5064f680cc6SAli Bahrami ehdr->e_ident[EI_OSABI], ehdr->e_machine);
507d29b2c44Sab196087 } else {
508d29b2c44Sab196087 /*
509d29b2c44Sab196087 * In simple or numeric mode under a print type
510d29b2c44Sab196087 * that is based on tag type rather than on index,
5115c02782fSAli Bahrami * if there are more than one qualifying tag, we
5125c02782fSAli Bahrami * want to skip printing redundant information.
513d29b2c44Sab196087 */
514d29b2c44Sab196087 switch (print_type) {
515d29b2c44Sab196087 case PRINT_DYN_T_TAG:
5165c02782fSAli Bahrami switch (dyn->d_tag) {
5175c02782fSAli Bahrami case DT_NEEDED:
5185c02782fSAli Bahrami /* Multiple NEEDED entries are normal */
51955ef6355Sab196087 break;
5205c02782fSAli Bahrami case DT_POSFLAG_1:
5215c02782fSAli Bahrami /*
5225c02782fSAli Bahrami * Positional flags don't count,
5235c02782fSAli Bahrami * because each one affects a different
5245c02782fSAli Bahrami * item. Don't skip those even if they
5255c02782fSAli Bahrami * have duplicate values.
5265c02782fSAli Bahrami */
5275c02782fSAli Bahrami break;
5285c02782fSAli Bahrami default:
5295c02782fSAli Bahrami /*
5305c02782fSAli Bahrami * Anything else: If we've already
5315c02782fSAli Bahrami * printed this value, don't print
5325c02782fSAli Bahrami * it again.
5335c02782fSAli Bahrami */
5345c02782fSAli Bahrami if (printed &&
5355c02782fSAli Bahrami (last_d_val == dyn->d_un.d_val))
5365c02782fSAli Bahrami continue;
5375c02782fSAli Bahrami }
5385c02782fSAli Bahrami break;
539d29b2c44Sab196087 case PRINT_DYN_T_RUNPATH:
5405c02782fSAli Bahrami /*
5415c02782fSAli Bahrami * If we've already printed this value,
5425c02782fSAli Bahrami * don't print it again. This commonly
5435c02782fSAli Bahrami * happens when both DT_RPATH and DT_RUNPATH
5445c02782fSAli Bahrami * are present with the same value.
5455c02782fSAli Bahrami */
546d29b2c44Sab196087 if (printed && (last_d_val == dyn->d_un.d_val))
547d29b2c44Sab196087 continue;
54855ef6355Sab196087 break;
549d29b2c44Sab196087 }
550d29b2c44Sab196087
551d29b2c44Sab196087 if ((name != NULL) &&
552d29b2c44Sab196087 (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)) {
553d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL), name);
554d29b2c44Sab196087 } else {
555d29b2c44Sab196087 elfedit_printf(MSG_ORIG(MSG_FMT_HEXXWORDNL),
556*08278a5eSRod Evans EC_XWORD(dyn->d_un.d_val));
557d29b2c44Sab196087 }
558d29b2c44Sab196087 }
559d29b2c44Sab196087 printed = 1;
560d29b2c44Sab196087 last_d_val = dyn->d_un.d_val;
561d29b2c44Sab196087 }
562d29b2c44Sab196087
563d29b2c44Sab196087 /*
564d29b2c44Sab196087 * If nothing was output under the print types that are
565d29b2c44Sab196087 * based on tag type, issue an error saying it doesn't exist.
566d29b2c44Sab196087 */
567d29b2c44Sab196087 if (!printed) {
568d29b2c44Sab196087 if (print_type == PRINT_DYN_T_TAG) {
569d29b2c44Sab196087 Conv_inv_buf_t inv_buf;
5704f680cc6SAli Bahrami Ehdr *ehdr = argstate->obj_state->os_ehdr;
571d29b2c44Sab196087
572d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR,
573d29b2c44Sab196087 MSG_INTL(MSG_ERR_NODYNELT),
574d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
575d29b2c44Sab196087 argstate->dyn.sec->sec_name, conv_dyn_tag(arg,
5764f680cc6SAli Bahrami ehdr->e_ident[EI_OSABI], ehdr->e_machine,
577d29b2c44Sab196087 0, &inv_buf));
578d29b2c44Sab196087 }
579d29b2c44Sab196087
580d29b2c44Sab196087 if (print_type == PRINT_DYN_T_RUNPATH)
581d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR,
582d29b2c44Sab196087 MSG_INTL(MSG_ERR_NORUNPATH),
583d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
584d29b2c44Sab196087 argstate->dyn.sec->sec_name);
585d29b2c44Sab196087 }
586d29b2c44Sab196087 }
587d29b2c44Sab196087
588d29b2c44Sab196087
589d29b2c44Sab196087 /*
59055ef6355Sab196087 * Determine the index(s) of the dynamic element(s) to be displayed and/or
59155ef6355Sab196087 * manipulated.
592d29b2c44Sab196087 *
593d29b2c44Sab196087 * entry:
594d29b2c44Sab196087 * argstate - Argument state block
59555ef6355Sab196087 * arg - If the command being called accepts a first plain argument
59655ef6355Sab196087 * named 'elt' which is used to specify the dynamic element,
59755ef6355Sab196087 * arg is the value of argv[0] for that command. If the
59855ef6355Sab196087 * command does not accept an 'elt' argument and instead
59955ef6355Sab196087 * implicitly assumes a tag type, arg is the constant string
60055ef6355Sab196087 * for that type (e.g. "DT_POSFLAG_1").
601d29b2c44Sab196087 * print_request - True if the command is to print the current
602d29b2c44Sab196087 * value(s) and return without changing anything.
603d29b2c44Sab196087 * print_type - Address of variable containing PRINT_DYN_T_
604d29b2c44Sab196087 * code specifying how the elements will be displayed.
605d29b2c44Sab196087 *
606d29b2c44Sab196087 * exit:
60755ef6355Sab196087 * If print_request is False: This routine always returns the index
60855ef6355Sab196087 * of a single dynamic element. *print_type is set to PRINT_DYN_T_NDX.
60955ef6355Sab196087 * The 'elt' argument as well as any modifier options (-dynndx, -needed)
61055ef6355Sab196087 * are examined to determine this index. If there are no modifier options,
61155ef6355Sab196087 * the dynamic section contains no element of the desired type, and there
61255ef6355Sab196087 * is an extra DT_NULL element in the section, then a new element of
61355ef6355Sab196087 * the desired type is created and its index returned. Otherwise an
61455ef6355Sab196087 * error is issued.
615d29b2c44Sab196087 *
61655ef6355Sab196087 * If print_request is True: If a modifier (-dynndx, -needed) was used,
61755ef6355Sab196087 * *print_type is set to PRINT_DYN_T_NDX and the index of the
61855ef6355Sab196087 * corresponding single dynamic element is returned. If no modifier
61955ef6355Sab196087 * was used, *print_type is set to PRINT_DYN_T_TAG, and the tag
62055ef6355Sab196087 * type code is returned.
621d29b2c44Sab196087 */
622d29b2c44Sab196087 static Word
arg_to_index(ARGSTATE * argstate,const char * arg,int print_request,PRINT_DYN_T * print_type)62355ef6355Sab196087 arg_to_index(ARGSTATE *argstate, const char *arg,
624d29b2c44Sab196087 int print_request, PRINT_DYN_T *print_type)
625d29b2c44Sab196087 {
6264f680cc6SAli Bahrami Word ndx;
6274f680cc6SAli Bahrami Xword dt_value;
62855ef6355Sab196087 Dyn *dyn;
629d29b2c44Sab196087
630d29b2c44Sab196087
631d29b2c44Sab196087 /* Assume we are returning an index, alter as needed below */
632d29b2c44Sab196087 *print_type = PRINT_DYN_T_NDX;
633d29b2c44Sab196087
63455ef6355Sab196087 /*
63555ef6355Sab196087 * All the commands that accept the DYN_OPT_F_DYNNDX_ELT form
63655ef6355Sab196087 * of -dynndx require a plain argument named 'elt' as their first
63755ef6355Sab196087 * argument. -dynndx is a modifier that means that 'elt' is a
63855ef6355Sab196087 * simple numeric section index. Routines that accept this form
63955ef6355Sab196087 * of -dynndx are willing to handle any tag type, so all we need
64055ef6355Sab196087 * to check is that the value is in range.
64155ef6355Sab196087 */
64255ef6355Sab196087 if ((argstate->optmask & DYN_OPT_F_DYNNDX_ELT) != 0)
64355ef6355Sab196087 return ((Word) elfedit_atoui_range(arg, MSG_ORIG(MSG_STR_ELT),
64455ef6355Sab196087 0, argstate->dyn.num - 1, NULL));
645d29b2c44Sab196087
64655ef6355Sab196087 /* arg is a DT_ tag type, not a numeric index */
647d29b2c44Sab196087 dt_value = (Word) elfedit_atoconst(arg, ELFEDIT_CONST_DT);
648d29b2c44Sab196087
649d29b2c44Sab196087 /*
65055ef6355Sab196087 * Commands that accept the DYN_OPT_F_DYNNDX_VAL form of
65155ef6355Sab196087 * dynndx do not accept the 'elt' argument. The index is a
65255ef6355Sab196087 * value that follows the option, and was saved in argstate by
65355ef6355Sab196087 * process_args(). Routines that accept this form of -dynndx
65455ef6355Sab196087 * require the specified element to have a specific tag type,
65555ef6355Sab196087 * so we test for this as well as for the index being in range.
65655ef6355Sab196087 */
65755ef6355Sab196087 if ((argstate->optmask & DYN_OPT_F_DYNNDX_VAL) != 0) {
65855ef6355Sab196087 ndx = ((Word) elfedit_atoui_range(argstate->dyn_elt_str,
65955ef6355Sab196087 MSG_ORIG(MSG_STR_INDEX), 0, argstate->dyn.num - 1, NULL));
66055ef6355Sab196087 if (argstate->dyn.data[ndx].d_tag != dt_value) {
6614f680cc6SAli Bahrami Ehdr *ehdr = argstate->obj_state->os_ehdr;
6624f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI];
6634f680cc6SAli Bahrami Half mach = ehdr->e_machine;
66455ef6355Sab196087 Conv_inv_buf_t is, want;
66555ef6355Sab196087
66655ef6355Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_WRONGTAG),
66755ef6355Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
66855ef6355Sab196087 argstate->dyn.sec->sec_name, ndx,
6694f680cc6SAli Bahrami conv_dyn_tag(dt_value, osabi, mach, 0, &want),
6704f680cc6SAli Bahrami conv_dyn_tag(argstate->dyn.data[ndx].d_tag,
6714f680cc6SAli Bahrami osabi, mach, 0, &is));
67255ef6355Sab196087 }
67355ef6355Sab196087 return (ndx);
67455ef6355Sab196087 }
67555ef6355Sab196087
67655ef6355Sab196087 /*
677d29b2c44Sab196087 * If this is a printing request, then we let print_dyn() show
678d29b2c44Sab196087 * all the items with this tag type.
679d29b2c44Sab196087 */
680d29b2c44Sab196087 if (print_request) {
681d29b2c44Sab196087 *print_type = PRINT_DYN_T_TAG;
682d29b2c44Sab196087 return (dt_value);
683d29b2c44Sab196087 }
684d29b2c44Sab196087
68555ef6355Sab196087 /*
68655ef6355Sab196087 * Commands that accept -needed are looking for the dt_value element
68755ef6355Sab196087 * (usually DT_POSFLAG_1) that immediately preceeds the DT_NEEDED
68855ef6355Sab196087 * element with the string given by argstate->dyn_elt_str.
68955ef6355Sab196087 */
69055ef6355Sab196087 if ((argstate->optmask & DYN_OPT_F_NEEDED) != 0) {
69155ef6355Sab196087 Word retndx = argstate->dyn.num; /* Out of range value */
69255ef6355Sab196087 const char *name;
69355ef6355Sab196087 size_t len;
69455ef6355Sab196087
69555ef6355Sab196087 len = strlen(argstate->dyn_elt_str);
69655ef6355Sab196087 for (ndx = 0, dyn = argstate->dyn.data;
69755ef6355Sab196087 ndx < argstate->dyn.num; dyn++, ndx++) {
69855ef6355Sab196087 /*
69955ef6355Sab196087 * If the immediately preceeding item has the
70055ef6355Sab196087 * tag type we're looking for, and the current item
70155ef6355Sab196087 * is a DT_NEEDED with a string that matches,
70255ef6355Sab196087 * then the preceeding item is the one we want.
70355ef6355Sab196087 */
70455ef6355Sab196087 if ((dyn->d_tag == DT_NEEDED) &&
70555ef6355Sab196087 (ndx > 0) && (retndx == (ndx - 1))) {
70655ef6355Sab196087 name = elfedit_offset_to_str(argstate->strsec,
70755ef6355Sab196087 dyn->d_un.d_val, ELFEDIT_MSG_DEBUG, 0);
70855ef6355Sab196087
70955ef6355Sab196087 if (strncmp(name,
71055ef6355Sab196087 argstate->dyn_elt_str, len) == 0)
71155ef6355Sab196087 return (retndx);
71255ef6355Sab196087 continue;
71355ef6355Sab196087 }
71455ef6355Sab196087
71555ef6355Sab196087 /*
71655ef6355Sab196087 * If the current item has the tag type we're
71755ef6355Sab196087 * looking for, make it our current candidate.
71855ef6355Sab196087 * If the next item is a DT_NEEDED with the right
71955ef6355Sab196087 * string value, we'll use it then.
72055ef6355Sab196087 */
72155ef6355Sab196087 if (dyn->d_tag == dt_value)
72255ef6355Sab196087 retndx = ndx;
72355ef6355Sab196087 }
72455ef6355Sab196087
72555ef6355Sab196087 /* If we get here, no matching DT_NEEDED was found */
72655ef6355Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NEEDEDNOMATCH),
72755ef6355Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
72855ef6355Sab196087 argstate->dyn.sec->sec_name, argstate->dyn_elt_str);
72955ef6355Sab196087 }
73055ef6355Sab196087
731d29b2c44Sab196087 /* Locate the first entry with the given tag type */
732d29b2c44Sab196087 for (ndx = 0; ndx < argstate->dyn.num; ndx++) {
733d29b2c44Sab196087 if (argstate->dyn.data[ndx].d_tag == dt_value) {
734d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
735d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_DT2NDX),
736d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
737d29b2c44Sab196087 argstate->dyn.sec->sec_name, EC_WORD(ndx), arg);
738d29b2c44Sab196087 return (ndx);
739d29b2c44Sab196087 }
740d29b2c44Sab196087 }
741d29b2c44Sab196087
742d29b2c44Sab196087 /* Not found. Can we create one? */
743d29b2c44Sab196087 if (argstate->dyn.num_null_ndx > 1)
744d29b2c44Sab196087 return (convert_dt_null(argstate, dt_value, 0));
745d29b2c44Sab196087
746d29b2c44Sab196087 /* No room to create one, so we're out of options and must fail */
747d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NODTELT),
748d29b2c44Sab196087 EC_WORD(argstate->dyn.sec->sec_shndx),
749d29b2c44Sab196087 argstate->dyn.sec->sec_name, arg);
750d29b2c44Sab196087
751d29b2c44Sab196087 /*NOTREACHED*/
752d29b2c44Sab196087 return (0); /* For lint */
753d29b2c44Sab196087 }
754d29b2c44Sab196087
755d29b2c44Sab196087
756d29b2c44Sab196087 /*
757d29b2c44Sab196087 * Called by cmd_body() for dyn:value. Implements the core functionality
758d29b2c44Sab196087 * for that command.
759d29b2c44Sab196087 *
760d29b2c44Sab196087 * This routine expects that both the index and value arguments are
761d29b2c44Sab196087 * present.
762d29b2c44Sab196087 */
763d29b2c44Sab196087 static elfedit_cmdret_t
cmd_body_value(ARGSTATE * argstate,Word * ret_ndx)764d29b2c44Sab196087 cmd_body_value(ARGSTATE *argstate, Word *ret_ndx)
765d29b2c44Sab196087 {
766d29b2c44Sab196087 elfedit_section_t *dynsec = argstate->dyn.sec;
767d29b2c44Sab196087 elfedit_section_t *strsec = argstate->strsec;
768d29b2c44Sab196087 elfedit_dyn_elt_t strpad_elt;
769d29b2c44Sab196087 Word i;
770d29b2c44Sab196087 Dyn *dyn = argstate->dyn.data;
771d29b2c44Sab196087 Word numdyn = argstate->dyn.num;
77255ef6355Sab196087 int minus_add, minus_s, minus_dynndx;
7734f680cc6SAli Bahrami Word tmp_val;
7744f680cc6SAli Bahrami Xword arg1, arg2;
775d29b2c44Sab196087 int arg2_known = 1;
776d29b2c44Sab196087
77755ef6355Sab196087 minus_add = ((argstate->optmask & DYN_OPT_F_ADD) != 0);
77855ef6355Sab196087 minus_s = ((argstate->optmask & DYN_OPT_F_STRVAL) != 0);
77955ef6355Sab196087 minus_dynndx = ((argstate->optmask & DYN_OPT_F_DYNNDX_ELT) != 0);
780d29b2c44Sab196087
781d29b2c44Sab196087 elfedit_dyn_elt_init(&strpad_elt);
782d29b2c44Sab196087
783d29b2c44Sab196087 /*
784d29b2c44Sab196087 * The first argument is an index if -dynndx is used, and is a
785d29b2c44Sab196087 * tag value otherwise.
786d29b2c44Sab196087 */
787d29b2c44Sab196087 arg1 = minus_dynndx ?
788d29b2c44Sab196087 elfedit_atoui_range(argstate->argv[0], MSG_ORIG(MSG_STR_ELT),
789d29b2c44Sab196087 0, numdyn - 1, NULL) :
790d29b2c44Sab196087 elfedit_atoconst(argstate->argv[0], ELFEDIT_CONST_DT);
791d29b2c44Sab196087
792d29b2c44Sab196087 if (minus_s) {
793d29b2c44Sab196087 /*
794d29b2c44Sab196087 * Don't allow the user to specify -s when manipulating a
795d29b2c44Sab196087 * DT_SUNW_STRPAD element. Since DT_SUNW_STRPAD is used to
796d29b2c44Sab196087 * manage the extra space used for strings, this would break
797d29b2c44Sab196087 * our ability to add the string.
798d29b2c44Sab196087 */
799d29b2c44Sab196087 if ((!minus_dynndx && (arg1 == DT_SUNW_STRPAD)) ||
800d29b2c44Sab196087 (minus_dynndx && (dyn[arg1].d_tag == DT_SUNW_STRPAD)))
801d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR,
802d29b2c44Sab196087 MSG_INTL(MSG_ERR_STRPADSTRVAL),
803d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx), dynsec->sec_name);
804d29b2c44Sab196087
805d29b2c44Sab196087 /* Locate DT_SUNW_STRPAD element if present */
806d29b2c44Sab196087 strpad_elt.dn_dyn.d_un.d_val = 0;
8074f680cc6SAli Bahrami (void) elfedit_dynstr_getpad(argstate->obj_state,
8084f680cc6SAli Bahrami argstate->dyn.sec, &strpad_elt);
809d29b2c44Sab196087
810d29b2c44Sab196087 /*
811d29b2c44Sab196087 * Look up the string: If the user specified the -dynndx
812d29b2c44Sab196087 * -option, then we will insert it if possible, and
813d29b2c44Sab196087 * fail with an error if not. However, if they did not
814d29b2c44Sab196087 * specify -dynndx, we want to look up the string if it is
815d29b2c44Sab196087 * already there, but defer the insertion. The reason for
816d29b2c44Sab196087 * this is that we may have to grab an unused DT_NULL element
817d29b2c44Sab196087 * below, and if there are none available, we won't want
818d29b2c44Sab196087 * to have modified the string table.
819d29b2c44Sab196087 *
820d29b2c44Sab196087 * This isn't a problem, because if the string isn't
821d29b2c44Sab196087 * in the string table, it can't be used by a dynamic element.
822d29b2c44Sab196087 * Hence, we don't need to insert it to know that there is
823d29b2c44Sab196087 * no match.
824d29b2c44Sab196087 */
825d29b2c44Sab196087 if (minus_dynndx == 0) {
826d29b2c44Sab196087 if (elfedit_sec_findstr(strsec,
827d29b2c44Sab196087 strpad_elt.dn_dyn.d_un.d_val, argstate->argv[1],
828d29b2c44Sab196087 &tmp_val) == 0) {
829d29b2c44Sab196087 arg2_known = 0;
830d29b2c44Sab196087 } else {
831d29b2c44Sab196087 arg2 = tmp_val;
832d29b2c44Sab196087 }
833d29b2c44Sab196087 } else {
834d29b2c44Sab196087 arg2 = elfedit_dynstr_insert(dynsec, strsec,
835d29b2c44Sab196087 &strpad_elt, argstate->argv[1]);
836d29b2c44Sab196087 }
837d29b2c44Sab196087 } else { /* Argument 2 is an integer */
838d29b2c44Sab196087 arg2 = elfedit_atoui(argstate->argv[1], NULL);
839d29b2c44Sab196087 }
840d29b2c44Sab196087
841d29b2c44Sab196087
842d29b2c44Sab196087 if (!minus_dynndx && !(minus_add && !arg2_known)) {
843d29b2c44Sab196087 /*
844d29b2c44Sab196087 * Search the dynamic section and see if an item with the
845d29b2c44Sab196087 * specified tag value already exists. We can reduce this
846d29b2c44Sab196087 * to a simple update of an existing value if -add is not
847d29b2c44Sab196087 * specified or the existing d_un value matches the new one.
848d29b2c44Sab196087 *
849d29b2c44Sab196087 * In either of these cases, we will change arg1 to be the
850d29b2c44Sab196087 * index, and set minus_dynndx, causing the simple update to
851d29b2c44Sab196087 * happen immediately below.
852d29b2c44Sab196087 */
853d29b2c44Sab196087 for (i = 0; i < numdyn; i++) {
854d29b2c44Sab196087 if ((dyn[i].d_tag == arg1) &&
855d29b2c44Sab196087 (!minus_add || (dyn[i].d_un.d_val == arg2))) {
856d29b2c44Sab196087 arg1 = i;
857d29b2c44Sab196087 minus_dynndx = 1;
858d29b2c44Sab196087 break;
859d29b2c44Sab196087 }
860d29b2c44Sab196087 }
861d29b2c44Sab196087 }
862d29b2c44Sab196087
863d29b2c44Sab196087 /*
864d29b2c44Sab196087 * If -dynndx is used, then this is a relatively simple
865d29b2c44Sab196087 * operation, as we simply write over the specified index.
866d29b2c44Sab196087 */
867d29b2c44Sab196087 if (minus_dynndx) {
868d29b2c44Sab196087 /*
869d29b2c44Sab196087 * If we held back from inserting a new string into
870d29b2c44Sab196087 * the dynstr above, we insert it now, because we
871d29b2c44Sab196087 * have a slot in the dynamic section, and we need
872d29b2c44Sab196087 * the string offset ot finish.
873d29b2c44Sab196087 */
874d29b2c44Sab196087 if (!arg2_known)
875d29b2c44Sab196087 arg2 = elfedit_dynstr_insert(dynsec, strsec,
876d29b2c44Sab196087 &strpad_elt, argstate->argv[1]);
877d29b2c44Sab196087
878d29b2c44Sab196087 *ret_ndx = arg1;
879d29b2c44Sab196087 if (dyn[arg1].d_un.d_val == arg2) {
880d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
881d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_OK),
882d29b2c44Sab196087 dynsec->sec_shndx, dynsec->sec_name,
883d29b2c44Sab196087 EC_WORD(arg1), EC_XWORD(arg2));
884d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE);
885d29b2c44Sab196087 } else {
886d29b2c44Sab196087 /* Warn if setting DT_NULL value to non-zero */
887d29b2c44Sab196087 if ((dyn[arg1].d_tag == DT_NULL) && (arg2 != 0))
888d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
889d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_DTNULLVALUE),
890d29b2c44Sab196087 dynsec->sec_shndx, dynsec->sec_name,
891d29b2c44Sab196087 EC_WORD(arg1), EC_XWORD(arg2));
892d29b2c44Sab196087
893d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
894d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_CHG),
895d29b2c44Sab196087 dynsec->sec_shndx, dynsec->sec_name,
896d29b2c44Sab196087 EC_WORD(arg1), EC_XWORD(dyn[arg1].d_un.d_val),
897d29b2c44Sab196087 EC_XWORD(arg2));
898d29b2c44Sab196087 dyn[arg1].d_un.d_val = arg2;
899d29b2c44Sab196087 return (ELFEDIT_CMDRET_MOD);
900d29b2c44Sab196087 }
901d29b2c44Sab196087 }
902d29b2c44Sab196087
903d29b2c44Sab196087 /*
904d29b2c44Sab196087 * We need a new slot in the dynamic section. If we can't have
905d29b2c44Sab196087 * one, then we fail.
906d29b2c44Sab196087 */
907d29b2c44Sab196087 if (argstate->dyn.num_null_ndx <= 1)
908d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOEXTRANULL),
909d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx), dynsec->sec_name);
910d29b2c44Sab196087
911d29b2c44Sab196087 /*
912d29b2c44Sab196087 * If we still need to insert a new string into the dynstr,
913d29b2c44Sab196087 * then it is safe now, because if we succeed, we know that
914d29b2c44Sab196087 * there is an available slot to receive it. If we fail, we
915d29b2c44Sab196087 * haven't claimed the extra slot yet, and it will be unharmed.
916d29b2c44Sab196087 */
917d29b2c44Sab196087 if (!arg2_known)
918d29b2c44Sab196087 arg2 = elfedit_dynstr_insert(dynsec, strsec,
919d29b2c44Sab196087 &strpad_elt, argstate->argv[1]);
920d29b2c44Sab196087
921d29b2c44Sab196087 /* Use an extra DT_NULL slot and enter the new element */
922d29b2c44Sab196087 *ret_ndx = convert_dt_null(argstate, arg1, arg2);
923d29b2c44Sab196087 return (ELFEDIT_CMDRET_MOD);
924d29b2c44Sab196087 }
925d29b2c44Sab196087
926d29b2c44Sab196087
927d29b2c44Sab196087
928d29b2c44Sab196087 /*
929d29b2c44Sab196087 * Called by cmd_body() for dyn:runpath. Implements the core functionality
930d29b2c44Sab196087 * for that command.
931d29b2c44Sab196087 *
932d29b2c44Sab196087 * History Lesson And Strategy:
933d29b2c44Sab196087 *
934d29b2c44Sab196087 * This routine handles both DT_RPATH and DT_RUNPATH entries, altering
935d29b2c44Sab196087 * either or both if they are present.
936d29b2c44Sab196087 *
937d29b2c44Sab196087 * The original SYSV ABI only had DT_RPATH, and the runtime loader used
938d29b2c44Sab196087 * it to search for things in the following order:
939d29b2c44Sab196087 *
940d29b2c44Sab196087 * DT_RPATH, LD_LIBRARY_PATH, defaults
941d29b2c44Sab196087 *
942d29b2c44Sab196087 * Solaris did not follow this rule, an extremely rare deviation from
943d29b2c44Sab196087 * the ABI. Environment variables should supercede everything else,
944d29b2c44Sab196087 * otherwise they are not very useful. This decision was made at the
945d29b2c44Sab196087 * very beginning of the SunOS 5.x development, so we have always
946d29b2c44Sab196087 * deviated from the ABI and and instead search in the order
947d29b2c44Sab196087 *
948d29b2c44Sab196087 * LD_LIBRARY_PATH, DT_RPATH, defaults
949d29b2c44Sab196087 *
950d29b2c44Sab196087 * Other Unix variants initially followed the ABI, but in recent years
951d29b2c44Sab196087 * have come to agree with the early Solaris folks that it was a mistake.
952d29b2c44Sab196087 * Hence, DT_RUNPATH was invented, with the search order:
953d29b2c44Sab196087 *
954d29b2c44Sab196087 * LD_LIBRARY_PATH, DT_RUNPATH, defaults
955d29b2c44Sab196087 *
956d29b2c44Sab196087 * So for Solaris, DT_RPATH and DT_RUNPATH mean the same thing. If both
957d29b2c44Sab196087 * are present (which does happen), we set them both to the new
958d29b2c44Sab196087 * value. If either one is present, we set that one. If neither is
959d29b2c44Sab196087 * present, and we have a spare DT_NULL slot, we create a DT_RUNPATH, but
960d29b2c44Sab196087 * not a DT_RPATH, to conserve available slots for other uses.
961d29b2c44Sab196087 */
962d29b2c44Sab196087 static elfedit_cmdret_t
cmd_body_runpath(ARGSTATE * argstate)963d29b2c44Sab196087 cmd_body_runpath(ARGSTATE *argstate)
964d29b2c44Sab196087 {
965d29b2c44Sab196087 elfedit_section_t *dynsec = argstate->dyn.sec;
966d29b2c44Sab196087 elfedit_section_t *strsec = argstate->strsec;
967d29b2c44Sab196087 elfedit_dyn_elt_t rpath_elt;
968d29b2c44Sab196087 elfedit_dyn_elt_t runpath_elt;
969d29b2c44Sab196087 elfedit_dyn_elt_t strpad_elt;
970d29b2c44Sab196087 Word i;
971d29b2c44Sab196087 Dyn *dyn = argstate->dyn.data;
972d29b2c44Sab196087 Word numdyn = argstate->dyn.num;
973d29b2c44Sab196087
974d29b2c44Sab196087 /* Go through the tags and gather what we need */
975d29b2c44Sab196087 elfedit_dyn_elt_init(&rpath_elt);
976d29b2c44Sab196087 elfedit_dyn_elt_init(&runpath_elt);
977d29b2c44Sab196087 elfedit_dyn_elt_init(&strpad_elt);
978d29b2c44Sab196087 for (i = 0; i < numdyn; i++) {
979d29b2c44Sab196087 switch (dyn[i].d_tag) {
980d29b2c44Sab196087 case DT_RPATH:
981d29b2c44Sab196087 elfedit_dyn_elt_save(&rpath_elt, i, &dyn[i]);
982d29b2c44Sab196087 break;
983d29b2c44Sab196087
984d29b2c44Sab196087 case DT_RUNPATH:
985d29b2c44Sab196087 elfedit_dyn_elt_save(&runpath_elt, i, &dyn[i]);
986d29b2c44Sab196087 break;
987d29b2c44Sab196087
988d29b2c44Sab196087 case DT_SUNW_STRPAD:
9894f680cc6SAli Bahrami if (elfedit_test_osabi(argstate->obj_state,
9904f680cc6SAli Bahrami ELFOSABI_SOLARIS, 0))
991d29b2c44Sab196087 elfedit_dyn_elt_save(&strpad_elt, i, &dyn[i]);
992d29b2c44Sab196087 break;
993d29b2c44Sab196087 }
994d29b2c44Sab196087 }
995d29b2c44Sab196087
996d29b2c44Sab196087 /* Do we have an available dynamic section entry to use? */
997d29b2c44Sab196087 if (rpath_elt.dn_seen || runpath_elt.dn_seen) {
998d29b2c44Sab196087 /*
999d29b2c44Sab196087 * We have seen a DT_RPATH, or a DT_RUNPATH, or both.
1000d29b2c44Sab196087 * If all of these have the same string as the desired
1001d29b2c44Sab196087 * new value, then we don't need to alter anything and can
1002d29b2c44Sab196087 * simply return. Otherwise, we'll modify them all to have
1003d29b2c44Sab196087 * the new string (below).
1004d29b2c44Sab196087 */
1005d29b2c44Sab196087 if ((!rpath_elt.dn_seen ||
1006d29b2c44Sab196087 (strcmp(elfedit_dyn_offset_to_str(strsec, &rpath_elt),
1007d29b2c44Sab196087 argstate->argv[0]) == 0)) &&
1008d29b2c44Sab196087 (!runpath_elt.dn_seen ||
1009d29b2c44Sab196087 (strcmp(elfedit_dyn_offset_to_str(strsec, &runpath_elt),
1010d29b2c44Sab196087 argstate->argv[0]) == 0))) {
1011d29b2c44Sab196087 if (rpath_elt.dn_seen)
1012d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1013d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_OLDRPATHOK),
1014d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx),
1015d29b2c44Sab196087 dynsec->sec_name, EC_WORD(rpath_elt.dn_ndx),
1016d29b2c44Sab196087 elfedit_atoconst_value_to_str(
1017d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_RPATH, 1));
1018d29b2c44Sab196087 if (runpath_elt.dn_seen)
1019d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1020d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_OLDRPATHOK),
1021d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx),
1022d29b2c44Sab196087 dynsec->sec_name,
1023d29b2c44Sab196087 EC_WORD(runpath_elt.dn_ndx),
1024d29b2c44Sab196087 elfedit_atoconst_value_to_str(
1025d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_RUNPATH, 1));
1026d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE);
1027d29b2c44Sab196087 }
1028d29b2c44Sab196087 } else if (argstate->dyn.num_null_ndx <= 1) {
1029d29b2c44Sab196087 /*
1030d29b2c44Sab196087 * There is no DT_RPATH or DT_RUNPATH in the dynamic array,
1031d29b2c44Sab196087 * and there are no extra DT_NULL entries that we can
1032d29b2c44Sab196087 * convert into one. We cannot proceed.
1033d29b2c44Sab196087 */
1034d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_NOEXTRANULL),
1035d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx), dynsec->sec_name);
1036d29b2c44Sab196087 }
1037d29b2c44Sab196087
1038d29b2c44Sab196087 /* Does the string exist in the table already, or can we add it? */
1039d29b2c44Sab196087 rpath_elt.dn_dyn.d_un.d_val = runpath_elt.dn_dyn.d_un.d_val =
1040d29b2c44Sab196087 elfedit_dynstr_insert(dynsec, strsec, &strpad_elt,
1041d29b2c44Sab196087 argstate->argv[0]);
1042d29b2c44Sab196087
1043d29b2c44Sab196087 /* Update DT_RPATH entry if present */
1044d29b2c44Sab196087 if (rpath_elt.dn_seen) {
1045d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG, MSG_INTL(MSG_DEBUG_PREVRPATH),
1046d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx), dynsec->sec_name,
1047d29b2c44Sab196087 EC_WORD(rpath_elt.dn_ndx),
1048d29b2c44Sab196087 elfedit_atoconst_value_to_str(
1049d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_RPATH, 1),
1050d29b2c44Sab196087 elfedit_dyn_offset_to_str(strsec, &rpath_elt));
1051d29b2c44Sab196087 dyn[rpath_elt.dn_ndx] = rpath_elt.dn_dyn;
1052d29b2c44Sab196087 }
1053d29b2c44Sab196087
1054d29b2c44Sab196087 /*
1055d29b2c44Sab196087 * Update the DT_RUNPATH entry in the dynamic section, if present.
1056d29b2c44Sab196087 * If one is not present, and there is also no DT_RPATH, then
1057d29b2c44Sab196087 * we use a spare DT_NULL entry to create a new DT_RUNPATH.
1058d29b2c44Sab196087 */
1059d29b2c44Sab196087 if (runpath_elt.dn_seen || !rpath_elt.dn_seen) {
1060d29b2c44Sab196087 if (runpath_elt.dn_seen) {
1061d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1062d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_PREVRPATH),
1063d29b2c44Sab196087 EC_WORD(dynsec->sec_shndx), dynsec->sec_name,
1064d29b2c44Sab196087 EC_WORD(runpath_elt.dn_ndx),
1065d29b2c44Sab196087 elfedit_atoconst_value_to_str(
1066d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_RUNPATH, 1),
1067d29b2c44Sab196087 elfedit_dyn_offset_to_str(strsec, &runpath_elt));
1068d29b2c44Sab196087 dyn[runpath_elt.dn_ndx] = runpath_elt.dn_dyn;
1069d29b2c44Sab196087 } else { /* Using a spare DT_NULL entry */
1070d29b2c44Sab196087 (void) convert_dt_null(argstate, DT_RUNPATH,
1071d29b2c44Sab196087 runpath_elt.dn_dyn.d_un.d_val);
1072d29b2c44Sab196087 }
1073d29b2c44Sab196087 }
1074d29b2c44Sab196087
1075d29b2c44Sab196087 return (ELFEDIT_CMDRET_MOD);
1076d29b2c44Sab196087 }
1077d29b2c44Sab196087
1078d29b2c44Sab196087
1079d29b2c44Sab196087
1080d29b2c44Sab196087 /*
1081d29b2c44Sab196087 * Argument processing for the bitmask commands. Convert the arguments
1082d29b2c44Sab196087 * to integer form, apply -and/-cmp/-or, and return the resulting value.
1083d29b2c44Sab196087 *
1084d29b2c44Sab196087 * entry:
1085d29b2c44Sab196087 * argstate - Argument state block
1086d29b2c44Sab196087 * orig - Value of original bitmask
1087d29b2c44Sab196087 * const_type - ELFEDIT_CONST_* value for type of constants
1088d29b2c44Sab196087 */
1089d29b2c44Sab196087 static Word
flag_bitop(ARGSTATE * argstate,Word orig,elfedit_const_t const_type)1090d29b2c44Sab196087 flag_bitop(ARGSTATE *argstate, Word orig, elfedit_const_t const_type)
1091d29b2c44Sab196087 {
1092d29b2c44Sab196087 Word flags = 0;
1093d29b2c44Sab196087 int i;
1094d29b2c44Sab196087
1095d29b2c44Sab196087 /* Collect the arguments */
1096d29b2c44Sab196087 for (i = 0; i < argstate->argc; i++)
1097d29b2c44Sab196087 flags |= (Word) elfedit_atoconst(argstate->argv[i], const_type);
1098d29b2c44Sab196087
1099d29b2c44Sab196087 /* Complement the value? */
1100d29b2c44Sab196087 if (argstate->optmask & DYN_OPT_F_CMP)
1101d29b2c44Sab196087 flags = ~flags;
1102d29b2c44Sab196087
1103d29b2c44Sab196087 /* Perform any requested bit operations */
1104d29b2c44Sab196087 if (argstate->optmask & DYN_OPT_F_AND)
1105d29b2c44Sab196087 flags &= orig;
1106d29b2c44Sab196087 else if (argstate->optmask & DYN_OPT_F_OR)
1107d29b2c44Sab196087 flags |= orig;
1108d29b2c44Sab196087
1109d29b2c44Sab196087 return (flags);
1110d29b2c44Sab196087 }
1111d29b2c44Sab196087
1112d29b2c44Sab196087
1113d29b2c44Sab196087
1114d29b2c44Sab196087 /*
1115d29b2c44Sab196087 * Common body for the dyn: module commands. These commands
1116d29b2c44Sab196087 * share a large amount of common behavior, so it is convenient
1117d29b2c44Sab196087 * to centralize things and use the cmd argument to handle the
1118d29b2c44Sab196087 * small differences.
1119d29b2c44Sab196087 *
1120d29b2c44Sab196087 * entry:
1121d29b2c44Sab196087 * cmd - One of the DYN_CMD_T_* constants listed above, specifying
1122d29b2c44Sab196087 * which command to implement.
1123d29b2c44Sab196087 * obj_state, argc, argv - Standard command arguments
1124d29b2c44Sab196087 */
1125d29b2c44Sab196087 static elfedit_cmdret_t
cmd_body(DYN_CMD_T cmd,elfedit_obj_state_t * obj_state,int argc,const char * argv[])1126d29b2c44Sab196087 cmd_body(DYN_CMD_T cmd, elfedit_obj_state_t *obj_state,
1127d29b2c44Sab196087 int argc, const char *argv[])
1128d29b2c44Sab196087 {
1129d29b2c44Sab196087 ARGSTATE argstate;
1130d29b2c44Sab196087 Dyn *dyn;
1131d29b2c44Sab196087 const char *dyn_name;
1132d29b2c44Sab196087 Word dyn_ndx, dyn_num, null_ndx;
1133d29b2c44Sab196087 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE;
1134d29b2c44Sab196087 PRINT_DYN_T print_type = PRINT_DYN_T_ALL;
1135d29b2c44Sab196087 Word ndx;
1136d29b2c44Sab196087 int print_only = 0;
1137d29b2c44Sab196087 int do_autoprint = 1;
1138d29b2c44Sab196087
1139d29b2c44Sab196087 /* Process the optional arguments */
1140d29b2c44Sab196087 process_args(obj_state, argc, argv, &argstate);
1141d29b2c44Sab196087
1142d29b2c44Sab196087 dyn = argstate.dyn.data;
1143d29b2c44Sab196087 dyn_num = argstate.dyn.num;
1144d29b2c44Sab196087 dyn_name = argstate.dyn.sec->sec_name;
1145d29b2c44Sab196087 dyn_ndx = argstate.dyn.sec->sec_shndx;
1146d29b2c44Sab196087
1147d29b2c44Sab196087 /* Check number of arguments, gather information */
1148d29b2c44Sab196087 switch (cmd) {
1149d29b2c44Sab196087 case DYN_CMD_T_DUMP:
1150d29b2c44Sab196087 /* dyn:dump can accept an optional index argument */
1151d29b2c44Sab196087 if (argstate.argc > 1)
1152d29b2c44Sab196087 elfedit_command_usage();
1153d29b2c44Sab196087 print_only = 1;
1154d29b2c44Sab196087 if (argstate.argc == 1)
1155d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
115655ef6355Sab196087 print_only, &print_type);
1157d29b2c44Sab196087 break;
1158d29b2c44Sab196087
1159d29b2c44Sab196087 case DYN_CMD_T_TAG:
1160d29b2c44Sab196087 print_only = (argstate.argc != 2);
1161d29b2c44Sab196087 if (argstate.argc > 0) {
1162d29b2c44Sab196087 if (argstate.argc > 2)
1163d29b2c44Sab196087 elfedit_command_usage();
1164d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
116555ef6355Sab196087 print_only, &print_type);
1166d29b2c44Sab196087 }
1167d29b2c44Sab196087 break;
1168d29b2c44Sab196087
1169d29b2c44Sab196087 case DYN_CMD_T_VALUE:
1170d29b2c44Sab196087 print_only = (argstate.argc != 2);
1171d29b2c44Sab196087 if (argstate.argc > 2)
1172d29b2c44Sab196087 elfedit_command_usage();
1173d29b2c44Sab196087 if (argstate.argc > 0) {
1174d29b2c44Sab196087 if (print_only) {
1175d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
1176d29b2c44Sab196087 print_only, &print_type);
1177d29b2c44Sab196087 } else {
1178d29b2c44Sab196087 print_type = PRINT_DYN_T_NDX;
1179d29b2c44Sab196087 }
1180d29b2c44Sab196087 }
1181d29b2c44Sab196087 break;
1182d29b2c44Sab196087
1183d29b2c44Sab196087 case DYN_CMD_T_DELETE:
1184d29b2c44Sab196087 if ((argstate.argc < 1) || (argstate.argc > 2))
1185d29b2c44Sab196087 elfedit_command_usage();
1186d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
1187d29b2c44Sab196087 0, &print_type);
1188d29b2c44Sab196087 do_autoprint = 0;
1189d29b2c44Sab196087 break;
1190d29b2c44Sab196087
1191d29b2c44Sab196087 case DYN_CMD_T_MOVE:
1192d29b2c44Sab196087 if ((argstate.argc < 2) || (argstate.argc > 3))
1193d29b2c44Sab196087 elfedit_command_usage();
1194d29b2c44Sab196087 ndx = arg_to_index(&argstate, argstate.argv[0],
119555ef6355Sab196087 0, &print_type);
1196d29b2c44Sab196087 do_autoprint = 0;
1197d29b2c44Sab196087 break;
1198d29b2c44Sab196087
1199d29b2c44Sab196087 case DYN_CMD_T_RUNPATH:
1200d29b2c44Sab196087 if (argstate.argc > 1)
1201d29b2c44Sab196087 elfedit_command_usage();
1202d29b2c44Sab196087 /*
1203d29b2c44Sab196087 * dyn:runpath does not accept an explicit index
1204d29b2c44Sab196087 * argument, so we implicitly only show the DT_RPATH and
1205d29b2c44Sab196087 * DT_RUNPATH elements.
1206d29b2c44Sab196087 */
1207d29b2c44Sab196087 print_type = PRINT_DYN_T_RUNPATH;
1208d29b2c44Sab196087 print_only = (argstate.argc == 0);
1209d29b2c44Sab196087 break;
1210d29b2c44Sab196087
1211d29b2c44Sab196087 case DYN_CMD_T_POSFLAG1:
1212d29b2c44Sab196087 print_only = (argstate.argc == 0);
1213d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1214d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_POSFLAG_1, 1),
121555ef6355Sab196087 print_only, &print_type);
1216d29b2c44Sab196087 break;
1217d29b2c44Sab196087
1218d29b2c44Sab196087 case DYN_CMD_T_FLAGS:
1219d29b2c44Sab196087 print_only = (argstate.argc == 0);
1220d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1221d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_FLAGS, 1),
122255ef6355Sab196087 print_only, &print_type);
1223d29b2c44Sab196087 break;
1224d29b2c44Sab196087
1225d29b2c44Sab196087 case DYN_CMD_T_FLAGS1:
1226d29b2c44Sab196087 print_only = (argstate.argc == 0);
1227d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1228d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_FLAGS_1, 1),
122955ef6355Sab196087 print_only, &print_type);
1230d29b2c44Sab196087 break;
1231d29b2c44Sab196087
1232d29b2c44Sab196087 case DYN_CMD_T_FEATURE1:
1233d29b2c44Sab196087 print_only = (argstate.argc == 0);
1234d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1235d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_FEATURE_1, 1),
123655ef6355Sab196087 print_only, &print_type);
1237d29b2c44Sab196087 break;
1238d29b2c44Sab196087
1239d29b2c44Sab196087 case DYN_CMD_T_CHECKSUM:
1240d29b2c44Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1241d29b2c44Sab196087 ELFEDIT_CONST_DT, DT_CHECKSUM, 1),
124255ef6355Sab196087 print_only, &print_type);
1243d29b2c44Sab196087 break;
1244d29b2c44Sab196087
1245ba2be530Sab196087 case DYN_CMD_T_SUNW_LDMACH:
1246ba2be530Sab196087 if (argstate.argc > 1)
1247ba2be530Sab196087 elfedit_command_usage();
12484f680cc6SAli Bahrami /* DT_SUNW_LDMACH is an ELFOSABI_SOLARIS feature */
12494f680cc6SAli Bahrami (void) elfedit_test_osabi(argstate.obj_state,
12504f680cc6SAli Bahrami ELFOSABI_SOLARIS, 1);
1251ba2be530Sab196087 print_only = (argstate.argc == 0);
1252ba2be530Sab196087 ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
1253ba2be530Sab196087 ELFEDIT_CONST_DT, DT_SUNW_LDMACH, 1),
125455ef6355Sab196087 print_only, &print_type);
1255ba2be530Sab196087 break;
1256ba2be530Sab196087
1257d29b2c44Sab196087 default:
1258d29b2c44Sab196087 /* Note expected: All commands should have been caught above */
1259d29b2c44Sab196087 elfedit_command_usage();
1260d29b2c44Sab196087 break;
1261d29b2c44Sab196087 }
1262d29b2c44Sab196087
1263d29b2c44Sab196087
1264d29b2c44Sab196087 /* If this is a request to print current values, do it and return */
1265d29b2c44Sab196087 if (print_only) {
1266d29b2c44Sab196087 print_dyn(cmd, 0, &argstate, print_type, ndx);
1267d29b2c44Sab196087 return (ELFEDIT_CMDRET_NONE);
1268d29b2c44Sab196087 }
1269d29b2c44Sab196087
1270d29b2c44Sab196087
1271d29b2c44Sab196087 switch (cmd) {
1272d29b2c44Sab196087 /*
1273d29b2c44Sab196087 * DYN_CMD_T_DUMP can't get here: It is a print-only
1274d29b2c44Sab196087 * command.
1275d29b2c44Sab196087 */
1276d29b2c44Sab196087
1277d29b2c44Sab196087 case DYN_CMD_T_TAG:
1278d29b2c44Sab196087 {
12794f680cc6SAli Bahrami Ehdr *ehdr = argstate.obj_state->os_ehdr;
12804f680cc6SAli Bahrami uchar_t osabi = ehdr->e_ident[EI_OSABI];
12814f680cc6SAli Bahrami Half mach = ehdr->e_machine;
1282d29b2c44Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
12834f680cc6SAli Bahrami Xword d_tag = (Xword) elfedit_atoconst(argstate.argv[1],
1284d29b2c44Sab196087 ELFEDIT_CONST_DT);
1285d29b2c44Sab196087
1286d29b2c44Sab196087 if (dyn[ndx].d_tag == d_tag) {
1287d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
12884f680cc6SAli Bahrami MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx, dyn_name,
12894f680cc6SAli Bahrami EC_WORD(ndx), conv_dyn_tag(d_tag, osabi,
12904f680cc6SAli Bahrami mach, 0, &inv_buf1));
1291d29b2c44Sab196087 } else {
12924f680cc6SAli Bahrami Xword orig_d_tag = dyn[ndx].d_tag;
1293d29b2c44Sab196087
1294d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1295d29b2c44Sab196087 dyn[ndx].d_tag = d_tag;
1296d29b2c44Sab196087
1297d29b2c44Sab196087 /*
1298d29b2c44Sab196087 * Update null termination index. Warn if we
1299d29b2c44Sab196087 * just clobbered the only DT_NULL termination
1300d29b2c44Sab196087 * for the array.
1301d29b2c44Sab196087 */
1302d29b2c44Sab196087 null_ndx = argstate.dyn.null_ndx;
1303d29b2c44Sab196087 set_null_ndx(&argstate);
1304d29b2c44Sab196087 if ((argstate.dyn.null_ndx >=
1305d29b2c44Sab196087 argstate.dyn.num) &&
1306d29b2c44Sab196087 (null_ndx != argstate.dyn.null_ndx))
1307d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1308d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_NULLTERM),
1309d29b2c44Sab196087 dyn_ndx, dyn_name,
13104f680cc6SAli Bahrami EC_WORD(ndx), conv_dyn_tag(d_tag,
13114f680cc6SAli Bahrami osabi, mach, 0, &inv_buf1));
1312d29b2c44Sab196087
1313d29b2c44Sab196087 /*
1314d29b2c44Sab196087 * Warning if
1315d29b2c44Sab196087 * - Inserting a DT_NULL cuts off following
1316d29b2c44Sab196087 * non-null elements.
1317d29b2c44Sab196087 * - Inserting a non-DT_NULL after the
1318d29b2c44Sab196087 * first null element, will be
1319d29b2c44Sab196087 * ignored by rtld.
1320d29b2c44Sab196087 */
1321d29b2c44Sab196087 if (d_tag == DT_NULL) {
1322d29b2c44Sab196087 if ((ndx + 1) < null_ndx)
1323d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1324d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_NULCLIP),
1325d29b2c44Sab196087 dyn_ndx, dyn_name,
1326d29b2c44Sab196087 EC_WORD(ndx),
13274f680cc6SAli Bahrami conv_dyn_tag(d_tag, osabi,
13284f680cc6SAli Bahrami mach, 0, &inv_buf1));
1329d29b2c44Sab196087 } else {
1330d29b2c44Sab196087 if ((ndx + 1) > argstate.dyn.null_ndx)
1331d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1332d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_NULHIDE),
1333d29b2c44Sab196087 dyn_ndx, dyn_name,
1334d29b2c44Sab196087 EC_WORD(ndx),
13354f680cc6SAli Bahrami conv_dyn_tag(d_tag, osabi,
13364f680cc6SAli Bahrami mach, 0, &inv_buf1));
1337d29b2c44Sab196087 }
1338d29b2c44Sab196087
1339d29b2c44Sab196087 /* Debug message that we changed it */
1340d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1341d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1342d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
13434f680cc6SAli Bahrami conv_dyn_tag(orig_d_tag, osabi, mach, 0,
1344d29b2c44Sab196087 &inv_buf1),
13454f680cc6SAli Bahrami conv_dyn_tag(d_tag, osabi, mach, 0,
13464f680cc6SAli Bahrami &inv_buf2));
1347d29b2c44Sab196087 }
1348d29b2c44Sab196087 }
1349d29b2c44Sab196087 break;
1350d29b2c44Sab196087
1351d29b2c44Sab196087 case DYN_CMD_T_VALUE:
1352d29b2c44Sab196087 ret = cmd_body_value(&argstate, &ndx);
1353d29b2c44Sab196087 break;
1354d29b2c44Sab196087
1355d29b2c44Sab196087 case DYN_CMD_T_DELETE:
1356d29b2c44Sab196087 {
1357d29b2c44Sab196087 Word cnt = (argstate.argc == 1) ? 1 :
1358d29b2c44Sab196087 (Word) elfedit_atoui_range(argstate.argv[1],
1359d29b2c44Sab196087 MSG_ORIG(MSG_STR_COUNT), 1, dyn_num - ndx, NULL);
1360d29b2c44Sab196087 const char *msg_prefix =
1361d29b2c44Sab196087 elfedit_sec_msgprefix(argstate.dyn.sec);
1362d29b2c44Sab196087
1363d29b2c44Sab196087 elfedit_array_elts_delete(msg_prefix, argstate.dyn.data,
1364d29b2c44Sab196087 sizeof (Dyn), dyn_num, ndx, cnt);
1365d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1366d29b2c44Sab196087 }
1367d29b2c44Sab196087 break;
1368d29b2c44Sab196087
1369d29b2c44Sab196087 case DYN_CMD_T_MOVE:
1370d29b2c44Sab196087 {
1371d29b2c44Sab196087 Dyn save;
1372d29b2c44Sab196087 Word cnt;
1373d29b2c44Sab196087 Word dstndx;
1374d29b2c44Sab196087 const char *msg_prefix =
1375d29b2c44Sab196087 elfedit_sec_msgprefix(argstate.dyn.sec);
1376d29b2c44Sab196087
1377d29b2c44Sab196087 dstndx = (Word)
1378d29b2c44Sab196087 elfedit_atoui_range(argstate.argv[1],
1379d29b2c44Sab196087 MSG_ORIG(MSG_STR_DST_INDEX), 0, dyn_num - 1,
1380d29b2c44Sab196087 NULL);
1381d29b2c44Sab196087 if (argstate.argc == 2) {
1382d29b2c44Sab196087 cnt = 1;
1383d29b2c44Sab196087 } else {
1384d29b2c44Sab196087 cnt = (Word) elfedit_atoui_range(
1385d29b2c44Sab196087 argstate.argv[2], MSG_ORIG(MSG_STR_COUNT),
1386d29b2c44Sab196087 1, dyn_num, NULL);
1387d29b2c44Sab196087 }
1388d29b2c44Sab196087 elfedit_array_elts_move(msg_prefix, argstate.dyn.data,
1389d29b2c44Sab196087 sizeof (save), dyn_num, ndx, dstndx, cnt, &save);
1390d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1391d29b2c44Sab196087 }
1392d29b2c44Sab196087 break;
1393d29b2c44Sab196087
1394d29b2c44Sab196087
1395d29b2c44Sab196087 case DYN_CMD_T_RUNPATH:
1396d29b2c44Sab196087 ret = cmd_body_runpath(&argstate);
1397d29b2c44Sab196087 break;
1398d29b2c44Sab196087
1399d29b2c44Sab196087 case DYN_CMD_T_POSFLAG1:
1400d29b2c44Sab196087 {
1401d29b2c44Sab196087 Conv_dyn_posflag1_buf_t buf1, buf2;
1402d29b2c44Sab196087 Word flags;
1403d29b2c44Sab196087
1404d29b2c44Sab196087 flags = flag_bitop(&argstate, dyn[ndx].d_un.d_val,
1405d29b2c44Sab196087 ELFEDIT_CONST_DF_P1);
1406d29b2c44Sab196087
1407d29b2c44Sab196087 /* Set the value */
1408d29b2c44Sab196087 if (dyn[ndx].d_un.d_val == flags) {
1409d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1410d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx,
1411d29b2c44Sab196087 dyn_name, EC_WORD(ndx),
1412d29b2c44Sab196087 conv_dyn_posflag1(dyn[ndx].d_un.d_val, 0,
1413d29b2c44Sab196087 &buf1));
1414d29b2c44Sab196087 } else {
1415d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1416d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1417d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1418d29b2c44Sab196087 conv_dyn_posflag1(dyn[ndx].d_un.d_val, 0,
1419d29b2c44Sab196087 &buf1),
1420d29b2c44Sab196087 conv_dyn_posflag1(flags, 0, &buf2));
1421d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1422d29b2c44Sab196087 dyn[ndx].d_un.d_val = flags;
1423d29b2c44Sab196087 }
1424d29b2c44Sab196087 }
1425d29b2c44Sab196087 break;
1426d29b2c44Sab196087
1427d29b2c44Sab196087 case DYN_CMD_T_FLAGS:
1428d29b2c44Sab196087 {
1429d29b2c44Sab196087 Conv_dyn_flag_buf_t buf1, buf2;
1430d29b2c44Sab196087 Word flags;
1431d29b2c44Sab196087
1432d29b2c44Sab196087 flags = flag_bitop(&argstate, dyn[ndx].d_un.d_val,
1433d29b2c44Sab196087 ELFEDIT_CONST_DF);
1434d29b2c44Sab196087
1435d29b2c44Sab196087 /* Set the value */
1436d29b2c44Sab196087 if (dyn[ndx].d_un.d_val == flags) {
1437d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1438d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx,
1439d29b2c44Sab196087 dyn_name, EC_WORD(ndx),
1440d29b2c44Sab196087 conv_dyn_flag(dyn[ndx].d_un.d_val, 0,
1441d29b2c44Sab196087 &buf1));
1442d29b2c44Sab196087 } else {
1443d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1444d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1445d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1446d29b2c44Sab196087 conv_dyn_flag(dyn[ndx].d_un.d_val, 0,
1447d29b2c44Sab196087 &buf1),
1448d29b2c44Sab196087 conv_dyn_flag(flags, 0, &buf2));
1449d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1450d29b2c44Sab196087 dyn[ndx].d_un.d_val = flags;
1451d29b2c44Sab196087 }
1452d29b2c44Sab196087 }
1453d29b2c44Sab196087 break;
1454d29b2c44Sab196087
1455d29b2c44Sab196087 case DYN_CMD_T_FLAGS1:
1456d29b2c44Sab196087 {
1457d29b2c44Sab196087 Conv_dyn_flag1_buf_t buf1, buf2;
1458d29b2c44Sab196087 Word flags1;
1459d29b2c44Sab196087
1460d29b2c44Sab196087 flags1 = flag_bitop(&argstate, dyn[ndx].d_un.d_val,
1461d29b2c44Sab196087 ELFEDIT_CONST_DF_1);
1462d29b2c44Sab196087
1463d29b2c44Sab196087 /* Set the value */
1464d29b2c44Sab196087 if (dyn[ndx].d_un.d_val == flags1) {
1465d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1466d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx,
1467d29b2c44Sab196087 dyn_name, EC_WORD(ndx),
1468d29b2c44Sab196087 conv_dyn_flag1(dyn[ndx].d_un.d_val,
1469d29b2c44Sab196087 0, &buf1));
1470d29b2c44Sab196087 } else {
1471d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1472d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1473d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1474d29b2c44Sab196087 conv_dyn_flag1(dyn[ndx].d_un.d_val,
1475d29b2c44Sab196087 0, &buf1),
1476d29b2c44Sab196087 conv_dyn_flag1(flags1, 0, &buf2));
1477d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1478d29b2c44Sab196087 dyn[ndx].d_un.d_val = flags1;
1479d29b2c44Sab196087 }
1480d29b2c44Sab196087 }
1481d29b2c44Sab196087 break;
1482d29b2c44Sab196087
1483d29b2c44Sab196087 case DYN_CMD_T_FEATURE1:
1484d29b2c44Sab196087 {
1485d29b2c44Sab196087 Conv_dyn_feature1_buf_t buf1, buf2;
1486d29b2c44Sab196087 Word flags;
1487d29b2c44Sab196087
1488d29b2c44Sab196087 flags = flag_bitop(&argstate, dyn[ndx].d_un.d_val,
1489d29b2c44Sab196087 ELFEDIT_CONST_DTF_1);
1490d29b2c44Sab196087
1491d29b2c44Sab196087 /* Set the value */
1492d29b2c44Sab196087 if (dyn[ndx].d_un.d_val == flags) {
1493d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1494d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx,
1495d29b2c44Sab196087 dyn_name, EC_WORD(ndx),
1496d29b2c44Sab196087 conv_dyn_feature1(dyn[ndx].d_un.d_val, 0,
1497d29b2c44Sab196087 &buf1));
1498d29b2c44Sab196087 } else {
1499d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1500d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1501d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1502d29b2c44Sab196087 conv_dyn_feature1(dyn[ndx].d_un.d_val, 0,
1503d29b2c44Sab196087 &buf1),
1504d29b2c44Sab196087 conv_dyn_feature1(flags, 0, &buf2));
1505d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1506d29b2c44Sab196087 dyn[ndx].d_un.d_val = flags;
1507d29b2c44Sab196087 }
1508d29b2c44Sab196087 }
1509d29b2c44Sab196087 break;
1510d29b2c44Sab196087
1511d29b2c44Sab196087 case DYN_CMD_T_CHECKSUM:
1512d29b2c44Sab196087 {
1513d29b2c44Sab196087 long checksum = elf_checksum(obj_state->os_elf);
1514d29b2c44Sab196087
1515d29b2c44Sab196087 /* Set the value */
1516d29b2c44Sab196087 if (dyn[ndx].d_un.d_val == checksum) {
1517d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1518d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_OK), dyn_ndx,
1519d29b2c44Sab196087 dyn_name, EC_WORD(ndx), EC_XWORD(checksum));
1520d29b2c44Sab196087 } else {
1521d29b2c44Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1522d29b2c44Sab196087 MSG_INTL(MSG_DEBUG_X_CHG),
1523d29b2c44Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1524d29b2c44Sab196087 EC_XWORD(dyn[ndx].d_un.d_val),
1525d29b2c44Sab196087 EC_XWORD(checksum));
1526d29b2c44Sab196087 ret = ELFEDIT_CMDRET_MOD;
1527d29b2c44Sab196087 dyn[ndx].d_un.d_val = checksum;
1528d29b2c44Sab196087 }
1529d29b2c44Sab196087
1530d29b2c44Sab196087 }
1531ba2be530Sab196087 break;
1532ba2be530Sab196087
1533ba2be530Sab196087 case DYN_CMD_T_SUNW_LDMACH:
1534ba2be530Sab196087 {
1535ba2be530Sab196087 Conv_inv_buf_t buf1, buf2;
1536ba2be530Sab196087 Half ldmach;
1537ba2be530Sab196087
1538ba2be530Sab196087 ldmach = (Half) elfedit_atoconst(argstate.argv[0],
1539ba2be530Sab196087 ELFEDIT_CONST_EM);
1540ba2be530Sab196087
1541ba2be530Sab196087 /* Set the value */
1542ba2be530Sab196087 if (dyn[ndx].d_un.d_val == ldmach) {
1543ba2be530Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1544ba2be530Sab196087 MSG_INTL(MSG_DEBUG_S_OK), dyn_ndx,
1545ba2be530Sab196087 dyn_name, EC_WORD(ndx),
1546ba2be530Sab196087 conv_ehdr_mach(dyn[ndx].d_un.d_val, 0,
1547ba2be530Sab196087 &buf1));
1548ba2be530Sab196087 } else {
1549ba2be530Sab196087 elfedit_msg(ELFEDIT_MSG_DEBUG,
1550ba2be530Sab196087 MSG_INTL(MSG_DEBUG_S_CHG),
1551ba2be530Sab196087 dyn_ndx, dyn_name, EC_WORD(ndx),
1552ba2be530Sab196087 conv_ehdr_mach(dyn[ndx].d_un.d_val, 0,
1553ba2be530Sab196087 &buf1),
1554ba2be530Sab196087 conv_ehdr_mach(ldmach, 0, &buf2));
1555ba2be530Sab196087 ret = ELFEDIT_CMDRET_MOD;
1556ba2be530Sab196087 dyn[ndx].d_un.d_val = ldmach;
1557ba2be530Sab196087 }
1558ba2be530Sab196087 }
1559ba2be530Sab196087 break;
1560ba2be530Sab196087
1561d29b2c44Sab196087 }
1562d29b2c44Sab196087
1563d29b2c44Sab196087 /*
1564d29b2c44Sab196087 * If we modified the dynamic section header, tell libelf.
1565d29b2c44Sab196087 */
1566d29b2c44Sab196087 if (ret == ELFEDIT_CMDRET_MOD)
1567d29b2c44Sab196087 elfedit_modified_data(argstate.dyn.sec);
1568d29b2c44Sab196087
1569d29b2c44Sab196087 /* Do autoprint */
1570d29b2c44Sab196087 if (do_autoprint)
1571d29b2c44Sab196087 print_dyn(cmd, 1, &argstate, print_type, ndx);
1572d29b2c44Sab196087
1573d29b2c44Sab196087 return (ret);
1574d29b2c44Sab196087 }
1575d29b2c44Sab196087
1576d29b2c44Sab196087
1577d29b2c44Sab196087
1578d29b2c44Sab196087 /*
1579d29b2c44Sab196087 * Command completion functions for the commands
1580d29b2c44Sab196087 */
1581d29b2c44Sab196087
1582d29b2c44Sab196087 /*
1583d29b2c44Sab196087 * Command completion for the first argument, which specifies
1584d29b2c44Sab196087 * the dynamic element to use. Examines the options to see if
1585d29b2c44Sab196087 * -dynndx is present, and if not, supplies the completion
1586d29b2c44Sab196087 * strings for argument 1.
1587d29b2c44Sab196087 */
1588d29b2c44Sab196087 /*ARGSUSED*/
1589d29b2c44Sab196087 static void
cpl_eltarg(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1590d29b2c44Sab196087 cpl_eltarg(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1591d29b2c44Sab196087 const char *argv[], int num_opt)
1592d29b2c44Sab196087 {
1593d29b2c44Sab196087 elfedit_section_t *cache;
1594d29b2c44Sab196087 Dyn *dyn;
1595d29b2c44Sab196087 Word i;
1596d29b2c44Sab196087 const char *s;
1597d29b2c44Sab196087 char *s2;
1598d29b2c44Sab196087 char buf[128];
1599d29b2c44Sab196087
1600d29b2c44Sab196087 /* Make sure it's the first argument */
1601d29b2c44Sab196087 if ((argc - num_opt) != 1)
1602d29b2c44Sab196087 return;
1603d29b2c44Sab196087
1604d29b2c44Sab196087 /* Is -dynndx present? If so, we don't complete tag types */
1605d29b2c44Sab196087 for (i = 0; i < num_opt; i++)
1606d29b2c44Sab196087 if (strcmp(argv[i], MSG_ORIG(MSG_STR_MINUS_DYNNDX)) == 0)
1607d29b2c44Sab196087 return;
1608d29b2c44Sab196087
1609d29b2c44Sab196087 /*
1610d29b2c44Sab196087 * If there is no object, or if there is no dynamic section,
1611d29b2c44Sab196087 * then supply all possible names.
1612d29b2c44Sab196087 */
1613d29b2c44Sab196087 if ((obj_state == NULL) || (obj_state->os_dynndx == SHN_UNDEF)) {
1614d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DT);
1615d29b2c44Sab196087 return;
1616d29b2c44Sab196087 }
1617d29b2c44Sab196087
1618d29b2c44Sab196087 /* Supply completions for the tags present in the dynamic section */
1619d29b2c44Sab196087 cache = &obj_state->os_secarr[obj_state->os_dynndx];
1620d29b2c44Sab196087 dyn = (Dyn *) cache->sec_data->d_buf;
1621d29b2c44Sab196087 i = cache->sec_shdr->sh_size / cache->sec_shdr->sh_entsize;
1622d29b2c44Sab196087 for (; i-- > 0; dyn++) {
1623d29b2c44Sab196087 s = elfedit_atoconst_value_to_str(ELFEDIT_CONST_DT,
1624d29b2c44Sab196087 dyn->d_tag, 0);
1625d29b2c44Sab196087 if (s == NULL)
1626d29b2c44Sab196087 continue;
1627d29b2c44Sab196087 elfedit_cpl_match(cpldata, s, 1);
1628d29b2c44Sab196087
1629d29b2c44Sab196087 /*
1630d29b2c44Sab196087 * To get the informal tag names that are lowercase
1631d29b2c44Sab196087 * and lack the leading DT_, we copy the string we
1632d29b2c44Sab196087 * have into a buffer and process it.
1633d29b2c44Sab196087 */
1634d29b2c44Sab196087 if (strlen(s) < 3)
1635d29b2c44Sab196087 continue;
1636d29b2c44Sab196087 (void) strlcpy(buf, s + 3, sizeof (buf));
1637d29b2c44Sab196087 for (s2 = buf; *s2 != '\0'; s2++)
1638d29b2c44Sab196087 if (isupper(*s2))
1639d29b2c44Sab196087 *s2 = tolower(*s2);
1640d29b2c44Sab196087 elfedit_cpl_match(cpldata, buf, 1);
1641d29b2c44Sab196087 }
1642d29b2c44Sab196087 }
1643d29b2c44Sab196087
1644d29b2c44Sab196087
1645d29b2c44Sab196087 /*ARGSUSED*/
1646d29b2c44Sab196087 static void
cpl_tag(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1647d29b2c44Sab196087 cpl_tag(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1648d29b2c44Sab196087 const char *argv[], int num_opt)
1649d29b2c44Sab196087 {
1650d29b2c44Sab196087 /* First argument */
1651d29b2c44Sab196087 if ((argc - num_opt) == 1) {
1652d29b2c44Sab196087 cpl_eltarg(obj_state, cpldata, argc, argv, num_opt);
1653d29b2c44Sab196087 return;
1654d29b2c44Sab196087 }
1655d29b2c44Sab196087
1656d29b2c44Sab196087 /* The second argument is always a tag value */
1657d29b2c44Sab196087 if ((argc - num_opt) == 2)
1658d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DT);
1659d29b2c44Sab196087 }
1660d29b2c44Sab196087
1661d29b2c44Sab196087 /*ARGSUSED*/
1662d29b2c44Sab196087 static void
cpl_posflag1(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1663d29b2c44Sab196087 cpl_posflag1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1664d29b2c44Sab196087 const char *argv[], int num_opt)
1665d29b2c44Sab196087 {
166655ef6355Sab196087 /*
166755ef6355Sab196087 * dyn:posflag1 accepts two mutually exclusive options that have
166855ef6355Sab196087 * a corresponding value argument: -dynndx and -needed. If we
166955ef6355Sab196087 * are being called to supply options for the value, handle that here.
167055ef6355Sab196087 */
167155ef6355Sab196087 if ((num_opt > 1) && (argc == num_opt)) {
167255ef6355Sab196087 elfedit_section_t *dynsec, *strsec;
167355ef6355Sab196087 const char *opt = argv[num_opt - 2];
167455ef6355Sab196087 dyn_opt_t type;
167555ef6355Sab196087 Dyn *dyn;
167655ef6355Sab196087 Word i, num;
167755ef6355Sab196087
167855ef6355Sab196087 /*
167955ef6355Sab196087 * If there is no object available, or if the object has no
168055ef6355Sab196087 * dynamic section, then there is nothing to report.
168155ef6355Sab196087 */
168255ef6355Sab196087 if ((obj_state == NULL) || obj_state->os_dynndx == SHN_UNDEF)
168355ef6355Sab196087 return;
168455ef6355Sab196087
168555ef6355Sab196087 /*
168655ef6355Sab196087 * Determine which option it is, bail if it isn't one of
168755ef6355Sab196087 * the ones we are concerned with.
168855ef6355Sab196087 */
168955ef6355Sab196087 if ((strcmp(opt, MSG_ORIG(MSG_STR_MINUS_NEEDED)) == 0))
169055ef6355Sab196087 type = DYN_OPT_F_NEEDED;
169155ef6355Sab196087 else if ((strcmp(opt, MSG_ORIG(MSG_STR_MINUS_DYNNDX)) == 0))
169255ef6355Sab196087 type = DYN_OPT_F_DYNNDX_VAL;
169355ef6355Sab196087 else
169455ef6355Sab196087 return;
169555ef6355Sab196087
169655ef6355Sab196087 dynsec = elfedit_sec_getdyn(obj_state, &dyn, &num);
169755ef6355Sab196087 switch (type) {
169855ef6355Sab196087 case DYN_OPT_F_NEEDED:
169955ef6355Sab196087 strsec = elfedit_sec_getstr(obj_state,
170055ef6355Sab196087 dynsec->sec_shdr->sh_link, 0);
170155ef6355Sab196087 for (; num-- > 0; dyn++)
170255ef6355Sab196087 if (dyn->d_tag == DT_NEEDED)
170355ef6355Sab196087 elfedit_cpl_match(cpldata,
170455ef6355Sab196087 elfedit_offset_to_str(strsec,
170555ef6355Sab196087 dyn->d_un.d_val, ELFEDIT_MSG_DEBUG,
170655ef6355Sab196087 0), 0);
170755ef6355Sab196087 break;
170855ef6355Sab196087
170955ef6355Sab196087 case DYN_OPT_F_DYNNDX_VAL:
171055ef6355Sab196087 for (i = 0; i < num; i++, dyn++)
171155ef6355Sab196087 if (dyn->d_tag == DT_POSFLAG_1)
171255ef6355Sab196087 elfedit_cpl_ndx(cpldata, i);
171355ef6355Sab196087 break;
171455ef6355Sab196087 }
171555ef6355Sab196087 return;
171655ef6355Sab196087 }
171755ef6355Sab196087
1718d29b2c44Sab196087 /* This routine allows multiple flags to be specified */
1719d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DF_P1);
1720d29b2c44Sab196087 }
1721d29b2c44Sab196087
1722d29b2c44Sab196087 /*ARGSUSED*/
1723d29b2c44Sab196087 static void
cpl_flags(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1724d29b2c44Sab196087 cpl_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1725d29b2c44Sab196087 const char *argv[], int num_opt)
1726d29b2c44Sab196087 {
1727d29b2c44Sab196087 /* This routine allows multiple flags to be specified */
1728d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DF);
1729d29b2c44Sab196087 }
1730d29b2c44Sab196087
1731d29b2c44Sab196087 /*ARGSUSED*/
1732d29b2c44Sab196087 static void
cpl_flags1(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1733d29b2c44Sab196087 cpl_flags1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1734d29b2c44Sab196087 const char *argv[], int num_opt)
1735d29b2c44Sab196087 {
1736d29b2c44Sab196087 /* This routine allows multiple flags to be specified */
1737d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DF_1);
1738d29b2c44Sab196087 }
1739d29b2c44Sab196087
1740d29b2c44Sab196087 /*ARGSUSED*/
1741d29b2c44Sab196087 static void
cpl_feature1(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1742d29b2c44Sab196087 cpl_feature1(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1743d29b2c44Sab196087 const char *argv[], int num_opt)
1744d29b2c44Sab196087 {
1745d29b2c44Sab196087 /* This routine allows multiple flags to be specified */
1746d29b2c44Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_DTF_1);
1747d29b2c44Sab196087 }
1748d29b2c44Sab196087
1749ba2be530Sab196087 /*ARGSUSED*/
1750ba2be530Sab196087 static void
cpl_sunw_ldmach(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1751ba2be530Sab196087 cpl_sunw_ldmach(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1752ba2be530Sab196087 const char *argv[], int num_opt)
1753ba2be530Sab196087 {
1754ba2be530Sab196087 /*
1755ba2be530Sab196087 * This command doesn't accept options, so num_opt should be
1756ba2be530Sab196087 * 0. This is a defensive measure, in case that should change.
1757ba2be530Sab196087 */
1758ba2be530Sab196087 argc -= num_opt;
1759ba2be530Sab196087 argv += num_opt;
1760ba2be530Sab196087
1761ba2be530Sab196087 if (argc == 1)
1762ba2be530Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM);
1763ba2be530Sab196087 }
1764ba2be530Sab196087
1765d29b2c44Sab196087
1766d29b2c44Sab196087 /*
1767d29b2c44Sab196087 * Implementation functions for the commands
1768d29b2c44Sab196087 */
1769d29b2c44Sab196087 static elfedit_cmdret_t
cmd_dump(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1770d29b2c44Sab196087 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1771d29b2c44Sab196087 {
1772d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_DUMP, obj_state, argc, argv));
1773d29b2c44Sab196087 }
1774d29b2c44Sab196087
1775d29b2c44Sab196087 static elfedit_cmdret_t
cmd_tag(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1776d29b2c44Sab196087 cmd_tag(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1777d29b2c44Sab196087 {
1778d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_TAG, obj_state, argc, argv));
1779d29b2c44Sab196087 }
1780d29b2c44Sab196087
1781d29b2c44Sab196087 static elfedit_cmdret_t
cmd_value(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1782d29b2c44Sab196087 cmd_value(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1783d29b2c44Sab196087 {
1784d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_VALUE, obj_state, argc, argv));
1785d29b2c44Sab196087 }
1786d29b2c44Sab196087
1787d29b2c44Sab196087 static elfedit_cmdret_t
cmd_delete(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1788d29b2c44Sab196087 cmd_delete(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1789d29b2c44Sab196087 {
1790d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_DELETE, obj_state, argc, argv));
1791d29b2c44Sab196087 }
1792d29b2c44Sab196087
1793d29b2c44Sab196087 static elfedit_cmdret_t
cmd_move(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1794d29b2c44Sab196087 cmd_move(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1795d29b2c44Sab196087 {
1796d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_MOVE, obj_state, argc, argv));
1797d29b2c44Sab196087 }
1798d29b2c44Sab196087
1799d29b2c44Sab196087 static elfedit_cmdret_t
cmd_runpath(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1800d29b2c44Sab196087 cmd_runpath(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1801d29b2c44Sab196087 {
1802d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_RUNPATH, obj_state, argc, argv));
1803d29b2c44Sab196087 }
1804d29b2c44Sab196087
1805d29b2c44Sab196087 static elfedit_cmdret_t
cmd_posflag1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1806d29b2c44Sab196087 cmd_posflag1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1807d29b2c44Sab196087 {
1808d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_POSFLAG1, obj_state, argc, argv));
1809d29b2c44Sab196087 }
1810d29b2c44Sab196087
1811d29b2c44Sab196087 static elfedit_cmdret_t
cmd_flags(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1812d29b2c44Sab196087 cmd_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1813d29b2c44Sab196087 {
1814d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_FLAGS, obj_state, argc, argv));
1815d29b2c44Sab196087 }
1816d29b2c44Sab196087
1817d29b2c44Sab196087 static elfedit_cmdret_t
cmd_flags1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1818d29b2c44Sab196087 cmd_flags1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1819d29b2c44Sab196087 {
1820d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_FLAGS1, obj_state, argc, argv));
1821d29b2c44Sab196087 }
1822d29b2c44Sab196087
1823d29b2c44Sab196087 static elfedit_cmdret_t
cmd_feature1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1824d29b2c44Sab196087 cmd_feature1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1825d29b2c44Sab196087 {
1826d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_FEATURE1, obj_state, argc, argv));
1827d29b2c44Sab196087 }
1828d29b2c44Sab196087
1829d29b2c44Sab196087 static elfedit_cmdret_t
cmd_checksum(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1830d29b2c44Sab196087 cmd_checksum(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1831d29b2c44Sab196087 {
1832d29b2c44Sab196087 return (cmd_body(DYN_CMD_T_CHECKSUM, obj_state, argc, argv));
1833d29b2c44Sab196087 }
1834d29b2c44Sab196087
1835ba2be530Sab196087 static elfedit_cmdret_t
cmd_sunw_ldmach(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1836ba2be530Sab196087 cmd_sunw_ldmach(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1837ba2be530Sab196087 {
1838ba2be530Sab196087 return (cmd_body(DYN_CMD_T_SUNW_LDMACH, obj_state, argc, argv));
1839ba2be530Sab196087 }
1840ba2be530Sab196087
1841d29b2c44Sab196087
1842d29b2c44Sab196087
1843d29b2c44Sab196087 /*ARGSUSED*/
1844d29b2c44Sab196087 elfedit_module_t *
elfedit_init(elfedit_module_version_t version)1845d29b2c44Sab196087 elfedit_init(elfedit_module_version_t version)
1846d29b2c44Sab196087 {
1847d29b2c44Sab196087 /* For commands that only accept -o */
1848d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_ostyle[] = {
1849d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
1850d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1851d29b2c44Sab196087 { NULL }
1852d29b2c44Sab196087 };
1853d29b2c44Sab196087
1854d29b2c44Sab196087 /* For commands that only accept -and, -cmp, -o, -or */
1855d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_ostyle_bitop[] = {
1856d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL,
1857d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_AND, DYN_OPT_F_OR },
1858d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL,
1859d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_CMP, 0 },
1860d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
1861d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1862d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL,
1863d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_OR, DYN_OPT_F_AND },
1864d29b2c44Sab196087 { NULL }
1865d29b2c44Sab196087 };
1866d29b2c44Sab196087
1867d29b2c44Sab196087 /* For commands that only accept -dynndx */
1868d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_minus_dynndx[] = {
1869d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_DYNNDX),
187055ef6355Sab196087 /* MSG_INTL(MSG_OPTDESC_DYNNDX_ELT) */
187155ef6355Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_DYNNDX_ELT), 0,
187255ef6355Sab196087 DYN_OPT_F_DYNNDX_ELT, 0 },
1873d29b2c44Sab196087 { NULL }
1874d29b2c44Sab196087 };
1875d29b2c44Sab196087
1876d29b2c44Sab196087 /* dyn:dump */
1877d29b2c44Sab196087 static const char *name_dump[] = {
1878d29b2c44Sab196087 MSG_ORIG(MSG_CMD_DUMP),
1879d29b2c44Sab196087 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */
1880d29b2c44Sab196087 NULL
1881d29b2c44Sab196087 };
1882d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_dump[] = {
1883d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1884d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1885d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1886d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1887d29b2c44Sab196087 { NULL }
1888d29b2c44Sab196087 };
1889d29b2c44Sab196087
1890d29b2c44Sab196087
1891d29b2c44Sab196087 /* dyn:tag */
1892d29b2c44Sab196087 static const char *name_tag[] = { MSG_ORIG(MSG_CMD_TAG), NULL };
1893d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_tag[] = {
1894d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_DYNNDX),
189555ef6355Sab196087 /* MSG_INTL(MSG_OPTDESC_DYNNDX_ELT) */
189655ef6355Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_DYNNDX_ELT), 0,
189755ef6355Sab196087 DYN_OPT_F_DYNNDX_ELT, 0 },
1898d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
1899d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1900d29b2c44Sab196087 { NULL }
1901d29b2c44Sab196087 };
1902d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_tag[] = {
1903d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1904d29b2c44Sab196087 /* MSG_INTL(MSG_A1_TAG_ELT) */
1905d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_TAG_ELT),
1906d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1907d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1908d29b2c44Sab196087 /* MSG_INTL(MSG_A2_TAG_VALUE) */
1909d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_TAG_VALUE),
1910d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1911d29b2c44Sab196087 { NULL }
1912d29b2c44Sab196087 };
1913d29b2c44Sab196087
1914d29b2c44Sab196087
1915d29b2c44Sab196087 /* dyn:value */
1916d29b2c44Sab196087 static const char *name_value[] = { MSG_ORIG(MSG_CMD_VALUE), NULL };
1917d29b2c44Sab196087 static elfedit_cmd_optarg_t opt_value[] = {
1918d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_ADD),
1919d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_ADD) */
1920d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_ADD), 0,
192155ef6355Sab196087 DYN_OPT_F_ADD, DYN_OPT_F_DYNNDX_ELT },
1922d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_DYNNDX),
192355ef6355Sab196087 /* MSG_INTL(MSG_OPTDESC_DYNNDX_ELT) */
192455ef6355Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_DYNNDX_ELT), 0,
192555ef6355Sab196087 DYN_OPT_F_DYNNDX_ELT, DYN_OPT_F_ADD },
1926d29b2c44Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
1927d29b2c44Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1928d29b2c44Sab196087 { MSG_ORIG(MSG_STR_MINUS_S),
1929d29b2c44Sab196087 /* MSG_INTL(MSG_OPTDESC_S) */
1930d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_S), 0,
1931d29b2c44Sab196087 DYN_OPT_F_STRVAL, 0 },
1932d29b2c44Sab196087 { NULL }
1933d29b2c44Sab196087 };
1934d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_value[] = {
1935d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1936d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1937d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1938d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1939d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
1940d29b2c44Sab196087 /* MSG_INTL(MSG_A2_VALUE_VALUE) */
1941d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_VALUE_VALUE),
1942d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1943d29b2c44Sab196087 { NULL }
1944d29b2c44Sab196087 };
1945d29b2c44Sab196087
1946d29b2c44Sab196087 /* dyn:delete */
1947d29b2c44Sab196087 static const char *name_delete[] = { MSG_ORIG(MSG_CMD_DELETE), NULL };
1948d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_delete[] = {
1949d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1950d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1951d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1952d29b2c44Sab196087 0 },
1953d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT),
1954d29b2c44Sab196087 /* MSG_INTL(MSG_A2_DELETE_COUNT) */
1955d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_DELETE_COUNT),
1956d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1957d29b2c44Sab196087 { NULL }
1958d29b2c44Sab196087 };
1959d29b2c44Sab196087
1960d29b2c44Sab196087 /* dyn:move */
1961d29b2c44Sab196087 static const char *name_move[] = { MSG_ORIG(MSG_CMD_MOVE), NULL };
1962d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_move[] = {
1963d29b2c44Sab196087 { MSG_ORIG(MSG_STR_ELT),
1964d29b2c44Sab196087 /* MSG_INTL(MSG_ARGDESC_ELT) */
1965d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_ELT),
1966d29b2c44Sab196087 0 },
1967d29b2c44Sab196087 { MSG_ORIG(MSG_STR_DST_INDEX),
1968d29b2c44Sab196087 /* MSG_INTL(MSG_A2_MOVE_DST_INDEX) */
1969d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A2_MOVE_DST_INDEX),
1970d29b2c44Sab196087 0 },
1971d29b2c44Sab196087 { MSG_ORIG(MSG_STR_COUNT),
1972d29b2c44Sab196087 /* MSG_INTL(MSG_A3_MOVE_COUNT) */
1973d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A3_MOVE_COUNT),
1974d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1975d29b2c44Sab196087 { NULL }
1976d29b2c44Sab196087 };
1977d29b2c44Sab196087
1978d29b2c44Sab196087 /* dyn:runpath / dyn:rpath */
1979d29b2c44Sab196087 static const char *name_runpath[] = { MSG_ORIG(MSG_CMD_RUNPATH),
1980d29b2c44Sab196087 MSG_ORIG(MSG_CMD_RUNPATH_A1), NULL };
1981d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_runpath[] = {
1982d29b2c44Sab196087 { MSG_ORIG(MSG_STR_NEWPATH),
1983d29b2c44Sab196087 /* MSG_INTL(MSG_A1_RUNPATH_NEWPATH) */
1984d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_RUNPATH_NEWPATH),
1985d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT },
1986d29b2c44Sab196087 { NULL }
1987d29b2c44Sab196087 };
1988d29b2c44Sab196087
1989d29b2c44Sab196087 /* dyn:posflag1 */
1990d29b2c44Sab196087 static const char *name_posflag1[] = { MSG_ORIG(MSG_CMD_POSFLAG1),
1991d29b2c44Sab196087 NULL };
199255ef6355Sab196087 static elfedit_cmd_optarg_t opt_posflag1[] = {
199355ef6355Sab196087 { ELFEDIT_STDOA_OPT_AND, NULL,
199455ef6355Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_AND, DYN_OPT_F_OR },
199555ef6355Sab196087 { ELFEDIT_STDOA_OPT_CMP, NULL,
199655ef6355Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_CMP, 0 },
199755ef6355Sab196087 { MSG_ORIG(MSG_STR_MINUS_DYNNDX),
199855ef6355Sab196087 /* MSG_INTL(MSG_OPTDESC_DYNNDX_VAL) */
199955ef6355Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_DYNNDX_VAL),
200055ef6355Sab196087 ELFEDIT_CMDOA_F_VALUE,
200155ef6355Sab196087 DYN_OPT_F_DYNNDX_VAL, DYN_OPT_F_NEEDED },
200255ef6355Sab196087 { MSG_ORIG(MSG_STR_INDEX), NULL, 0, 0 },
200355ef6355Sab196087 { MSG_ORIG(MSG_STR_MINUS_NEEDED),
200455ef6355Sab196087 /* MSG_INTL(MSG_OPTDESC_NEEDED) */
200555ef6355Sab196087 ELFEDIT_I18NHDL(MSG_OPTDESC_NEEDED),
200655ef6355Sab196087 ELFEDIT_CMDOA_F_VALUE,
200755ef6355Sab196087 DYN_OPT_F_NEEDED, DYN_OPT_F_DYNNDX_VAL },
200855ef6355Sab196087 { MSG_ORIG(MSG_STR_PREFIX), NULL, 0, 0 },
200955ef6355Sab196087 { ELFEDIT_STDOA_OPT_O, NULL,
201055ef6355Sab196087 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
201155ef6355Sab196087 { ELFEDIT_STDOA_OPT_OR, NULL,
201255ef6355Sab196087 ELFEDIT_CMDOA_F_INHERIT, DYN_OPT_F_OR, DYN_OPT_F_AND },
201355ef6355Sab196087 { NULL }
201455ef6355Sab196087 };
2015d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_posflag1[] = {
2016d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
2017d29b2c44Sab196087 /* MSG_INTL(MSG_A1_POSFLAG1_VALUE) */
2018d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_POSFLAG1_VALUE),
2019d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
2020d29b2c44Sab196087 { NULL }
2021d29b2c44Sab196087 };
2022d29b2c44Sab196087
2023d29b2c44Sab196087 /* dyn:flags */
2024d29b2c44Sab196087 static const char *name_flags[] = { MSG_ORIG(MSG_CMD_FLAGS), NULL };
2025d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_flags[] = {
2026d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
2027d29b2c44Sab196087 /* MSG_INTL(MSG_A1_FLAGS_VALUE) */
2028d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_FLAGS_VALUE),
2029d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
2030d29b2c44Sab196087 { NULL }
2031d29b2c44Sab196087 };
2032d29b2c44Sab196087
2033d29b2c44Sab196087 /* dyn:flags1 */
2034d29b2c44Sab196087 static const char *name_flags1[] = { MSG_ORIG(MSG_CMD_FLAGS1), NULL };
2035d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_flags1[] = {
2036d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
2037d29b2c44Sab196087 /* MSG_INTL(MSG_A1_FLAGS1_VALUE) */
2038d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_FLAGS1_VALUE),
2039d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
2040d29b2c44Sab196087 { NULL }
2041d29b2c44Sab196087 };
2042d29b2c44Sab196087
2043d29b2c44Sab196087 /* dyn:feature1 */
2044d29b2c44Sab196087 static const char *name_feature1[] = { MSG_ORIG(MSG_CMD_FEATURE1),
2045d29b2c44Sab196087 NULL };
2046d29b2c44Sab196087 static elfedit_cmd_optarg_t arg_feature1[] = {
2047d29b2c44Sab196087 { MSG_ORIG(MSG_STR_VALUE),
2048d29b2c44Sab196087 /* MSG_INTL(MSG_A1_FEATURE1_VALUE) */
2049d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_A1_FEATURE1_VALUE),
2050d29b2c44Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT },
2051d29b2c44Sab196087 { NULL }
2052d29b2c44Sab196087 };
2053d29b2c44Sab196087
2054d29b2c44Sab196087 /* dyn:checksum */
2055d29b2c44Sab196087 static const char *name_checksum[] = { MSG_ORIG(MSG_CMD_CHECKSUM),
2056d29b2c44Sab196087 NULL };
2057d29b2c44Sab196087
2058ba2be530Sab196087 /* dyn:sunw_ldmach */
2059ba2be530Sab196087 static const char *name_sunw_ldmach[] = { MSG_ORIG(MSG_CMD_SUNW_LDMACH),
2060ba2be530Sab196087 NULL };
2061ba2be530Sab196087 static elfedit_cmd_optarg_t arg_sunw_ldmach[] = {
2062ba2be530Sab196087 { MSG_ORIG(MSG_STR_VALUE),
2063ba2be530Sab196087 /* MSG_INTL(MSG_A1_SUNW_LDMACH_VALUE) */
2064ba2be530Sab196087 ELFEDIT_I18NHDL(MSG_A1_SUNW_LDMACH_VALUE),
2065ba2be530Sab196087 ELFEDIT_CMDOA_F_OPT },
2066ba2be530Sab196087 { NULL }
2067ba2be530Sab196087 };
2068ba2be530Sab196087
2069d29b2c44Sab196087
2070d29b2c44Sab196087
2071d29b2c44Sab196087 static elfedit_cmd_t cmds[] = {
2072d29b2c44Sab196087 /* dyn:dump */
2073d29b2c44Sab196087 { cmd_dump, cpl_eltarg, name_dump,
2074d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DUMP) */
2075d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DUMP),
2076d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DUMP) */
2077d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DUMP),
2078d29b2c44Sab196087 opt_minus_dynndx, arg_dump },
2079d29b2c44Sab196087
2080d29b2c44Sab196087 /* dyn:tag */
2081d29b2c44Sab196087 { cmd_tag, cpl_tag, name_tag,
2082d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_TAG) */
2083d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_TAG),
2084d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_TAG) */
2085d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_TAG),
2086d29b2c44Sab196087 opt_tag, arg_tag },
2087d29b2c44Sab196087
2088d29b2c44Sab196087 /* dyn:value */
2089d29b2c44Sab196087 { cmd_value, cpl_eltarg, name_value,
2090d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_VALUE) */
2091d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_VALUE),
2092d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_VALUE) */
2093d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_VALUE),
2094d29b2c44Sab196087 opt_value, arg_value },
2095d29b2c44Sab196087
2096d29b2c44Sab196087 /* dyn:delete */
2097d29b2c44Sab196087 { cmd_delete, cpl_eltarg, name_delete,
2098d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_DELETE) */
2099d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_DELETE),
2100d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_DELETE) */
2101d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_DELETE),
2102d29b2c44Sab196087 opt_minus_dynndx, arg_delete },
2103d29b2c44Sab196087
2104d29b2c44Sab196087 /* dyn:move */
2105d29b2c44Sab196087 { cmd_move, cpl_eltarg, name_move,
2106d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_MOVE) */
2107d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_MOVE),
2108d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_MOVE) */
2109d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_MOVE),
2110d29b2c44Sab196087 opt_minus_dynndx, arg_move },
2111d29b2c44Sab196087
2112d29b2c44Sab196087 /* dyn:runpath */
2113d29b2c44Sab196087 { cmd_runpath, NULL, name_runpath,
2114d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_RUNPATH) */
2115d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_RUNPATH),
2116d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_RUNPATH) */
2117d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_RUNPATH),
2118d29b2c44Sab196087 opt_ostyle, arg_runpath },
2119d29b2c44Sab196087
2120d29b2c44Sab196087 /* dyn:posflag1 */
2121d29b2c44Sab196087 { cmd_posflag1, cpl_posflag1, name_posflag1,
2122d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_POSFLAG1) */
2123d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_POSFLAG1),
2124d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_POSFLAG1) */
2125d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_POSFLAG1),
212655ef6355Sab196087 opt_posflag1, arg_posflag1 },
2127d29b2c44Sab196087
2128d29b2c44Sab196087 /* dyn:flags */
2129d29b2c44Sab196087 { cmd_flags, cpl_flags, name_flags,
2130d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_FLAGS) */
2131d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_FLAGS),
2132d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_FLAGS) */
2133d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_FLAGS),
2134d29b2c44Sab196087 opt_ostyle_bitop, arg_flags },
2135d29b2c44Sab196087
2136d29b2c44Sab196087 /* dyn:flags1 */
2137d29b2c44Sab196087 { cmd_flags1, cpl_flags1, name_flags1,
2138d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_FLAGS1) */
2139d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_FLAGS1),
2140d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_FLAGS1) */
2141d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_FLAGS1),
2142d29b2c44Sab196087 opt_ostyle_bitop, arg_flags1 },
2143d29b2c44Sab196087
2144d29b2c44Sab196087 /* dyn:feature1 */
2145d29b2c44Sab196087 { cmd_feature1, cpl_feature1, name_feature1,
2146d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_FEATURE1) */
2147d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_FEATURE1),
2148d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_FEATURE1) */
2149d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_FEATURE1),
2150d29b2c44Sab196087 opt_ostyle_bitop, arg_feature1 },
2151d29b2c44Sab196087
2152d29b2c44Sab196087 /* dyn:checksum */
2153d29b2c44Sab196087 { cmd_checksum, NULL, name_checksum,
2154d29b2c44Sab196087 /* MSG_INTL(MSG_DESC_CHECKSUM) */
2155d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_DESC_CHECKSUM),
2156d29b2c44Sab196087 /* MSG_INTL(MSG_HELP_CHECKSUM) */
2157d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_HELP_CHECKSUM),
2158d29b2c44Sab196087 NULL, NULL },
2159d29b2c44Sab196087
2160ba2be530Sab196087 /* dyn:sunw_ldmach */
2161ba2be530Sab196087 { cmd_sunw_ldmach, cpl_sunw_ldmach, name_sunw_ldmach,
2162ba2be530Sab196087 /* MSG_INTL(MSG_DESC_SUNW_LDMACH) */
2163ba2be530Sab196087 ELFEDIT_I18NHDL(MSG_DESC_SUNW_LDMACH),
2164ba2be530Sab196087 /* MSG_INTL(MSG_HELP_SUNW_LDMACH) */
2165ba2be530Sab196087 ELFEDIT_I18NHDL(MSG_HELP_SUNW_LDMACH),
2166ba2be530Sab196087 opt_ostyle, arg_sunw_ldmach },
2167ba2be530Sab196087
2168d29b2c44Sab196087 { NULL }
2169d29b2c44Sab196087 };
2170d29b2c44Sab196087
2171d29b2c44Sab196087 static elfedit_module_t module = {
2172d29b2c44Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
2173d29b2c44Sab196087 /* MSG_INTL(MSG_MOD_DESC) */
2174d29b2c44Sab196087 ELFEDIT_I18NHDL(MSG_MOD_DESC), cmds, mod_i18nhdl_to_str };
2175d29b2c44Sab196087
2176d29b2c44Sab196087 return (&module);
2177d29b2c44Sab196087 }
2178