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