xref: /onnv-gate/usr/src/cmd/sgs/libelf/common/decl.h (revision 12792:1f56a791e275)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51698Sab196087  * Common Development and Distribution License (the "License").
61698Sab196087  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
220Sstevel@tonic-gate /*	  All Rights Reserved  	*/
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
26*12792SAli.Bahrami@Oracle.COM  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
270Sstevel@tonic-gate  */
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #ifndef	_DECL_H
300Sstevel@tonic-gate #define	_DECL_H
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <thread.h>
330Sstevel@tonic-gate #include <note.h>
341698Sab196087 #include <_libelf.h>
350Sstevel@tonic-gate #include <sys/machelf.h>
360Sstevel@tonic-gate #include <msg.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #ifdef	__cplusplus
400Sstevel@tonic-gate extern "C" {
410Sstevel@tonic-gate #endif
420Sstevel@tonic-gate 
430Sstevel@tonic-gate typedef struct Member	Member;
440Sstevel@tonic-gate typedef struct Memlist	Memlist;
450Sstevel@tonic-gate typedef struct Memident	Memident;
460Sstevel@tonic-gate typedef struct Dnode	Dnode;
470Sstevel@tonic-gate typedef struct Snode32	Snode32;
480Sstevel@tonic-gate typedef struct Snode64	Snode64;
490Sstevel@tonic-gate 
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * Data alignment
530Sstevel@tonic-gate  *	An elf file is defined to have its structures aligned on
540Sstevel@tonic-gate  *	appropriate boundaries.  The following type lets the
550Sstevel@tonic-gate  *	library test whether the file's alignment meets its own
560Sstevel@tonic-gate  *	constraints in memory.  This assumes every machine uses
570Sstevel@tonic-gate  *	an alignment that is no greater than an object's size.
580Sstevel@tonic-gate  *	The pointer isn't relevant for the file, but the code uses
590Sstevel@tonic-gate  *	it to get memory alignment.  ANSI C void * holds any pointer,
600Sstevel@tonic-gate  *	making it appropriate here.
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate 
630Sstevel@tonic-gate typedef union
640Sstevel@tonic-gate {
650Sstevel@tonic-gate 	Elf32_Word	w;
660Sstevel@tonic-gate 	Elf32_Addr	a;
670Sstevel@tonic-gate 	Elf32_Off	o;
680Sstevel@tonic-gate } Elf32;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate typedef union {
710Sstevel@tonic-gate 	Elf64_Xword	x;
720Sstevel@tonic-gate 	Elf64_Word	w;
730Sstevel@tonic-gate 	Elf64_Addr	a;
740Sstevel@tonic-gate 	Elf64_Off	o;
750Sstevel@tonic-gate 	Elf_Void	*p;
760Sstevel@tonic-gate } Elf64;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate 
790Sstevel@tonic-gate /*
800Sstevel@tonic-gate  * Memory allocation
810Sstevel@tonic-gate  *	Structures are obtained several ways: file mapping,
820Sstevel@tonic-gate  *	malloc(), from the user.  A status bit in the structures
830Sstevel@tonic-gate  *	tells whether an object was obtained with malloc() and
840Sstevel@tonic-gate  *	therefore should be released with free().  The bits
850Sstevel@tonic-gate  *	named ...ALLOC indicate this.
860Sstevel@tonic-gate  */
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate  * Data descriptor
910Sstevel@tonic-gate  *	db_data must be first in the Dnode structure, because
920Sstevel@tonic-gate  *	&db_data must == &Dnode.
930Sstevel@tonic-gate  *
940Sstevel@tonic-gate  *	db_buf is a pointer to an allocated buffer.  The same value
950Sstevel@tonic-gate  *	goes into db_data.d_buf originally, but the user can touch
960Sstevel@tonic-gate  *	it.  If the data buffer is not to be freed, db_buf is null.
970Sstevel@tonic-gate  *
980Sstevel@tonic-gate  *	When "reading" an input file's buffer, the data are left
990Sstevel@tonic-gate  *	alone until needed.  When they've been converted to internal
1000Sstevel@tonic-gate  *	form, the READY flag is set.
1010Sstevel@tonic-gate  *
1020Sstevel@tonic-gate  *	db_raw points to a parallel raw buffer.  Raw buffers
1030Sstevel@tonic-gate  *	have null db_raw.
1040Sstevel@tonic-gate  */
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate struct	Dnode
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate 	Elf_Data	db_data;
1090Sstevel@tonic-gate 	Elf_Scn		*db_scn;	/* section parent */
1100Sstevel@tonic-gate 	Dnode		*db_next;
1110Sstevel@tonic-gate 	Dnode		*db_raw;	/* raw data */
1120Sstevel@tonic-gate 	off_t		db_off;		/* orig file offset, 0 o/w */
1130Sstevel@tonic-gate 	size_t		db_fsz;		/* orig file size, 0 o/w */
1140Sstevel@tonic-gate 	size_t		db_shsz;	/* orig shdr size, 0 o/w */
1150Sstevel@tonic-gate 	size_t		db_osz;		/* output size for update */
1160Sstevel@tonic-gate 	Elf_Void	*db_buf;	/* allocated data buffer */
1170Sstevel@tonic-gate 	unsigned	db_uflags;	/* user flags: ELF_F_... */
1180Sstevel@tonic-gate 	unsigned	db_myflags;	/* internal flags: DBF_... */
1190Sstevel@tonic-gate 	Elf64_Off	db_xoff;	/* extended offset for 32-bit Elf64 */
1200Sstevel@tonic-gate };
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate #define	DBF_ALLOC	0x1	/* applies to Dnode itself */
1230Sstevel@tonic-gate #define	DBF_READY	0x2	/* buffer ready */
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate /*
1270Sstevel@tonic-gate  * Section descriptor
1280Sstevel@tonic-gate  *	These are sometimes allocated in a block.  If the SF_ALLOC
1290Sstevel@tonic-gate  *	bit is set in the flags, the Scn address may be passed to free.
1300Sstevel@tonic-gate  *	The caller must first follow the s_next list to the next freeable
1310Sstevel@tonic-gate  *	node, because free can clobber the s_next value in the block.
1320Sstevel@tonic-gate  */
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate struct	Elf_Scn
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate 	mutex_t		s_mutex;
1370Sstevel@tonic-gate 	Elf_Scn		*s_next;	/* next section */
1380Sstevel@tonic-gate 	Elf		*s_elf; 	/* parent file */
1390Sstevel@tonic-gate 	Dnode		*s_hdnode;	/* head Dnode */
1400Sstevel@tonic-gate 	Dnode		*s_tlnode;	/* tail Dnode */
1410Sstevel@tonic-gate 	Elf_Void	*s_shdr;	/* Elf32 or Elf64 scn header */
1420Sstevel@tonic-gate 	size_t		s_index;	/* section index */
1430Sstevel@tonic-gate 	int		s_err;		/* for delaying data error */
1440Sstevel@tonic-gate 	unsigned	s_shflags;	/* user shdr flags */
1450Sstevel@tonic-gate 	unsigned	s_uflags;	/* user flags */
1460Sstevel@tonic-gate 	unsigned	s_myflags;	/* SF_... */
1470Sstevel@tonic-gate 	Dnode		s_dnode;	/* every scn needs one */
1480Sstevel@tonic-gate };
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(Elf_Scn::s_mutex, Elf_Scn Dnode Elf_Data))
1510Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf_Data))
1520Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf32_Shdr Elf32_Sym))
1530Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Elf_Scn::s_elf))
1540Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Dnode::db_scn))
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate /*
1580Sstevel@tonic-gate  * Designates whether or not we are in a threaded_app.
1590Sstevel@tonic-gate  */
1600Sstevel@tonic-gate extern int *_elf_libc_threaded;
1610Sstevel@tonic-gate #define	elf_threaded	(_elf_libc_threaded && *_elf_libc_threaded)
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate #ifdef	__lock_lint
1640Sstevel@tonic-gate #define	SCNLOCK(x)	(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
1650Sstevel@tonic-gate #else
1660Sstevel@tonic-gate #define	SCNLOCK(x) \
1670Sstevel@tonic-gate 	if (elf_threaded) \
1680Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
1690Sstevel@tonic-gate #endif
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate #ifdef	__lock_lint
1720Sstevel@tonic-gate #define	SCNUNLOCK(x)	(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
1730Sstevel@tonic-gate #else
1740Sstevel@tonic-gate #define	SCNUNLOCK(x) \
1750Sstevel@tonic-gate 	if (elf_threaded) \
1760Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
1770Sstevel@tonic-gate #endif
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate #ifdef	__lock_lint
1800Sstevel@tonic-gate #define	UPGRADELOCKS(e, s)\
1810Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
1820Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1830Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
1840Sstevel@tonic-gate #else
1850Sstevel@tonic-gate #define	UPGRADELOCKS(e, s)\
1860Sstevel@tonic-gate 	if (elf_threaded) { \
1870Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
1880Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1890Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock); \
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate #endif
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate #ifdef	__lock_lint
1940Sstevel@tonic-gate #define	DOWNGRADELOCKS(e, s)\
1950Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1960Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
1970Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
1980Sstevel@tonic-gate #else
1990Sstevel@tonic-gate #define	DOWNGRADELOCKS(e, s)\
2000Sstevel@tonic-gate 	if (elf_threaded) { \
2010Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
2020Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
2030Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate #endif
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate #ifdef	__lock_lint
2080Sstevel@tonic-gate #define	READLOCKS(e, s) \
2090Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
2100Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
2110Sstevel@tonic-gate #else
2120Sstevel@tonic-gate #define	READLOCKS(e, s) \
2130Sstevel@tonic-gate 	if (elf_threaded) { \
2140Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
2150Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
2160Sstevel@tonic-gate 	}
2170Sstevel@tonic-gate #endif
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate #ifdef	__lock_lint
2200Sstevel@tonic-gate #define	READUNLOCKS(e, s) \
2210Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
2220Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock);
2230Sstevel@tonic-gate #else
2240Sstevel@tonic-gate #define	READUNLOCKS(e, s) \
2250Sstevel@tonic-gate 	if (elf_threaded) { \
2260Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
2270Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
2280Sstevel@tonic-gate 	}
2290Sstevel@tonic-gate #endif
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate #define	SF_ALLOC	0x1	/* applies to Scn */
2350Sstevel@tonic-gate #define	SF_READY	0x2	/* has section been cooked */
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate struct	Snode32
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
2410Sstevel@tonic-gate 	Elf32_Shdr	sb_shdr;
2420Sstevel@tonic-gate };
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate struct	Snode64
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
2470Sstevel@tonic-gate 	Elf64_Shdr	sb_shdr;
2480Sstevel@tonic-gate };
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate  *	A file's status controls how the library can use file data.
2530Sstevel@tonic-gate  *	This is important to keep "raw" operations and "cooked"
2540Sstevel@tonic-gate  *	operations from interfering with each other.
2550Sstevel@tonic-gate  *
2560Sstevel@tonic-gate  *	A file's status is "fresh" until something touches it.
2570Sstevel@tonic-gate  *	If the first thing is a raw operation, we freeze the data
2580Sstevel@tonic-gate  *	and force all cooking operations to make a copy.  If the
2590Sstevel@tonic-gate  *	first operation cooks, raw operations use the file system.
2600Sstevel@tonic-gate  */
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate typedef enum
2630Sstevel@tonic-gate {
2640Sstevel@tonic-gate 	ES_FRESH = 0,	/* unchanged */
2650Sstevel@tonic-gate 	ES_COOKED,	/* translated */
2660Sstevel@tonic-gate 	ES_FROZEN	/* raw, can't be translated */
2670Sstevel@tonic-gate } Status;
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate /*
2710Sstevel@tonic-gate  * Elf descriptor
2720Sstevel@tonic-gate  *	The major handle between user code and the library.
2730Sstevel@tonic-gate  *
2740Sstevel@tonic-gate  *	Descriptors can have parents: archive members reference
2750Sstevel@tonic-gate  *	the archive itself.  Relevant "offsets:"
2760Sstevel@tonic-gate  *
2770Sstevel@tonic-gate  *	ed_baseoff	The file offset, relative to zero, to the first
2780Sstevel@tonic-gate  *			byte in the file.  For all files, this gives
2790Sstevel@tonic-gate  *			the lseek(fd, ed_baseoff, 0) value.
2800Sstevel@tonic-gate  *
2810Sstevel@tonic-gate  *	ed_memoff	The offset from the beginning of the nesting file
2820Sstevel@tonic-gate  *			to the bytes of a member.  For an archive member,
2830Sstevel@tonic-gate  *			this is the offset from the beginning of the
2840Sstevel@tonic-gate  *			archive to the member bytes (not the hdr).  If an
2850Sstevel@tonic-gate  *			archive member slides, memoff changes.
2860Sstevel@tonic-gate  *
2870Sstevel@tonic-gate  *	ed_siboff	Similar to ed_memoff, this gives the offset from
2880Sstevel@tonic-gate  *			the beginning of the nesting file to the following
2890Sstevel@tonic-gate  *			sibling's header (not the sibling's bytes).  This
2900Sstevel@tonic-gate  *			value is necessary, because of archive sliding.
2910Sstevel@tonic-gate  *
2920Sstevel@tonic-gate  *	ed_nextoff	For an archive, this gives the offset of the next
2930Sstevel@tonic-gate  *			member to process on elf_begin.  That is,
2940Sstevel@tonic-gate  *			(ed_ident + ed_nextoff) gives pointer to member hdr.
2950Sstevel@tonic-gate  *
2960Sstevel@tonic-gate  *	Keeping these absolute and relative offsets allows nesting of
2970Sstevel@tonic-gate  *	files, including archives within archives, etc.  The only current
2980Sstevel@tonic-gate  *	nesting file is archive, but others might be supported.
2990Sstevel@tonic-gate  *
3000Sstevel@tonic-gate  *	ed_image	This is a pointer to the base memory image holding
3010Sstevel@tonic-gate  *			the file.  Library code assumes the image is aligned
3020Sstevel@tonic-gate  *			to a boundary appropriate for any object.  This must
3030Sstevel@tonic-gate  *			be true, because we get an image only from malloc
3040Sstevel@tonic-gate  *			or mmap, both of which guarantee alignment.
3050Sstevel@tonic-gate  */
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate struct Elf
3080Sstevel@tonic-gate {
3090Sstevel@tonic-gate 	rwlock_t	ed_rwlock;
3100Sstevel@tonic-gate 	Elf		*ed_parent;	/* archive parent */
3110Sstevel@tonic-gate 	int		ed_activ;	/* activation count */
3120Sstevel@tonic-gate 	int		ed_fd;		/* file descriptor */
3130Sstevel@tonic-gate 	Status		ed_status;	/* file's memory status */
3140Sstevel@tonic-gate 	off_t		ed_baseoff;	/* base file offset, zero based */
3150Sstevel@tonic-gate 	size_t		ed_memoff;	/* offset within archive */
3160Sstevel@tonic-gate 	size_t		ed_siboff;	/* sibling offset with archive */
3170Sstevel@tonic-gate 	size_t		ed_nextoff;	/* next archive member hdr offset */
3180Sstevel@tonic-gate 	char		*ed_image;	/* pointer to file image */
3190Sstevel@tonic-gate 	size_t		ed_imagesz;	/* # bytes in ed_image */
3200Sstevel@tonic-gate 	char		*ed_wrimage;	/* pointer to output image */
3210Sstevel@tonic-gate 	size_t		ed_wrimagesz;	/* # bytes in ed_wrimagesz */
3220Sstevel@tonic-gate 	char		*ed_ident;	/* file start, getident() bytes */
3230Sstevel@tonic-gate 	size_t		ed_identsz;	/* # bytes for getident() */
3240Sstevel@tonic-gate 	char		*ed_raw;	/* raw file ptr */
3250Sstevel@tonic-gate 	size_t		ed_fsz;		/* file size */
3260Sstevel@tonic-gate 	unsigned	*ed_vm;		/* virtual memory map */
3270Sstevel@tonic-gate 	size_t		ed_vmsz;	/* # regions in vm */
3280Sstevel@tonic-gate 	unsigned	ed_encode;	/* data encoding */
3290Sstevel@tonic-gate 	unsigned	ed_version;	/* file version */
3300Sstevel@tonic-gate 	int		ed_class;	/* file class */
3310Sstevel@tonic-gate 	Elf_Kind	ed_kind;	/* file type */
3320Sstevel@tonic-gate 	Elf_Void	*ed_ehdr;	/* Elf{32,64}_Ehdr elf header */
3330Sstevel@tonic-gate 	Elf_Void	*ed_phdr;	/* Elf{32,64}_Phdr phdr table */
3340Sstevel@tonic-gate 	size_t		ed_phdrsz;	/* sizeof phdr table */
3350Sstevel@tonic-gate 	Elf_Void	*ed_shdr;	/* Elf{32,64}_Shdr shdr table */
3360Sstevel@tonic-gate 	Elf_Scn		*ed_hdscn;	/* head scn */
3370Sstevel@tonic-gate 	Elf_Scn		*ed_tlscn;	/* tail scn */
3380Sstevel@tonic-gate 	size_t		ed_scntabsz;	/* number sects. alloc. in table */
3390Sstevel@tonic-gate 	Memlist		*ed_memlist;	/* list of archive member nodes */
3400Sstevel@tonic-gate 	Member		*ed_armem;	/* archive member header */
3410Sstevel@tonic-gate 	Elf_Void	*ed_arsym;	/* archive symbol table */
3420Sstevel@tonic-gate 	size_t		ed_arsymsz;	/* archive symbol table size */
3430Sstevel@tonic-gate 	size_t		ed_arsymoff;	/* archive symbol table hdr offset */
3440Sstevel@tonic-gate 	char		*ed_arstr;	/* archive string table */
3450Sstevel@tonic-gate 	size_t		ed_arstrsz;	/* archive string table size */
3460Sstevel@tonic-gate 	size_t		ed_arstroff;	/* archive string table hdr offset */
3470Sstevel@tonic-gate 	unsigned	ed_myflags;	/* EDF_... */
3480Sstevel@tonic-gate 	unsigned	ed_ehflags;	/* ehdr flags */
3490Sstevel@tonic-gate 	unsigned	ed_phflags;	/* phdr flags */
3500Sstevel@tonic-gate 	unsigned	ed_uflags;	/* elf descriptor flags */
3510Sstevel@tonic-gate };
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate NOTE(RWLOCK_PROTECTS_DATA(Elf::ed_rwlock, Elf))
3540Sstevel@tonic-gate NOTE(RWLOCK_COVERS_LOCKS(Elf::ed_rwlock, Elf_Scn::s_mutex))
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate #ifdef	__lock_lint
3570Sstevel@tonic-gate #define	ELFRLOCK(e)	(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
3580Sstevel@tonic-gate #else
3590Sstevel@tonic-gate #define	ELFRLOCK(e) \
3600Sstevel@tonic-gate 	if (elf_threaded) \
3610Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
3620Sstevel@tonic-gate #endif
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate #ifdef	__lock_lint
3650Sstevel@tonic-gate #define	ELFWLOCK(e)	(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
3660Sstevel@tonic-gate #else
3670Sstevel@tonic-gate #define	ELFWLOCK(e) \
3680Sstevel@tonic-gate 	if (elf_threaded) \
3690Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
3700Sstevel@tonic-gate #endif
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate #ifdef	__lock_lint
3730Sstevel@tonic-gate #define	ELFUNLOCK(e)	(void) rw_unlock(&((Elf *)e)->ed_rwlock);
3740Sstevel@tonic-gate #else
3750Sstevel@tonic-gate #define	ELFUNLOCK(e) \
3760Sstevel@tonic-gate 	if (elf_threaded) \
3770Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock);
3780Sstevel@tonic-gate #endif
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate #define	EDF_ASALLOC	0x1	/* applies to ed_arsym */
3810Sstevel@tonic-gate #define	EDF_EHALLOC	0x2	/* applies to ed_ehdr */
3820Sstevel@tonic-gate #define	EDF_PHALLOC	0x4	/* applies to ed_phdr */
3830Sstevel@tonic-gate #define	EDF_SHALLOC	0x8	/* applies to ed_shdr */
3840Sstevel@tonic-gate #define	EDF_COFFAOUT	0x10	/* original file was coff a.out */
3850Sstevel@tonic-gate #define	EDF_RAWALLOC	0x20	/* applies to ed_raw */
3860Sstevel@tonic-gate #define	EDF_READ	0x40	/* file can be read */
3870Sstevel@tonic-gate #define	EDF_WRITE	0x80	/* file can be written */
3880Sstevel@tonic-gate #define	EDF_MEMORY	0x100	/* file opened via elf_memory() */
3890Sstevel@tonic-gate #define	EDF_ASTRALLOC	0x200	/* applies to ed_arstr */
3900Sstevel@tonic-gate #define	EDF_MPROTECT	0x400	/* applies to slideable archives */
3910Sstevel@tonic-gate #define	EDF_IMALLOC	0x800	/* wrimage dynamically allocated */
3920Sstevel@tonic-gate #define	EDF_WRALLOC	0x1000	/* wrimage is to by dyn allocated */
393*12792SAli.Bahrami@Oracle.COM #define	EDF_ARSYM64	0x2000	/* archive symbol table is 64-bit format */
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate typedef enum
3970Sstevel@tonic-gate {
3980Sstevel@tonic-gate 	OK_YES = 0,
3990Sstevel@tonic-gate 	OK_NO = ~0
4000Sstevel@tonic-gate } Okay;
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate #define	_(a)		a
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate /*
4050Sstevel@tonic-gate  * Max size for an Elf error message string
4060Sstevel@tonic-gate  */
4070Sstevel@tonic-gate #define	MAXELFERR	1024
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate /*
4100Sstevel@tonic-gate  * General thread management macros
4110Sstevel@tonic-gate  */
4120Sstevel@tonic-gate #ifdef __lock_lint
4130Sstevel@tonic-gate #define	ELFACCESSDATA(a, b) \
4140Sstevel@tonic-gate 	(void) mutex_lock(&_elf_globals_mutex); \
4150Sstevel@tonic-gate 	a = b; \
4160Sstevel@tonic-gate 	(void) mutex_unlock(&_elf_globals_mutex);
4170Sstevel@tonic-gate #else
4180Sstevel@tonic-gate #define	ELFACCESSDATA(a, b) \
4190Sstevel@tonic-gate 	if (elf_threaded) { \
4200Sstevel@tonic-gate 		(void) mutex_lock(&_elf_globals_mutex); \
4210Sstevel@tonic-gate 		a = b; \
4220Sstevel@tonic-gate 		(void) mutex_unlock(&_elf_globals_mutex); \
4230Sstevel@tonic-gate 	} else \
4240Sstevel@tonic-gate 		a = b;
4250Sstevel@tonic-gate #endif
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate #ifdef __lock_lint
4280Sstevel@tonic-gate #define	ELFRWLOCKINIT(lock) \
4290Sstevel@tonic-gate 	(void) rwlock_init((lock), USYNC_THREAD, 0);
4300Sstevel@tonic-gate #else
4310Sstevel@tonic-gate #define	ELFRWLOCKINIT(lock) \
4320Sstevel@tonic-gate 	if (elf_threaded) { \
4330Sstevel@tonic-gate 		(void) rwlock_init((lock), USYNC_THREAD, 0); \
4340Sstevel@tonic-gate 	}
4350Sstevel@tonic-gate #endif
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate #ifdef	__lock_lint
4380Sstevel@tonic-gate #define	ELFMUTEXINIT(lock) \
4390Sstevel@tonic-gate 	(void) mutex_init(lock, USYNC_THREAD, 0);
4400Sstevel@tonic-gate #else
4410Sstevel@tonic-gate #define	ELFMUTEXINIT(lock) \
4420Sstevel@tonic-gate 	if (elf_threaded) { \
4430Sstevel@tonic-gate 		(void) mutex_init(lock, USYNC_THREAD, 0); \
4440Sstevel@tonic-gate 	}
4450Sstevel@tonic-gate #endif
4460Sstevel@tonic-gate 
4470Sstevel@tonic-gate 
4481698Sab196087 extern Member		*_elf_armem(Elf *, char *, size_t);
4490Sstevel@tonic-gate extern void		_elf_arinit(Elf *);
4500Sstevel@tonic-gate extern Okay		_elf_cook(Elf *);
4510Sstevel@tonic-gate extern Okay		_elf_cookscn(Elf_Scn * s);
4520Sstevel@tonic-gate extern Okay		_elf32_cookscn(Elf_Scn * s);
4530Sstevel@tonic-gate extern Okay		_elf64_cookscn(Elf_Scn * s);
4541698Sab196087 extern Dnode		*_elf_dnode(void);
4551698Sab196087 extern Elf_Data		*_elf_locked_getdata(Elf_Scn *, Elf_Data *);
4563621Sab196087 extern size_t		_elf32_entsz(Elf *elf, Elf32_Word, unsigned);
4573621Sab196087 extern size_t		_elf64_entsz(Elf *elf, Elf64_Word, unsigned);
4580Sstevel@tonic-gate extern Okay		_elf_inmap(Elf *);
4591698Sab196087 extern char		*_elf_outmap(int, size_t, unsigned *);
4600Sstevel@tonic-gate extern size_t		_elf_outsync(int, char *, size_t, unsigned);
4610Sstevel@tonic-gate extern size_t		_elf32_msize(Elf_Type, unsigned);
4620Sstevel@tonic-gate extern size_t		_elf64_msize(Elf_Type, unsigned);
4630Sstevel@tonic-gate extern Elf_Type		_elf32_mtype(Elf *, Elf32_Word, unsigned);
4640Sstevel@tonic-gate extern Elf_Type		_elf64_mtype(Elf *, Elf64_Word, unsigned);
4651698Sab196087 extern char		*_elf_read(int, off_t, size_t);
4661698Sab196087 extern Snode32		*_elf32_snode(void);
4671698Sab196087 extern Snode64		*_elf64_snode(void);
4680Sstevel@tonic-gate extern void		_elf_unmap(char *, size_t);
4690Sstevel@tonic-gate extern Okay		_elf_vm(Elf *, size_t, size_t);
4700Sstevel@tonic-gate extern int		_elf32_ehdr(Elf *, int);
4710Sstevel@tonic-gate extern int		_elf32_phdr(Elf *, int);
4720Sstevel@tonic-gate extern int		_elf32_shdr(Elf *, int);
4730Sstevel@tonic-gate extern int		_elf64_ehdr(Elf *, int);
4740Sstevel@tonic-gate extern int		_elf64_phdr(Elf *, int);
4750Sstevel@tonic-gate extern int		_elf64_shdr(Elf *, int);
4760Sstevel@tonic-gate extern int		_elf_byte;
4770Sstevel@tonic-gate extern const Elf32_Ehdr	_elf32_ehdr_init;
4780Sstevel@tonic-gate extern const Elf64_Ehdr	_elf64_ehdr_init;
4790Sstevel@tonic-gate extern unsigned		_elf_encode;
48010809SAli.Bahrami@Sun.COM extern _elf_execfill_func_t *_elf_execfill_func;
4810Sstevel@tonic-gate extern void		_elf_seterr(Msg, int);
4820Sstevel@tonic-gate extern const Snode32	_elf32_snode_init;
4830Sstevel@tonic-gate extern const Snode64	_elf64_snode_init;
4840Sstevel@tonic-gate extern const Dnode	_elf_dnode_init;
4850Sstevel@tonic-gate extern unsigned		_elf_work;
4860Sstevel@tonic-gate extern mutex_t		_elf_globals_mutex;
4870Sstevel@tonic-gate extern off_t		_elf64_update(Elf * elf, Elf_Cmd cmd);
4886206Sab196087 extern int		_elf64_swap_wrimage(Elf *elf);
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate /* CSTYLED */
4910Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \
4920Sstevel@tonic-gate 	_elf_byte _elf32_ehdr_init _elf64_ehdr_init _elf_encode \
4930Sstevel@tonic-gate 	_elf_snode_init _elf_work))
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate #ifdef	__cplusplus
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate #endif
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate #endif	/* _DECL_H */
500