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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 #include <sys/types.h>
36 /* The following are here to support use of elfedit_msg() */
37 #include <sys/machelf.h> /* EC_ macros */
46 * elfedit uses elfedit_printf() to produce generic output to stdout.
47 * elfedit_msg() is used to produce error message, or specific types
48 * of terse informational messages:
51 * Issues an error to stderr. elfedit_msg() does not return
52 * to the caller. Control returns to the outer loop in
53 * interactive use. elfedit exits in non-interactive use.
56 * Issues an error to stderr. elfedit_msg() exits the process,
57 * and does not return to the caller.
60 * Issues an elfedit usage message to stderr, and
61 * returns to the caller.
63 * ELFEDIT_MSG_CMDUSAGE
64 * Issues an elfedit usage message to stderr, and
65 * does not return to the caller.
68 * If the ELFEDIT_F_DEBUG flag is set, the message
69 * is printed to stdout, otherwise no output is produced.
70 * elfedit_msg() returns to the caller.
73 * This is a very special case, intended to handle the
74 * case where the pager subprocess exits before we are
75 * done producing output (the user presses 'q'). It acts
76 * just like ELFEDIT_MSG_ERR, except that no message is
79 * In the cases where elfedit_msg() does not return to the caller, the
80 * behavior depends on the mode of execution. If running in interactive
81 * mode (reading from a tty), control is returned directly to the outer
82 * elfedit control loop to read another command. If not running in interactive
83 * mode, elfedit exits with a non-zero status.
87 ELFEDIT_MSG_FATAL
= 1,
88 ELFEDIT_MSG_USAGE
= 2,
89 ELFEDIT_MSG_CMDUSAGE
= 3,
90 ELFEDIT_MSG_DEBUG
= 4,
96 * Information for a single ELF section.
99 * A symbol table can have an associated SHT_SYMTAB_SHNDX section. This
100 * happens when the number of sections is too large to fit in the
101 * ELF symbol st_shndx field, which is a 16-bit value. The sec_xshndx
102 * field will be SHN_UNDEF if there is no such section, and will be
103 * the section index of the extended section index section assocated
104 * with the symbol table otherwise.
107 * Symbol table sections can have an SHT_SUNW_VERSYM section that
108 * contains its version indices. Other types of section will have
109 * this field set to SHN_UNDEF.
112 Elf32_Word sec_shndx
; /* Section index */
113 Elf_Scn
*sec_scn
; /* Section descriptor */
114 Elf32_Shdr
*sec_shdr
; /* Section header */
115 Elf_Data
*sec_data
; /* Data region of section */
116 const char *sec_name
; /* Name of section */
117 } elfedit32_section_t
;
120 Elf64_Word sec_shndx
;
122 Elf64_Shdr
*sec_shdr
;
124 const char *sec_name
;
125 } elfedit64_section_t
;
128 #define elfedit_section_t elfedit64_section_t
130 #define elfedit_section_t elfedit32_section_t
135 * We maintain extra information for symbol tables. We look them
136 * up frequently, so we want to eliminate expensive linear searches
137 * of the entire section header array. Also, symbol tables usually
138 * have associated parallal sections (syminfo, versym, extended indexes, etc)
139 * and we want to eliminate repeated linear lookups for them, as well as
140 * the basic error checking that is necessary to ensure they match the
141 * symbol table they're given.
143 * This extra information is kept in elfedit_symtab_t structs. Each field
144 * is a section index, with SHN_UNDEF used for those that do not apply.
147 Elf32_Word symt_shndx
; /* Symbol table section index */
148 Elf32_Word symt_xshndx
; /* Index of extended index section */
149 Elf32_Word symt_syminfo
; /* Index of versym section */
150 Elf32_Word symt_versym
; /* Index of versym section */
151 } elfedit32_symtab_t
;
154 Elf64_Word symt_shndx
;
155 Elf64_Word symt_xshndx
;
156 Elf64_Word symt_versym
;
157 Elf64_Word symt_syminfo
;
158 } elfedit64_symtab_t
;
161 #define elfedit_symtab_t elfedit64_symtab_t
163 #define elfedit_symtab_t elfedit32_symtab_t
168 * Information for a single ELF object.
171 * elfedit is intended to be an expert's tool, capable of modifying
172 * nearly everything in the file, whether or not such modifications
173 * are a good idea. At the same time, elfedit, via libelf, relies
174 * on the contents of the object to properly locate information in
175 * the file. As this is the same information that elfedit allows the
176 * user to modify, it should be obvious that the potential exists
177 * for users to corrupt the file to the degree that elfedit itself
178 * may fail, or produce spurious results. We allow such changes for
181 * 1) Such corruption does not happen in the most obvious and
182 * useful operations elfedit supports, but comes as a result
183 * of modifying fields that contain size and offset information
184 * used to navigate the file. Non-ELF developers have
185 * little practical reason to change such things.
187 * 2) Producing a corrupt ELF file can be very useful
188 * for R&D and/or testing purposes.
190 * 3) ELF is sufficiently complex that no absolute guarantees can
191 * be made about "safe" operations, beyond the basic
192 * and obvious things that are of practical use.
194 * One way we protect ourselves is via the information cached in
195 * the elfedit_obj_state_t structure at startup. By using this
196 * information, rather than constantly fetching it via libelf,
197 * we protect ourselves against many user changes, such as changing the
198 * program or section header offsets, or similar size/position fields.
200 * Of course, we make no assurances that that we will be able to
201 * read the resulting file in a subsequent session.
204 const char *os_file
; /* Path to ELF file */
205 int os_fd
; /* Open file descriptor */
206 Elf
*os_elf
; /* ELF descriptor */
207 Elf32_Ehdr
*os_ehdr
; /* ELF header */
208 Elf32_Word os_dynndx
; /* Index of dynamic section */
209 size_t os_shstrndx
; /* Index of section header */
210 /* string table section */
211 size_t os_shnum
; /* # of sections in file */
212 elfedit32_section_t
*os_secarr
; /* Section data */
213 size_t os_phnum
; /* # of program headers */
214 Elf32_Phdr
*os_phdr
; /* Program header array */
215 size_t os_symtabnum
; /* # items in os_symtab[] */
216 elfedit32_symtab_t
*os_symtab
; /* Array of symbol tbl info */
217 } elfedit32_obj_state_t
;
224 Elf64_Word os_dynndx
;
227 elfedit64_section_t
*os_secarr
;
231 elfedit64_symtab_t
*os_symtab
;
232 } elfedit64_obj_state_t
;
235 #define elfedit_obj_state_t elfedit64_obj_state_t
237 #define elfedit_obj_state_t elfedit32_obj_state_t
242 * Bit values for editor state.
245 ELFEDIT_F_AUTOPRINT
= 1, /* Print informational text about edits */
246 ELFEDIT_F_DEBUG
= 2, /* Print informational text about operations */
247 ELFEDIT_F_READONLY
= 4, /* File is processed readonly */
251 * Type used to represent the output style for printing ELF values.
253 * DEFAULT - Output is in 'elfdump' style, designed for human eyes.
254 * Headers, and additional information are shown.
255 * SIMPLE - Output is simple, consisting only of the target item.
256 * Integer values are shown as symbolic constants when possible,
257 * and integers otherwise.
258 * NUM - Like SIMPLE, except integer values are always shown as
259 * integer constants, and strings are shown as the integer
260 * offset into the string table.
263 ELFEDIT_OUTSTYLE_DEFAULT
= 0,
264 ELFEDIT_OUTSTYLE_SIMPLE
= 1,
265 ELFEDIT_OUTSTYLE_NUM
= 2
266 } elfedit_outstyle_t
;
270 * The elfedit_module_t, and the types it references, are defined
271 * by loadable elfedit modules, and used by elfedit. These structures
272 * need to communicate internationalized strings for elfedit to print.
274 * We want to leave the choice of internationalization APIs, as well as
275 * the decision about whether or not to even to it to the individual
276 * modules. Hence, we do not use a simple (const char *) pointer to
277 * communicate potentially internationalized strings. Instead, we define
278 * elfedit_i18nhdl_t, an opaque type guaranteed to be large enough
279 * to hold a pointer. Each module casts the handle needed to access the
280 * string to this type. Each module also supplies a function
281 * (mod_i18nhdl_to_str field of elfedit_module_t) that given one
282 * of these opaque keys, will return a (const char *) pointer to the
283 * actual string, for elfedit to print.
285 * If the underlying module doesn't want to implement i18n support,
286 * all it has to do is cast the strings to elfedit_i18nhdl_t and
289 typedef uintptr_t elfedit_i18nhdl_t
;
294 * Macro to handle casting international string "handles" to the
295 * elfedit_i18nhdl_t opaque type.
297 #define ELFEDIT_I18NHDL(_i18n_str_ref) ((elfedit_i18nhdl_t)_i18n_str_ref)
301 * Return values from command functions
304 ELFEDIT_CMDRET_NONE
= 0, /* Nothing to report */
305 ELFEDIT_CMDRET_MOD
= 1, /* Command modified output ELF file */
306 ELFEDIT_CMDRET_MOD_OS_MACH
= 2, /* As per _MOD, include ELF header */
307 /* osabi or machine change */
308 ELFEDIT_CMDRET_FLUSH
= 3 /* Output file flushed: elf_update() */
312 * Prototype of an implementation function for an edit command. Note that
313 * commands do not return a status:
314 * - Success is indicated by a normal return.
315 * - The command indicates a fatal error by calling elfedit_msg() with the
316 * ELFEDIT_MSG_ERR type, in which case execution does not return
317 * to the command, and the elfedit command loop knows that an
319 * - The command is responsible for using the standard libelf
320 * mechanisms to indicate when changes have been made to
323 typedef elfedit_cmdret_t
elfedit32_cmd_func_t(elfedit32_obj_state_t
*state
,
324 int argc
, const char *argv
[]);
325 typedef elfedit_cmdret_t
elfedit64_cmd_func_t(elfedit64_obj_state_t
*state
,
326 int argc
, const char *argv
[]);
328 #define elfedit_cmd_func_t elfedit64_cmd_func_t
330 #define elfedit_cmd_func_t elfedit32_cmd_func_t
335 * An elfedit command (elfedit_cmd_t) has a cmd_cpl field that
336 * can be set to a command completion function. If such a function
337 * is present (non-NULL), and the user presses the tab key at the
338 * command line while the cursor is at a plain (non option) argument,
339 * elfedit calls the function, passing it all the tokens up through
340 * the one needing completion. The function can use elfedit_cpl_match()
341 * to enter possible alternatives. Additionally, there are helper
342 * functions built on top of elfedit_cpl_match() that simplify common cases.
344 * elfedit_cpl_ato[iu]() - enter matches from elfedit_ato[iu]_sym_t
346 * elfedit_cpl_atoconst() - Enter matches for well known constants
347 * elfedit_cpl_command() - enter matches for all known commands
348 * elfedit_cpl_mod() - enter matches for all known modules.
349 * elfedit_cpl_ndx() - enter numeric index as a match
351 * The completion function is passed the following arguments:
353 * obj_state - Object state. Will be NULL if elfedit session does not
354 * have an active object. The completion function must test
355 * the pointer before using it.
356 * cpldata - Completion data, to be passed to elfedit_cpl_match()
357 * or the helper functions built on it to register alternative
359 * argc, argv - The tokens from the start of the line through
360 * the one needing completion, which will always
361 * be cmdcpl_argv[cmdcpl_argc - 1].
362 * num_opt - A count of the optional arguments (those starting with
363 * '-' at the beginning of argv. This means that argv[num_opt]
364 * is the first plain argument, and the 1-based positional
365 * number of the plain argument for which command completion
366 * is needed is (argc - num_opt).
368 typedef void elfedit32_cmdcpl_func_t(elfedit32_obj_state_t
*state
,
369 void *cpldata
, int argc
, const char *argv
[], int num_opt
);
370 typedef void elfedit64_cmdcpl_func_t(elfedit64_obj_state_t
*state
,
371 void *cpldata
, int argc
, const char *argv
[], int num_opt
);
373 #define elfedit_cmdcpl_func_t elfedit64_cmdcpl_func_t
375 #define elfedit_cmdcpl_func_t elfedit32_cmdcpl_func_t
382 * Command option/argument descriptor. These structures
383 * are used to represent each option and plain argument accepted
384 * by a command, via the cmd_opt and cmd_args fields in the
385 * command definition (elfedit_cmd_t). Each descriptor consists
386 * of a name, a help string (formatted for display via sys:help),
387 * and a flags field that conveys extra information about the
390 * ELFEDIT_CMDOA_F_OPT
391 * The item is optional. This flag is implicit for options
392 * and need only be set for plain arguments.
394 * ELFEDIT_CMDOA_F_VALUE
395 * The item has a value, which is found in the following
396 * item. This flag only has meaning for options, and should
397 * not be set for plain arguments. The descriptor for the
398 * value is found in the next array element, and only the
399 * oa_name field is used (the other should be set t 0).
401 * ELFEDIT_CMDOA_F_MULT
402 * More than one of the specified items may be specified
404 * ELFEDIT_CMDOA_F_INHERIT
405 * This is an item for which a common definition exists.
406 * Elfedit will substitute the standard values for the
407 * name, help text, and flags. This enforces consistency
408 * in documentation, plus it is easier for the module author.
409 * When ELFEDIT_CMDOA_F_INHERIT is set:
410 * - oa_name should be set to one of the ELFEDIT_STDOA_
411 * values to specifiy which standard item is being
413 * - oa_help must be set to NULL.
414 * - It is an error to set any other flags with
415 * ELFEDIT_CMDOA_F_INHERIT.
416 * - oa_idmask and oa_excmask are used in the normal way.
418 * The oa_idmask and oa_excmask fields are used to identify options,
419 * and to support mutual exclusion (when two or more options cannot be
420 * used together). They are ignored for arguments, and should be set to 0.
421 * oa_idmask is used to uniquely identify each item. When elfedit_getopt()
422 * matches an option, it returns the value of oa_idmask to the caller to
423 * indicate which option was matched. elfedit enforces the following rules
424 * for oa_idmask, and will refuse to load a module that does not follow them:
425 * - The value of oa_idmask must be 0, or have a value that
426 * is a power of 2 (i.e. only has one bit set).
427 * - Each item that sets a non-0 value for oa_idmask must have
429 * - If oa_idmask is 0, oa_excmask must be 0 also.
430 * - oa_excmask is set to 0 if an item is not mutually exclusive
431 * to any other item. Otherwise, it should set the bit
432 * values representing the items it is mutually exclusive to.
433 * - An oa_idmask value of 0 can be used for any item that
434 * the module does not need to identify, and which
435 * is not mutually exclusive to any other item.
436 * As elfedit_getopt() processes items, it maintains a bitmask combining the
437 * oa_idmask fields of all the options already seen. For each option, it uses
438 * oa_excmask to check for conflicts.
440 * note: elfedit enforces the rule that options consist of a '-'
441 * character followed by at least one character when a module
445 ELFEDIT_CMDOA_F_OPT
= 1, /* Item is optional */
446 ELFEDIT_CMDOA_F_VALUE
= 2, /* Item has a value arg following */
447 ELFEDIT_CMDOA_F_MULT
= 4, /* More than one are allowed */
448 ELFEDIT_CMDOA_F_INHERIT
= 8, /* Inherit definition: See above */
449 } elfedit_cmd_oa_flag_t
;
451 typedef u_longlong_t elfedit_cmd_oa_mask_t
;
454 const char *oa_name
; /* Name of option */
455 elfedit_i18nhdl_t oa_help
; /* Help text for option */
456 elfedit_cmd_oa_flag_t oa_flags
; /* Additional attributes */
457 elfedit_cmd_oa_mask_t oa_idmask
; /* Unique id, returned by */
459 /* for use by caller */
460 elfedit_cmd_oa_mask_t oa_excmask
; /* Mutual exclusion mask */
461 } elfedit_cmd_optarg_t
;
466 * These values define the standard options and arguments that a module
467 * can inherit using the ELFEDIT_CMDOA_F_INHERIT flag (described above).
468 * New items must be added at the end --- reordering the list will
469 * require all modules to be rebuilt.
471 * Note: 0 cannot be used as a ELFEDIT_STDOA_ value, because a NULL
472 * value of oa_name is used to terminate argument and options lists.
473 * Therefore, these values start at 1.
475 #define ELFEDIT_STDOA_OPT_O ((const char *) 1) /* -o ostyle */
476 #define ELFEDIT_STDOA_OPT_AND ((const char *) 2) /* -and */
477 #define ELFEDIT_STDOA_OPT_CMP ((const char *) 3) /* -cmp */
478 #define ELFEDIT_STDOA_OPT_OR ((const char *) 4) /* -or */
480 #define ELFEDIT_NUM_STDOA 4 /* # of ELFEDIT_STDOA_ definitions */
485 * Definition of a command
487 * This structure includes an elfedit_cmd_func_t pointer, which has
488 * different definitions for different ELFCLASS. Rather than needlessly
489 * complicate the code with three versions of this type, and any
490 * type that uses it, we simply use the GenericClass type. elfedit
491 * will always cast this to the correct type before calling a module.
493 * cmd_name is an array of pointers to the names for the command.
494 * The "primary" name should always be first, followed by any alias
495 * names. The final element of the array must be a NULL pointer,
496 * which terminates the list. Every command is required to have at
497 * least one name, so code is allowed to assume that the first element
498 * of cmd_name is non-NULL, and contains the primary name.
500 * Many modules provide a "default" command, which is a command
501 * that is run if only the module name is specified, followed
502 * by a colon (i.e. "sym:"). The way this is implemented is to
503 * give the desired default command an empty string as an alias.
504 * Note that the primary name cannot be an empty string, only the
507 * cmd_opts and cmd_args are each an array of elfedit_cmd_argdesc_t
508 * structures, that describe the options and plain arguments accepted
509 * by the command. These arrays are used to general help text for
510 * the commands. The cmd_opts array is also used to provide command
511 * completion for options. Both of these arrays are terminated by
512 * a final NULL element (all fields zero).
515 elfedit32_cmd_func_t
*cmd_func
; /* Implementation */
516 elfedit32_cmdcpl_func_t
*cmd_cplfunc
; /* Completion function */
517 const char **cmd_name
; /* Cmd names (null term.) */
518 elfedit_i18nhdl_t cmd_desc
; /* Short desc. of cmd purpose */
519 elfedit_i18nhdl_t cmd_help
; /* Help text for the command */
520 elfedit_cmd_optarg_t
*cmd_opt
; /* Options */
521 elfedit_cmd_optarg_t
*cmd_args
; /* Plain arguments */
525 elfedit64_cmd_func_t
*cmd_func
;
526 elfedit64_cmdcpl_func_t
*cmd_cplfunc
;
527 const char **cmd_name
;
528 elfedit_i18nhdl_t cmd_desc
;
529 elfedit_i18nhdl_t cmd_help
;
530 elfedit_cmd_optarg_t
*cmd_opt
;
531 elfedit_cmd_optarg_t
*cmd_args
;
535 #define elfedit_cmd_t elfedit64_cmd_t
537 #define elfedit_cmd_t elfedit32_cmd_t
543 * elfedit modules version themselves so that we can alter the definition
544 * of elfedit_module_t in a backward compatible way.
547 ELFEDIT_VER_NONE
= 0,
548 ELFEDIT_VER_CURRENT
= 1,
550 } elfedit_module_version_t
;
554 * Each module returns a pointer to an elfedit_module_t, describing
555 * what commands the module provides.
557 * Note: mod_cmds is a NULL terminated array of command defs. This
558 * means that the final element in the array should have all of its
559 * fields set to NULL.
561 * The mod_i18nhdl_to_str function pointer is explained above
562 * with the definition of elfedit_i18nhdl_t.
564 typedef const char *(* elfedit_mod_i18nhdl_to_str_func_t
)(elfedit_i18nhdl_t
);
567 elfedit_module_version_t mod_version
; /* version */
568 const char *mod_name
; /* Name of module */
569 elfedit_i18nhdl_t mod_desc
; /* Short desc. of mod purpose */
570 elfedit32_cmd_t
*mod_cmds
; /* Array of command defs */
571 /* i18n -> (char *) fcn */
572 elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str
;
573 } elfedit32_module_t
;
576 elfedit_module_version_t mod_version
;
577 const char *mod_name
;
578 elfedit_i18nhdl_t mod_desc
;
579 elfedit64_cmd_t
*mod_cmds
;
580 elfedit_mod_i18nhdl_to_str_func_t mod_i18nhdl_to_str
;
581 } elfedit64_module_t
;
584 #define elfedit_module_t elfedit64_module_t
586 #define elfedit_module_t elfedit32_module_t
591 * Each module is a sharable library, expected to provide a single global
592 * function, named elfedit_init(), with the following prototype.
594 typedef elfedit_module_t
*elfedit_init_func_t(elfedit_module_version_t version
);
598 * Prototype for elfedit_write(), and for outfunc argument
599 * to elfedit_str_to_c_literal().
601 typedef void elfedit_write_func_t(const void *ptr
, size_t size
);
605 * Core elfedit functions exported for use by modules
607 extern void elfedit_command_usage(void);
608 extern void elfedit_cpl_command(void *cpldata
);
609 extern void elfedit_cpl_match(void *cpldata
, const char *str
, int casefold
);
610 extern void elfedit_cpl_ndx(void *cpldata
, uint_t ndx
);
611 extern void elfedit_elferr(const char *file
, const char *libelf_rtn_name
);
612 extern elfedit_flag_t
elfedit_flags(void);
613 extern void *elfedit_malloc(const char *item_name
, size_t size
);
614 extern void elfedit_msg(elfedit_msg_t type
, const char *format
, ...);
615 extern elfedit_outstyle_t
elfedit_outstyle(void);
616 extern void elfedit_pager_init(void);
617 extern void elfedit_printf(const char *format
, ...);
618 extern void *elfedit_realloc(const char *item_name
, void *ptr
, size_t size
);
619 extern void elfedit_str_to_c_literal(const char *str
,
620 elfedit_write_func_t
*outfunc
);
621 extern elfedit_write_func_t elfedit_write
;
624 * Core elfedit functions exported for use by sys: module only
626 extern void elfedit_cpl_module(void *cpldata
, int load_all_modules
);
630 * elfedit modules are expected to define two functions, one for
631 * each ELFCLASS. Define a generic name for this function, based on
632 * the class being supported by the including module.
635 #define elfedit_init elfedit64_init
637 #define elfedit_init elfedit32_init
643 * It is common to search the dynamic section for specific elements.
644 * Structures of this type are used to represent the contents of such
645 * elements in a systematic way. The elfedit_dyn_elt_init() function
646 * is used to prepare these strucutres for use.
649 int dn_seen
; /* True if this item has been seen */
650 Elf32_Word dn_ndx
; /* Index of item in dynamic array */
651 Elf32_Dyn dn_dyn
; /* Contents of dynamic item */
652 } elfedit32_dyn_elt_t
;
658 } elfedit64_dyn_elt_t
;
661 #define elfedit_dyn_elt_t elfedit64_dyn_elt_t
663 #define elfedit_dyn_elt_t elfedit32_dyn_elt_t
667 * The elfedit_atoi() and elfedit_atoui() functions can optionally
668 * accept an array of these structures, giving symbolic names that
669 * will be accepted instead of numeric codes. If such an array is
670 * present, the supplied string has it's leading and trailing whitespace
671 * removed and is then compared to the list, and if there is a match,
672 * the corresponding integer value is returned.
674 * The final array element must have its name field set to NULL.
676 typedef u_longlong_t elfedit_atoui_t
;
678 const char *sym_name
;
679 elfedit_atoui_t sym_value
;
680 } elfedit_atoui_sym_t
;
681 typedef longlong_t elfedit_atoi_t
;
683 const char *sym_name
;
684 elfedit_atoi_t sym_value
;
685 } elfedit_atoi_sym_t
;
689 * The elfedit_atoconst*() functions are built on top of the atoui routines.
690 * These routines accept an elfedit_const_t code instead of a
691 * pointer to an elfedit_atoui_sym_t array, and use internally
692 * predefined tables of elfedit_atoui_sym_t in order to do the desired
693 * mappings. elfedit modules are encouraged to use these standard
694 * tables instead of defining their own elfedit_atoui_sym_t arrays.
697 * - The values assigned here must be in agreement with the
698 * sym_table[] array defined in elfconst.c.
699 * - Once defined, these values must not change. Reordering the
700 * list will require all modules to be rebuilt, and will
701 * break backward compatability. New items should be
705 ELFEDIT_CONST_OUTSTYLE
= 0, /* elfedit output styles */
706 ELFEDIT_CONST_OUTSTYLE_MO
= 1, /* ostyles with -o prefix */
707 ELFEDIT_CONST_BOOL
= 2, /* boolean names */
708 ELFEDIT_CONST_SHT_STRTAB
= 3, /* ELF SHT_STRTAB */
709 ELFEDIT_CONST_SHT_SYMTAB
= 4, /* ELF SHT_SYMTAB */
710 ELFEDIT_CONST_SHT_DYNSYM
= 5, /* ELF SHT_DYNSYM */
711 ELFEDIT_CONST_SHT_LDYNSYM
= 6, /* ELF SHT_SUNW_LDYNSYM */
712 ELFEDIT_CONST_SHN
= 7, /* ELF SHN_ section indexes */
713 ELFEDIT_CONST_SHT
= 8, /* ELF SHT_ section types */
714 ELFEDIT_CONST_SHT_ALLSYMTAB
= 9, /* ELF SHT_ symbol table */
716 ELFEDIT_CONST_DT
= 10, /* Dynamic tags: DT_ */
717 ELFEDIT_CONST_DF
= 11, /* DT_FLAGS bits */
718 ELFEDIT_CONST_DF_P1
= 12, /* DF_POSFLAG_1 bits */
719 ELFEDIT_CONST_DF_1
= 13, /* DT_FLAGS_1 bits */
720 ELFEDIT_CONST_DTF_1
= 14, /* DT_FEATURE_1 bits */
721 ELFEDIT_CONST_EI
= 15, /* ELF header e_ident indexes */
722 ELFEDIT_CONST_ET
= 16, /* Ehdr obj type */
723 ELFEDIT_CONST_ELFCLASS
= 17, /* Ehdr wordsize (32,64) */
724 ELFEDIT_CONST_ELFDATA
= 18, /* Ehdr endian */
725 ELFEDIT_CONST_EF
= 19, /* Ehdr flags */
726 ELFEDIT_CONST_EV
= 20, /* Ehdr version */
727 ELFEDIT_CONST_EM
= 21, /* Ehdr machine */
728 ELFEDIT_CONST_ELFOSABI
= 22, /* Ehdr ABI */
729 ELFEDIT_CONST_EAV
= 23, /* Ehdr ABI version */
730 ELFEDIT_CONST_PT
= 24, /* Phdr type */
731 ELFEDIT_CONST_PF
= 25, /* Phdr flags */
732 ELFEDIT_CONST_SHF
= 26, /* Shdr flags */
733 ELFEDIT_CONST_STB
= 27, /* Sym binding */
734 ELFEDIT_CONST_STT
= 28, /* Sym type */
735 ELFEDIT_CONST_STV
= 29, /* Sym visibility */
736 ELFEDIT_CONST_SYMINFO_BT
= 30, /* Syminfo boundto */
737 ELFEDIT_CONST_SYMINFO_FLG
= 31, /* Syminfo flags */
738 ELFEDIT_CONST_CA
= 32, /* Capabilities tags */
739 ELFEDIT_CONST_HW1_SUNW
= 33, /* hardware capabilities */
740 ELFEDIT_CONST_SF1_SUNW
= 34, /* software capabilities */
741 ELFEDIT_CONST_HW2_SUNW
= 35, /* hardware capabilities */
743 ELFEDIT_CONST_NUM
= 36, /* # of constant types */
747 * Given an elfedit_const_t, return the array of elfedit_atoui_sym_t
748 * entries that it represents.
750 extern elfedit_atoui_sym_t
*elfedit_const_to_atoui(elfedit_const_t const_type
);
753 * ato[u]i and const routines, used to turn strings into numeric values,
754 * with support for mapping symbol names to numbers, and range checking.
756 extern elfedit_atoi_t
elfedit_atoi(const char *str
,
757 const elfedit_atoi_sym_t
*sym
);
758 extern elfedit_atoui_t
elfedit_atoui(const char *str
,
759 const elfedit_atoui_sym_t
*sym
);
760 extern elfedit_atoui_t
elfedit_atoconst(const char *str
,
761 elfedit_const_t const_type
);
763 extern int elfedit_atoi2(const char *str
, const elfedit_atoi_sym_t
*sym
,
765 extern int elfedit_atoui2(const char *str
, const elfedit_atoui_sym_t
*sym
,
767 extern int elfedit_atoconst2(const char *str
, elfedit_const_t const_type
,
770 extern elfedit_atoi_t
elfedit_atoi_range(const char *str
,
771 const char *item_name
, elfedit_atoi_t min
, elfedit_atoi_t max
,
772 const elfedit_atoi_sym_t
*sym
);
773 extern elfedit_atoui_t
elfedit_atoui_range(const char *str
,
774 const char *item_name
, elfedit_atoui_t min
, elfedit_atoui_t max
,
775 const elfedit_atoui_sym_t
*sym
);
776 extern elfedit_atoui_t
elfedit_atoconst_range(const char *str
,
777 const char *item_name
, elfedit_atoui_t min
, elfedit_atoui_t max
,
778 elfedit_const_t const_type
);
780 extern int elfedit_atoi_range2(const char *str
, elfedit_atoi_t min
,
781 elfedit_atoi_t max
, const elfedit_atoi_sym_t
*sym
, elfedit_atoi_t
*v
);
782 extern int elfedit_atoui_range2(const char *str
, elfedit_atoui_t min
,
783 elfedit_atoui_t max
, const elfedit_atoui_sym_t
*sym
, elfedit_atoui_t
*v
);
784 extern int elfedit_atoconst_range2(const char *str
, elfedit_atoui_t min
,
785 elfedit_atoui_t max
, elfedit_const_t const_type
, elfedit_atoui_t
*v
);
787 extern const char *elfedit_atoi_value_to_str(const elfedit_atoi_sym_t
*sym
,
788 elfedit_atoi_t value
, int required
);
789 extern const char *elfedit_atoui_value_to_str(const elfedit_atoui_sym_t
*sym
,
790 elfedit_atoui_t value
, int required
);
791 extern const char *elfedit_atoconst_value_to_str(elfedit_const_t const_type
,
792 elfedit_atoui_t value
, int required
);
794 extern void elfedit_cpl_atoi(void *cpldata
, const elfedit_atoi_sym_t
*sym
);
795 extern void elfedit_cpl_atoui(void *cpldata
, const elfedit_atoui_sym_t
*sym
);
796 extern void elfedit_cpl_atoconst(void *cpldata
, elfedit_const_t const_type
);
800 * Convenience functions built on top of the ato[u]i routines.
802 extern int elfedit_atobool(const char *str
, const char *item_name
);
803 extern elfedit_atoui_t
elfedit_atoshndx(const char *str
, size_t shnum
);
807 * elfedit provides a getopt utility for use by the module commands.
808 * elfedit_getopt_state_t is the state block used by elfedit_getopt().
809 * elfedit_getopt_ret_t is the definition of the values returned to
810 * the user by elfedit_getopt() when an option is matched. Elfedit
811 * getopt processing is done as follows:
813 * 1) The caller initializes an elfedit_getopt_state_t struct via
814 * a call to elfedit_getopt_init(). The contents of this structure
815 * must not be accessed by the caller, as they are all private and
817 * 2) Repeated calls are made to elfedit_getopt(), as long as it returns
818 * a non-NULL pointer to an elfedit_getopt_ret_t structure. If the
819 * matched option has a value (ELFEDIT_CMDOA_F_VALUE), then the gor_value
820 * field contains the pointer to the string. Otherwise, gor_value is NULL.
821 * 3) As elfedit_getopt() consumes optional arguments from the argc/argv
822 * passed to elfedit_getopt_init(), it adjusts argc/argc to skip over
823 * them. Once elfedit_getopt() returns NULL to indicate that there are no
824 * more options to match, argc/argv have been adjusted so that they
825 * reference the plain arguments.
828 elfedit_cmd_oa_mask_t gor_idmask
; /* oa_idmask from matching */
829 /* elfedit_cmd_optarg_t. Can be */
830 /* used to quickly identify opt */
831 const char *gor_value
; /* Opt value if ELFEDIT_CMDOA_F_VALUE */
832 /* Otherwise, NULL */
833 } elfedit_getopt_ret_t
;
835 int *go_argc
; /* Pointer to # of options */
836 const char ***go_argv
; /* Ptr to array of opt strs */
837 elfedit_cmd_optarg_t
*go_optarg
; /* Array of allowed options */
838 elfedit_cmd_oa_mask_t go_idmask
; /* Combined id masks of all */
840 int go_done
; /* True if last option seen */
841 const char *go_sglgrp
; /* Group of 1-letter opts */
842 elfedit_getopt_ret_t go_ret
; /* Data returned to user */
843 } elfedit_getopt_state_t
;
848 * getopt related routines
850 extern void elfedit_getopt_init(elfedit_getopt_state_t
*,
851 int *, const char ***);
852 extern elfedit_getopt_ret_t
*elfedit_getopt(elfedit_getopt_state_t
*);
857 * Additional utility functions exported for use by modules
859 extern void elfedit_array_elts_delete(const char *name_str
, void *data_start
,
860 size_t entsize
, size_t num_ent
, size_t start_ndx
, size_t cnt
);
862 extern void elfedit_array_elts_move(const char *name_str
, void *data_start
,
863 size_t entsize
, size_t num_ent
, size_t srcndx
,
864 size_t dstndx
, size_t cnt
, void *scr_item
);
866 extern int elfedit_bits_set(u_longlong_t v
, int sizeof_orig_v
);
868 extern void elfedit32_dyn_elt_init(elfedit32_dyn_elt_t
*dyn_elt
);
869 extern void elfedit64_dyn_elt_init(elfedit64_dyn_elt_t
*dyn_elt
);
871 extern void elfedit32_dyn_elt_save(elfedit32_dyn_elt_t
*elt
, Elf32_Word ndx
,
873 extern void elfedit64_dyn_elt_save(elfedit64_dyn_elt_t
*elt
, Elf64_Word ndx
,
876 const char *elfedit32_dyn_offset_to_str(elfedit32_section_t
*strsec
,
877 elfedit32_dyn_elt_t
*dynelt
);
878 const char *elfedit64_dyn_offset_to_str(elfedit64_section_t
*strsec
,
879 elfedit64_dyn_elt_t
*dynelt
);
881 extern int elfedit32_dynstr_getpad(elfedit32_obj_state_t
*obj_state
,
882 elfedit32_section_t
*dynsec
, elfedit32_dyn_elt_t
*dyn_strpad
);
883 extern int elfedit64_dynstr_getpad(elfedit64_obj_state_t
*obj_state
,
884 elfedit64_section_t
*dynsec
, elfedit64_dyn_elt_t
*dyn_strpad
);
886 extern Elf32_Word
elfedit32_dynstr_insert(elfedit32_section_t
*dynsec
,
887 elfedit32_section_t
*strsec
, elfedit32_dyn_elt_t
*dyn_strpad
,
889 extern Elf64_Word
elfedit64_dynstr_insert(elfedit64_section_t
*dynsec
,
890 elfedit64_section_t
*strsec
, elfedit64_dyn_elt_t
*dyn_strpad
,
893 extern void elfedit32_modified_data(elfedit32_section_t
*s
);
894 extern void elfedit64_modified_data(elfedit64_section_t
*s
);
896 extern void elfedit32_modified_ehdr(elfedit32_obj_state_t
*obj_state
);
897 extern void elfedit64_modified_ehdr(elfedit64_obj_state_t
*obj_state
);
899 extern void elfedit32_modified_phdr(elfedit32_obj_state_t
*obj_state
);
900 extern void elfedit64_modified_phdr(elfedit64_obj_state_t
*obj_state
);
902 extern void elfedit32_modified_shdr(elfedit32_section_t
*s
);
903 extern void elfedit64_modified_shdr(elfedit64_section_t
*s
);
905 extern Elf32_Word
elfedit32_name_to_shndx(elfedit32_obj_state_t
*obj_state
,
907 extern Elf64_Word
elfedit64_name_to_shndx(elfedit64_obj_state_t
*obj_state
,
910 extern int elfedit32_name_to_symndx(elfedit32_section_t
*symsec
,
911 elfedit32_section_t
*strsec
, const char *name
, elfedit_msg_t msg_type
,
912 Elf32_Word
*ret_symndx
);
913 extern int elfedit64_name_to_symndx(elfedit64_section_t
*symsec
,
914 elfedit64_section_t
*strsec
, const char *name
, elfedit_msg_t msg_type
,
915 Elf64_Word
*ret_symndx
);
917 extern const char *elfedit32_offset_to_str(elfedit32_section_t
*strsec
,
918 Elf32_Word offset
, elfedit_msg_t msg_type
, int debug_msg
);
919 extern const char *elfedit64_offset_to_str(elfedit64_section_t
*strsec
,
920 Elf64_Word offset
, elfedit_msg_t msg_type
, int debug_msg
);
922 extern int elfedit32_sec_findstr(elfedit32_section_t
*sec
, Elf32_Word tail_ign
,
923 const char *str
, Elf32_Word
*ret_offset
);
924 extern int elfedit64_sec_findstr(elfedit64_section_t
*sec
, Elf64_Word tail_ign
,
925 const char *str
, Elf64_Word
*ret_offset
);
927 extern elfedit32_section_t
*elfedit32_sec_get(
928 elfedit32_obj_state_t
*obj_state
, Elf32_Word shndx
);
929 extern elfedit64_section_t
*elfedit64_sec_get(
930 elfedit64_obj_state_t
*obj_state
, Elf64_Word shndx
);
932 extern elfedit32_section_t
*elfedit32_sec_getcap(
933 elfedit32_obj_state_t
*obj_state
, Elf32_Cap
**cap
, Elf32_Word
*num
);
934 extern elfedit64_section_t
*elfedit64_sec_getcap(
935 elfedit64_obj_state_t
*obj_state
, Elf64_Cap
**cap
, Elf64_Word
*num
);
937 extern elfedit32_section_t
*elfedit32_sec_getdyn(
938 elfedit32_obj_state_t
*obj_state
, Elf32_Dyn
**dyn
, Elf32_Word
*num
);
939 extern elfedit64_section_t
*elfedit64_sec_getdyn(
940 elfedit64_obj_state_t
*obj_state
, Elf64_Dyn
**dyn
, Elf64_Word
*num
);
942 extern elfedit32_section_t
*elfedit32_sec_getstr(
943 elfedit32_obj_state_t
*obj_state
, Elf32_Word shndx
, int);
944 extern elfedit64_section_t
*elfedit64_sec_getstr(
945 elfedit64_obj_state_t
*obj_state
, Elf64_Word shndx
, int);
947 extern elfedit32_section_t
*elfedit32_sec_getsyminfo(
948 elfedit32_obj_state_t
*obj_state
, Elf32_Syminfo
**syminfo
, Elf32_Word
*num
);
949 extern elfedit64_section_t
*elfedit64_sec_getsyminfo(
950 elfedit64_obj_state_t
*obj_state
, Elf64_Syminfo
**syminfo
, Elf64_Word
*num
);
952 extern elfedit32_section_t
*elfedit32_sec_getsymtab(
953 elfedit32_obj_state_t
*obj_state
, int by_index
, Elf32_Word index
,
954 const char *name
, Elf32_Sym
**sym
, Elf32_Word
*num
,
955 elfedit32_symtab_t
**aux_info
);
956 extern elfedit64_section_t
*elfedit64_sec_getsymtab(
957 elfedit64_obj_state_t
*obj_state
, int by_index
, Elf64_Word index
,
958 const char *name
, Elf64_Sym
**sym
, Elf64_Word
*num
,
959 elfedit64_symtab_t
**aux_info
);
961 extern elfedit32_section_t
*elfedit32_sec_getversym(
962 elfedit32_obj_state_t
*obj_state
, elfedit32_section_t
*symsec
,
963 Elf32_Versym
**versym
, Elf32_Word
*num
);
964 extern elfedit64_section_t
*elfedit64_sec_getversym(
965 elfedit64_obj_state_t
*obj_state
, elfedit64_section_t
*symsec
,
966 Elf64_Versym
**versym
, Elf64_Word
*num
);
968 extern elfedit32_section_t
*elfedit32_sec_getxshndx(
969 elfedit32_obj_state_t
*obj_state
, elfedit32_section_t
*symsec
,
970 Elf32_Word
**xshndx
, Elf32_Word
*num
);
971 extern elfedit64_section_t
*elfedit64_sec_getxshndx(
972 elfedit64_obj_state_t
*obj_state
, elfedit64_section_t
*symsec
,
973 Elf64_Word
**xshndx
, Elf64_Word
*num
);
975 extern int elfedit32_sec_issymtab(elfedit32_obj_state_t
*obj_state
,
976 elfedit32_section_t
*sec
, int issue_err
, elfedit_atoui_sym_t
**atoui_list
);
977 extern int elfedit64_sec_issymtab(elfedit64_obj_state_t
*obj_state
,
978 elfedit64_section_t
*sec
, int issue_err
, elfedit_atoui_sym_t
**atoui_list
);
980 extern const char *elfedit32_sec_msgprefix(elfedit32_section_t
*sec
);
981 extern const char *elfedit64_sec_msgprefix(elfedit64_section_t
*sec
);
983 extern const char *elfedit32_shndx_to_name(elfedit32_obj_state_t
*obj_state
,
985 extern const char *elfedit64_shndx_to_name(elfedit64_obj_state_t
*obj_state
,
988 extern Elf32_Word
elfedit32_strtab_insert(elfedit32_obj_state_t
*obj_state
,
989 elfedit32_section_t
*strsec
, elfedit32_section_t
*dynsec
, const char *str
);
990 extern Elf64_Word
elfedit64_strtab_insert(elfedit64_obj_state_t
*obj_state
,
991 elfedit64_section_t
*strsec
, elfedit64_section_t
*dynsec
, const char *str
);
993 extern void elfedit32_strtab_insert_test(elfedit32_obj_state_t
*obj_state
,
994 elfedit32_section_t
*strsec
, elfedit32_section_t
*dynsec
, const char *str
);
995 extern void elfedit64_strtab_insert_test(elfedit64_obj_state_t
*obj_state
,
996 elfedit64_section_t
*strsec
, elfedit64_section_t
*dynsec
, const char *str
);
998 extern int elfedit32_test_osabi(elfedit32_obj_state_t
*obj_state
, uchar_t osabi
,
1000 extern int elfedit64_test_osabi(elfedit64_obj_state_t
*obj_state
, uchar_t osabi
,
1003 extern Elf32_Word
elfedit32_type_to_shndx(elfedit32_obj_state_t
*obj_state
,
1005 extern Elf64_Word
elfedit64_type_to_shndx(elfedit64_obj_state_t
*obj_state
,
1011 * Map the generic names for each of the ELFCLASS specific routines
1012 * above to reference the proper routine for the current compilation.
1015 #define elfedit_dyn_elt_init elfedit64_dyn_elt_init
1016 #define elfedit_dyn_elt_save elfedit64_dyn_elt_save
1017 #define elfedit_dyn_offset_to_str elfedit64_dyn_offset_to_str
1018 #define elfedit_dynstr_getpad elfedit64_dynstr_getpad
1019 #define elfedit_dynstr_insert elfedit64_dynstr_insert
1020 #define elfedit_modified_data elfedit64_modified_data
1021 #define elfedit_modified_ehdr elfedit64_modified_ehdr
1022 #define elfedit_modified_phdr elfedit64_modified_phdr
1023 #define elfedit_modified_shdr elfedit64_modified_shdr
1024 #define elfedit_name_to_shndx elfedit64_name_to_shndx
1025 #define elfedit_name_to_symndx elfedit64_name_to_symndx
1026 #define elfedit_offset_to_str elfedit64_offset_to_str
1027 #define elfedit_sec_findstr elfedit64_sec_findstr
1028 #define elfedit_sec_get elfedit64_sec_get
1029 #define elfedit_sec_getcap elfedit64_sec_getcap
1030 #define elfedit_sec_getdyn elfedit64_sec_getdyn
1031 #define elfedit_sec_getstr elfedit64_sec_getstr
1032 #define elfedit_sec_getsyminfo elfedit64_sec_getsyminfo
1033 #define elfedit_sec_getsymtab elfedit64_sec_getsymtab
1034 #define elfedit_sec_getversym elfedit64_sec_getversym
1035 #define elfedit_sec_getxshndx elfedit64_sec_getxshndx
1036 #define elfedit_sec_issymtab elfedit64_sec_issymtab
1037 #define elfedit_shndx_to_name elfedit64_shndx_to_name
1038 #define elfedit_sec_msgprefix elfedit64_sec_msgprefix
1039 #define elfedit_strtab_insert elfedit64_strtab_insert
1040 #define elfedit_strtab_insert_test elfedit64_strtab_insert_test
1041 #define elfedit_test_osabi elfedit64_test_osabi
1042 #define elfedit_type_to_shndx elfedit64_type_to_shndx
1044 #define elfedit_dyn_elt_init elfedit32_dyn_elt_init
1045 #define elfedit_dyn_elt_save elfedit32_dyn_elt_save
1046 #define elfedit_dyn_offset_to_str elfedit32_dyn_offset_to_str
1047 #define elfedit_dynstr_getpad elfedit32_dynstr_getpad
1048 #define elfedit_dynstr_insert elfedit32_dynstr_insert
1049 #define elfedit_modified_data elfedit32_modified_data
1050 #define elfedit_modified_ehdr elfedit32_modified_ehdr
1051 #define elfedit_modified_phdr elfedit32_modified_phdr
1052 #define elfedit_modified_shdr elfedit32_modified_shdr
1053 #define elfedit_name_to_shndx elfedit32_name_to_shndx
1054 #define elfedit_name_to_symndx elfedit32_name_to_symndx
1055 #define elfedit_offset_to_str elfedit32_offset_to_str
1056 #define elfedit_sec_findstr elfedit32_sec_findstr
1057 #define elfedit_sec_get elfedit32_sec_get
1058 #define elfedit_sec_getcap elfedit32_sec_getcap
1059 #define elfedit_sec_getdyn elfedit32_sec_getdyn
1060 #define elfedit_sec_getstr elfedit32_sec_getstr
1061 #define elfedit_sec_getsyminfo elfedit32_sec_getsyminfo
1062 #define elfedit_sec_getsymtab elfedit32_sec_getsymtab
1063 #define elfedit_sec_getversym elfedit32_sec_getversym
1064 #define elfedit_sec_getxshndx elfedit32_sec_getxshndx
1065 #define elfedit_sec_issymtab elfedit32_sec_issymtab
1066 #define elfedit_shndx_to_name elfedit32_shndx_to_name
1067 #define elfedit_sec_msgprefix elfedit32_sec_msgprefix
1068 #define elfedit_strtab_insert elfedit32_strtab_insert
1069 #define elfedit_strtab_insert_test elfedit32_strtab_insert_test
1070 #define elfedit_test_osabi elfedit32_test_osabi
1071 #define elfedit_type_to_shndx elfedit32_type_to_shndx
1079 #endif /* _ELFEDIT_H */