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