xref: /onnv-gate/usr/src/cmd/sgs/libelf/common/decl.h (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
28*0Sstevel@tonic-gate  * Use is subject to license terms.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #ifndef	_DECL_H
32*0Sstevel@tonic-gate #define	_DECL_H
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI" 	/* SVr4.0 1.9	*/
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #include <thread.h>
37*0Sstevel@tonic-gate #include <note.h>
38*0Sstevel@tonic-gate #include <libelf.h>
39*0Sstevel@tonic-gate #include <sys/machelf.h>
40*0Sstevel@tonic-gate #include <gelf.h>
41*0Sstevel@tonic-gate #include <msg.h>
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #ifdef	__cplusplus
45*0Sstevel@tonic-gate extern "C" {
46*0Sstevel@tonic-gate #endif
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate typedef struct Member	Member;
49*0Sstevel@tonic-gate typedef struct Memlist	Memlist;
50*0Sstevel@tonic-gate typedef struct Memident	Memident;
51*0Sstevel@tonic-gate typedef struct Dnode	Dnode;
52*0Sstevel@tonic-gate typedef struct Snode32	Snode32;
53*0Sstevel@tonic-gate typedef struct Snode64	Snode64;
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate /*
57*0Sstevel@tonic-gate  * Data alignment
58*0Sstevel@tonic-gate  *	An elf file is defined to have its structures aligned on
59*0Sstevel@tonic-gate  *	appropriate boundaries.  The following type lets the
60*0Sstevel@tonic-gate  *	library test whether the file's alignment meets its own
61*0Sstevel@tonic-gate  *	constraints in memory.  This assumes every machine uses
62*0Sstevel@tonic-gate  *	an alignment that is no greater than an object's size.
63*0Sstevel@tonic-gate  *	The pointer isn't relevant for the file, but the code uses
64*0Sstevel@tonic-gate  *	it to get memory alignment.  ANSI C void * holds any pointer,
65*0Sstevel@tonic-gate  *	making it appropriate here.
66*0Sstevel@tonic-gate  */
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate typedef union
69*0Sstevel@tonic-gate {
70*0Sstevel@tonic-gate 	Elf32_Word	w;
71*0Sstevel@tonic-gate 	Elf32_Addr	a;
72*0Sstevel@tonic-gate 	Elf32_Off	o;
73*0Sstevel@tonic-gate } Elf32;
74*0Sstevel@tonic-gate 
75*0Sstevel@tonic-gate typedef union {
76*0Sstevel@tonic-gate 	Elf64_Xword	x;
77*0Sstevel@tonic-gate 	Elf64_Word	w;
78*0Sstevel@tonic-gate 	Elf64_Addr	a;
79*0Sstevel@tonic-gate 	Elf64_Off	o;
80*0Sstevel@tonic-gate 	Elf_Void	*p;
81*0Sstevel@tonic-gate } Elf64;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate /*
85*0Sstevel@tonic-gate  * Memory allocation
86*0Sstevel@tonic-gate  *	Structures are obtained several ways: file mapping,
87*0Sstevel@tonic-gate  *	malloc(), from the user.  A status bit in the structures
88*0Sstevel@tonic-gate  *	tells whether an object was obtained with malloc() and
89*0Sstevel@tonic-gate  *	therefore should be released with free().  The bits
90*0Sstevel@tonic-gate  *	named ...ALLOC indicate this.
91*0Sstevel@tonic-gate  */
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate /*
95*0Sstevel@tonic-gate  * Data descriptor
96*0Sstevel@tonic-gate  *	db_data must be first in the Dnode structure, because
97*0Sstevel@tonic-gate  *	&db_data must == &Dnode.
98*0Sstevel@tonic-gate  *
99*0Sstevel@tonic-gate  *	db_buf is a pointer to an allocated buffer.  The same value
100*0Sstevel@tonic-gate  *	goes into db_data.d_buf originally, but the user can touch
101*0Sstevel@tonic-gate  *	it.  If the data buffer is not to be freed, db_buf is null.
102*0Sstevel@tonic-gate  *
103*0Sstevel@tonic-gate  *	When "reading" an input file's buffer, the data are left
104*0Sstevel@tonic-gate  *	alone until needed.  When they've been converted to internal
105*0Sstevel@tonic-gate  *	form, the READY flag is set.
106*0Sstevel@tonic-gate  *
107*0Sstevel@tonic-gate  *	db_raw points to a parallel raw buffer.  Raw buffers
108*0Sstevel@tonic-gate  *	have null db_raw.
109*0Sstevel@tonic-gate  */
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate struct	Dnode
112*0Sstevel@tonic-gate {
113*0Sstevel@tonic-gate 	Elf_Data	db_data;
114*0Sstevel@tonic-gate 	Elf_Scn		*db_scn;	/* section parent */
115*0Sstevel@tonic-gate 	Dnode		*db_next;
116*0Sstevel@tonic-gate 	Dnode		*db_raw;	/* raw data */
117*0Sstevel@tonic-gate 	off_t		db_off;		/* orig file offset, 0 o/w */
118*0Sstevel@tonic-gate 	size_t		db_fsz;		/* orig file size, 0 o/w */
119*0Sstevel@tonic-gate 	size_t		db_shsz;	/* orig shdr size, 0 o/w */
120*0Sstevel@tonic-gate 	size_t		db_osz;		/* output size for update */
121*0Sstevel@tonic-gate 	Elf_Void	*db_buf;	/* allocated data buffer */
122*0Sstevel@tonic-gate 	unsigned	db_uflags;	/* user flags: ELF_F_... */
123*0Sstevel@tonic-gate 	unsigned	db_myflags;	/* internal flags: DBF_... */
124*0Sstevel@tonic-gate 	Elf64_Off	db_xoff;	/* extended offset for 32-bit Elf64 */
125*0Sstevel@tonic-gate };
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate #define	DBF_ALLOC	0x1	/* applies to Dnode itself */
128*0Sstevel@tonic-gate #define	DBF_READY	0x2	/* buffer ready */
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate /*
132*0Sstevel@tonic-gate  * Section descriptor
133*0Sstevel@tonic-gate  *	These are sometimes allocated in a block.  If the SF_ALLOC
134*0Sstevel@tonic-gate  *	bit is set in the flags, the Scn address may be passed to free.
135*0Sstevel@tonic-gate  *	The caller must first follow the s_next list to the next freeable
136*0Sstevel@tonic-gate  *	node, because free can clobber the s_next value in the block.
137*0Sstevel@tonic-gate  */
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate struct	Elf_Scn
140*0Sstevel@tonic-gate {
141*0Sstevel@tonic-gate 	mutex_t		s_mutex;
142*0Sstevel@tonic-gate 	Elf_Scn		*s_next;	/* next section */
143*0Sstevel@tonic-gate 	Elf		*s_elf; 	/* parent file */
144*0Sstevel@tonic-gate 	Dnode		*s_hdnode;	/* head Dnode */
145*0Sstevel@tonic-gate 	Dnode		*s_tlnode;	/* tail Dnode */
146*0Sstevel@tonic-gate 	Elf_Void	*s_shdr;	/* Elf32 or Elf64 scn header */
147*0Sstevel@tonic-gate 	size_t		s_index;	/* section index */
148*0Sstevel@tonic-gate 	int		s_err;		/* for delaying data error */
149*0Sstevel@tonic-gate 	unsigned	s_shflags;	/* user shdr flags */
150*0Sstevel@tonic-gate 	unsigned	s_uflags;	/* user flags */
151*0Sstevel@tonic-gate 	unsigned	s_myflags;	/* SF_... */
152*0Sstevel@tonic-gate 	Dnode		s_dnode;	/* every scn needs one */
153*0Sstevel@tonic-gate };
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(Elf_Scn::s_mutex, Elf_Scn Dnode Elf_Data))
156*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf_Data))
157*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf32_Shdr Elf32_Sym))
158*0Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Elf_Scn::s_elf))
159*0Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Dnode::db_scn))
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate /*
163*0Sstevel@tonic-gate  * Designates whether or not we are in a threaded_app.
164*0Sstevel@tonic-gate  */
165*0Sstevel@tonic-gate extern int *_elf_libc_threaded;
166*0Sstevel@tonic-gate #define	elf_threaded	(_elf_libc_threaded && *_elf_libc_threaded)
167*0Sstevel@tonic-gate 
168*0Sstevel@tonic-gate #ifdef	__lock_lint
169*0Sstevel@tonic-gate #define	SCNLOCK(x)	(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
170*0Sstevel@tonic-gate #else
171*0Sstevel@tonic-gate #define	SCNLOCK(x) \
172*0Sstevel@tonic-gate 	if (elf_threaded) \
173*0Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
174*0Sstevel@tonic-gate #endif
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate #ifdef	__lock_lint
177*0Sstevel@tonic-gate #define	SCNUNLOCK(x)	(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
178*0Sstevel@tonic-gate #else
179*0Sstevel@tonic-gate #define	SCNUNLOCK(x) \
180*0Sstevel@tonic-gate 	if (elf_threaded) \
181*0Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
182*0Sstevel@tonic-gate #endif
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate #ifdef	__lock_lint
185*0Sstevel@tonic-gate #define	UPGRADELOCKS(e, s)\
186*0Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
187*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
188*0Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
189*0Sstevel@tonic-gate #else
190*0Sstevel@tonic-gate #define	UPGRADELOCKS(e, s)\
191*0Sstevel@tonic-gate 	if (elf_threaded) { \
192*0Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
193*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
194*0Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock); \
195*0Sstevel@tonic-gate 	}
196*0Sstevel@tonic-gate #endif
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate #ifdef	__lock_lint
199*0Sstevel@tonic-gate #define	DOWNGRADELOCKS(e, s)\
200*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
201*0Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
202*0Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
203*0Sstevel@tonic-gate #else
204*0Sstevel@tonic-gate #define	DOWNGRADELOCKS(e, s)\
205*0Sstevel@tonic-gate 	if (elf_threaded) { \
206*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
207*0Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
208*0Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
209*0Sstevel@tonic-gate 	}
210*0Sstevel@tonic-gate #endif
211*0Sstevel@tonic-gate 
212*0Sstevel@tonic-gate #ifdef	__lock_lint
213*0Sstevel@tonic-gate #define	READLOCKS(e, s) \
214*0Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
215*0Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
216*0Sstevel@tonic-gate #else
217*0Sstevel@tonic-gate #define	READLOCKS(e, s) \
218*0Sstevel@tonic-gate 	if (elf_threaded) { \
219*0Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
220*0Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
221*0Sstevel@tonic-gate 	}
222*0Sstevel@tonic-gate #endif
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate #ifdef	__lock_lint
225*0Sstevel@tonic-gate #define	READUNLOCKS(e, s) \
226*0Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
227*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock);
228*0Sstevel@tonic-gate #else
229*0Sstevel@tonic-gate #define	READUNLOCKS(e, s) \
230*0Sstevel@tonic-gate 	if (elf_threaded) { \
231*0Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
232*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
233*0Sstevel@tonic-gate 	}
234*0Sstevel@tonic-gate #endif
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate #define	SF_ALLOC	0x1	/* applies to Scn */
240*0Sstevel@tonic-gate #define	SF_READY	0x2	/* has section been cooked */
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate struct	Snode32
244*0Sstevel@tonic-gate {
245*0Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
246*0Sstevel@tonic-gate 	Elf32_Shdr	sb_shdr;
247*0Sstevel@tonic-gate };
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate struct	Snode64
250*0Sstevel@tonic-gate {
251*0Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
252*0Sstevel@tonic-gate 	Elf64_Shdr	sb_shdr;
253*0Sstevel@tonic-gate };
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate /*
257*0Sstevel@tonic-gate  *	A file's status controls how the library can use file data.
258*0Sstevel@tonic-gate  *	This is important to keep "raw" operations and "cooked"
259*0Sstevel@tonic-gate  *	operations from interfering with each other.
260*0Sstevel@tonic-gate  *
261*0Sstevel@tonic-gate  *	A file's status is "fresh" until something touches it.
262*0Sstevel@tonic-gate  *	If the first thing is a raw operation, we freeze the data
263*0Sstevel@tonic-gate  *	and force all cooking operations to make a copy.  If the
264*0Sstevel@tonic-gate  *	first operation cooks, raw operations use the file system.
265*0Sstevel@tonic-gate  */
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate typedef enum
268*0Sstevel@tonic-gate {
269*0Sstevel@tonic-gate 	ES_FRESH = 0,	/* unchanged */
270*0Sstevel@tonic-gate 	ES_COOKED,	/* translated */
271*0Sstevel@tonic-gate 	ES_FROZEN	/* raw, can't be translated */
272*0Sstevel@tonic-gate } Status;
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate /*
276*0Sstevel@tonic-gate  * Elf descriptor
277*0Sstevel@tonic-gate  *	The major handle between user code and the library.
278*0Sstevel@tonic-gate  *
279*0Sstevel@tonic-gate  *	Descriptors can have parents: archive members reference
280*0Sstevel@tonic-gate  *	the archive itself.  Relevant "offsets:"
281*0Sstevel@tonic-gate  *
282*0Sstevel@tonic-gate  *	ed_baseoff	The file offset, relative to zero, to the first
283*0Sstevel@tonic-gate  *			byte in the file.  For all files, this gives
284*0Sstevel@tonic-gate  *			the lseek(fd, ed_baseoff, 0) value.
285*0Sstevel@tonic-gate  *
286*0Sstevel@tonic-gate  *	ed_memoff	The offset from the beginning of the nesting file
287*0Sstevel@tonic-gate  *			to the bytes of a member.  For an archive member,
288*0Sstevel@tonic-gate  *			this is the offset from the beginning of the
289*0Sstevel@tonic-gate  *			archive to the member bytes (not the hdr).  If an
290*0Sstevel@tonic-gate  *			archive member slides, memoff changes.
291*0Sstevel@tonic-gate  *
292*0Sstevel@tonic-gate  *	ed_siboff	Similar to ed_memoff, this gives the offset from
293*0Sstevel@tonic-gate  *			the beginning of the nesting file to the following
294*0Sstevel@tonic-gate  *			sibling's header (not the sibling's bytes).  This
295*0Sstevel@tonic-gate  *			value is necessary, because of archive sliding.
296*0Sstevel@tonic-gate  *
297*0Sstevel@tonic-gate  *	ed_nextoff	For an archive, this gives the offset of the next
298*0Sstevel@tonic-gate  *			member to process on elf_begin.  That is,
299*0Sstevel@tonic-gate  *			(ed_ident + ed_nextoff) gives pointer to member hdr.
300*0Sstevel@tonic-gate  *
301*0Sstevel@tonic-gate  *	Keeping these absolute and relative offsets allows nesting of
302*0Sstevel@tonic-gate  *	files, including archives within archives, etc.  The only current
303*0Sstevel@tonic-gate  *	nesting file is archive, but others might be supported.
304*0Sstevel@tonic-gate  *
305*0Sstevel@tonic-gate  *	ed_image	This is a pointer to the base memory image holding
306*0Sstevel@tonic-gate  *			the file.  Library code assumes the image is aligned
307*0Sstevel@tonic-gate  *			to a boundary appropriate for any object.  This must
308*0Sstevel@tonic-gate  *			be true, because we get an image only from malloc
309*0Sstevel@tonic-gate  *			or mmap, both of which guarantee alignment.
310*0Sstevel@tonic-gate  */
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate struct Elf
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate 	rwlock_t	ed_rwlock;
315*0Sstevel@tonic-gate 	Elf		*ed_parent;	/* archive parent */
316*0Sstevel@tonic-gate 	int		ed_activ;	/* activation count */
317*0Sstevel@tonic-gate 	int		ed_fd;		/* file descriptor */
318*0Sstevel@tonic-gate 	Status		ed_status;	/* file's memory status */
319*0Sstevel@tonic-gate 	off_t		ed_baseoff;	/* base file offset, zero based */
320*0Sstevel@tonic-gate 	size_t		ed_memoff;	/* offset within archive */
321*0Sstevel@tonic-gate 	size_t		ed_siboff;	/* sibling offset with archive */
322*0Sstevel@tonic-gate 	size_t		ed_nextoff;	/* next archive member hdr offset */
323*0Sstevel@tonic-gate 	char		*ed_image;	/* pointer to file image */
324*0Sstevel@tonic-gate 	size_t		ed_imagesz;	/* # bytes in ed_image */
325*0Sstevel@tonic-gate 	char		*ed_wrimage;	/* pointer to output image */
326*0Sstevel@tonic-gate 	size_t		ed_wrimagesz;	/* # bytes in ed_wrimagesz */
327*0Sstevel@tonic-gate 	char		*ed_ident;	/* file start, getident() bytes */
328*0Sstevel@tonic-gate 	size_t		ed_identsz;	/* # bytes for getident() */
329*0Sstevel@tonic-gate 	char		*ed_raw;	/* raw file ptr */
330*0Sstevel@tonic-gate 	size_t		ed_fsz;		/* file size */
331*0Sstevel@tonic-gate 	unsigned	*ed_vm;		/* virtual memory map */
332*0Sstevel@tonic-gate 	size_t		ed_vmsz;	/* # regions in vm */
333*0Sstevel@tonic-gate 	unsigned	ed_encode;	/* data encoding */
334*0Sstevel@tonic-gate 	unsigned	ed_version;	/* file version */
335*0Sstevel@tonic-gate 	int		ed_class;	/* file class */
336*0Sstevel@tonic-gate 	Elf_Kind	ed_kind;	/* file type */
337*0Sstevel@tonic-gate 	Elf_Void	*ed_ehdr;	/* Elf{32,64}_Ehdr elf header */
338*0Sstevel@tonic-gate 	Elf_Void	*ed_phdr;	/* Elf{32,64}_Phdr phdr table */
339*0Sstevel@tonic-gate 	size_t		ed_phdrsz;	/* sizeof phdr table */
340*0Sstevel@tonic-gate 	Elf_Void	*ed_shdr;	/* Elf{32,64}_Shdr shdr table */
341*0Sstevel@tonic-gate 	Elf_Scn		*ed_hdscn;	/* head scn */
342*0Sstevel@tonic-gate 	Elf_Scn		*ed_tlscn;	/* tail scn */
343*0Sstevel@tonic-gate 	size_t		ed_scntabsz;	/* number sects. alloc. in table */
344*0Sstevel@tonic-gate 	Memlist		*ed_memlist;	/* list of archive member nodes */
345*0Sstevel@tonic-gate 	Member		*ed_armem;	/* archive member header */
346*0Sstevel@tonic-gate 	Elf_Void	*ed_arsym;	/* archive symbol table */
347*0Sstevel@tonic-gate 	size_t		ed_arsymsz;	/* archive symbol table size */
348*0Sstevel@tonic-gate 	size_t		ed_arsymoff;	/* archive symbol table hdr offset */
349*0Sstevel@tonic-gate 	char		*ed_arstr;	/* archive string table */
350*0Sstevel@tonic-gate 	size_t		ed_arstrsz;	/* archive string table size */
351*0Sstevel@tonic-gate 	size_t		ed_arstroff;	/* archive string table hdr offset */
352*0Sstevel@tonic-gate 	unsigned	ed_myflags;	/* EDF_... */
353*0Sstevel@tonic-gate 	unsigned	ed_ehflags;	/* ehdr flags */
354*0Sstevel@tonic-gate 	unsigned	ed_phflags;	/* phdr flags */
355*0Sstevel@tonic-gate 	unsigned	ed_uflags;	/* elf descriptor flags */
356*0Sstevel@tonic-gate };
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate NOTE(RWLOCK_PROTECTS_DATA(Elf::ed_rwlock, Elf))
359*0Sstevel@tonic-gate NOTE(RWLOCK_COVERS_LOCKS(Elf::ed_rwlock, Elf_Scn::s_mutex))
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate #ifdef	__lock_lint
362*0Sstevel@tonic-gate #define	ELFRLOCK(e)	(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
363*0Sstevel@tonic-gate #else
364*0Sstevel@tonic-gate #define	ELFRLOCK(e) \
365*0Sstevel@tonic-gate 	if (elf_threaded) \
366*0Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
367*0Sstevel@tonic-gate #endif
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate #ifdef	__lock_lint
370*0Sstevel@tonic-gate #define	ELFWLOCK(e)	(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
371*0Sstevel@tonic-gate #else
372*0Sstevel@tonic-gate #define	ELFWLOCK(e) \
373*0Sstevel@tonic-gate 	if (elf_threaded) \
374*0Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
375*0Sstevel@tonic-gate #endif
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate #ifdef	__lock_lint
378*0Sstevel@tonic-gate #define	ELFUNLOCK(e)	(void) rw_unlock(&((Elf *)e)->ed_rwlock);
379*0Sstevel@tonic-gate #else
380*0Sstevel@tonic-gate #define	ELFUNLOCK(e) \
381*0Sstevel@tonic-gate 	if (elf_threaded) \
382*0Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock);
383*0Sstevel@tonic-gate #endif
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate #define	EDF_ASALLOC	0x1	/* applies to ed_arsym */
386*0Sstevel@tonic-gate #define	EDF_EHALLOC	0x2	/* applies to ed_ehdr */
387*0Sstevel@tonic-gate #define	EDF_PHALLOC	0x4	/* applies to ed_phdr */
388*0Sstevel@tonic-gate #define	EDF_SHALLOC	0x8	/* applies to ed_shdr */
389*0Sstevel@tonic-gate #define	EDF_COFFAOUT	0x10	/* original file was coff a.out */
390*0Sstevel@tonic-gate #define	EDF_RAWALLOC	0x20	/* applies to ed_raw */
391*0Sstevel@tonic-gate #define	EDF_READ	0x40	/* file can be read */
392*0Sstevel@tonic-gate #define	EDF_WRITE	0x80	/* file can be written */
393*0Sstevel@tonic-gate #define	EDF_MEMORY	0x100	/* file opened via elf_memory() */
394*0Sstevel@tonic-gate #define	EDF_ASTRALLOC	0x200	/* applies to ed_arstr */
395*0Sstevel@tonic-gate #define	EDF_MPROTECT	0x400	/* applies to slideable archives */
396*0Sstevel@tonic-gate #define	EDF_IMALLOC	0x800	/* wrimage dynamically allocated */
397*0Sstevel@tonic-gate #define	EDF_WRALLOC	0x1000	/* wrimage is to by dyn allocated */
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate typedef enum
401*0Sstevel@tonic-gate {
402*0Sstevel@tonic-gate 	OK_YES = 0,
403*0Sstevel@tonic-gate 	OK_NO = ~0
404*0Sstevel@tonic-gate } Okay;
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate #define	_(a)		a
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate /*
409*0Sstevel@tonic-gate  * Max size for an Elf error message string
410*0Sstevel@tonic-gate  */
411*0Sstevel@tonic-gate #define	MAXELFERR	1024
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate /*
414*0Sstevel@tonic-gate  * General thread management macros
415*0Sstevel@tonic-gate  */
416*0Sstevel@tonic-gate #ifdef __lock_lint
417*0Sstevel@tonic-gate #define	ELFACCESSDATA(a, b) \
418*0Sstevel@tonic-gate 	(void) mutex_lock(&_elf_globals_mutex); \
419*0Sstevel@tonic-gate 	a = b; \
420*0Sstevel@tonic-gate 	(void) mutex_unlock(&_elf_globals_mutex);
421*0Sstevel@tonic-gate #else
422*0Sstevel@tonic-gate #define	ELFACCESSDATA(a, b) \
423*0Sstevel@tonic-gate 	if (elf_threaded) { \
424*0Sstevel@tonic-gate 		(void) mutex_lock(&_elf_globals_mutex); \
425*0Sstevel@tonic-gate 		a = b; \
426*0Sstevel@tonic-gate 		(void) mutex_unlock(&_elf_globals_mutex); \
427*0Sstevel@tonic-gate 	} else \
428*0Sstevel@tonic-gate 		a = b;
429*0Sstevel@tonic-gate #endif
430*0Sstevel@tonic-gate 
431*0Sstevel@tonic-gate #ifdef __lock_lint
432*0Sstevel@tonic-gate #define	ELFRWLOCKINIT(lock) \
433*0Sstevel@tonic-gate 	(void) rwlock_init((lock), USYNC_THREAD, 0);
434*0Sstevel@tonic-gate #else
435*0Sstevel@tonic-gate #define	ELFRWLOCKINIT(lock) \
436*0Sstevel@tonic-gate 	if (elf_threaded) { \
437*0Sstevel@tonic-gate 		(void) rwlock_init((lock), USYNC_THREAD, 0); \
438*0Sstevel@tonic-gate 	}
439*0Sstevel@tonic-gate #endif
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate #ifdef	__lock_lint
442*0Sstevel@tonic-gate #define	ELFMUTEXINIT(lock) \
443*0Sstevel@tonic-gate 	(void) mutex_init(lock, USYNC_THREAD, 0);
444*0Sstevel@tonic-gate #else
445*0Sstevel@tonic-gate #define	ELFMUTEXINIT(lock) \
446*0Sstevel@tonic-gate 	if (elf_threaded) { \
447*0Sstevel@tonic-gate 		(void) mutex_init(lock, USYNC_THREAD, 0); \
448*0Sstevel@tonic-gate 	}
449*0Sstevel@tonic-gate #endif
450*0Sstevel@tonic-gate 
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate extern Member *		_elf_armem(Elf *, char *, size_t);
453*0Sstevel@tonic-gate extern void		_elf_arinit(Elf *);
454*0Sstevel@tonic-gate extern Okay		_elf_cook(Elf *);
455*0Sstevel@tonic-gate extern Okay		_elf_cookscn(Elf_Scn * s);
456*0Sstevel@tonic-gate extern Okay		_elf32_cookscn(Elf_Scn * s);
457*0Sstevel@tonic-gate extern Okay		_elf64_cookscn(Elf_Scn * s);
458*0Sstevel@tonic-gate extern Dnode *		_elf_dnode(void);
459*0Sstevel@tonic-gate extern Elf_Data *	_elf_locked_getdata(Elf_Scn *, Elf_Data *);
460*0Sstevel@tonic-gate extern size_t		_elf32_entsz(Elf32_Word, unsigned);
461*0Sstevel@tonic-gate extern size_t		_elf64_entsz(Elf64_Word, unsigned);
462*0Sstevel@tonic-gate extern Okay		_elf_inmap(Elf *);
463*0Sstevel@tonic-gate extern char *		_elf_outmap(int, size_t, unsigned *);
464*0Sstevel@tonic-gate extern size_t		_elf_outsync(int, char *, size_t, unsigned);
465*0Sstevel@tonic-gate extern size_t		_elf32_msize(Elf_Type, unsigned);
466*0Sstevel@tonic-gate extern size_t		_elf64_msize(Elf_Type, unsigned);
467*0Sstevel@tonic-gate extern Elf_Type		_elf32_mtype(Elf *, Elf32_Word, unsigned);
468*0Sstevel@tonic-gate extern Elf_Type		_elf64_mtype(Elf *, Elf64_Word, unsigned);
469*0Sstevel@tonic-gate extern char *		_elf_read(int, off_t, size_t);
470*0Sstevel@tonic-gate extern Snode32 *	_elf32_snode(void);
471*0Sstevel@tonic-gate extern Snode64 *	_elf64_snode(void);
472*0Sstevel@tonic-gate extern void		_elf_unmap(char *, size_t);
473*0Sstevel@tonic-gate extern Okay		_elf_vm(Elf *, size_t, size_t);
474*0Sstevel@tonic-gate extern int		_elf32_ehdr(Elf *, int);
475*0Sstevel@tonic-gate extern int		_elf32_phdr(Elf *, int);
476*0Sstevel@tonic-gate extern int		_elf32_shdr(Elf *, int);
477*0Sstevel@tonic-gate extern int		_elf64_ehdr(Elf *, int);
478*0Sstevel@tonic-gate extern int		_elf64_phdr(Elf *, int);
479*0Sstevel@tonic-gate extern int		_elf64_shdr(Elf *, int);
480*0Sstevel@tonic-gate extern int		_elf_byte;
481*0Sstevel@tonic-gate extern const Elf32_Ehdr	_elf32_ehdr_init;
482*0Sstevel@tonic-gate extern const Elf64_Ehdr	_elf64_ehdr_init;
483*0Sstevel@tonic-gate extern unsigned		_elf_encode;
484*0Sstevel@tonic-gate extern void		_elf_seterr(Msg, int);
485*0Sstevel@tonic-gate extern const Snode32	_elf32_snode_init;
486*0Sstevel@tonic-gate extern const Snode64	_elf64_snode_init;
487*0Sstevel@tonic-gate extern const Dnode	_elf_dnode_init;
488*0Sstevel@tonic-gate extern unsigned		_elf_work;
489*0Sstevel@tonic-gate extern mutex_t		_elf_globals_mutex;
490*0Sstevel@tonic-gate extern off_t		_elf64_update(Elf * elf, Elf_Cmd cmd);
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate /* CSTYLED */
493*0Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \
494*0Sstevel@tonic-gate 	_elf_byte _elf32_ehdr_init _elf64_ehdr_init _elf_encode \
495*0Sstevel@tonic-gate 	_elf_snode_init _elf_work))
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate #ifdef	__cplusplus
498*0Sstevel@tonic-gate }
499*0Sstevel@tonic-gate #endif
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate #endif	/* _DECL_H */
502