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 2010 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_ELFEDIT_H
28#define	_ELFEDIT_H
29
30#include	<stdio.h>
31#include	<stdlib.h>
32#include	<sys/types.h>
33#include	<libelf.h>
34#include	<stdarg.h>
35
36/* The following are here to support use of elfedit_msg() */
37#include	<sys/machelf.h>		/* EC_ macros */
38#include	<libintl.h>
39
40#ifdef	__cplusplus
41extern "C" {
42#endif
43
44
45/*
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:
49 *
50 *	ELFEDIT_MSG_ERR:
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.
54 *
55 *	ELFEDIT_MSG_FATAL:
56 *		Issues an error to stderr. elfedit_msg() exits the process,
57 *		and does not return to the caller.
58 *
59 *	ELFEDIT_MSG_USAGE:
60 *		Issues an elfedit usage message to stderr, and
61 *		returns to the caller.
62 *
63 *	ELFEDIT_MSG_CMDUSAGE
64 *		Issues an elfedit usage message to stderr, and
65 *		does not return to the caller.
66 *
67 *	ELFEDIT_MSG_DEBUG
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.
71 *
72 *	ELFEDIT_MSG_QUIET
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
77 *		actually printed.
78 *
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.
84 */
85typedef enum {
86	ELFEDIT_MSG_ERR = 0,
87	ELFEDIT_MSG_FATAL = 1,
88	ELFEDIT_MSG_USAGE = 2,
89	ELFEDIT_MSG_CMDUSAGE = 3,
90	ELFEDIT_MSG_DEBUG = 4,
91	ELFEDIT_MSG_QUIET = 5
92} elfedit_msg_t;
93
94
95/*
96 * Information for a single ELF section.
97 *
98 * NOTE: sec_xshndx
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.
105 *
106 * NOTE: sec_versym
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.
110 */
111typedef struct {
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;
118
119typedef struct {
120	Elf64_Word	sec_shndx;
121	Elf_Scn		*sec_scn;
122	Elf64_Shdr	*sec_shdr;
123	Elf_Data	*sec_data;
124	const char	*sec_name;
125} elfedit64_section_t;
126
127#ifdef _ELF64
128#define	elfedit_section_t	elfedit64_section_t
129#else
130#define	elfedit_section_t	elfedit32_section_t
131#endif
132
133
134/*
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.
142 *
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.
145 */
146typedef struct {
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;
152
153typedef struct {
154	Elf64_Word	symt_shndx;
155	Elf64_Word	symt_xshndx;
156	Elf64_Word	symt_versym;
157	Elf64_Word	symt_syminfo;
158} elfedit64_symtab_t;
159
160#ifdef _ELF64
161#define	elfedit_symtab_t	elfedit64_symtab_t
162#else
163#define	elfedit_symtab_t	elfedit32_symtab_t
164#endif
165
166
167/*
168 * Information for a single ELF object.
169 *
170 * note:
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
179 *	several reasons:
180 *
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.
186 *
187 *	2) Producing a corrupt ELF file can be very useful
188 *		for R&D and/or testing purposes.
189 *
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.
193 *
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.
199 *
200 *	Of course, we make no assurances that that we will be able to
201 *	read the resulting file in a subsequent session.
202 */
203typedef struct {
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;
218
219typedef struct {
220	const char		*os_file;
221	int			os_fd;
222	Elf			*os_elf;
223	Elf64_Ehdr		*os_ehdr;
224	Elf64_Word		os_dynndx;
225	size_t			os_shstrndx;
226	size_t			os_shnum;
227	elfedit64_section_t	*os_secarr;
228	size_t			os_phnum;
229	Elf64_Phdr		*os_phdr;
230	size_t			os_symtabnum;
231	elfedit64_symtab_t	*os_symtab;
232} elfedit64_obj_state_t;
233
234#ifdef _ELF64
235#define	elfedit_obj_state_t	elfedit64_obj_state_t
236#else
237#define	elfedit_obj_state_t	elfedit32_obj_state_t
238#endif
239
240
241/*
242 * Bit values for editor state.
243 */
244typedef enum {
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 */
248} elfedit_flag_t;
249
250/*
251 * Type used to represent the output style for printing ELF values.
252 *
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.
261 */
262typedef enum {
263	ELFEDIT_OUTSTYLE_DEFAULT = 0,
264	ELFEDIT_OUTSTYLE_SIMPLE = 1,
265	ELFEDIT_OUTSTYLE_NUM = 2
266} elfedit_outstyle_t;
267
268
269/*
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.
273 *
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.
284 *
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
287 * back.
288 */
289typedef uintptr_t elfedit_i18nhdl_t;
290
291
292
293/*
294 * Macro to handle casting international string "handles" to the
295 * elfedit_i18nhdl_t opaque type.
296 */
297#define	ELFEDIT_I18NHDL(_i18n_str_ref) ((elfedit_i18nhdl_t)_i18n_str_ref)
298
299
300/*
301 * Return values from command functions
302 */
303typedef enum {
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() */
309} elfedit_cmdret_t;
310
311/*
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
318 *		error occurred.
319 *	- The command is responsible for using the standard libelf
320 *		mechanisms to indicate when changes have been made to
321 *		the ELF file.
322 */
323typedef elfedit_cmdret_t elfedit32_cmd_func_t(elfedit32_obj_state_t *state,
324    int argc, const char *argv[]);
325typedef elfedit_cmdret_t elfedit64_cmd_func_t(elfedit64_obj_state_t *state,
326    int argc, const char *argv[]);
327#ifdef _ELF64
328#define	elfedit_cmd_func_t	elfedit64_cmd_func_t
329#else
330#define	elfedit_cmd_func_t	elfedit32_cmd_func_t
331#endif
332
333
334/*
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.
343 *
344 *	elfedit_cpl_ato[iu]() - enter matches from elfedit_ato[iu]_sym_t
345 *		mappings.
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
350 *
351 * The completion function is passed the following arguments:
352 *
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
358 *		strings.
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).
367 */
368typedef void elfedit32_cmdcpl_func_t(elfedit32_obj_state_t *state,
369    void *cpldata, int argc, const char *argv[], int num_opt);
370typedef void elfedit64_cmdcpl_func_t(elfedit64_obj_state_t *state,
371    void *cpldata, int argc, const char *argv[], int num_opt);
372#ifdef _ELF64
373#define	elfedit_cmdcpl_func_t	elfedit64_cmdcpl_func_t
374#else
375#define	elfedit_cmdcpl_func_t	elfedit32_cmdcpl_func_t
376#endif
377
378
379
380
381/*
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
388 * item:
389 *
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.
393 *
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).
400 *
401 *	ELFEDIT_CMDOA_F_MULT
402 *	More than one of the specified items may be specified
403 *
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
412 *			inherited.
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.
417 *
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
428 *		a unique value.
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.
439 *
440 * note: elfedit enforces the rule that options consist of a '-'
441 *	character followed by at least one character when a module
442 *	is loaded.
443 */
444typedef enum {
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;
450
451typedef u_longlong_t elfedit_cmd_oa_mask_t;
452
453typedef struct {
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 */
458						/* 	elfedit_getopt */
459						/*	for use by caller */
460	elfedit_cmd_oa_mask_t	oa_excmask;	/* Mutual exclusion mask */
461} elfedit_cmd_optarg_t;
462
463
464
465/*
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.
470 *
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.
474 */
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 */
479
480#define	ELFEDIT_NUM_STDOA	4	/* # of ELFEDIT_STDOA_ definitions */
481
482
483
484/*
485 * Definition of a command
486 *
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.
492 *
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.
499 *
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
505 * alias name.
506 *
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).
513 */
514typedef struct {
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 */
522} elfedit32_cmd_t;
523
524typedef struct {
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;
532} elfedit64_cmd_t;
533
534#ifdef _ELF64
535#define	elfedit_cmd_t		elfedit64_cmd_t
536#else
537#define	elfedit_cmd_t		elfedit32_cmd_t
538#endif
539
540
541
542/*
543 * elfedit modules version themselves so that we can alter the definition
544 * of elfedit_module_t in a backward compatible way.
545 */
546typedef enum {
547	ELFEDIT_VER_NONE = 0,
548	ELFEDIT_VER_CURRENT = 1,
549	ELFEDIT_VER_NUM = 2
550} elfedit_module_version_t;
551
552
553/*
554 * Each module returns a pointer to an elfedit_module_t, describing
555 * what commands the module provides.
556 *
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.
560 *
561 * The mod_i18nhdl_to_str function pointer is explained above
562 * with the definition of elfedit_i18nhdl_t.
563 */
564typedef const char *(* elfedit_mod_i18nhdl_to_str_func_t)(elfedit_i18nhdl_t);
565
566typedef struct {
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;
574
575typedef struct {
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;
582
583#ifdef _ELF64
584#define	elfedit_module_t	elfedit64_module_t
585#else
586#define	elfedit_module_t	elfedit32_module_t
587#endif
588
589
590/*
591 * Each module is a sharable library, expected to provide a single global
592 * function, named elfedit_init(), with the following prototype.
593 */
594typedef elfedit_module_t *elfedit_init_func_t(elfedit_module_version_t version);
595
596
597/*
598 * Prototype for elfedit_write(), and for outfunc argument
599 * to elfedit_str_to_c_literal().
600 */
601typedef void elfedit_write_func_t(const void *ptr, size_t size);
602
603
604/*
605 * Core elfedit functions exported for use by modules
606 */
607extern void elfedit_command_usage(void);
608extern void elfedit_cpl_command(void *cpldata);
609extern void elfedit_cpl_match(void *cpldata, const char *str, int casefold);
610extern void elfedit_cpl_ndx(void *cpldata, uint_t ndx);
611extern void elfedit_elferr(const char *file, const char *libelf_rtn_name);
612extern elfedit_flag_t elfedit_flags(void);
613extern void *elfedit_malloc(const char *item_name, size_t size);
614extern void elfedit_msg(elfedit_msg_t type, const char *format, ...);
615extern elfedit_outstyle_t elfedit_outstyle(void);
616extern void elfedit_pager_init(void);
617extern void elfedit_printf(const char *format, ...);
618extern void *elfedit_realloc(const char *item_name, void *ptr, size_t size);
619extern void elfedit_str_to_c_literal(const char *str,
620    elfedit_write_func_t *outfunc);
621extern elfedit_write_func_t elfedit_write;
622
623/*
624 * Core elfedit functions exported for use by sys: module only
625 */
626extern void elfedit_cpl_module(void *cpldata, int load_all_modules);
627
628
629/*
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.
633 */
634#ifdef _ELF64
635#define	elfedit_init		elfedit64_init
636#else
637#define	elfedit_init		elfedit32_init
638#endif
639
640
641
642/*
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.
647 */
648typedef struct {
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;
653
654typedef struct {
655	int		dn_seen;
656	Elf64_Word	dn_ndx;
657	Elf64_Dyn	dn_dyn;
658} elfedit64_dyn_elt_t;
659
660#ifdef _ELF64
661#define	elfedit_dyn_elt_t	elfedit64_dyn_elt_t
662#else
663#define	elfedit_dyn_elt_t	elfedit32_dyn_elt_t
664#endif
665
666/*
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.
673 *
674 * The final array element must have its name field set to NULL.
675 */
676typedef u_longlong_t elfedit_atoui_t;
677typedef struct {
678	const char	*sym_name;
679	elfedit_atoui_t	sym_value;
680} elfedit_atoui_sym_t;
681typedef longlong_t elfedit_atoi_t;
682typedef struct {
683	const char	*sym_name;
684	elfedit_atoi_t	sym_value;
685} elfedit_atoi_sym_t;
686
687
688/*
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.
695 *
696 * note:
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
702 *		added to the end.
703 */
704typedef enum {
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 */
715						/*	section types */
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 */
742
743	ELFEDIT_CONST_NUM =		36,	/* # of constant types */
744} elfedit_const_t;
745
746/*
747 * Given an elfedit_const_t, return the array of elfedit_atoui_sym_t
748 * entries that it represents.
749 */
750extern elfedit_atoui_sym_t *elfedit_const_to_atoui(elfedit_const_t const_type);
751
752/*
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.
755 */
756extern elfedit_atoi_t elfedit_atoi(const char *str,
757    const elfedit_atoi_sym_t *sym);
758extern elfedit_atoui_t elfedit_atoui(const char *str,
759    const elfedit_atoui_sym_t *sym);
760extern elfedit_atoui_t elfedit_atoconst(const char *str,
761    elfedit_const_t const_type);
762
763extern int elfedit_atoi2(const char *str, const elfedit_atoi_sym_t *sym,
764    elfedit_atoi_t *v);
765extern int elfedit_atoui2(const char *str, const elfedit_atoui_sym_t *sym,
766    elfedit_atoui_t *);
767extern int elfedit_atoconst2(const char *str, elfedit_const_t const_type,
768    elfedit_atoui_t *);
769
770extern 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);
773extern 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);
776extern 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);
779
780extern 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);
782extern 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);
784extern 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);
786
787extern const char *elfedit_atoi_value_to_str(const elfedit_atoi_sym_t *sym,
788    elfedit_atoi_t value, int required);
789extern const char *elfedit_atoui_value_to_str(const elfedit_atoui_sym_t *sym,
790    elfedit_atoui_t value, int required);
791extern const char *elfedit_atoconst_value_to_str(elfedit_const_t const_type,
792    elfedit_atoui_t value, int required);
793
794extern void elfedit_cpl_atoi(void *cpldata, const elfedit_atoi_sym_t *sym);
795extern void elfedit_cpl_atoui(void *cpldata, const elfedit_atoui_sym_t *sym);
796extern void elfedit_cpl_atoconst(void *cpldata, elfedit_const_t const_type);
797
798
799/*
800 * Convenience functions built on top of the ato[u]i routines.
801 */
802extern int elfedit_atobool(const char *str, const char *item_name);
803extern elfedit_atoui_t elfedit_atoshndx(const char *str, size_t shnum);
804
805
806/*
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:
812 *
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
816 *	subject to change.
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.
826 */
827typedef struct {
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;
834typedef struct {
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 */
839						/*	seen options */
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;
844
845
846
847/*
848 * getopt related routines
849 */
850extern void elfedit_getopt_init(elfedit_getopt_state_t *,
851    int *, const char ***);
852extern elfedit_getopt_ret_t *elfedit_getopt(elfedit_getopt_state_t *);
853
854
855
856/*
857 * Additional utility functions exported for use by modules
858 */
859extern 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);
861
862extern 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);
865
866extern int elfedit_bits_set(u_longlong_t v, int sizeof_orig_v);
867
868extern void elfedit32_dyn_elt_init(elfedit32_dyn_elt_t *dyn_elt);
869extern void elfedit64_dyn_elt_init(elfedit64_dyn_elt_t *dyn_elt);
870
871extern void elfedit32_dyn_elt_save(elfedit32_dyn_elt_t *elt, Elf32_Word ndx,
872    Elf32_Dyn *dyn);
873extern void elfedit64_dyn_elt_save(elfedit64_dyn_elt_t *elt, Elf64_Word ndx,
874    Elf64_Dyn *dyn);
875
876const char *elfedit32_dyn_offset_to_str(elfedit32_section_t *strsec,
877    elfedit32_dyn_elt_t *dynelt);
878const char *elfedit64_dyn_offset_to_str(elfedit64_section_t *strsec,
879    elfedit64_dyn_elt_t *dynelt);
880
881extern int elfedit32_dynstr_getpad(elfedit32_obj_state_t *obj_state,
882    elfedit32_section_t *dynsec, elfedit32_dyn_elt_t *dyn_strpad);
883extern int elfedit64_dynstr_getpad(elfedit64_obj_state_t *obj_state,
884    elfedit64_section_t *dynsec, elfedit64_dyn_elt_t *dyn_strpad);
885
886extern Elf32_Word elfedit32_dynstr_insert(elfedit32_section_t *dynsec,
887    elfedit32_section_t *strsec, elfedit32_dyn_elt_t *dyn_strpad,
888    const char *str);
889extern Elf64_Word elfedit64_dynstr_insert(elfedit64_section_t *dynsec,
890    elfedit64_section_t *strsec, elfedit64_dyn_elt_t *dyn_strpad,
891    const char *str);
892
893extern void elfedit32_modified_data(elfedit32_section_t *s);
894extern void elfedit64_modified_data(elfedit64_section_t *s);
895
896extern void elfedit32_modified_ehdr(elfedit32_obj_state_t *obj_state);
897extern void elfedit64_modified_ehdr(elfedit64_obj_state_t *obj_state);
898
899extern void elfedit32_modified_phdr(elfedit32_obj_state_t *obj_state);
900extern void elfedit64_modified_phdr(elfedit64_obj_state_t *obj_state);
901
902extern void elfedit32_modified_shdr(elfedit32_section_t *s);
903extern void elfedit64_modified_shdr(elfedit64_section_t *s);
904
905extern Elf32_Word elfedit32_name_to_shndx(elfedit32_obj_state_t *obj_state,
906    const char *shnam);
907extern Elf64_Word elfedit64_name_to_shndx(elfedit64_obj_state_t *obj_state,
908    const char *shnam);
909
910extern 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);
913extern 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);
916
917extern const char *elfedit32_offset_to_str(elfedit32_section_t *strsec,
918    Elf32_Word offset, elfedit_msg_t msg_type, int debug_msg);
919extern const char *elfedit64_offset_to_str(elfedit64_section_t *strsec,
920    Elf64_Word offset, elfedit_msg_t msg_type, int debug_msg);
921
922extern int elfedit32_sec_findstr(elfedit32_section_t *sec, Elf32_Word tail_ign,
923    const char *str, Elf32_Word *ret_offset);
924extern int elfedit64_sec_findstr(elfedit64_section_t *sec, Elf64_Word tail_ign,
925    const char *str, Elf64_Word *ret_offset);
926
927extern elfedit32_section_t *elfedit32_sec_get(
928    elfedit32_obj_state_t *obj_state, Elf32_Word shndx);
929extern elfedit64_section_t *elfedit64_sec_get(
930    elfedit64_obj_state_t *obj_state, Elf64_Word shndx);
931
932extern elfedit32_section_t *elfedit32_sec_getcap(
933    elfedit32_obj_state_t *obj_state, Elf32_Cap **cap, Elf32_Word *num);
934extern elfedit64_section_t *elfedit64_sec_getcap(
935    elfedit64_obj_state_t *obj_state, Elf64_Cap **cap, Elf64_Word *num);
936
937extern elfedit32_section_t *elfedit32_sec_getdyn(
938    elfedit32_obj_state_t *obj_state, Elf32_Dyn **dyn, Elf32_Word *num);
939extern elfedit64_section_t *elfedit64_sec_getdyn(
940    elfedit64_obj_state_t *obj_state, Elf64_Dyn **dyn, Elf64_Word *num);
941
942extern elfedit32_section_t *elfedit32_sec_getstr(
943    elfedit32_obj_state_t *obj_state, Elf32_Word shndx, int);
944extern elfedit64_section_t *elfedit64_sec_getstr(
945    elfedit64_obj_state_t *obj_state, Elf64_Word shndx, int);
946
947extern elfedit32_section_t *elfedit32_sec_getsyminfo(
948    elfedit32_obj_state_t *obj_state, Elf32_Syminfo **syminfo, Elf32_Word *num);
949extern elfedit64_section_t *elfedit64_sec_getsyminfo(
950    elfedit64_obj_state_t *obj_state, Elf64_Syminfo **syminfo, Elf64_Word *num);
951
952extern 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);
956extern 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);
960
961extern elfedit32_section_t *elfedit32_sec_getversym(
962    elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec,
963    Elf32_Versym **versym, Elf32_Word *num);
964extern elfedit64_section_t *elfedit64_sec_getversym(
965    elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec,
966    Elf64_Versym **versym, Elf64_Word *num);
967
968extern elfedit32_section_t *elfedit32_sec_getxshndx(
969    elfedit32_obj_state_t *obj_state, elfedit32_section_t *symsec,
970    Elf32_Word **xshndx, Elf32_Word *num);
971extern elfedit64_section_t *elfedit64_sec_getxshndx(
972    elfedit64_obj_state_t *obj_state, elfedit64_section_t *symsec,
973    Elf64_Word **xshndx, Elf64_Word *num);
974
975extern int elfedit32_sec_issymtab(elfedit32_obj_state_t *obj_state,
976    elfedit32_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list);
977extern int elfedit64_sec_issymtab(elfedit64_obj_state_t *obj_state,
978    elfedit64_section_t *sec, int issue_err, elfedit_atoui_sym_t **atoui_list);
979
980extern const char *elfedit32_sec_msgprefix(elfedit32_section_t *sec);
981extern const char *elfedit64_sec_msgprefix(elfedit64_section_t *sec);
982
983extern const char *elfedit32_shndx_to_name(elfedit32_obj_state_t *obj_state,
984    Elf32_Word shndx);
985extern const char *elfedit64_shndx_to_name(elfedit64_obj_state_t *obj_state,
986    Elf64_Word shndx);
987
988extern Elf32_Word elfedit32_strtab_insert(elfedit32_obj_state_t *obj_state,
989    elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str);
990extern Elf64_Word elfedit64_strtab_insert(elfedit64_obj_state_t *obj_state,
991    elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str);
992
993extern void elfedit32_strtab_insert_test(elfedit32_obj_state_t *obj_state,
994    elfedit32_section_t *strsec, elfedit32_section_t *dynsec, const char *str);
995extern void elfedit64_strtab_insert_test(elfedit64_obj_state_t *obj_state,
996    elfedit64_section_t *strsec, elfedit64_section_t *dynsec, const char *str);
997
998extern int elfedit32_test_osabi(elfedit32_obj_state_t *obj_state, uchar_t osabi,
999    int issue_err);
1000extern int elfedit64_test_osabi(elfedit64_obj_state_t *obj_state, uchar_t osabi,
1001    int issue_err);
1002
1003extern Elf32_Word elfedit32_type_to_shndx(elfedit32_obj_state_t *obj_state,
1004    Elf32_Word shtype);
1005extern Elf64_Word elfedit64_type_to_shndx(elfedit64_obj_state_t *obj_state,
1006    Elf64_Word shtype);
1007
1008
1009
1010/*
1011 * Map the generic names for each of the ELFCLASS specific routines
1012 * above to reference the proper routine for the current compilation.
1013 */
1014#ifdef _ELF64
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
1043#else
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
1072#endif
1073
1074
1075#ifdef	__cplusplus
1076}
1077#endif
1078
1079#endif	/* _ELFEDIT_H */
1080