1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdio.h>
28 #include <ctype.h>
29 #include <elfedit.h>
30 #include <sys/elf_SPARC.h>
31 #include <sys/elf_amd64.h>
32 #include <strings.h>
33 #include <conv.h>
34 #include <debug.h>
35 #include <ehdr_msg.h>
36
37
38
39
40 /*
41 * This module handles changes to the ELF header
42 */
43
44
45
46 /*
47 * This module uses shared code for several of the commands.
48 * It is sometimes necessary to know which specific command
49 * is active.
50 */
51 typedef enum {
52 /* Dump command, used as module default to display ELF header */
53 EHDR_CMD_T_DUMP = 0, /* ehdr:dump */
54
55 /* Commands that correspond directly to ELF header fields */
56 EHDR_CMD_T_E_IDENT = 1, /* ehdr:e_ident */
57 EHDR_CMD_T_E_TYPE = 2, /* ehdr:e_type */
58 EHDR_CMD_T_E_MACHINE = 3, /* ehdr:e_machine */
59 EHDR_CMD_T_E_VERSION = 4, /* ehdr:e_version */
60 EHDR_CMD_T_E_ENTRY = 5, /* ehdr:e_entry */
61 EHDR_CMD_T_E_PHOFF = 6, /* ehdr:e_phoff */
62 EHDR_CMD_T_E_SHOFF = 7, /* ehdr:e_shoff */
63 EHDR_CMD_T_E_FLAGS = 8, /* ehdr:e_flags */
64 EHDR_CMD_T_E_EHSIZE = 9, /* ehdr:e_ehsize */
65 EHDR_CMD_T_E_PHENTSIZE = 10, /* ehdr:e_phentsize */
66 EHDR_CMD_T_E_PHNUM = 11, /* ehdr:e_phnum */
67 EHDR_CMD_T_E_SHENTSIZE = 12, /* ehdr:e_shentsize */
68 EHDR_CMD_T_E_SHNUM = 13, /* ehdr:e_shnum */
69 EHDR_CMD_T_E_SHSTRNDX = 14, /* ehdr:e_shstrndx */
70
71 /* Commands that correspond to the e_ident[] array in ELF hdr */
72 EHDR_CMD_T_EI_MAG0 = 15, /* ehdr:ei_mag0 */
73 EHDR_CMD_T_EI_MAG1 = 16, /* ehdr:ei_mag1 */
74 EHDR_CMD_T_EI_MAG2 = 17, /* ehdr:ei_mag2 */
75 EHDR_CMD_T_EI_MAG3 = 18, /* ehdr:ei_mag3 */
76 EHDR_CMD_T_EI_CLASS = 19, /* ehdr:ei_class */
77 EHDR_CMD_T_EI_DATA = 20, /* ehdr:ei_data */
78 EHDR_CMD_T_EI_VERSION = 21, /* ehdr:ei_version */
79 EHDR_CMD_T_EI_OSABI = 22, /* ehdr:ei_osabi */
80 EHDR_CMD_T_EI_ABIVERSION = 23 /* ehdr:ei_abiversion */
81 } EHDR_CMD_T;
82
83
84
85
86
87
88 #ifndef _ELF64
89 /*
90 * We supply this function for the msg module
91 */
92 const char *
_ehdr_msg(Msg mid)93 _ehdr_msg(Msg mid)
94 {
95 return (gettext(MSG_ORIG(mid)));
96 }
97 #endif
98
99
100 /*
101 * This function is supplied to elfedit through our elfedit_module_t
102 * definition. It translates the opaque elfedit_i18nhdl_t handles
103 * in our module interface into the actual strings for elfedit to
104 * use.
105 *
106 * note:
107 * This module uses Msg codes for its i18n handle type.
108 * So the translation is simply to use MSG_INTL() to turn
109 * it into a string and return it.
110 */
111 static const char *
mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)112 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl)
113 {
114 Msg msg = (Msg)hdl;
115
116 return (MSG_INTL(msg));
117 }
118
119
120
121 /*
122 * The ehdr_opt_t enum specifies a bit value for every optional
123 * argument allowed by a command in this module.
124 */
125 typedef enum {
126 EHDR_OPT_F_AND = 1, /* -and: AND (&) values to dest */
127 EHDR_OPT_F_CMP = 2, /* -cmp: Complement (~) values */
128 EHDR_OPT_F_OR = 4, /* -or: OR (|) values to dest */
129 EHDR_OPT_F_SHNDX = 8, /* -shndx: sec argument is index of */
130 /* section, not name */
131 EHDR_OPT_F_SHTYP = 16 /* -shtyp: sec argument is type of */
132 /* section, not name */
133 } ehdr_opt_t;
134
135
136 /*
137 * A variable of type ARGSTATE is used by each command to maintain
138 * information about the arguments and related things. It is
139 * initialized by process_args(), and used by the other routines.
140 */
141 typedef struct {
142 elfedit_obj_state_t *obj_state;
143 ehdr_opt_t optmask; /* Mask of options used */
144 int argc; /* # of plain arguments */
145 const char **argv; /* Plain arguments */
146 } ARGSTATE;
147
148
149
150 /*
151 * Standard argument processing for ehdr module
152 *
153 * entry
154 * obj_state, argc, argv - Standard command arguments
155 * argstate - Address of ARGSTATE block to be initialized
156 *
157 * exit:
158 * On success, *argstate is initialized. On error,
159 * an error is issued and this routine does not return.
160 */
161 static void
process_args(elfedit_obj_state_t * obj_state,int argc,const char * argv[],ARGSTATE * argstate)162 process_args(elfedit_obj_state_t *obj_state, int argc, const char *argv[],
163 ARGSTATE *argstate)
164 {
165 elfedit_getopt_state_t getopt_state;
166 elfedit_getopt_ret_t *getopt_ret;
167
168 bzero(argstate, sizeof (*argstate));
169 argstate->obj_state = obj_state;
170
171 elfedit_getopt_init(&getopt_state, &argc, &argv);
172 /* Add each new option to the options mask */
173 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL)
174 argstate->optmask |= getopt_ret->gor_idmask;
175
176 /* If there may be an arbitrary amount of output, use a pager */
177 if (argc == 0)
178 elfedit_pager_init();
179
180 /* Return the updated values of argc/argv */
181 argstate->argc = argc;
182 argstate->argv = argv;
183 }
184
185
186
187
188
189
190 /*
191 * Format the given magic number byte into a buffer
192 *
193 * entry:
194 * value - Value of the magic value byte given by
195 * ehdr->ei_ident[EI_MAG?]
196 */
197 static const char *
conv_magic_value(int value)198 conv_magic_value(int value)
199 {
200 /*
201 * This routine can be called twice within a single C statement,
202 * so we use alternating buffers on each call to allow this
203 * without requiring the caller to supply a buffer (the size of
204 * which they don't know).
205 */
206 static char buf1[20];
207 static char buf2[20];
208 static char *buf;
209
210 /* Switch buffers */
211 buf = (buf == buf1) ? buf2 : buf1;
212
213 if (isprint(value))
214 (void) snprintf(buf, sizeof (buf1),
215 MSG_ORIG(MSG_FMT_HEXNUM_QCHR), value, value);
216 else
217 (void) snprintf(buf, sizeof (buf1),
218 MSG_ORIG(MSG_FMT_HEXNUM), value);
219 return (buf);
220 }
221
222
223
224 /*
225 * Print ELF header values, taking the calling command, and output style
226 * into account.
227 *
228 * entry:
229 * cmd - EHDR_CMD_T_* value giving identify of caller
230 * e_ident_ndx - Ignored unless cmd is EHDR_CMD_T_E_IDENT. In IDENT
231 * case, index of item in e_ident[] array to display, or
232 * -1 to display the entire array.
233 * autoprint - If True, output is only produced if the elfedit
234 * autoprint flag is set. If False, output is always produced.
235 * argstate - Argument state block
236 */
237 static void
print_ehdr(EHDR_CMD_T cmd,int e_ident_ndx,int autoprint,ARGSTATE * argstate)238 print_ehdr(EHDR_CMD_T cmd, int e_ident_ndx, int autoprint,
239 ARGSTATE *argstate)
240 {
241 elfedit_outstyle_t outstyle;
242 Conv_fmt_flags_t flags_fmt_flags = 0;
243 Ehdr *ehdr;
244 int c;
245 Conv_inv_buf_t inv_buf;
246
247 if (autoprint && ((elfedit_flags() & ELFEDIT_F_AUTOPRINT) == 0))
248 return;
249
250 /*
251 * Pick an output style. ehdr:dump is required to use the default
252 * style. The other commands use the current output style.
253 */
254 if (cmd == EHDR_CMD_T_DUMP) {
255 outstyle = ELFEDIT_OUTSTYLE_DEFAULT;
256 } else {
257 outstyle = elfedit_outstyle();
258
259 /*
260 * When the caller specifies the simple output style,
261 * omit the brackets from around the values.
262 */
263 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
264 flags_fmt_flags = CONV_FMT_NOBKT;
265
266 /*
267 * For things that show a single header item, switch
268 * from default to simple mode.
269 */
270 if ((outstyle == ELFEDIT_OUTSTYLE_DEFAULT) &&
271 ((cmd != EHDR_CMD_T_E_IDENT) || (e_ident_ndx != -1)))
272 outstyle = ELFEDIT_OUTSTYLE_SIMPLE;
273 }
274
275 ehdr = argstate->obj_state->os_ehdr;
276
277 /*
278 * If doing default output, use elfdump style where we
279 * show the full ELF header. In this case, the command
280 * that called us doesn't matter. This can only happen
281 * from ehdr:dump or ehdr:e_ident/
282 */
283 if (outstyle == ELFEDIT_OUTSTYLE_DEFAULT) {
284 const char *ndx, *value;
285 char ndx_buf[64], value_buf[20];
286 int i;
287
288 if (cmd == EHDR_CMD_T_DUMP) {
289 Elf_ehdr(NULL, ehdr,
290 argstate->obj_state->os_secarr[0].sec_shdr);
291 elfedit_printf(MSG_ORIG(MSG_STR_NL));
292 }
293
294 /*
295 * Elf_ehdr() does not display all of e_ident[], so we
296 * augment by displaying the entire array separately.
297 */
298 elfedit_printf(MSG_ORIG(MSG_STR_EIDENT_HDR));
299
300 for (i = 0; i < EI_NIDENT; i++) {
301 ndx = value = NULL;
302
303 switch (i) {
304 case EI_MAG0:
305 case EI_MAG1:
306 case EI_MAG2:
307 case EI_MAG3:
308 ndx = elfedit_atoconst_value_to_str(
309 ELFEDIT_CONST_EI, i, 1);
310 value = conv_magic_value(ehdr->e_ident[i]);
311 break;
312 case EI_CLASS:
313 ndx = elfedit_atoconst_value_to_str(
314 ELFEDIT_CONST_EI, EI_CLASS, 1);
315 value = conv_ehdr_class(ehdr->e_ident[EI_CLASS],
316 0, &inv_buf);
317 break;
318 case EI_DATA:
319 ndx = elfedit_atoconst_value_to_str(
320 ELFEDIT_CONST_EI, EI_DATA, 1);
321 value = conv_ehdr_data(ehdr->e_ident[EI_DATA],
322 0, &inv_buf);
323 break;
324 case EI_VERSION:
325 ndx = elfedit_atoconst_value_to_str(
326 ELFEDIT_CONST_EI, EI_VERSION, 1);
327 value = conv_ehdr_vers(
328 ehdr->e_ident[EI_VERSION], 0, &inv_buf);
329 break;
330 case EI_OSABI:
331 ndx = elfedit_atoconst_value_to_str(
332 ELFEDIT_CONST_EI, EI_OSABI, 1);
333 value = conv_ehdr_osabi(ehdr->e_ident[EI_OSABI],
334 0, &inv_buf);
335 break;
336 case EI_ABIVERSION:
337 ndx = elfedit_atoconst_value_to_str(
338 ELFEDIT_CONST_EI, EI_ABIVERSION, 1);
339 value = conv_ehdr_abivers(
340 ehdr->e_ident[EI_OSABI],
341 ehdr->e_ident[EI_ABIVERSION],
342 CONV_FMT_DECIMAL, &inv_buf);
343 break;
344 default:
345 value = value_buf;
346 (void) snprintf(value_buf, sizeof (value_buf),
347 MSG_ORIG(MSG_FMT_HEXNUM), ehdr->e_ident[i]);
348 break;
349 }
350
351 if (ndx == NULL)
352 (void) snprintf(ndx_buf, sizeof (ndx_buf),
353 MSG_ORIG(MSG_FMT_BKTINT), i);
354 else
355 (void) snprintf(ndx_buf, sizeof (ndx_buf),
356 MSG_ORIG(MSG_FMT_BKTSTR), ndx);
357 elfedit_printf(MSG_ORIG(MSG_FMT_EI_ELT),
358 ndx_buf, value);
359 }
360 return;
361 }
362
363
364 switch (cmd) {
365 case EHDR_CMD_T_E_IDENT:
366 {
367 int i, cnt;
368
369 /* Show one element, or the entire thing? */
370 if (e_ident_ndx == -1) {
371 i = 0;
372 cnt = EI_NIDENT;
373 } else {
374 i = e_ident_ndx;
375 cnt = 1;
376 }
377
378 for (; cnt-- > 0; i++) {
379 /*
380 * If using numeric style, or there is
381 * no conversion routine for this item,
382 * print a simple hex value.
383 */
384 if ((outstyle == ELFEDIT_OUTSTYLE_NUM) ||
385 (i > EI_ABIVERSION)) {
386 elfedit_printf(
387 MSG_ORIG(MSG_FMT_HEXNUMNL),
388 ehdr->e_ident[i]);
389 continue;
390 }
391
392 /* Handle special cases in simple mode */
393 switch (i) {
394 case EI_MAG0:
395 case EI_MAG1:
396 case EI_MAG2:
397 case EI_MAG3:
398 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
399 conv_magic_value(ehdr->e_ident[i]));
400 continue;
401 case EI_CLASS:
402 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
403 conv_ehdr_class(
404 ehdr->e_ident[EI_CLASS], 0,
405 &inv_buf));
406 continue;
407 case EI_DATA:
408 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
409 conv_ehdr_data(
410 ehdr->e_ident[EI_DATA], 0,
411 &inv_buf));
412 continue;
413 case EI_VERSION:
414 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
415 conv_ehdr_vers(
416 ehdr->e_ident[EI_VERSION], 0,
417 &inv_buf));
418 continue;
419 case EI_OSABI:
420 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
421 conv_ehdr_osabi(
422 ehdr->e_ident[EI_OSABI], 0,
423 &inv_buf));
424 continue;
425 case EI_ABIVERSION:
426 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
427 conv_ehdr_abivers(
428 ehdr->e_ident[EI_OSABI],
429 ehdr->e_ident[EI_ABIVERSION],
430 CONV_FMT_DECIMAL, &inv_buf));
431 continue;
432 }
433 }
434 }
435 return;
436
437 case EHDR_CMD_T_E_TYPE:
438 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
439 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
440 conv_ehdr_type(ehdr->e_ident[EI_OSABI],
441 ehdr->e_type, 0, &inv_buf));
442 else
443 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
444 ehdr->e_type);
445 return;
446
447 case EHDR_CMD_T_E_MACHINE:
448 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
449 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
450 conv_ehdr_mach(ehdr->e_machine, 0, &inv_buf));
451 } else {
452 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
453 EC_WORD(ehdr->e_machine));
454 }
455 return;
456
457 case EHDR_CMD_T_E_VERSION:
458 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
459 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
460 conv_ehdr_vers(ehdr->e_version, 0, &inv_buf));
461 else
462 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
463 ehdr->e_version);
464 return;
465
466 case EHDR_CMD_T_E_ENTRY:
467 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
468 EC_WORD(ehdr->e_entry));
469 return;
470
471 case EHDR_CMD_T_E_PHOFF:
472 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
473 EC_WORD(ehdr->e_phoff));
474 return;
475
476 case EHDR_CMD_T_E_SHOFF:
477 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
478 EC_WORD(ehdr->e_shoff));
479 return;
480
481 case EHDR_CMD_T_E_FLAGS:
482 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
483 Conv_ehdr_flags_buf_t flags_buf;
484
485 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
486 conv_ehdr_flags(ehdr->e_machine, ehdr->e_flags,
487 flags_fmt_flags, &flags_buf));
488 } else {
489 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
490 ehdr->e_flags);
491 }
492 return;
493
494 case EHDR_CMD_T_E_EHSIZE:
495 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
496 EC_WORD(ehdr->e_ehsize));
497 return;
498
499 case EHDR_CMD_T_E_PHENTSIZE:
500 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
501 EC_WORD(ehdr->e_phentsize));
502 return;
503
504 case EHDR_CMD_T_E_PHNUM:
505 {
506 Word num = ehdr->e_phnum;
507
508 /*
509 * If using extended indexes, fetch the real
510 * value from shdr[0].sh_info
511 */
512 if (num == PN_XNUM)
513 num = argstate->obj_state->
514 os_secarr[0].sec_shdr->sh_info;
515
516 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
517 EC_WORD(num));
518 }
519 return;
520
521 case EHDR_CMD_T_E_SHENTSIZE:
522 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
523 EC_WORD(ehdr->e_shentsize));
524 return;
525
526 case EHDR_CMD_T_E_SHNUM:
527 {
528 Word num = ehdr->e_shnum;
529
530 /*
531 * If using extended indexes, fetch the real
532 * value from shdr[0].sh_size
533 */
534 if (num == 0)
535 num = argstate->obj_state->
536 os_secarr[0].sec_shdr->sh_size;
537
538 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
539 EC_WORD(num));
540 }
541 return;
542
543 case EHDR_CMD_T_E_SHSTRNDX:
544 {
545 Word num = ehdr->e_shstrndx;
546
547 /*
548 * If using extended indexes, fetch the real
549 * value from shdr[0].sh_link
550 */
551 if (num == SHN_XINDEX)
552 num = argstate->obj_state->
553 os_secarr[0].sec_shdr->sh_link;
554
555 elfedit_printf(MSG_ORIG(MSG_FMT_DECNUMNL),
556 EC_WORD(num));
557 }
558 return;
559
560 case EHDR_CMD_T_EI_MAG0:
561 case EHDR_CMD_T_EI_MAG1:
562 case EHDR_CMD_T_EI_MAG2:
563 case EHDR_CMD_T_EI_MAG3:
564 /* This depends on EHDR_CMD_T_EI_MAG[0-3] being contiguous */
565 c = ehdr->e_ident[cmd - EHDR_CMD_T_EI_MAG0];
566 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
567 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
568 conv_magic_value(c));
569 else
570 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
571 return;
572
573 case EHDR_CMD_T_EI_CLASS:
574 c = ehdr->e_ident[EI_CLASS];
575 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
576 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
577 conv_ehdr_class(c, 0, &inv_buf));
578 else
579 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
580 return;
581
582 case EHDR_CMD_T_EI_DATA:
583 c = ehdr->e_ident[EI_DATA];
584 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
585 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
586 conv_ehdr_data(c, 0, &inv_buf));
587 else
588 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
589 return;
590
591 case EHDR_CMD_T_EI_VERSION:
592 c = ehdr->e_ident[EI_VERSION];
593 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE)
594 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
595 conv_ehdr_vers(c, 0, &inv_buf));
596 else
597 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL), c);
598 return;
599
600 case EHDR_CMD_T_EI_OSABI:
601 c = ehdr->e_ident[EI_OSABI];
602 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
603 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
604 conv_ehdr_osabi(c, 0, &inv_buf));
605 } else {
606 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
607 EC_WORD(c));
608 }
609 return;
610
611 case EHDR_CMD_T_EI_ABIVERSION:
612 c = ehdr->e_ident[EI_ABIVERSION];
613 if (outstyle == ELFEDIT_OUTSTYLE_SIMPLE) {
614 elfedit_printf(MSG_ORIG(MSG_FMT_STRNL),
615 conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
616 c, CONV_FMT_DECIMAL, &inv_buf));
617 } else {
618 elfedit_printf(MSG_ORIG(MSG_FMT_HEXNUMNL),
619 EC_WORD(c));
620 }
621 return;
622 }
623 }
624
625
626 /*
627 * Common body for the ehdr: module commands. These commands
628 * share a large amount of common behavior, so it is convenient
629 * to centralize things and use the cmd argument to handle the
630 * small differences.
631 *
632 * entry:
633 * cmd - One of the EHDR_CMD_T_* constants listed above, specifying
634 * which command to implement.
635 * obj_state, argc, argv - Standard command arguments
636 */
637 static elfedit_cmdret_t
cmd_body(EHDR_CMD_T cmd,elfedit_obj_state_t * obj_state,int argc,const char * argv[])638 cmd_body(EHDR_CMD_T cmd, elfedit_obj_state_t *obj_state,
639 int argc, const char *argv[])
640 {
641 /*
642 * When a call comes in for ehdr:e_ident[ndx], and the
643 * specified element is one that we have a special command
644 * for, then we revector to that special command instead
645 * of using the generic ehdr:e_ident processing. This array,
646 * which is indexed by the e_ident[] index value is used
647 * to decide if that is the case. If the resulting value
648 * is EHDR_CMD_T_E_IDENT, then the generic processing is
649 * used. Otherwise, we revector to the specified command.
650 */
651 static const int e_ident_revector[16] = {
652 EHDR_CMD_T_EI_MAG0, /* 0: EI_MAG0 */
653 EHDR_CMD_T_EI_MAG1, /* 1: EI_MAG1 */
654 EHDR_CMD_T_EI_MAG2, /* 2: EI_MAG2 */
655 EHDR_CMD_T_EI_MAG3, /* 3: EI_MAG3 */
656 EHDR_CMD_T_EI_CLASS, /* 4: EI_CLASS */
657 EHDR_CMD_T_EI_DATA, /* 5: EI_DATA */
658 EHDR_CMD_T_EI_VERSION, /* 6: EI_VERSION */
659 EHDR_CMD_T_EI_OSABI, /* 7: EI_OSABI */
660 EHDR_CMD_T_EI_ABIVERSION, /* 8: EI_ABIVERSION */
661 EHDR_CMD_T_E_IDENT, /* 9: generic */
662 EHDR_CMD_T_E_IDENT, /* 10: generic */
663 EHDR_CMD_T_E_IDENT, /* 11: generic */
664 EHDR_CMD_T_E_IDENT, /* 12: generic */
665 EHDR_CMD_T_E_IDENT, /* 13: generic */
666 EHDR_CMD_T_E_IDENT, /* 14: generic */
667 EHDR_CMD_T_E_IDENT, /* 15: generic */
668 };
669
670
671 ARGSTATE argstate;
672 Ehdr *ehdr;
673 elfedit_cmdret_t ret = ELFEDIT_CMDRET_NONE;
674 int e_ident_ndx = -1;
675 Conv_inv_buf_t inv_buf1, inv_buf2;
676
677 /* Process the optional arguments */
678 process_args(obj_state, argc, argv, &argstate);
679
680 /* Check number of arguments */
681 switch (cmd) {
682 case EHDR_CMD_T_DUMP:
683 /* ehdr:dump does not accept arguments */
684 if (argstate.argc > 0)
685 elfedit_command_usage();
686 break;
687 case EHDR_CMD_T_E_IDENT:
688 /*
689 * ehdr:e_ident accepts 1 or 2 arguments, the first
690 * being the index into the array, and the second being
691 * the value. If there are arguments, then process the
692 * index, and remove it from the argument list.
693 */
694 if (argstate.argc > 0) {
695 if (argstate.argc > 2)
696 elfedit_command_usage();
697 e_ident_ndx = (int)
698 elfedit_atoconst_range(argstate.argv[0],
699 MSG_ORIG(MSG_STR_INDEX), 0, EI_NIDENT - 1,
700 ELFEDIT_CONST_EI);
701 argstate.argc--;
702 argstate.argv++;
703
704 /*
705 * If the index is for one of the e_ident elements
706 * that we have a special command for, then switch
707 * to that command. e_ident_revector[] returns
708 * EHDR_CMD_T_E_IDENT in the cases where such a command
709 * does not exist, in which case we'll continue with the
710 * generic code.
711 */
712 cmd = e_ident_revector[e_ident_ndx];
713 }
714 break;
715 case EHDR_CMD_T_E_FLAGS:
716 /* ehdr:e_flags accepts an arbitrary number of arguments */
717 break;
718 default:
719 /* The remaining commands accept a single optional argument */
720 if (argstate.argc > 1)
721 elfedit_command_usage();
722 break;
723 }
724
725 /* If there are no arguments, dump the ELF header and return */
726 if (argstate.argc == 0) {
727 print_ehdr(cmd, e_ident_ndx, 0, &argstate);
728 return (ELFEDIT_CMDRET_NONE);
729 }
730
731 ehdr = obj_state->os_ehdr;
732 switch (cmd) {
733 /*
734 * EHDR_CMD_T_DUMP can't get here: It never has an
735 * argument, and is handled above.
736 */
737
738 case EHDR_CMD_T_E_IDENT:
739 {
740 /*
741 * Only those e_ident[] elements for which we
742 * don't have a specialized command come here.
743 * The argument is a value to be set in
744 * e_ident[e_ident_ndx].
745 */
746 uchar_t value = (uchar_t)
747 elfedit_atoui_range(argstate.argv[0],
748 MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL);
749
750 if (ehdr->e_ident[e_ident_ndx] == value) {
751 elfedit_msg(ELFEDIT_MSG_DEBUG,
752 MSG_INTL(MSG_DEBUG_EI_D_X_OK),
753 e_ident_ndx, EC_WORD(value));
754 } else {
755 elfedit_msg(ELFEDIT_MSG_DEBUG,
756 MSG_INTL(MSG_DEBUG_EI_D_X_CHG),
757 e_ident_ndx, ehdr->e_ident[e_ident_ndx],
758 value);
759 ret = ELFEDIT_CMDRET_MOD;
760 ehdr->e_ident[e_ident_ndx] = value;
761 }
762 }
763 break;
764
765 case EHDR_CMD_T_E_TYPE:
766 {
767 /* The argument gives the object type */
768 Half type = (Half) elfedit_atoconst(argstate.argv[0],
769 ELFEDIT_CONST_ET);
770 const char *name = MSG_ORIG(MSG_CMD_E_TYPE);
771
772 if (ehdr->e_type == type) {
773 elfedit_msg(ELFEDIT_MSG_DEBUG,
774 MSG_INTL(MSG_DEBUG_E_S_OK), name,
775 conv_ehdr_type(ehdr->e_ident[EI_OSABI],
776 ehdr->e_type, 0, &inv_buf1));
777 } else {
778 elfedit_msg(ELFEDIT_MSG_DEBUG,
779 MSG_INTL(MSG_DEBUG_E_S_CHG), name,
780 conv_ehdr_type(ehdr->e_ident[EI_OSABI],
781 ehdr->e_type, 0, &inv_buf1),
782 conv_ehdr_type(ehdr->e_ident[EI_OSABI],
783 type, 0, &inv_buf2));
784 ret = ELFEDIT_CMDRET_MOD;
785 ehdr->e_type = type;
786 }
787 }
788 break;
789
790 case EHDR_CMD_T_E_MACHINE:
791 {
792 /* The argument gives the machine code */
793 Half mach = (Half) elfedit_atoconst(argstate.argv[0],
794 ELFEDIT_CONST_EM);
795 const char *name = MSG_ORIG(MSG_CMD_E_MACHINE);
796
797 if (ehdr->e_machine == mach) {
798 elfedit_msg(ELFEDIT_MSG_DEBUG,
799 MSG_INTL(MSG_DEBUG_E_S_OK), name,
800 conv_ehdr_mach(ehdr->e_machine, 0,
801 &inv_buf1));
802 } else {
803 elfedit_msg(ELFEDIT_MSG_DEBUG,
804 MSG_INTL(MSG_DEBUG_E_S_CHG), name,
805 conv_ehdr_mach(ehdr->e_machine, 0,
806 &inv_buf1),
807 conv_ehdr_mach(mach, 0, &inv_buf2));
808 ret = ELFEDIT_CMDRET_MOD_OS_MACH;
809 ehdr->e_machine = mach;
810
811 }
812 }
813 break;
814
815 case EHDR_CMD_T_E_VERSION:
816 {
817 /* The argument gives the version */
818 Word ver = (Word) elfedit_atoconst(argstate.argv[0],
819 ELFEDIT_CONST_EV);
820 const char *name = MSG_ORIG(MSG_CMD_E_VERSION);
821
822 if (ehdr->e_version == ver) {
823 elfedit_msg(ELFEDIT_MSG_DEBUG,
824 MSG_INTL(MSG_DEBUG_E_S_OK), name,
825 conv_ehdr_vers(ehdr->e_version, 0,
826 &inv_buf1));
827 } else {
828 elfedit_msg(ELFEDIT_MSG_DEBUG,
829 MSG_INTL(MSG_DEBUG_E_S_CHG), name,
830 conv_ehdr_vers(ehdr->e_version, 0,
831 &inv_buf1),
832 conv_ehdr_vers(ver, 0, &inv_buf2));
833 ret = ELFEDIT_CMDRET_MOD;
834 ehdr->e_version = ver;
835 }
836 }
837 break;
838
839 case EHDR_CMD_T_E_ENTRY:
840 {
841 /* The argument gives the entry address */
842 Addr entry = (Addr)
843 elfedit_atoui(argstate.argv[0], NULL);
844 const char *name = MSG_ORIG(MSG_CMD_E_ENTRY);
845
846 if (ehdr->e_entry == entry) {
847 elfedit_msg(ELFEDIT_MSG_DEBUG,
848 MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
849 EC_ADDR(ehdr->e_entry));
850 } else {
851 elfedit_msg(ELFEDIT_MSG_DEBUG,
852 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
853 EC_ADDR(ehdr->e_entry), EC_ADDR(entry));
854 ret = ELFEDIT_CMDRET_MOD;
855 ehdr->e_entry = entry;
856 }
857 }
858 break;
859
860 case EHDR_CMD_T_E_PHOFF:
861 {
862 /* The argument gives the program header offset */
863 Off off = (Off) elfedit_atoui(argstate.argv[0],
864 NULL);
865 const char *name = MSG_ORIG(MSG_CMD_E_PHOFF);
866
867 if (ehdr->e_phoff == off) {
868 elfedit_msg(ELFEDIT_MSG_DEBUG,
869 MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
870 EC_OFF(ehdr->e_phoff));
871 } else {
872 elfedit_msg(ELFEDIT_MSG_DEBUG,
873 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
874 EC_OFF(ehdr->e_phoff), EC_OFF(off));
875 ret = ELFEDIT_CMDRET_MOD;
876 ehdr->e_phoff = off;
877 }
878 }
879 break;
880
881 case EHDR_CMD_T_E_SHOFF:
882 {
883 /* The argument gives the section header offset */
884 Off off = (Off) elfedit_atoui(argstate.argv[0],
885 NULL);
886 const char *name = MSG_ORIG(MSG_CMD_E_SHOFF);
887
888 if (ehdr->e_shoff == off) {
889 elfedit_msg(ELFEDIT_MSG_DEBUG,
890 MSG_INTL(MSG_DEBUG_E_LLX_OK), name,
891 EC_OFF(ehdr->e_shoff));
892 } else {
893 elfedit_msg(ELFEDIT_MSG_DEBUG,
894 MSG_INTL(MSG_DEBUG_E_LLX_CHG), name,
895 EC_OFF(ehdr->e_shoff), EC_OFF(off));
896 ret = ELFEDIT_CMDRET_MOD;
897 ehdr->e_shoff = off;
898 }
899 }
900 break;
901
902 case EHDR_CMD_T_E_FLAGS:
903 {
904 Conv_ehdr_flags_buf_t flags_buf1, flags_buf2;
905 const char *name = MSG_ORIG(MSG_CMD_E_FLAGS);
906 Word flags = 0;
907 int i;
908
909 /* Collect the arguments */
910 for (i = 0; i < argstate.argc; i++)
911 flags |= (Word)
912 elfedit_atoconst(argstate.argv[i],
913 ELFEDIT_CONST_EF);
914
915 /* Complement the value? */
916 if (argstate.optmask & EHDR_OPT_F_CMP)
917 flags = ~flags;
918
919 /* Perform any requested bit operations */
920 if (argstate.optmask & EHDR_OPT_F_AND)
921 flags &= ehdr->e_flags;
922 else if (argstate.optmask & EHDR_OPT_F_OR)
923 flags |= ehdr->e_flags;
924
925 /* Set the value */
926 if (ehdr->e_flags == flags) {
927 elfedit_msg(ELFEDIT_MSG_DEBUG,
928 MSG_INTL(MSG_DEBUG_E_S_OK), name,
929 conv_ehdr_flags(ehdr->e_machine,
930 ehdr->e_flags, 0, &flags_buf1));
931 } else {
932 elfedit_msg(ELFEDIT_MSG_DEBUG,
933 MSG_INTL(MSG_DEBUG_E_S_CHG), name,
934 conv_ehdr_flags(ehdr->e_machine,
935 ehdr->e_flags, 0, &flags_buf1),
936 conv_ehdr_flags(ehdr->e_machine,
937 flags, 0, &flags_buf2));
938 ret = ELFEDIT_CMDRET_MOD;
939 ehdr->e_flags = flags;
940 }
941 }
942 break;
943
944 case EHDR_CMD_T_E_EHSIZE:
945 {
946 /* The argument gives the ELF header size */
947 Half ehsize = (Half) elfedit_atoui(argstate.argv[0],
948 NULL);
949 const char *name = MSG_ORIG(MSG_CMD_E_EHSIZE);
950
951 if (ehdr->e_ehsize == ehsize) {
952 elfedit_msg(ELFEDIT_MSG_DEBUG,
953 MSG_INTL(MSG_DEBUG_E_D_OK), name,
954 EC_WORD(ehdr->e_ehsize));
955 } else {
956 elfedit_msg(ELFEDIT_MSG_DEBUG,
957 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
958 EC_WORD(ehdr->e_ehsize), EC_WORD(ehsize));
959 ret = ELFEDIT_CMDRET_MOD;
960 ehdr->e_ehsize = ehsize;
961 }
962 }
963 break;
964
965 case EHDR_CMD_T_E_PHENTSIZE:
966 {
967 /*
968 * The argument gives the size of a program
969 * header element.
970 */
971 Half phentsize = (Half) elfedit_atoui(argstate.argv[0],
972 NULL);
973 const char *name = MSG_ORIG(MSG_CMD_E_PHENTSIZE);
974
975 if (ehdr->e_phentsize == phentsize) {
976 elfedit_msg(ELFEDIT_MSG_DEBUG,
977 MSG_INTL(MSG_DEBUG_E_D_OK), name,
978 EC_WORD(ehdr->e_phentsize));
979 } else {
980 elfedit_msg(ELFEDIT_MSG_DEBUG,
981 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
982 EC_WORD(ehdr->e_phentsize),
983 EC_WORD(phentsize));
984 ret = ELFEDIT_CMDRET_MOD;
985 ehdr->e_phentsize = phentsize;
986 }
987 }
988 break;
989
990 case EHDR_CMD_T_E_PHNUM:
991 {
992 /* The argument gives the number of program headers */
993 Word phnum = (Word) elfedit_atoui(argstate.argv[0],
994 NULL);
995 const char *name = MSG_ORIG(MSG_CMD_E_PHNUM);
996 elfedit_section_t *sec0 = &obj_state->os_secarr[0];
997 Shdr *shdr0 = sec0->sec_shdr;
998 Half e_phnum;
999 Word sh_info;
1000
1001 if (phnum >= PN_XNUM) {
1002 e_phnum = PN_XNUM;
1003 sh_info = phnum;
1004 } else {
1005 e_phnum = phnum;
1006 sh_info = 0;
1007 }
1008
1009 if (ehdr->e_phnum == e_phnum) {
1010 elfedit_msg(ELFEDIT_MSG_DEBUG,
1011 MSG_INTL(MSG_DEBUG_E_D_OK), name,
1012 EC_WORD(ehdr->e_phnum));
1013 } else {
1014 elfedit_msg(ELFEDIT_MSG_DEBUG,
1015 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
1016 EC_WORD(ehdr->e_phnum), e_phnum);
1017 ret = ELFEDIT_CMDRET_MOD;
1018 ehdr->e_phnum = e_phnum;
1019 }
1020 if (shdr0->sh_info == sh_info) {
1021 elfedit_msg(ELFEDIT_MSG_DEBUG,
1022 MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
1023 MSG_ORIG(MSG_STR_SH_INFO),
1024 EC_WORD(shdr0->sh_info));
1025 } else {
1026 elfedit_msg(ELFEDIT_MSG_DEBUG,
1027 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
1028 MSG_ORIG(MSG_STR_SH_INFO),
1029 EC_WORD(shdr0->sh_info), sh_info);
1030 ret = ELFEDIT_CMDRET_MOD;
1031 shdr0->sh_info = sh_info;
1032 elfedit_modified_shdr(sec0);
1033 }
1034 }
1035 break;
1036
1037 case EHDR_CMD_T_E_SHENTSIZE:
1038 {
1039 /*
1040 * The argument gives the size of a program
1041 * header element.
1042 */
1043 Half shentsize = (Half) elfedit_atoui(argstate.argv[0],
1044 NULL);
1045 const char *name = MSG_ORIG(MSG_CMD_E_SHENTSIZE);
1046
1047 if (ehdr->e_shentsize == shentsize) {
1048 elfedit_msg(ELFEDIT_MSG_DEBUG,
1049 MSG_INTL(MSG_DEBUG_E_D_OK), name,
1050 EC_WORD(ehdr->e_shentsize));
1051 } else {
1052 elfedit_msg(ELFEDIT_MSG_DEBUG,
1053 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
1054 EC_WORD(ehdr->e_shentsize),
1055 EC_WORD(shentsize));
1056 ret = ELFEDIT_CMDRET_MOD;
1057 ehdr->e_shentsize = shentsize;
1058 }
1059 }
1060 break;
1061
1062 case EHDR_CMD_T_E_SHNUM:
1063 {
1064 /* The argument gives the number of section headers */
1065 Word shnum = (Word) elfedit_atoui(argstate.argv[0],
1066 NULL);
1067 const char *name = MSG_ORIG(MSG_CMD_E_SHNUM);
1068 elfedit_section_t *sec0 = &obj_state->os_secarr[0];
1069 Shdr *shdr0 = sec0->sec_shdr;
1070 Half e_shnum;
1071 Word sh_size;
1072
1073 if (shnum >= SHN_LORESERVE) {
1074 e_shnum = 0;
1075 sh_size = shnum;
1076 } else {
1077 e_shnum = shnum;
1078 sh_size = 0;
1079 }
1080
1081 if (ehdr->e_shnum == e_shnum) {
1082 elfedit_msg(ELFEDIT_MSG_DEBUG,
1083 MSG_INTL(MSG_DEBUG_E_D_OK), name,
1084 EC_WORD(ehdr->e_shnum));
1085 } else {
1086 elfedit_msg(ELFEDIT_MSG_DEBUG,
1087 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
1088 EC_WORD(ehdr->e_shnum), e_shnum);
1089 ret = ELFEDIT_CMDRET_MOD;
1090 ehdr->e_shnum = e_shnum;
1091 }
1092 if (shdr0->sh_size == sh_size) {
1093 elfedit_msg(ELFEDIT_MSG_DEBUG,
1094 MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
1095 MSG_ORIG(MSG_STR_SH_SIZE),
1096 EC_WORD(shdr0->sh_size));
1097 } else {
1098 elfedit_msg(ELFEDIT_MSG_DEBUG,
1099 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
1100 MSG_ORIG(MSG_STR_SH_SIZE),
1101 EC_WORD(shdr0->sh_size), sh_size);
1102 ret = ELFEDIT_CMDRET_MOD;
1103 shdr0->sh_size = sh_size;
1104 elfedit_modified_shdr(sec0);
1105 }
1106 }
1107 break;
1108
1109 case EHDR_CMD_T_E_SHSTRNDX:
1110 {
1111 const char *name = MSG_ORIG(MSG_CMD_E_SHSTRNDX);
1112 Word shstrndx;
1113 elfedit_section_t *sec0 = &obj_state->os_secarr[0];
1114 Shdr *shdr0 = sec0->sec_shdr;
1115 Half e_shstrndx;
1116 Word sh_link;
1117
1118 /*
1119 * By default, sec argument is name of section.
1120 * If -shndx is used, it is a numeric index, and
1121 * if -shtyp is used, it is a section type.
1122 */
1123 if (argstate.optmask & EHDR_OPT_F_SHNDX)
1124 shstrndx = elfedit_atoshndx(argstate.argv[0],
1125 obj_state->os_shnum);
1126 else if (argstate.optmask & EHDR_OPT_F_SHTYP)
1127 shstrndx = elfedit_type_to_shndx(obj_state,
1128 elfedit_atoconst(argstate.argv[0],
1129 ELFEDIT_CONST_SHT));
1130 else
1131 shstrndx = elfedit_name_to_shndx(obj_state,
1132 argstate.argv[0]);
1133
1134 /* Warn if the section isn't a string table */
1135 if ((shstrndx >= obj_state->os_shnum) ||
1136 ((shstrndx >= SHN_LORESERVE) &&
1137 (shstrndx <= SHN_HIRESERVE)) ||
1138 (obj_state->os_secarr[shstrndx].sec_shdr->sh_type !=
1139 SHT_STRTAB))
1140 elfedit_msg(ELFEDIT_MSG_DEBUG,
1141 MSG_INTL(MSG_DEBUG_NOTSTRTAB), name,
1142 EC_WORD(shstrndx));
1143
1144 if (shstrndx >= SHN_LORESERVE) {
1145 e_shstrndx = SHN_XINDEX;
1146 sh_link = shstrndx;
1147 } else {
1148 e_shstrndx = shstrndx;
1149 sh_link = 0;
1150 }
1151
1152 if (ehdr->e_shstrndx == e_shstrndx) {
1153 elfedit_msg(ELFEDIT_MSG_DEBUG,
1154 MSG_INTL(MSG_DEBUG_E_D_OK), name,
1155 EC_WORD(ehdr->e_shstrndx));
1156 } else {
1157 elfedit_msg(ELFEDIT_MSG_DEBUG,
1158 MSG_INTL(MSG_DEBUG_E_D_CHG), name,
1159 EC_WORD(ehdr->e_shstrndx), e_shstrndx);
1160 ret = ELFEDIT_CMDRET_MOD;
1161 ehdr->e_shstrndx = e_shstrndx;
1162 }
1163 if (shdr0->sh_link == sh_link) {
1164 elfedit_msg(ELFEDIT_MSG_DEBUG,
1165 MSG_INTL(MSG_DEBUG_SHDR0_D_OK),
1166 MSG_ORIG(MSG_STR_SH_LINK),
1167 EC_WORD(shdr0->sh_link));
1168 } else {
1169 elfedit_msg(ELFEDIT_MSG_DEBUG,
1170 MSG_INTL(MSG_DEBUG_SHDR0_D_CHG),
1171 MSG_ORIG(MSG_STR_SH_LINK),
1172 EC_WORD(shdr0->sh_link), sh_link);
1173 ret = ELFEDIT_CMDRET_MOD;
1174 shdr0->sh_link = sh_link;
1175 elfedit_modified_shdr(sec0);
1176 }
1177 }
1178 break;
1179
1180 case EHDR_CMD_T_EI_MAG0:
1181 case EHDR_CMD_T_EI_MAG1:
1182 case EHDR_CMD_T_EI_MAG2:
1183 case EHDR_CMD_T_EI_MAG3:
1184 {
1185 /*
1186 * This depends on EHDR_CMD_T_EI_MAG[0-3]
1187 * being contiguous
1188 */
1189 int ei_ndx = (cmd - EHDR_CMD_T_EI_MAG0) + EI_MAG0;
1190
1191 /* The argument gives the magic number byte */
1192 int mag = (int)elfedit_atoui_range(argstate.argv[0],
1193 MSG_ORIG(MSG_STR_VALUE), 0, 255, NULL);
1194
1195 if (ehdr->e_ident[ei_ndx] == mag) {
1196 elfedit_msg(ELFEDIT_MSG_DEBUG,
1197 MSG_INTL(MSG_DEBUG_EI_S_S_OK),
1198 elfedit_atoconst_value_to_str(
1199 ELFEDIT_CONST_EI, ei_ndx, 1),
1200 conv_magic_value(ehdr->e_ident[ei_ndx]));
1201 } else {
1202 elfedit_msg(ELFEDIT_MSG_DEBUG,
1203 MSG_INTL(MSG_DEBUG_EI_S_S_CHG),
1204 elfedit_atoconst_value_to_str(
1205 ELFEDIT_CONST_EI, ei_ndx, 1),
1206 conv_magic_value(ehdr->e_ident[ei_ndx]),
1207 conv_magic_value(mag));
1208 ret = ELFEDIT_CMDRET_MOD;
1209 ehdr->e_ident[ei_ndx] = mag;
1210 }
1211 }
1212 break;
1213
1214 case EHDR_CMD_T_EI_CLASS:
1215 {
1216 /* The argument gives the ELFCLASS value */
1217 int class = (int)elfedit_atoconst_range(
1218 argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
1219 ELFEDIT_CONST_ELFCLASS);
1220 const char *name = elfedit_atoconst_value_to_str(
1221 ELFEDIT_CONST_EI, EI_CLASS, 1);
1222
1223 if (ehdr->e_ident[EI_CLASS] == class) {
1224 elfedit_msg(ELFEDIT_MSG_DEBUG,
1225 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
1226 conv_ehdr_class(class, 0, &inv_buf1));
1227 } else {
1228 elfedit_msg(ELFEDIT_MSG_DEBUG,
1229 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
1230 conv_ehdr_class(ehdr->e_ident[EI_CLASS],
1231 0, &inv_buf1),
1232 conv_ehdr_class(class, 0, &inv_buf2));
1233 ret = ELFEDIT_CMDRET_MOD;
1234 ehdr->e_ident[EI_CLASS] = class;
1235 }
1236 }
1237 break;
1238
1239 case EHDR_CMD_T_EI_DATA:
1240 {
1241 /* The argument gives the ELFDATA value */
1242 int data = (int)elfedit_atoconst_range(argstate.argv[0],
1243 MSG_ORIG(MSG_STR_VALUE), 0, 255,
1244 ELFEDIT_CONST_ELFDATA);
1245 const char *name = elfedit_atoconst_value_to_str(
1246 ELFEDIT_CONST_EI, EI_DATA, 1);
1247
1248 if (ehdr->e_ident[EI_DATA] == data) {
1249 elfedit_msg(ELFEDIT_MSG_DEBUG,
1250 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
1251 conv_ehdr_data(data, 0, &inv_buf1));
1252 } else {
1253 elfedit_msg(ELFEDIT_MSG_DEBUG,
1254 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
1255 conv_ehdr_data(ehdr->e_ident[EI_DATA],
1256 0, &inv_buf1),
1257 conv_ehdr_data(data, 0, &inv_buf2));
1258 ret = ELFEDIT_CMDRET_MOD;
1259 ehdr->e_ident[EI_DATA] = data;
1260 }
1261 }
1262 break;
1263
1264 case EHDR_CMD_T_EI_VERSION:
1265 {
1266 /* The argument gives the version */
1267 int ver = (int)elfedit_atoconst_range(argstate.argv[0],
1268 MSG_ORIG(MSG_STR_VALUE), 0, 255, ELFEDIT_CONST_EV);
1269 const char *name = elfedit_atoconst_value_to_str(
1270 ELFEDIT_CONST_EI, EI_VERSION, 1);
1271
1272 if (ehdr->e_ident[EI_VERSION] == ver) {
1273 elfedit_msg(ELFEDIT_MSG_DEBUG,
1274 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
1275 conv_ehdr_vers(ver, 0, &inv_buf1));
1276 } else {
1277 elfedit_msg(ELFEDIT_MSG_DEBUG,
1278 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
1279 conv_ehdr_vers(ehdr->e_ident[EI_VERSION],
1280 0, &inv_buf1),
1281 conv_ehdr_vers(ver, 0, &inv_buf2));
1282 ret = ELFEDIT_CMDRET_MOD;
1283 ehdr->e_ident[EI_VERSION] = ver;
1284 }
1285 }
1286 break;
1287
1288 case EHDR_CMD_T_EI_OSABI:
1289 {
1290 /* The argument gives the ABI code */
1291 int osabi = (int)elfedit_atoconst_range(
1292 argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
1293 ELFEDIT_CONST_ELFOSABI);
1294 const char *name = elfedit_atoconst_value_to_str(
1295 ELFEDIT_CONST_EI, EI_OSABI, 1);
1296
1297 if (ehdr->e_ident[EI_OSABI] == osabi) {
1298 elfedit_msg(ELFEDIT_MSG_DEBUG,
1299 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
1300 conv_ehdr_osabi(osabi, 0, &inv_buf1));
1301 } else {
1302 elfedit_msg(ELFEDIT_MSG_DEBUG,
1303 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
1304 conv_ehdr_osabi(ehdr->e_ident[EI_OSABI],
1305 0, &inv_buf1),
1306 conv_ehdr_osabi(osabi, 0, &inv_buf2));
1307 ret = ELFEDIT_CMDRET_MOD_OS_MACH;
1308 ehdr->e_ident[EI_OSABI] = osabi;
1309 }
1310 }
1311 break;
1312
1313 case EHDR_CMD_T_EI_ABIVERSION:
1314 {
1315 /* The argument gives the ABI version */
1316 int abiver = (int)elfedit_atoconst_range(
1317 argstate.argv[0], MSG_ORIG(MSG_STR_VALUE), 0, 255,
1318 ELFEDIT_CONST_EAV);
1319 const char *name = elfedit_atoconst_value_to_str(
1320 ELFEDIT_CONST_EI, EI_ABIVERSION, 1);
1321
1322 if (ehdr->e_ident[EI_ABIVERSION] == abiver) {
1323 elfedit_msg(ELFEDIT_MSG_DEBUG,
1324 MSG_INTL(MSG_DEBUG_EI_S_S_OK), name,
1325 conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
1326 abiver, CONV_FMT_DECIMAL, &inv_buf1));
1327 } else {
1328 elfedit_msg(ELFEDIT_MSG_DEBUG,
1329 MSG_INTL(MSG_DEBUG_EI_S_S_CHG), name,
1330 conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
1331 ehdr->e_ident[EI_ABIVERSION],
1332 CONV_FMT_DECIMAL, &inv_buf1),
1333 conv_ehdr_abivers(ehdr->e_ident[EI_OSABI],
1334 abiver, CONV_FMT_DECIMAL, &inv_buf2));
1335 ret = ELFEDIT_CMDRET_MOD;
1336 ehdr->e_ident[EI_ABIVERSION] = abiver;
1337 }
1338 }
1339 break;
1340 }
1341
1342 /*
1343 * If we modified the ELF header, tell libelf.
1344 */
1345 if (ret == ELFEDIT_CMDRET_MOD)
1346 elfedit_modified_ehdr(obj_state);
1347
1348 /* Do autoprint */
1349 print_ehdr(cmd, e_ident_ndx, 1, &argstate);
1350
1351 return (ret);
1352 }
1353
1354
1355
1356
1357 /*
1358 * Command completion functions for the various commands
1359 */
1360
1361 /*ARGSUSED*/
1362 static void
cpl_e_ident(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1363 cpl_e_ident(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1364 const char *argv[], int num_opt)
1365 {
1366 elfedit_atoui_t ndx;
1367
1368 /*
1369 * This command doesn't accept options, so num_opt should be
1370 * 0. This is a defensive measure, in case that should change.
1371 */
1372 argc -= num_opt;
1373 argv += num_opt;
1374
1375 if (argc == 1) {
1376 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EI);
1377 return;
1378 }
1379
1380 if (argc != 2)
1381 return;
1382
1383 /*
1384 * In order to offer up the right completion strings for
1385 * the value, we need to know what index was given for
1386 * the first argument. If we don't recognize the index,
1387 * we want to return quietly without issuing an error,
1388 * so we use elfedit_atoui_range2(), which returns
1389 * a success/failure result and does not throw any errors.
1390 */
1391 if (elfedit_atoconst_range2(argv[0], 0, EI_NIDENT - 1,
1392 ELFEDIT_CONST_EI, &ndx) == 0)
1393 return;
1394 switch (ndx) {
1395 case EI_CLASS:
1396 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS);
1397 break;
1398 case EI_DATA:
1399 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA);
1400 break;
1401 case EI_VERSION:
1402 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV);
1403 break;
1404 case EI_OSABI:
1405 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI);
1406 break;
1407 }
1408 }
1409
1410 /*ARGSUSED*/
1411 static void
cpl_e_type(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1412 cpl_e_type(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1413 const char *argv[], int num_opt)
1414 {
1415 /*
1416 * This command doesn't accept options, so num_opt should be
1417 * 0. This is a defensive measure, in case that should change.
1418 */
1419 argc -= num_opt;
1420 argv += num_opt;
1421
1422 if (argc == 1)
1423 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ET);
1424 }
1425
1426 /*ARGSUSED*/
1427 static void
cpl_e_machine(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1428 cpl_e_machine(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1429 const char *argv[], int num_opt)
1430 {
1431 /*
1432 * This command doesn't accept options, so num_opt should be
1433 * 0. This is a defensive measure, in case that should change.
1434 */
1435 argc -= num_opt;
1436 argv += num_opt;
1437
1438 if (argc == 1)
1439 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EM);
1440 }
1441
1442 /*ARGSUSED*/
1443 static void
cpl_e_version(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1444 cpl_e_version(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1445 const char *argv[], int num_opt)
1446 {
1447 /*
1448 * This command doesn't accept options, so num_opt should be
1449 * 0. This is a defensive measure, in case that should change.
1450 */
1451 argc -= num_opt;
1452 argv += num_opt;
1453
1454 if (argc == 1)
1455 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EV);
1456 }
1457
1458 /*ARGSUSED*/
1459 static void
cpl_e_flags(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1460 cpl_e_flags(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1461 const char *argv[], int num_opt)
1462 {
1463 /* This routine allows multiple flags to be specified */
1464 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EF);
1465 }
1466
1467 /*ARGSUSED*/
1468 static void
cpl_e_shstrndx(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1469 cpl_e_shstrndx(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1470 const char *argv[], int num_opt)
1471 {
1472 enum { NAME, INDEX, TYPE } op;
1473 Word ndx;
1474
1475 /*
1476 * The plainargument can be a section name, index, or
1477 * type, based on the options used. All have completions.
1478 */
1479 if (argc != (num_opt + 1))
1480 return;
1481
1482 op = NAME;
1483 for (ndx = 0; ndx < num_opt; ndx++) {
1484 if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHNDX)) == 0)
1485 op = INDEX;
1486 else if (strcmp(argv[ndx], MSG_ORIG(MSG_STR_MINUS_SHTYP)) == 0)
1487 op = TYPE;
1488 }
1489
1490 if (obj_state == NULL) { /* No object available */
1491 if (op == TYPE)
1492 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT);
1493 return;
1494 }
1495
1496 /*
1497 * Loop over the sections and supply command completion
1498 * for the string tables in the file.
1499 */
1500 for (ndx = 0; ndx < obj_state->os_shnum; ndx++) {
1501 elfedit_section_t *sec = &obj_state->os_secarr[ndx];
1502
1503 if (sec->sec_shdr->sh_type != SHT_STRTAB)
1504 continue;
1505
1506 switch (op) {
1507 case NAME:
1508 elfedit_cpl_match(cpldata, sec->sec_name, 0);
1509 break;
1510 case INDEX:
1511 elfedit_cpl_ndx(cpldata, ndx);
1512 break;
1513 case TYPE:
1514 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_SHT_STRTAB);
1515 break;
1516 }
1517 }
1518 }
1519
1520 /*ARGSUSED*/
1521 static void
cpl_ei_class(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1522 cpl_ei_class(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1523 const char *argv[], int num_opt)
1524 {
1525 /*
1526 * This command doesn't accept options, so num_opt should be
1527 * 0. This is a defensive measure, in case that should change.
1528 */
1529 argc -= num_opt;
1530 argv += num_opt;
1531
1532 if (argc == 1)
1533 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFCLASS);
1534 }
1535
1536 /*ARGSUSED*/
1537 static void
cpl_ei_data(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1538 cpl_ei_data(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1539 const char *argv[], int num_opt)
1540 {
1541 /*
1542 * This command doesn't accept options, so num_opt should be
1543 * 0. This is a defensive measure, in case that should change.
1544 */
1545 argc -= num_opt;
1546 argv += num_opt;
1547
1548 if (argc == 1)
1549 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFDATA);
1550 }
1551
1552 /*ARGSUSED*/
1553 static void
cpl_ei_osabi(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1554 cpl_ei_osabi(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1555 const char *argv[], int num_opt)
1556 {
1557 /*
1558 * This command doesn't accept options, so num_opt should be
1559 * 0. This is a defensive measure, in case that should change.
1560 */
1561 argc -= num_opt;
1562 argv += num_opt;
1563
1564 if (argc == 1)
1565 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_ELFOSABI);
1566 }
1567
1568 /*ARGSUSED*/
1569 static void
cpl_ei_abiversion(elfedit_obj_state_t * obj_state,void * cpldata,int argc,const char * argv[],int num_opt)1570 cpl_ei_abiversion(elfedit_obj_state_t *obj_state, void *cpldata, int argc,
1571 const char *argv[], int num_opt)
1572 {
1573 /*
1574 * This command doesn't accept options, so num_opt should be
1575 * 0. This is a defensive measure, in case that should change.
1576 */
1577 argc -= num_opt;
1578 argv += num_opt;
1579
1580 if (argc == 1)
1581 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_EAV);
1582 }
1583
1584
1585
1586
1587 /*
1588 * Implementation functions for the commands
1589 */
1590 static elfedit_cmdret_t
cmd_dump(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1591 cmd_dump(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1592 {
1593 return (cmd_body(EHDR_CMD_T_DUMP, obj_state, argc, argv));
1594 }
1595
1596
1597 static elfedit_cmdret_t
cmd_e_ident(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1598 cmd_e_ident(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1599 {
1600 return (cmd_body(EHDR_CMD_T_E_IDENT, obj_state, argc, argv));
1601 }
1602
1603
1604 static elfedit_cmdret_t
cmd_e_type(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1605 cmd_e_type(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1606 {
1607 return (cmd_body(EHDR_CMD_T_E_TYPE, obj_state, argc, argv));
1608 }
1609
1610
1611 static elfedit_cmdret_t
cmd_e_machine(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1612 cmd_e_machine(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1613 {
1614 return (cmd_body(EHDR_CMD_T_E_MACHINE, obj_state, argc, argv));
1615 }
1616
1617
1618 static elfedit_cmdret_t
cmd_e_version(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1619 cmd_e_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1620 {
1621 return (cmd_body(EHDR_CMD_T_E_VERSION, obj_state, argc, argv));
1622 }
1623
1624
1625 static elfedit_cmdret_t
cmd_e_entry(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1626 cmd_e_entry(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1627 {
1628 return (cmd_body(EHDR_CMD_T_E_ENTRY, obj_state, argc, argv));
1629 }
1630
1631
1632 static elfedit_cmdret_t
cmd_e_phoff(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1633 cmd_e_phoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1634 {
1635 return (cmd_body(EHDR_CMD_T_E_PHOFF, obj_state, argc, argv));
1636 }
1637
1638
1639 static elfedit_cmdret_t
cmd_e_shoff(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1640 cmd_e_shoff(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1641 {
1642 return (cmd_body(EHDR_CMD_T_E_SHOFF, obj_state, argc, argv));
1643 }
1644
1645
1646 static elfedit_cmdret_t
cmd_e_flags(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1647 cmd_e_flags(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1648 {
1649 return (cmd_body(EHDR_CMD_T_E_FLAGS, obj_state, argc, argv));
1650 }
1651
1652
1653 static elfedit_cmdret_t
cmd_e_ehsize(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1654 cmd_e_ehsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1655 {
1656 return (cmd_body(EHDR_CMD_T_E_EHSIZE, obj_state, argc, argv));
1657 }
1658
1659
1660 static elfedit_cmdret_t
cmd_e_phentsize(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1661 cmd_e_phentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1662 {
1663 return (cmd_body(EHDR_CMD_T_E_PHENTSIZE, obj_state, argc, argv));
1664 }
1665
1666
1667 static elfedit_cmdret_t
cmd_e_phnum(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1668 cmd_e_phnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1669 {
1670 return (cmd_body(EHDR_CMD_T_E_PHNUM, obj_state, argc, argv));
1671 }
1672
1673
1674 static elfedit_cmdret_t
cmd_e_shentsize(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1675 cmd_e_shentsize(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1676 {
1677 return (cmd_body(EHDR_CMD_T_E_SHENTSIZE, obj_state, argc, argv));
1678 }
1679
1680
1681 static elfedit_cmdret_t
cmd_e_shnum(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1682 cmd_e_shnum(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1683 {
1684 return (cmd_body(EHDR_CMD_T_E_SHNUM, obj_state, argc, argv));
1685 }
1686
1687
1688 static elfedit_cmdret_t
cmd_e_shstrndx(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1689 cmd_e_shstrndx(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1690 {
1691 return (cmd_body(EHDR_CMD_T_E_SHSTRNDX, obj_state, argc, argv));
1692 }
1693
1694
1695 static elfedit_cmdret_t
cmd_ei_mag0(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1696 cmd_ei_mag0(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1697 {
1698 return (cmd_body(EHDR_CMD_T_EI_MAG0, obj_state, argc, argv));
1699 }
1700
1701
1702 static elfedit_cmdret_t
cmd_ei_mag1(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1703 cmd_ei_mag1(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1704 {
1705 return (cmd_body(EHDR_CMD_T_EI_MAG1, obj_state, argc, argv));
1706 }
1707
1708
1709 static elfedit_cmdret_t
cmd_ei_mag2(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1710 cmd_ei_mag2(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1711 {
1712 return (cmd_body(EHDR_CMD_T_EI_MAG2, obj_state, argc, argv));
1713 }
1714
1715
1716 static elfedit_cmdret_t
cmd_ei_mag3(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1717 cmd_ei_mag3(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1718 {
1719 return (cmd_body(EHDR_CMD_T_EI_MAG3, obj_state, argc, argv));
1720 }
1721
1722
1723 static elfedit_cmdret_t
cmd_ei_class(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1724 cmd_ei_class(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1725 {
1726 return (cmd_body(EHDR_CMD_T_EI_CLASS, obj_state, argc, argv));
1727 }
1728
1729
1730 static elfedit_cmdret_t
cmd_ei_data(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1731 cmd_ei_data(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1732 {
1733 return (cmd_body(EHDR_CMD_T_EI_DATA, obj_state, argc, argv));
1734 }
1735
1736
1737 static elfedit_cmdret_t
cmd_ei_version(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1738 cmd_ei_version(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1739 {
1740 return (cmd_body(EHDR_CMD_T_EI_VERSION, obj_state, argc, argv));
1741 }
1742
1743
1744 static elfedit_cmdret_t
cmd_ei_osabi(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1745 cmd_ei_osabi(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1746 {
1747 return (cmd_body(EHDR_CMD_T_EI_OSABI, obj_state, argc, argv));
1748 }
1749
1750
1751 static elfedit_cmdret_t
cmd_ei_abiversion(elfedit_obj_state_t * obj_state,int argc,const char * argv[])1752 cmd_ei_abiversion(elfedit_obj_state_t *obj_state, int argc, const char *argv[])
1753 {
1754 return (cmd_body(EHDR_CMD_T_EI_ABIVERSION, obj_state, argc, argv));
1755 }
1756
1757
1758
1759
1760 /*ARGSUSED*/
1761 elfedit_module_t *
elfedit_init(elfedit_module_version_t version)1762 elfedit_init(elfedit_module_version_t version)
1763 {
1764 /* Many of the commands only accept -o */
1765 static elfedit_cmd_optarg_t opt_std[] = {
1766 { ELFEDIT_STDOA_OPT_O, 0,
1767 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1768 { NULL }
1769 };
1770
1771
1772 /* ehdr:dump */
1773 static const char *name_dump[] = {
1774 MSG_ORIG(MSG_CMD_DUMP),
1775 MSG_ORIG(MSG_STR_EMPTY), /* "" makes this the default command */
1776 NULL
1777 };
1778
1779 /* ehdr:e_ident */
1780 static const char *name_e_ident[] = {
1781 MSG_ORIG(MSG_CMD_E_IDENT), NULL };
1782 static elfedit_cmd_optarg_t arg_e_ident[] = {
1783 { MSG_ORIG(MSG_STR_INDEX),
1784 /* MSG_INTL(MSG_ARGDESC_E_IDENT_NDX) */
1785 ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_NDX),
1786 ELFEDIT_CMDOA_F_OPT, 0 },
1787 { MSG_ORIG(MSG_STR_VALUE),
1788 /* MSG_INTL(MSG_ARGDESC_E_IDENT_VALUE) */
1789 ELFEDIT_I18NHDL(MSG_ARGDESC_E_IDENT_VALUE),
1790 ELFEDIT_CMDOA_F_OPT, 0 },
1791 { NULL }
1792 };
1793
1794 /* ehdr:e_type */
1795 static const char *name_e_type[] = {
1796 MSG_ORIG(MSG_CMD_E_TYPE), NULL };
1797 static elfedit_cmd_optarg_t arg_e_type[] = {
1798 { MSG_ORIG(MSG_STR_VALUE),
1799 /* MSG_INTL(MSG_ARGDESC_E_TYPE_VALUE) */
1800 ELFEDIT_I18NHDL(MSG_ARGDESC_E_TYPE_VALUE),
1801 ELFEDIT_CMDOA_F_OPT, 0 },
1802 { NULL }
1803 };
1804
1805 /* ehdr:e_machine */
1806 static const char *name_e_machine[] = {
1807 MSG_ORIG(MSG_CMD_E_MACHINE), NULL };
1808 static elfedit_cmd_optarg_t arg_e_machine[] = {
1809 { MSG_ORIG(MSG_STR_TYPE),
1810 /* MSG_INTL(MSG_ARGDESC_E_MACHINE_VALUE) */
1811 ELFEDIT_I18NHDL(MSG_ARGDESC_E_MACHINE_VALUE),
1812 ELFEDIT_CMDOA_F_OPT, 0 },
1813 { NULL }
1814 };
1815
1816 /* ehdr:e_version */
1817 static const char *name_e_version[] = {
1818 MSG_ORIG(MSG_CMD_E_VERSION), NULL };
1819 static elfedit_cmd_optarg_t arg_e_version[] = {
1820 { MSG_ORIG(MSG_STR_VERSION),
1821 /* MSG_INTL(MSG_ARGDESC_E_VERSION_VALUE) */
1822 ELFEDIT_I18NHDL(MSG_ARGDESC_E_VERSION_VALUE),
1823 ELFEDIT_CMDOA_F_OPT, 0 },
1824 { NULL }
1825 };
1826
1827 /* ehdr:e_entry */
1828 static const char *name_e_entry[] = {
1829 MSG_ORIG(MSG_CMD_E_ENTRY), NULL };
1830 static elfedit_cmd_optarg_t arg_e_entry[] = {
1831 { MSG_ORIG(MSG_STR_VALUE),
1832 /* MSG_INTL(MSG_ARGDESC_E_ENTRY_VALUE) */
1833 ELFEDIT_I18NHDL(MSG_ARGDESC_E_ENTRY_VALUE),
1834 ELFEDIT_CMDOA_F_OPT, 0 },
1835 { NULL }
1836 };
1837
1838 /* ehdr:e_phoff */
1839 static const char *name_e_phoff[] = {
1840 MSG_ORIG(MSG_CMD_E_PHOFF), NULL };
1841 static elfedit_cmd_optarg_t arg_e_phoff[] = {
1842 { MSG_ORIG(MSG_STR_OFFSET),
1843 /* MSG_INTL(MSG_ARGDESC_E_PHOFF_VALUE) */
1844 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHOFF_VALUE),
1845 ELFEDIT_CMDOA_F_OPT, 0 },
1846 { NULL }
1847 };
1848
1849 /* ehdr:e_shoff */
1850 static const char *name_e_shoff[] = {
1851 MSG_ORIG(MSG_CMD_E_SHOFF), NULL };
1852 static elfedit_cmd_optarg_t arg_e_shoff[] = {
1853 { MSG_ORIG(MSG_STR_OFFSET),
1854 /* MSG_INTL(MSG_ARGDESC_E_SHOFF_VALUE) */
1855 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHOFF_VALUE),
1856 ELFEDIT_CMDOA_F_OPT, 0 },
1857 { NULL }
1858 };
1859
1860 /* ehdr:e_flags */
1861 static const char *name_e_flags[] = {
1862 MSG_ORIG(MSG_CMD_E_FLAGS), NULL };
1863 static elfedit_cmd_optarg_t opt_e_flags[] = {
1864 { ELFEDIT_STDOA_OPT_AND, 0,
1865 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_AND, EHDR_OPT_F_OR },
1866 { ELFEDIT_STDOA_OPT_CMP, 0,
1867 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_CMP, 0 },
1868 { ELFEDIT_STDOA_OPT_O, 0,
1869 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1870 { ELFEDIT_STDOA_OPT_OR, 0,
1871 ELFEDIT_CMDOA_F_INHERIT, EHDR_OPT_F_OR, EHDR_OPT_F_AND },
1872 { NULL }
1873 };
1874 static elfedit_cmd_optarg_t arg_e_flags[] = {
1875 { MSG_ORIG(MSG_STR_FLAGVALUE),
1876 /* MSG_INTL(MSG_ARGDESC_E_FLAGS_VALUE) */
1877 ELFEDIT_I18NHDL(MSG_ARGDESC_E_FLAGS_VALUE),
1878 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT, 0 },
1879 { NULL }
1880 };
1881
1882 /* ehdr:e_ehsize */
1883 static const char *name_e_ehsize[] = {
1884 MSG_ORIG(MSG_CMD_E_EHSIZE), NULL };
1885 static elfedit_cmd_optarg_t arg_e_ehsize[] = {
1886 { MSG_ORIG(MSG_STR_VALUE),
1887 /* MSG_INTL(MSG_ARGDESC_E_EHSIZE_VALUE) */
1888 ELFEDIT_I18NHDL(MSG_ARGDESC_E_EHSIZE_VALUE),
1889 ELFEDIT_CMDOA_F_OPT, 0 },
1890 { NULL }
1891 };
1892
1893 /* ehdr:e_phentsize */
1894 static const char *name_e_phentsize[] = {
1895 MSG_ORIG(MSG_CMD_E_PHENTSIZE), NULL };
1896 static elfedit_cmd_optarg_t arg_e_phentsize[] = {
1897 { MSG_ORIG(MSG_STR_VALUE),
1898 /* MSG_INTL(MSG_ARGDESC_E_PHENTSIZE_VALUE) */
1899 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHENTSIZE_VALUE),
1900 ELFEDIT_CMDOA_F_OPT, 0 },
1901 { NULL }
1902 };
1903
1904 /* ehdr:e_phnum */
1905 static const char *name_e_phnum[] = {
1906 MSG_ORIG(MSG_CMD_E_PHNUM), NULL };
1907 static elfedit_cmd_optarg_t arg_e_phnum[] = {
1908 { MSG_ORIG(MSG_STR_VALUE),
1909 /* MSG_INTL(MSG_ARGDESC_E_PHNUM_VALUE) */
1910 ELFEDIT_I18NHDL(MSG_ARGDESC_E_PHNUM_VALUE),
1911 ELFEDIT_CMDOA_F_OPT, 0 },
1912 { NULL }
1913 };
1914
1915 /* ehdr:e_shentsize */
1916 static const char *name_e_shentsize[] = {
1917 MSG_ORIG(MSG_CMD_E_SHENTSIZE), NULL };
1918 static elfedit_cmd_optarg_t arg_e_shentsize[] = {
1919 { MSG_ORIG(MSG_STR_VALUE),
1920 /* MSG_INTL(MSG_ARGDESC_E_SHENTSIZE_VALUE) */
1921 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHENTSIZE_VALUE),
1922 ELFEDIT_CMDOA_F_OPT, 0 },
1923 { NULL }
1924 };
1925
1926 /* ehdr:e_shnum */
1927 static const char *name_e_shnum[] = {
1928 MSG_ORIG(MSG_CMD_E_SHNUM), NULL };
1929 static elfedit_cmd_optarg_t arg_e_shnum[] = {
1930 { MSG_ORIG(MSG_STR_VALUE),
1931 /* MSG_INTL(MSG_ARGDESC_E_SHNUM_VALUE) */
1932 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHNUM_VALUE),
1933 ELFEDIT_CMDOA_F_OPT, 0 },
1934 { NULL }
1935 };
1936
1937 /* ehdr:e_shstrndx */
1938 static const char *name_e_shstrndx[] = {
1939 MSG_ORIG(MSG_CMD_E_SHSTRNDX), NULL };
1940 static elfedit_cmd_optarg_t opt_e_shstrndx[] = {
1941 { ELFEDIT_STDOA_OPT_O, 0,
1942 ELFEDIT_CMDOA_F_INHERIT, 0, 0 },
1943 { MSG_ORIG(MSG_STR_MINUS_SHNDX),
1944 /* MSG_INTL(MSG_OPTDESC_SHNDX) */
1945 ELFEDIT_I18NHDL(MSG_OPTDESC_SHNDX), 0,
1946 EHDR_OPT_F_SHNDX, EHDR_OPT_F_SHTYP },
1947 { MSG_ORIG(MSG_STR_MINUS_SHTYP),
1948 /* MSG_INTL(MSG_OPTDESC_SHTYP) */
1949 ELFEDIT_I18NHDL(MSG_OPTDESC_SHTYP), 0,
1950 EHDR_OPT_F_SHTYP, EHDR_OPT_F_SHNDX, },
1951 { NULL }
1952 };
1953 static elfedit_cmd_optarg_t arg_e_shstrndx[] = {
1954 { MSG_ORIG(MSG_STR_SEC),
1955 /* MSG_INTL(MSG_ARGDESC_E_SHSTRNDX_SEC) */
1956 ELFEDIT_I18NHDL(MSG_ARGDESC_E_SHSTRNDX_SEC),
1957 ELFEDIT_CMDOA_F_OPT, 0 },
1958 { NULL }
1959 };
1960
1961 /* ehdr:ei_mag0 */
1962 static const char *name_ei_mag0[] = {
1963 MSG_ORIG(MSG_CMD_EI_MAG0), NULL };
1964 static elfedit_cmd_optarg_t arg_ei_mag0[] = {
1965 { MSG_ORIG(MSG_STR_VALUE),
1966 /* MSG_INTL(MSG_ARGDESC_EI_MAG0_VALUE) */
1967 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG0_VALUE),
1968 ELFEDIT_CMDOA_F_OPT, 0 },
1969 { NULL }
1970 };
1971
1972 /* ehdr:ei_mag1 */
1973 static const char *name_ei_mag1[] = {
1974 MSG_ORIG(MSG_CMD_EI_MAG1), NULL };
1975 static elfedit_cmd_optarg_t arg_ei_mag1[] = {
1976 { MSG_ORIG(MSG_STR_VALUE),
1977 /* MSG_INTL(MSG_ARGDESC_EI_MAG1_VALUE) */
1978 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG1_VALUE),
1979 ELFEDIT_CMDOA_F_OPT, 0 },
1980 { NULL }
1981 };
1982
1983 /* ehdr:ei_mag2 */
1984 static const char *name_ei_mag2[] = {
1985 MSG_ORIG(MSG_CMD_EI_MAG2), NULL };
1986 static elfedit_cmd_optarg_t arg_ei_mag2[] = {
1987 { MSG_ORIG(MSG_STR_VALUE),
1988 /* MSG_INTL(MSG_ARGDESC_EI_MAG2_VALUE) */
1989 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG2_VALUE),
1990 ELFEDIT_CMDOA_F_OPT, 0 },
1991 { NULL }
1992 };
1993
1994 /* ehdr:ei_mag3 */
1995 static const char *name_ei_mag3[] = {
1996 MSG_ORIG(MSG_CMD_EI_MAG3), NULL };
1997 static elfedit_cmd_optarg_t arg_ei_mag3[] = {
1998 { MSG_ORIG(MSG_STR_VALUE),
1999 /* MSG_INTL(MSG_ARGDESC_EI_MAG3_VALUE) */
2000 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_MAG3_VALUE),
2001 ELFEDIT_CMDOA_F_OPT, 0 },
2002 { NULL }
2003 };
2004
2005 /* ehdr:ei_class */
2006 static const char *name_ei_class[] = {
2007 MSG_ORIG(MSG_CMD_EI_CLASS), NULL };
2008 static elfedit_cmd_optarg_t arg_ei_class[] = {
2009 { MSG_ORIG(MSG_STR_VALUE),
2010 /* MSG_INTL(MSG_ARGDESC_EI_CLASS_VALUE) */
2011 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_CLASS_VALUE),
2012 ELFEDIT_CMDOA_F_OPT, 0 },
2013 { NULL }
2014 };
2015
2016 /* ehdr:ei_data */
2017 static const char *name_ei_data[] = {
2018 MSG_ORIG(MSG_CMD_EI_DATA), NULL };
2019 static elfedit_cmd_optarg_t arg_ei_data[] = {
2020 { MSG_ORIG(MSG_STR_VALUE),
2021 /* MSG_INTL(MSG_ARGDESC_EI_DATA_VALUE) */
2022 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_DATA_VALUE),
2023 ELFEDIT_CMDOA_F_OPT, 0 },
2024 { NULL }
2025 };
2026
2027 /* ehdr:ei_version */
2028 static const char *name_ei_version[] = {
2029 MSG_ORIG(MSG_CMD_EI_VERSION), NULL };
2030 /* Note: arg_e_version is also used for this command */
2031
2032 /* ehdr:ei_osabi */
2033 static const char *name_ei_osabi[] = {
2034 MSG_ORIG(MSG_CMD_EI_OSABI), NULL };
2035 static elfedit_cmd_optarg_t arg_ei_osabi[] = {
2036 { MSG_ORIG(MSG_STR_VALUE),
2037 /* MSG_INTL(MSG_ARGDESC_EI_OSABI_VALUE) */
2038 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_OSABI_VALUE),
2039 ELFEDIT_CMDOA_F_OPT, 0 },
2040 { NULL }
2041 };
2042
2043 /* ehdr:ei_abiversion */
2044 static const char *name_ei_abiversion[] = {
2045 MSG_ORIG(MSG_CMD_EI_ABIVERSION), NULL };
2046 static elfedit_cmd_optarg_t arg_ei_abiversion[] = {
2047 { MSG_ORIG(MSG_STR_VALUE),
2048 /* MSG_INTL(MSG_ARGDESC_EI_ABIVERSION_VALUE) */
2049 ELFEDIT_I18NHDL(MSG_ARGDESC_EI_ABIVERSION_VALUE),
2050 ELFEDIT_CMDOA_F_OPT, 0 },
2051 { NULL }
2052 };
2053
2054
2055
2056
2057 static elfedit_cmd_t cmds[] = {
2058 /* ehdr:dump */
2059 { cmd_dump, NULL, name_dump,
2060 /* MSG_INTL(MSG_DESC_DUMP) */
2061 ELFEDIT_I18NHDL(MSG_DESC_DUMP),
2062 /* MSG_INTL(MSG_HELP_DUMP) */
2063 ELFEDIT_I18NHDL(MSG_HELP_DUMP),
2064 NULL, NULL },
2065
2066 /* ehdr:e_ident */
2067 { cmd_e_ident, cpl_e_ident, name_e_ident,
2068 /* MSG_INTL(MSG_DESC_E_IDENT) */
2069 ELFEDIT_I18NHDL(MSG_DESC_E_IDENT),
2070 /* MSG_INTL(MSG_HELP_E_IDENT) */
2071 ELFEDIT_I18NHDL(MSG_HELP_E_IDENT),
2072 opt_std, arg_e_ident },
2073
2074 /* ehdr:e_type */
2075 { cmd_e_type, cpl_e_type, name_e_type,
2076 /* MSG_INTL(MSG_DESC_E_TYPE) */
2077 ELFEDIT_I18NHDL(MSG_DESC_E_TYPE),
2078 /* MSG_INTL(MSG_HELP_E_TYPE) */
2079 ELFEDIT_I18NHDL(MSG_HELP_E_TYPE),
2080 opt_std, arg_e_type },
2081
2082 /* ehdr:e_machine */
2083 { cmd_e_machine, cpl_e_machine, name_e_machine,
2084 /* MSG_INTL(MSG_DESC_E_MACHINE) */
2085 ELFEDIT_I18NHDL(MSG_DESC_E_MACHINE),
2086 /* MSG_INTL(MSG_HELP_E_MACHINE) */
2087 ELFEDIT_I18NHDL(MSG_HELP_E_MACHINE),
2088 opt_std, arg_e_machine },
2089
2090 /* ehdr:e_version */
2091 { cmd_e_version, cpl_e_version, name_e_version,
2092 /* MSG_INTL(MSG_DESC_E_VERSION) */
2093 ELFEDIT_I18NHDL(MSG_DESC_E_VERSION),
2094 /* MSG_INTL(MSG_HELP_E_VERSION) */
2095 ELFEDIT_I18NHDL(MSG_HELP_E_VERSION),
2096 opt_std, arg_e_version },
2097
2098 /* ehdr:e_entry */
2099 { cmd_e_entry, NULL, name_e_entry,
2100 /* MSG_INTL(MSG_DESC_E_ENTRY) */
2101 ELFEDIT_I18NHDL(MSG_DESC_E_ENTRY),
2102 /* MSG_INTL(MSG_HELP_E_ENTRY) */
2103 ELFEDIT_I18NHDL(MSG_HELP_E_ENTRY),
2104 opt_std, arg_e_entry },
2105
2106 /* ehdr:e_phoff */
2107 { cmd_e_phoff, NULL, name_e_phoff,
2108 /* MSG_INTL(MSG_DESC_E_PHOFF) */
2109 ELFEDIT_I18NHDL(MSG_DESC_E_PHOFF),
2110 /* MSG_INTL(MSG_HELP_E_PHOFF) */
2111 ELFEDIT_I18NHDL(MSG_HELP_E_PHOFF),
2112 opt_std, arg_e_phoff },
2113
2114 /* ehdr:e_shoff */
2115 { cmd_e_shoff, NULL, name_e_shoff,
2116 /* MSG_INTL(MSG_DESC_E_SHOFF) */
2117 ELFEDIT_I18NHDL(MSG_DESC_E_SHOFF),
2118 /* MSG_INTL(MSG_HELP_E_SHOFF) */
2119 ELFEDIT_I18NHDL(MSG_HELP_E_SHOFF),
2120 opt_std, arg_e_shoff },
2121
2122 /* ehdr:e_flags */
2123 { cmd_e_flags, cpl_e_flags, name_e_flags,
2124 /* MSG_INTL(MSG_DESC_E_FLAGS) */
2125 ELFEDIT_I18NHDL(MSG_DESC_E_FLAGS),
2126 /* MSG_INTL(MSG_HELP_E_FLAGS) */
2127 ELFEDIT_I18NHDL(MSG_HELP_E_FLAGS),
2128 opt_e_flags, arg_e_flags },
2129
2130 /* ehdr:e_ehsize */
2131 { cmd_e_ehsize, NULL, name_e_ehsize,
2132 /* MSG_INTL(MSG_DESC_E_EHSIZE) */
2133 ELFEDIT_I18NHDL(MSG_DESC_E_EHSIZE),
2134 /* MSG_INTL(MSG_HELP_E_EHSIZE) */
2135 ELFEDIT_I18NHDL(MSG_HELP_E_EHSIZE),
2136 opt_std, arg_e_ehsize },
2137
2138 /* ehdr:e_phentsize */
2139 { cmd_e_phentsize, NULL, name_e_phentsize,
2140 /* MSG_INTL(MSG_DESC_E_PHENTSIZE) */
2141 ELFEDIT_I18NHDL(MSG_DESC_E_PHENTSIZE),
2142 /* MSG_INTL(MSG_HELP_E_PHENTSIZE) */
2143 ELFEDIT_I18NHDL(MSG_HELP_E_PHENTSIZE),
2144 opt_std, arg_e_phentsize },
2145
2146 /* ehdr:e_phnum */
2147 { cmd_e_phnum, NULL, name_e_phnum,
2148 /* MSG_INTL(MSG_DESC_E_PHNUM) */
2149 ELFEDIT_I18NHDL(MSG_DESC_E_PHNUM),
2150 /* MSG_INTL(MSG_HELP_E_PHNUM) */
2151 ELFEDIT_I18NHDL(MSG_HELP_E_PHNUM),
2152 opt_std, arg_e_phnum },
2153
2154 /* ehdr:e_shentsize */
2155 { cmd_e_shentsize, NULL, name_e_shentsize,
2156 /* MSG_INTL(MSG_DESC_E_SHENTSIZE) */
2157 ELFEDIT_I18NHDL(MSG_DESC_E_SHENTSIZE),
2158 /* MSG_INTL(MSG_HELP_E_SHENTSIZE) */
2159 ELFEDIT_I18NHDL(MSG_HELP_E_SHENTSIZE),
2160 opt_std, arg_e_shentsize },
2161
2162 /* ehdr:e_shnum */
2163 { cmd_e_shnum, NULL, name_e_shnum,
2164 /* MSG_INTL(MSG_DESC_E_SHNUM) */
2165 ELFEDIT_I18NHDL(MSG_DESC_E_SHNUM),
2166 /* MSG_INTL(MSG_HELP_E_SHNUM) */
2167 ELFEDIT_I18NHDL(MSG_HELP_E_SHNUM),
2168 opt_std, arg_e_shnum },
2169
2170 /* ehdr:e_shstrndx */
2171 { cmd_e_shstrndx, cpl_e_shstrndx, name_e_shstrndx,
2172 /* MSG_INTL(MSG_DESC_E_SHSTRNDX) */
2173 ELFEDIT_I18NHDL(MSG_DESC_E_SHSTRNDX),
2174 /* MSG_INTL(MSG_HELP_E_SHSTRNDX) */
2175 ELFEDIT_I18NHDL(MSG_HELP_E_SHSTRNDX),
2176 opt_e_shstrndx, arg_e_shstrndx },
2177
2178 /* ehdr:ei_mag0 */
2179 { cmd_ei_mag0, NULL, name_ei_mag0,
2180 /* MSG_INTL(MSG_DESC_EI_MAG0) */
2181 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG0),
2182 /* MSG_INTL(MSG_HELP_EI_MAG0) */
2183 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG0),
2184 opt_std, arg_ei_mag0 },
2185
2186 /* ehdr:ei_mag1 */
2187 { cmd_ei_mag1, NULL, name_ei_mag1,
2188 /* MSG_INTL(MSG_DESC_EI_MAG1) */
2189 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG1),
2190 /* MSG_INTL(MSG_HELP_EI_MAG1) */
2191 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG1),
2192 opt_std, arg_ei_mag1 },
2193
2194 /* ehdr:ei_mag2 */
2195 { cmd_ei_mag2, NULL, name_ei_mag2,
2196 /* MSG_INTL(MSG_DESC_EI_MAG2) */
2197 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG2),
2198 /* MSG_INTL(MSG_HELP_EI_MAG2) */
2199 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG2),
2200 opt_std, arg_ei_mag2 },
2201
2202 /* ehdr:ei_mag3 */
2203 { cmd_ei_mag3, NULL, name_ei_mag3,
2204 /* MSG_INTL(MSG_DESC_EI_MAG3) */
2205 ELFEDIT_I18NHDL(MSG_DESC_EI_MAG3),
2206 /* MSG_INTL(MSG_HELP_EI_MAG3) */
2207 ELFEDIT_I18NHDL(MSG_HELP_EI_MAG3),
2208 opt_std, arg_ei_mag3 },
2209
2210 /* ehdr:ei_class */
2211 { cmd_ei_class, cpl_ei_class, name_ei_class,
2212 /* MSG_INTL(MSG_DESC_EI_CLASS) */
2213 ELFEDIT_I18NHDL(MSG_DESC_EI_CLASS),
2214 /* MSG_INTL(MSG_HELP_EI_CLASS) */
2215 ELFEDIT_I18NHDL(MSG_HELP_EI_CLASS),
2216 opt_std, arg_ei_class },
2217
2218 /* ehdr:ei_data */
2219 { cmd_ei_data, cpl_ei_data, name_ei_data,
2220 /* MSG_INTL(MSG_DESC_EI_DATA) */
2221 ELFEDIT_I18NHDL(MSG_DESC_EI_DATA),
2222 /* MSG_INTL(MSG_HELP_EI_DATA) */
2223 ELFEDIT_I18NHDL(MSG_HELP_EI_DATA),
2224 opt_std, arg_ei_data },
2225
2226 /* ehdr:ei_version */
2227 { cmd_ei_version, cpl_e_version, name_ei_version,
2228 /* MSG_INTL(MSG_DESC_EI_VERSION) */
2229 ELFEDIT_I18NHDL(MSG_DESC_EI_VERSION),
2230 /* MSG_INTL(MSG_HELP_EI_VERSION) */
2231 ELFEDIT_I18NHDL(MSG_HELP_EI_VERSION),
2232 opt_std, arg_e_version },
2233
2234 /* ehdr:ei_osabi */
2235 { cmd_ei_osabi, cpl_ei_osabi, name_ei_osabi,
2236 /* MSG_INTL(MSG_DESC_EI_OSABI) */
2237 ELFEDIT_I18NHDL(MSG_DESC_EI_OSABI),
2238 /* MSG_INTL(MSG_HELP_EI_OSABI) */
2239 ELFEDIT_I18NHDL(MSG_HELP_EI_OSABI),
2240 opt_std, arg_ei_osabi },
2241
2242 /* ehdr:ei_abiversion */
2243 { cmd_ei_abiversion, cpl_ei_abiversion, name_ei_abiversion,
2244 /* MSG_INTL(MSG_DESC_EI_ABIVERSION) */
2245 ELFEDIT_I18NHDL(MSG_DESC_EI_ABIVERSION),
2246 /* MSG_INTL(MSG_HELP_EI_ABIVERSION) */
2247 ELFEDIT_I18NHDL(MSG_HELP_EI_ABIVERSION),
2248 opt_std, arg_ei_abiversion },
2249
2250 { NULL }
2251 };
2252
2253 static elfedit_module_t module = {
2254 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_NAME),
2255 /* MSG_INTL(MSG_MOD_DESC) */
2256 ELFEDIT_I18NHDL(MSG_MOD_DESC),
2257 cmds, mod_i18nhdl_to_str };
2258
2259 return (&module);
2260 }
2261