xref: /illumos-gate/usr/src/cmd/sgs/libelf/common/decl.h (revision e2f4f3da)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
54899432aSab  * Common Development and Distribution License (the "License").
64899432aSab  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
227c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
26*ba7866cdSAli Bahrami  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifndef	_DECL_H
307c478bd9Sstevel@tonic-gate #define	_DECL_H
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <thread.h>
334899432aSab #include <_libelf.h>
347c478bd9Sstevel@tonic-gate #include <sys/machelf.h>
357c478bd9Sstevel@tonic-gate #include <msg.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
397c478bd9Sstevel@tonic-gate extern "C" {
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate typedef struct Member	Member;
437c478bd9Sstevel@tonic-gate typedef struct Memlist	Memlist;
447c478bd9Sstevel@tonic-gate typedef struct Memident	Memident;
457c478bd9Sstevel@tonic-gate typedef struct Dnode	Dnode;
467c478bd9Sstevel@tonic-gate typedef struct Snode32	Snode32;
477c478bd9Sstevel@tonic-gate typedef struct Snode64	Snode64;
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * Data alignment
527c478bd9Sstevel@tonic-gate  *	An elf file is defined to have its structures aligned on
537c478bd9Sstevel@tonic-gate  *	appropriate boundaries.  The following type lets the
547c478bd9Sstevel@tonic-gate  *	library test whether the file's alignment meets its own
557c478bd9Sstevel@tonic-gate  *	constraints in memory.  This assumes every machine uses
567c478bd9Sstevel@tonic-gate  *	an alignment that is no greater than an object's size.
577c478bd9Sstevel@tonic-gate  *	The pointer isn't relevant for the file, but the code uses
587c478bd9Sstevel@tonic-gate  *	it to get memory alignment.  ANSI C void * holds any pointer,
597c478bd9Sstevel@tonic-gate  *	making it appropriate here.
607c478bd9Sstevel@tonic-gate  */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate typedef union
637c478bd9Sstevel@tonic-gate {
647c478bd9Sstevel@tonic-gate 	Elf32_Word	w;
657c478bd9Sstevel@tonic-gate 	Elf32_Addr	a;
667c478bd9Sstevel@tonic-gate 	Elf32_Off	o;
677c478bd9Sstevel@tonic-gate } Elf32;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate typedef union {
707c478bd9Sstevel@tonic-gate 	Elf64_Xword	x;
717c478bd9Sstevel@tonic-gate 	Elf64_Word	w;
727c478bd9Sstevel@tonic-gate 	Elf64_Addr	a;
737c478bd9Sstevel@tonic-gate 	Elf64_Off	o;
747c478bd9Sstevel@tonic-gate 	Elf_Void	*p;
757c478bd9Sstevel@tonic-gate } Elf64;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate /*
797c478bd9Sstevel@tonic-gate  * Memory allocation
807c478bd9Sstevel@tonic-gate  *	Structures are obtained several ways: file mapping,
817c478bd9Sstevel@tonic-gate  *	malloc(), from the user.  A status bit in the structures
827c478bd9Sstevel@tonic-gate  *	tells whether an object was obtained with malloc() and
837c478bd9Sstevel@tonic-gate  *	therefore should be released with free().  The bits
847c478bd9Sstevel@tonic-gate  *	named ...ALLOC indicate this.
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * Data descriptor
907c478bd9Sstevel@tonic-gate  *	db_data must be first in the Dnode structure, because
917c478bd9Sstevel@tonic-gate  *	&db_data must == &Dnode.
927c478bd9Sstevel@tonic-gate  *
937c478bd9Sstevel@tonic-gate  *	db_buf is a pointer to an allocated buffer.  The same value
947c478bd9Sstevel@tonic-gate  *	goes into db_data.d_buf originally, but the user can touch
957c478bd9Sstevel@tonic-gate  *	it.  If the data buffer is not to be freed, db_buf is null.
967c478bd9Sstevel@tonic-gate  *
977c478bd9Sstevel@tonic-gate  *	When "reading" an input file's buffer, the data are left
987c478bd9Sstevel@tonic-gate  *	alone until needed.  When they've been converted to internal
997c478bd9Sstevel@tonic-gate  *	form, the READY flag is set.
1007c478bd9Sstevel@tonic-gate  *
1017c478bd9Sstevel@tonic-gate  *	db_raw points to a parallel raw buffer.  Raw buffers
1027c478bd9Sstevel@tonic-gate  *	have null db_raw.
1037c478bd9Sstevel@tonic-gate  */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate struct	Dnode
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate 	Elf_Data	db_data;
1087c478bd9Sstevel@tonic-gate 	Elf_Scn		*db_scn;	/* section parent */
1097c478bd9Sstevel@tonic-gate 	Dnode		*db_next;
1107c478bd9Sstevel@tonic-gate 	Dnode		*db_raw;	/* raw data */
1117c478bd9Sstevel@tonic-gate 	off_t		db_off;		/* orig file offset, 0 o/w */
1127c478bd9Sstevel@tonic-gate 	size_t		db_fsz;		/* orig file size, 0 o/w */
1137c478bd9Sstevel@tonic-gate 	size_t		db_shsz;	/* orig shdr size, 0 o/w */
1147c478bd9Sstevel@tonic-gate 	size_t		db_osz;		/* output size for update */
1157c478bd9Sstevel@tonic-gate 	Elf_Void	*db_buf;	/* allocated data buffer */
1167c478bd9Sstevel@tonic-gate 	unsigned	db_uflags;	/* user flags: ELF_F_... */
1177c478bd9Sstevel@tonic-gate 	unsigned	db_myflags;	/* internal flags: DBF_... */
1187c478bd9Sstevel@tonic-gate 	Elf64_Off	db_xoff;	/* extended offset for 32-bit Elf64 */
1197c478bd9Sstevel@tonic-gate };
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate #define	DBF_ALLOC	0x1	/* applies to Dnode itself */
1227c478bd9Sstevel@tonic-gate #define	DBF_READY	0x2	/* buffer ready */
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate  * Section descriptor
1277c478bd9Sstevel@tonic-gate  *	These are sometimes allocated in a block.  If the SF_ALLOC
1287c478bd9Sstevel@tonic-gate  *	bit is set in the flags, the Scn address may be passed to free.
1297c478bd9Sstevel@tonic-gate  *	The caller must first follow the s_next list to the next freeable
1307c478bd9Sstevel@tonic-gate  *	node, because free can clobber the s_next value in the block.
1317c478bd9Sstevel@tonic-gate  */
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate struct	Elf_Scn
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate 	mutex_t		s_mutex;
1367c478bd9Sstevel@tonic-gate 	Elf_Scn		*s_next;	/* next section */
1377c478bd9Sstevel@tonic-gate 	Elf		*s_elf; 	/* parent file */
1387c478bd9Sstevel@tonic-gate 	Dnode		*s_hdnode;	/* head Dnode */
1397c478bd9Sstevel@tonic-gate 	Dnode		*s_tlnode;	/* tail Dnode */
1407c478bd9Sstevel@tonic-gate 	Elf_Void	*s_shdr;	/* Elf32 or Elf64 scn header */
1417c478bd9Sstevel@tonic-gate 	size_t		s_index;	/* section index */
1427c478bd9Sstevel@tonic-gate 	int		s_err;		/* for delaying data error */
1437c478bd9Sstevel@tonic-gate 	unsigned	s_shflags;	/* user shdr flags */
1447c478bd9Sstevel@tonic-gate 	unsigned	s_uflags;	/* user flags */
1457c478bd9Sstevel@tonic-gate 	unsigned	s_myflags;	/* SF_... */
1467c478bd9Sstevel@tonic-gate 	Dnode		s_dnode;	/* every scn needs one */
1477c478bd9Sstevel@tonic-gate };
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate  * Designates whether or not we are in a threaded_app.
1517c478bd9Sstevel@tonic-gate  */
1527c478bd9Sstevel@tonic-gate extern int *_elf_libc_threaded;
1537c478bd9Sstevel@tonic-gate #define	elf_threaded	(_elf_libc_threaded && *_elf_libc_threaded)
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate #define	SCNLOCK(x) \
1567c478bd9Sstevel@tonic-gate 	if (elf_threaded) \
1577c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate #define	SCNUNLOCK(x) \
1607c478bd9Sstevel@tonic-gate 	if (elf_threaded) \
1617c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate #define	UPGRADELOCKS(e, s)\
1647c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
1657c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
1667c478bd9Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1677c478bd9Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock); \
1687c478bd9Sstevel@tonic-gate 	}
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate #define	DOWNGRADELOCKS(e, s)\
1717c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
1727c478bd9Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1737c478bd9Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
1747c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate #define	READLOCKS(e, s) \
1787c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
1797c478bd9Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
1807c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
1817c478bd9Sstevel@tonic-gate 	}
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate #define	READUNLOCKS(e, s) \
1847c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
1857c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
1867c478bd9Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #define	SF_ALLOC	0x1	/* applies to Scn */
1907c478bd9Sstevel@tonic-gate #define	SF_READY	0x2	/* has section been cooked */
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate struct	Snode32
1947c478bd9Sstevel@tonic-gate {
1957c478bd9Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
1967c478bd9Sstevel@tonic-gate 	Elf32_Shdr	sb_shdr;
1977c478bd9Sstevel@tonic-gate };
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate struct	Snode64
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 	Elf_Scn		sb_scn;		/* must be first */
2027c478bd9Sstevel@tonic-gate 	Elf64_Shdr	sb_shdr;
2037c478bd9Sstevel@tonic-gate };
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate /*
2077c478bd9Sstevel@tonic-gate  *	A file's status controls how the library can use file data.
2087c478bd9Sstevel@tonic-gate  *	This is important to keep "raw" operations and "cooked"
2097c478bd9Sstevel@tonic-gate  *	operations from interfering with each other.
2107c478bd9Sstevel@tonic-gate  *
2117c478bd9Sstevel@tonic-gate  *	A file's status is "fresh" until something touches it.
2127c478bd9Sstevel@tonic-gate  *	If the first thing is a raw operation, we freeze the data
2137c478bd9Sstevel@tonic-gate  *	and force all cooking operations to make a copy.  If the
2147c478bd9Sstevel@tonic-gate  *	first operation cooks, raw operations use the file system.
2157c478bd9Sstevel@tonic-gate  */
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate typedef enum
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 	ES_FRESH = 0,	/* unchanged */
2207c478bd9Sstevel@tonic-gate 	ES_COOKED,	/* translated */
2217c478bd9Sstevel@tonic-gate 	ES_FROZEN	/* raw, can't be translated */
2227c478bd9Sstevel@tonic-gate } Status;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * Elf descriptor
2277c478bd9Sstevel@tonic-gate  *	The major handle between user code and the library.
2287c478bd9Sstevel@tonic-gate  *
2297c478bd9Sstevel@tonic-gate  *	Descriptors can have parents: archive members reference
2307c478bd9Sstevel@tonic-gate  *	the archive itself.  Relevant "offsets:"
2317c478bd9Sstevel@tonic-gate  *
2327c478bd9Sstevel@tonic-gate  *	ed_baseoff	The file offset, relative to zero, to the first
2337c478bd9Sstevel@tonic-gate  *			byte in the file.  For all files, this gives
2347c478bd9Sstevel@tonic-gate  *			the lseek(fd, ed_baseoff, 0) value.
2357c478bd9Sstevel@tonic-gate  *
2367c478bd9Sstevel@tonic-gate  *	ed_memoff	The offset from the beginning of the nesting file
2377c478bd9Sstevel@tonic-gate  *			to the bytes of a member.  For an archive member,
2387c478bd9Sstevel@tonic-gate  *			this is the offset from the beginning of the
2397c478bd9Sstevel@tonic-gate  *			archive to the member bytes (not the hdr).  If an
2407c478bd9Sstevel@tonic-gate  *			archive member slides, memoff changes.
2417c478bd9Sstevel@tonic-gate  *
2427c478bd9Sstevel@tonic-gate  *	ed_siboff	Similar to ed_memoff, this gives the offset from
2437c478bd9Sstevel@tonic-gate  *			the beginning of the nesting file to the following
2447c478bd9Sstevel@tonic-gate  *			sibling's header (not the sibling's bytes).  This
2457c478bd9Sstevel@tonic-gate  *			value is necessary, because of archive sliding.
2467c478bd9Sstevel@tonic-gate  *
2477c478bd9Sstevel@tonic-gate  *	ed_nextoff	For an archive, this gives the offset of the next
2487c478bd9Sstevel@tonic-gate  *			member to process on elf_begin.  That is,
2497c478bd9Sstevel@tonic-gate  *			(ed_ident + ed_nextoff) gives pointer to member hdr.
2507c478bd9Sstevel@tonic-gate  *
2517c478bd9Sstevel@tonic-gate  *	Keeping these absolute and relative offsets allows nesting of
2527c478bd9Sstevel@tonic-gate  *	files, including archives within archives, etc.  The only current
2537c478bd9Sstevel@tonic-gate  *	nesting file is archive, but others might be supported.
2547c478bd9Sstevel@tonic-gate  *
2557c478bd9Sstevel@tonic-gate  *	ed_image	This is a pointer to the base memory image holding
2567c478bd9Sstevel@tonic-gate  *			the file.  Library code assumes the image is aligned
2577c478bd9Sstevel@tonic-gate  *			to a boundary appropriate for any object.  This must
2587c478bd9Sstevel@tonic-gate  *			be true, because we get an image only from malloc
2597c478bd9Sstevel@tonic-gate  *			or mmap, both of which guarantee alignment.
2607c478bd9Sstevel@tonic-gate  */
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate struct Elf
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate 	rwlock_t	ed_rwlock;
2657c478bd9Sstevel@tonic-gate 	Elf		*ed_parent;	/* archive parent */
2667c478bd9Sstevel@tonic-gate 	int		ed_activ;	/* activation count */
2677c478bd9Sstevel@tonic-gate 	int		ed_fd;		/* file descriptor */
2687c478bd9Sstevel@tonic-gate 	Status		ed_status;	/* file's memory status */
2697c478bd9Sstevel@tonic-gate 	off_t		ed_baseoff;	/* base file offset, zero based */
2707c478bd9Sstevel@tonic-gate 	size_t		ed_memoff;	/* offset within archive */
2717c478bd9Sstevel@tonic-gate 	size_t		ed_siboff;	/* sibling offset with archive */
2727c478bd9Sstevel@tonic-gate 	size_t		ed_nextoff;	/* next archive member hdr offset */
2737c478bd9Sstevel@tonic-gate 	char		*ed_image;	/* pointer to file image */
2747c478bd9Sstevel@tonic-gate 	size_t		ed_imagesz;	/* # bytes in ed_image */
2757c478bd9Sstevel@tonic-gate 	char		*ed_wrimage;	/* pointer to output image */
2767c478bd9Sstevel@tonic-gate 	size_t		ed_wrimagesz;	/* # bytes in ed_wrimagesz */
2777c478bd9Sstevel@tonic-gate 	char		*ed_ident;	/* file start, getident() bytes */
2787c478bd9Sstevel@tonic-gate 	size_t		ed_identsz;	/* # bytes for getident() */
2797c478bd9Sstevel@tonic-gate 	char		*ed_raw;	/* raw file ptr */
2807c478bd9Sstevel@tonic-gate 	size_t		ed_fsz;		/* file size */
2817c478bd9Sstevel@tonic-gate 	unsigned	*ed_vm;		/* virtual memory map */
2827c478bd9Sstevel@tonic-gate 	size_t		ed_vmsz;	/* # regions in vm */
2837c478bd9Sstevel@tonic-gate 	unsigned	ed_encode;	/* data encoding */
2847c478bd9Sstevel@tonic-gate 	unsigned	ed_version;	/* file version */
2857c478bd9Sstevel@tonic-gate 	int		ed_class;	/* file class */
2867c478bd9Sstevel@tonic-gate 	Elf_Kind	ed_kind;	/* file type */
2877c478bd9Sstevel@tonic-gate 	Elf_Void	*ed_ehdr;	/* Elf{32,64}_Ehdr elf header */
2887c478bd9Sstevel@tonic-gate 	Elf_Void	*ed_phdr;	/* Elf{32,64}_Phdr phdr table */
2897c478bd9Sstevel@tonic-gate 	size_t		ed_phdrsz;	/* sizeof phdr table */
2907c478bd9Sstevel@tonic-gate 	Elf_Void	*ed_shdr;	/* Elf{32,64}_Shdr shdr table */
2917c478bd9Sstevel@tonic-gate 	Elf_Scn		*ed_hdscn;	/* head scn */
2927c478bd9Sstevel@tonic-gate 	Elf_Scn		*ed_tlscn;	/* tail scn */
2937c478bd9Sstevel@tonic-gate 	size_t		ed_scntabsz;	/* number sects. alloc. in table */
2947c478bd9Sstevel@tonic-gate 	Memlist		*ed_memlist;	/* list of archive member nodes */
2957c478bd9Sstevel@tonic-gate 	Member		*ed_armem;	/* archive member header */
2967c478bd9Sstevel@tonic-gate 	Elf_Void	*ed_arsym;	/* archive symbol table */
2977c478bd9Sstevel@tonic-gate 	size_t		ed_arsymsz;	/* archive symbol table size */
2987c478bd9Sstevel@tonic-gate 	size_t		ed_arsymoff;	/* archive symbol table hdr offset */
2997c478bd9Sstevel@tonic-gate 	char		*ed_arstr;	/* archive string table */
3007c478bd9Sstevel@tonic-gate 	size_t		ed_arstrsz;	/* archive string table size */
3017c478bd9Sstevel@tonic-gate 	size_t		ed_arstroff;	/* archive string table hdr offset */
3027c478bd9Sstevel@tonic-gate 	unsigned	ed_myflags;	/* EDF_... */
3037c478bd9Sstevel@tonic-gate 	unsigned	ed_ehflags;	/* ehdr flags */
3047c478bd9Sstevel@tonic-gate 	unsigned	ed_phflags;	/* phdr flags */
3057c478bd9Sstevel@tonic-gate 	unsigned	ed_uflags;	/* elf descriptor flags */
3067c478bd9Sstevel@tonic-gate };
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate #define	ELFRLOCK(e) \
3097c478bd9Sstevel@tonic-gate 	if (elf_threaded) \
3107c478bd9Sstevel@tonic-gate 		(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate #define	ELFWLOCK(e) \
3137c478bd9Sstevel@tonic-gate 	if (elf_threaded) \
3147c478bd9Sstevel@tonic-gate 		(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate #define	ELFUNLOCK(e) \
3177c478bd9Sstevel@tonic-gate 	if (elf_threaded) \
3187c478bd9Sstevel@tonic-gate 		(void) rw_unlock(&((Elf *)e)->ed_rwlock);
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate #define	EDF_ASALLOC	0x1	/* applies to ed_arsym */
3217c478bd9Sstevel@tonic-gate #define	EDF_EHALLOC	0x2	/* applies to ed_ehdr */
3227c478bd9Sstevel@tonic-gate #define	EDF_PHALLOC	0x4	/* applies to ed_phdr */
3237c478bd9Sstevel@tonic-gate #define	EDF_SHALLOC	0x8	/* applies to ed_shdr */
3247c478bd9Sstevel@tonic-gate #define	EDF_COFFAOUT	0x10	/* original file was coff a.out */
3257c478bd9Sstevel@tonic-gate #define	EDF_RAWALLOC	0x20	/* applies to ed_raw */
3267c478bd9Sstevel@tonic-gate #define	EDF_READ	0x40	/* file can be read */
3277c478bd9Sstevel@tonic-gate #define	EDF_WRITE	0x80	/* file can be written */
3287c478bd9Sstevel@tonic-gate #define	EDF_MEMORY	0x100	/* file opened via elf_memory() */
3297c478bd9Sstevel@tonic-gate #define	EDF_ASTRALLOC	0x200	/* applies to ed_arstr */
3307c478bd9Sstevel@tonic-gate #define	EDF_MPROTECT	0x400	/* applies to slideable archives */
3317c478bd9Sstevel@tonic-gate #define	EDF_IMALLOC	0x800	/* wrimage dynamically allocated */
3327c478bd9Sstevel@tonic-gate #define	EDF_WRALLOC	0x1000	/* wrimage is to by dyn allocated */
333*ba7866cdSAli Bahrami #define	EDF_ARSYM64	0x2000	/* archive symbol table is 64-bit format */
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate typedef enum
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate 	OK_YES = 0,
3397c478bd9Sstevel@tonic-gate 	OK_NO = ~0
3407c478bd9Sstevel@tonic-gate } Okay;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate #define	_(a)		a
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate /*
3457c478bd9Sstevel@tonic-gate  * Max size for an Elf error message string
3467c478bd9Sstevel@tonic-gate  */
3477c478bd9Sstevel@tonic-gate #define	MAXELFERR	1024
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate /*
3507c478bd9Sstevel@tonic-gate  * General thread management macros
3517c478bd9Sstevel@tonic-gate  */
3527c478bd9Sstevel@tonic-gate #define	ELFACCESSDATA(a, b) \
3537c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
3547c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&_elf_globals_mutex); \
3557c478bd9Sstevel@tonic-gate 		a = b; \
3567c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&_elf_globals_mutex); \
3577c478bd9Sstevel@tonic-gate 	} else \
3587c478bd9Sstevel@tonic-gate 		a = b;
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate #define	ELFRWLOCKINIT(lock) \
3617c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
3627c478bd9Sstevel@tonic-gate 		(void) rwlock_init((lock), USYNC_THREAD, 0); \
3637c478bd9Sstevel@tonic-gate 	}
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate #define	ELFMUTEXINIT(lock) \
3667c478bd9Sstevel@tonic-gate 	if (elf_threaded) { \
3677c478bd9Sstevel@tonic-gate 		(void) mutex_init(lock, USYNC_THREAD, 0); \
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 
3704899432aSab extern Member		*_elf_armem(Elf *, char *, size_t);
3717c478bd9Sstevel@tonic-gate extern void		_elf_arinit(Elf *);
3727c478bd9Sstevel@tonic-gate extern Okay		_elf_cook(Elf *);
3737c478bd9Sstevel@tonic-gate extern Okay		_elf_cookscn(Elf_Scn * s);
3747c478bd9Sstevel@tonic-gate extern Okay		_elf32_cookscn(Elf_Scn * s);
3757c478bd9Sstevel@tonic-gate extern Okay		_elf64_cookscn(Elf_Scn * s);
3764899432aSab extern Dnode		*_elf_dnode(void);
3774899432aSab extern Elf_Data		*_elf_locked_getdata(Elf_Scn *, Elf_Data *);
3787a5d89c4Sab extern size_t		_elf32_entsz(Elf *elf, Elf32_Word, unsigned);
3797a5d89c4Sab extern size_t		_elf64_entsz(Elf *elf, Elf64_Word, unsigned);
3807c478bd9Sstevel@tonic-gate extern Okay		_elf_inmap(Elf *);
3814899432aSab extern char		*_elf_outmap(int, size_t, unsigned *);
3827c478bd9Sstevel@tonic-gate extern size_t		_elf_outsync(int, char *, size_t, unsigned);
3837c478bd9Sstevel@tonic-gate extern size_t		_elf32_msize(Elf_Type, unsigned);
3847c478bd9Sstevel@tonic-gate extern size_t		_elf64_msize(Elf_Type, unsigned);
3857c478bd9Sstevel@tonic-gate extern Elf_Type		_elf32_mtype(Elf *, Elf32_Word, unsigned);
3867c478bd9Sstevel@tonic-gate extern Elf_Type		_elf64_mtype(Elf *, Elf64_Word, unsigned);
3874899432aSab extern char		*_elf_read(int, off_t, size_t);
3884899432aSab extern Snode32		*_elf32_snode(void);
3894899432aSab extern Snode64		*_elf64_snode(void);
3907c478bd9Sstevel@tonic-gate extern void		_elf_unmap(char *, size_t);
3917c478bd9Sstevel@tonic-gate extern Okay		_elf_vm(Elf *, size_t, size_t);
3927c478bd9Sstevel@tonic-gate extern int		_elf32_ehdr(Elf *, int);
3937c478bd9Sstevel@tonic-gate extern int		_elf32_phdr(Elf *, int);
3947c478bd9Sstevel@tonic-gate extern int		_elf32_shdr(Elf *, int);
3957c478bd9Sstevel@tonic-gate extern int		_elf64_ehdr(Elf *, int);
3967c478bd9Sstevel@tonic-gate extern int		_elf64_phdr(Elf *, int);
3977c478bd9Sstevel@tonic-gate extern int		_elf64_shdr(Elf *, int);
3987c478bd9Sstevel@tonic-gate extern int		_elf_byte;
3997c478bd9Sstevel@tonic-gate extern const Elf32_Ehdr	_elf32_ehdr_init;
4007c478bd9Sstevel@tonic-gate extern const Elf64_Ehdr	_elf64_ehdr_init;
4017c478bd9Sstevel@tonic-gate extern unsigned		_elf_encode;
4023c573fccSAli Bahrami extern _elf_execfill_func_t *_elf_execfill_func;
4037c478bd9Sstevel@tonic-gate extern void		_elf_seterr(Msg, int);
4047c478bd9Sstevel@tonic-gate extern const Snode32	_elf32_snode_init;
4057c478bd9Sstevel@tonic-gate extern const Snode64	_elf64_snode_init;
4067c478bd9Sstevel@tonic-gate extern const Dnode	_elf_dnode_init;
4077c478bd9Sstevel@tonic-gate extern unsigned		_elf_work;
4087c478bd9Sstevel@tonic-gate extern mutex_t		_elf_globals_mutex;
4097c478bd9Sstevel@tonic-gate extern off_t		_elf64_update(Elf * elf, Elf_Cmd cmd);
410ba2be530Sab extern int		_elf64_swap_wrimage(Elf *elf);
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate #endif
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate #endif	/* _DECL_H */
417