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 54899432aSab196087 * Common Development and Distribution License (the "License"). 64899432aSab196087 * 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> 337c478bd9Sstevel@tonic-gate #include <note.h> 344899432aSab196087 #include <_libelf.h> 357c478bd9Sstevel@tonic-gate #include <sys/machelf.h> 367c478bd9Sstevel@tonic-gate #include <msg.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #ifdef __cplusplus 407c478bd9Sstevel@tonic-gate extern "C" { 417c478bd9Sstevel@tonic-gate #endif 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate typedef struct Member Member; 447c478bd9Sstevel@tonic-gate typedef struct Memlist Memlist; 457c478bd9Sstevel@tonic-gate typedef struct Memident Memident; 467c478bd9Sstevel@tonic-gate typedef struct Dnode Dnode; 477c478bd9Sstevel@tonic-gate typedef struct Snode32 Snode32; 487c478bd9Sstevel@tonic-gate typedef struct Snode64 Snode64; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * Data alignment 537c478bd9Sstevel@tonic-gate * An elf file is defined to have its structures aligned on 547c478bd9Sstevel@tonic-gate * appropriate boundaries. The following type lets the 557c478bd9Sstevel@tonic-gate * library test whether the file's alignment meets its own 567c478bd9Sstevel@tonic-gate * constraints in memory. This assumes every machine uses 577c478bd9Sstevel@tonic-gate * an alignment that is no greater than an object's size. 587c478bd9Sstevel@tonic-gate * The pointer isn't relevant for the file, but the code uses 597c478bd9Sstevel@tonic-gate * it to get memory alignment. ANSI C void * holds any pointer, 607c478bd9Sstevel@tonic-gate * making it appropriate here. 617c478bd9Sstevel@tonic-gate */ 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate typedef union 647c478bd9Sstevel@tonic-gate { 657c478bd9Sstevel@tonic-gate Elf32_Word w; 667c478bd9Sstevel@tonic-gate Elf32_Addr a; 677c478bd9Sstevel@tonic-gate Elf32_Off o; 687c478bd9Sstevel@tonic-gate } Elf32; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate typedef union { 717c478bd9Sstevel@tonic-gate Elf64_Xword x; 727c478bd9Sstevel@tonic-gate Elf64_Word w; 737c478bd9Sstevel@tonic-gate Elf64_Addr a; 747c478bd9Sstevel@tonic-gate Elf64_Off o; 757c478bd9Sstevel@tonic-gate Elf_Void *p; 767c478bd9Sstevel@tonic-gate } Elf64; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* 807c478bd9Sstevel@tonic-gate * Memory allocation 817c478bd9Sstevel@tonic-gate * Structures are obtained several ways: file mapping, 827c478bd9Sstevel@tonic-gate * malloc(), from the user. A status bit in the structures 837c478bd9Sstevel@tonic-gate * tells whether an object was obtained with malloc() and 847c478bd9Sstevel@tonic-gate * therefore should be released with free(). The bits 857c478bd9Sstevel@tonic-gate * named ...ALLOC indicate this. 867c478bd9Sstevel@tonic-gate */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /* 907c478bd9Sstevel@tonic-gate * Data descriptor 917c478bd9Sstevel@tonic-gate * db_data must be first in the Dnode structure, because 927c478bd9Sstevel@tonic-gate * &db_data must == &Dnode. 937c478bd9Sstevel@tonic-gate * 947c478bd9Sstevel@tonic-gate * db_buf is a pointer to an allocated buffer. The same value 957c478bd9Sstevel@tonic-gate * goes into db_data.d_buf originally, but the user can touch 967c478bd9Sstevel@tonic-gate * it. If the data buffer is not to be freed, db_buf is null. 977c478bd9Sstevel@tonic-gate * 987c478bd9Sstevel@tonic-gate * When "reading" an input file's buffer, the data are left 997c478bd9Sstevel@tonic-gate * alone until needed. When they've been converted to internal 1007c478bd9Sstevel@tonic-gate * form, the READY flag is set. 1017c478bd9Sstevel@tonic-gate * 1027c478bd9Sstevel@tonic-gate * db_raw points to a parallel raw buffer. Raw buffers 1037c478bd9Sstevel@tonic-gate * have null db_raw. 1047c478bd9Sstevel@tonic-gate */ 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate struct Dnode 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate Elf_Data db_data; 1097c478bd9Sstevel@tonic-gate Elf_Scn *db_scn; /* section parent */ 1107c478bd9Sstevel@tonic-gate Dnode *db_next; 1117c478bd9Sstevel@tonic-gate Dnode *db_raw; /* raw data */ 1127c478bd9Sstevel@tonic-gate off_t db_off; /* orig file offset, 0 o/w */ 1137c478bd9Sstevel@tonic-gate size_t db_fsz; /* orig file size, 0 o/w */ 1147c478bd9Sstevel@tonic-gate size_t db_shsz; /* orig shdr size, 0 o/w */ 1157c478bd9Sstevel@tonic-gate size_t db_osz; /* output size for update */ 1167c478bd9Sstevel@tonic-gate Elf_Void *db_buf; /* allocated data buffer */ 1177c478bd9Sstevel@tonic-gate unsigned db_uflags; /* user flags: ELF_F_... */ 1187c478bd9Sstevel@tonic-gate unsigned db_myflags; /* internal flags: DBF_... */ 1197c478bd9Sstevel@tonic-gate Elf64_Off db_xoff; /* extended offset for 32-bit Elf64 */ 1207c478bd9Sstevel@tonic-gate }; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate #define DBF_ALLOC 0x1 /* applies to Dnode itself */ 1237c478bd9Sstevel@tonic-gate #define DBF_READY 0x2 /* buffer ready */ 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * Section descriptor 1287c478bd9Sstevel@tonic-gate * These are sometimes allocated in a block. If the SF_ALLOC 1297c478bd9Sstevel@tonic-gate * bit is set in the flags, the Scn address may be passed to free. 1307c478bd9Sstevel@tonic-gate * The caller must first follow the s_next list to the next freeable 1317c478bd9Sstevel@tonic-gate * node, because free can clobber the s_next value in the block. 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate struct Elf_Scn 1357c478bd9Sstevel@tonic-gate { 1367c478bd9Sstevel@tonic-gate mutex_t s_mutex; 1377c478bd9Sstevel@tonic-gate Elf_Scn *s_next; /* next section */ 1387c478bd9Sstevel@tonic-gate Elf *s_elf; /* parent file */ 1397c478bd9Sstevel@tonic-gate Dnode *s_hdnode; /* head Dnode */ 1407c478bd9Sstevel@tonic-gate Dnode *s_tlnode; /* tail Dnode */ 1417c478bd9Sstevel@tonic-gate Elf_Void *s_shdr; /* Elf32 or Elf64 scn header */ 1427c478bd9Sstevel@tonic-gate size_t s_index; /* section index */ 1437c478bd9Sstevel@tonic-gate int s_err; /* for delaying data error */ 1447c478bd9Sstevel@tonic-gate unsigned s_shflags; /* user shdr flags */ 1457c478bd9Sstevel@tonic-gate unsigned s_uflags; /* user flags */ 1467c478bd9Sstevel@tonic-gate unsigned s_myflags; /* SF_... */ 1477c478bd9Sstevel@tonic-gate Dnode s_dnode; /* every scn needs one */ 1487c478bd9Sstevel@tonic-gate }; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(Elf_Scn::s_mutex, Elf_Scn Dnode Elf_Data)) 1517c478bd9Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf_Data)) 1527c478bd9Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf32_Shdr Elf32_Sym)) 1537c478bd9Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Elf_Scn::s_elf)) 1547c478bd9Sstevel@tonic-gate NOTE(READ_ONLY_DATA(Dnode::db_scn)) 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * Designates whether or not we are in a threaded_app. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate extern int *_elf_libc_threaded; 1617c478bd9Sstevel@tonic-gate #define elf_threaded (_elf_libc_threaded && *_elf_libc_threaded) 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate #ifdef __lock_lint 1647c478bd9Sstevel@tonic-gate #define SCNLOCK(x) (void) mutex_lock(&((Elf_Scn *)x)->s_mutex); 1657c478bd9Sstevel@tonic-gate #else 1667c478bd9Sstevel@tonic-gate #define SCNLOCK(x) \ 1677c478bd9Sstevel@tonic-gate if (elf_threaded) \ 1687c478bd9Sstevel@tonic-gate (void) mutex_lock(&((Elf_Scn *)x)->s_mutex); 1697c478bd9Sstevel@tonic-gate #endif 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate #ifdef __lock_lint 1727c478bd9Sstevel@tonic-gate #define SCNUNLOCK(x) (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex); 1737c478bd9Sstevel@tonic-gate #else 1747c478bd9Sstevel@tonic-gate #define SCNUNLOCK(x) \ 1757c478bd9Sstevel@tonic-gate if (elf_threaded) \ 1767c478bd9Sstevel@tonic-gate (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex); 1777c478bd9Sstevel@tonic-gate #endif 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate #ifdef __lock_lint 1807c478bd9Sstevel@tonic-gate #define UPGRADELOCKS(e, s)\ 1817c478bd9Sstevel@tonic-gate (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ 1827c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ 1837c478bd9Sstevel@tonic-gate (void) rw_wrlock(&((Elf *)e)->ed_rwlock); 1847c478bd9Sstevel@tonic-gate #else 1857c478bd9Sstevel@tonic-gate #define UPGRADELOCKS(e, s)\ 1867c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 1877c478bd9Sstevel@tonic-gate (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ 1887c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ 1897c478bd9Sstevel@tonic-gate (void) rw_wrlock(&((Elf *)e)->ed_rwlock); \ 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate #endif 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate #ifdef __lock_lint 1947c478bd9Sstevel@tonic-gate #define DOWNGRADELOCKS(e, s)\ 1957c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ 1967c478bd9Sstevel@tonic-gate (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ 1977c478bd9Sstevel@tonic-gate (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); 1987c478bd9Sstevel@tonic-gate #else 1997c478bd9Sstevel@tonic-gate #define DOWNGRADELOCKS(e, s)\ 2007c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 2017c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ 2027c478bd9Sstevel@tonic-gate (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ 2037c478bd9Sstevel@tonic-gate (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \ 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate #endif 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate #ifdef __lock_lint 2087c478bd9Sstevel@tonic-gate #define READLOCKS(e, s) \ 2097c478bd9Sstevel@tonic-gate (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ 2107c478bd9Sstevel@tonic-gate (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); 2117c478bd9Sstevel@tonic-gate #else 2127c478bd9Sstevel@tonic-gate #define READLOCKS(e, s) \ 2137c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 2147c478bd9Sstevel@tonic-gate (void) rw_rdlock(&((Elf *)e)->ed_rwlock); \ 2157c478bd9Sstevel@tonic-gate (void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \ 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate #endif 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate #ifdef __lock_lint 2207c478bd9Sstevel@tonic-gate #define READUNLOCKS(e, s) \ 2217c478bd9Sstevel@tonic-gate (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ 2227c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); 2237c478bd9Sstevel@tonic-gate #else 2247c478bd9Sstevel@tonic-gate #define READUNLOCKS(e, s) \ 2257c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 2267c478bd9Sstevel@tonic-gate (void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \ 2277c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); \ 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate #endif 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate #define SF_ALLOC 0x1 /* applies to Scn */ 2357c478bd9Sstevel@tonic-gate #define SF_READY 0x2 /* has section been cooked */ 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate struct Snode32 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate Elf_Scn sb_scn; /* must be first */ 2417c478bd9Sstevel@tonic-gate Elf32_Shdr sb_shdr; 2427c478bd9Sstevel@tonic-gate }; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate struct Snode64 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate Elf_Scn sb_scn; /* must be first */ 2477c478bd9Sstevel@tonic-gate Elf64_Shdr sb_shdr; 2487c478bd9Sstevel@tonic-gate }; 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * A file's status controls how the library can use file data. 2537c478bd9Sstevel@tonic-gate * This is important to keep "raw" operations and "cooked" 2547c478bd9Sstevel@tonic-gate * operations from interfering with each other. 2557c478bd9Sstevel@tonic-gate * 2567c478bd9Sstevel@tonic-gate * A file's status is "fresh" until something touches it. 2577c478bd9Sstevel@tonic-gate * If the first thing is a raw operation, we freeze the data 2587c478bd9Sstevel@tonic-gate * and force all cooking operations to make a copy. If the 2597c478bd9Sstevel@tonic-gate * first operation cooks, raw operations use the file system. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate typedef enum 2637c478bd9Sstevel@tonic-gate { 2647c478bd9Sstevel@tonic-gate ES_FRESH = 0, /* unchanged */ 2657c478bd9Sstevel@tonic-gate ES_COOKED, /* translated */ 2667c478bd9Sstevel@tonic-gate ES_FROZEN /* raw, can't be translated */ 2677c478bd9Sstevel@tonic-gate } Status; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate /* 2717c478bd9Sstevel@tonic-gate * Elf descriptor 2727c478bd9Sstevel@tonic-gate * The major handle between user code and the library. 2737c478bd9Sstevel@tonic-gate * 2747c478bd9Sstevel@tonic-gate * Descriptors can have parents: archive members reference 2757c478bd9Sstevel@tonic-gate * the archive itself. Relevant "offsets:" 2767c478bd9Sstevel@tonic-gate * 2777c478bd9Sstevel@tonic-gate * ed_baseoff The file offset, relative to zero, to the first 2787c478bd9Sstevel@tonic-gate * byte in the file. For all files, this gives 2797c478bd9Sstevel@tonic-gate * the lseek(fd, ed_baseoff, 0) value. 2807c478bd9Sstevel@tonic-gate * 2817c478bd9Sstevel@tonic-gate * ed_memoff The offset from the beginning of the nesting file 2827c478bd9Sstevel@tonic-gate * to the bytes of a member. For an archive member, 2837c478bd9Sstevel@tonic-gate * this is the offset from the beginning of the 2847c478bd9Sstevel@tonic-gate * archive to the member bytes (not the hdr). If an 2857c478bd9Sstevel@tonic-gate * archive member slides, memoff changes. 2867c478bd9Sstevel@tonic-gate * 2877c478bd9Sstevel@tonic-gate * ed_siboff Similar to ed_memoff, this gives the offset from 2887c478bd9Sstevel@tonic-gate * the beginning of the nesting file to the following 2897c478bd9Sstevel@tonic-gate * sibling's header (not the sibling's bytes). This 2907c478bd9Sstevel@tonic-gate * value is necessary, because of archive sliding. 2917c478bd9Sstevel@tonic-gate * 2927c478bd9Sstevel@tonic-gate * ed_nextoff For an archive, this gives the offset of the next 2937c478bd9Sstevel@tonic-gate * member to process on elf_begin. That is, 2947c478bd9Sstevel@tonic-gate * (ed_ident + ed_nextoff) gives pointer to member hdr. 2957c478bd9Sstevel@tonic-gate * 2967c478bd9Sstevel@tonic-gate * Keeping these absolute and relative offsets allows nesting of 2977c478bd9Sstevel@tonic-gate * files, including archives within archives, etc. The only current 2987c478bd9Sstevel@tonic-gate * nesting file is archive, but others might be supported. 2997c478bd9Sstevel@tonic-gate * 3007c478bd9Sstevel@tonic-gate * ed_image This is a pointer to the base memory image holding 3017c478bd9Sstevel@tonic-gate * the file. Library code assumes the image is aligned 3027c478bd9Sstevel@tonic-gate * to a boundary appropriate for any object. This must 3037c478bd9Sstevel@tonic-gate * be true, because we get an image only from malloc 3047c478bd9Sstevel@tonic-gate * or mmap, both of which guarantee alignment. 3057c478bd9Sstevel@tonic-gate */ 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate struct Elf 3087c478bd9Sstevel@tonic-gate { 3097c478bd9Sstevel@tonic-gate rwlock_t ed_rwlock; 3107c478bd9Sstevel@tonic-gate Elf *ed_parent; /* archive parent */ 3117c478bd9Sstevel@tonic-gate int ed_activ; /* activation count */ 3127c478bd9Sstevel@tonic-gate int ed_fd; /* file descriptor */ 3137c478bd9Sstevel@tonic-gate Status ed_status; /* file's memory status */ 3147c478bd9Sstevel@tonic-gate off_t ed_baseoff; /* base file offset, zero based */ 3157c478bd9Sstevel@tonic-gate size_t ed_memoff; /* offset within archive */ 3167c478bd9Sstevel@tonic-gate size_t ed_siboff; /* sibling offset with archive */ 3177c478bd9Sstevel@tonic-gate size_t ed_nextoff; /* next archive member hdr offset */ 3187c478bd9Sstevel@tonic-gate char *ed_image; /* pointer to file image */ 3197c478bd9Sstevel@tonic-gate size_t ed_imagesz; /* # bytes in ed_image */ 3207c478bd9Sstevel@tonic-gate char *ed_wrimage; /* pointer to output image */ 3217c478bd9Sstevel@tonic-gate size_t ed_wrimagesz; /* # bytes in ed_wrimagesz */ 3227c478bd9Sstevel@tonic-gate char *ed_ident; /* file start, getident() bytes */ 3237c478bd9Sstevel@tonic-gate size_t ed_identsz; /* # bytes for getident() */ 3247c478bd9Sstevel@tonic-gate char *ed_raw; /* raw file ptr */ 3257c478bd9Sstevel@tonic-gate size_t ed_fsz; /* file size */ 3267c478bd9Sstevel@tonic-gate unsigned *ed_vm; /* virtual memory map */ 3277c478bd9Sstevel@tonic-gate size_t ed_vmsz; /* # regions in vm */ 3287c478bd9Sstevel@tonic-gate unsigned ed_encode; /* data encoding */ 3297c478bd9Sstevel@tonic-gate unsigned ed_version; /* file version */ 3307c478bd9Sstevel@tonic-gate int ed_class; /* file class */ 3317c478bd9Sstevel@tonic-gate Elf_Kind ed_kind; /* file type */ 3327c478bd9Sstevel@tonic-gate Elf_Void *ed_ehdr; /* Elf{32,64}_Ehdr elf header */ 3337c478bd9Sstevel@tonic-gate Elf_Void *ed_phdr; /* Elf{32,64}_Phdr phdr table */ 3347c478bd9Sstevel@tonic-gate size_t ed_phdrsz; /* sizeof phdr table */ 3357c478bd9Sstevel@tonic-gate Elf_Void *ed_shdr; /* Elf{32,64}_Shdr shdr table */ 3367c478bd9Sstevel@tonic-gate Elf_Scn *ed_hdscn; /* head scn */ 3377c478bd9Sstevel@tonic-gate Elf_Scn *ed_tlscn; /* tail scn */ 3387c478bd9Sstevel@tonic-gate size_t ed_scntabsz; /* number sects. alloc. in table */ 3397c478bd9Sstevel@tonic-gate Memlist *ed_memlist; /* list of archive member nodes */ 3407c478bd9Sstevel@tonic-gate Member *ed_armem; /* archive member header */ 3417c478bd9Sstevel@tonic-gate Elf_Void *ed_arsym; /* archive symbol table */ 3427c478bd9Sstevel@tonic-gate size_t ed_arsymsz; /* archive symbol table size */ 3437c478bd9Sstevel@tonic-gate size_t ed_arsymoff; /* archive symbol table hdr offset */ 3447c478bd9Sstevel@tonic-gate char *ed_arstr; /* archive string table */ 3457c478bd9Sstevel@tonic-gate size_t ed_arstrsz; /* archive string table size */ 3467c478bd9Sstevel@tonic-gate size_t ed_arstroff; /* archive string table hdr offset */ 3477c478bd9Sstevel@tonic-gate unsigned ed_myflags; /* EDF_... */ 3487c478bd9Sstevel@tonic-gate unsigned ed_ehflags; /* ehdr flags */ 3497c478bd9Sstevel@tonic-gate unsigned ed_phflags; /* phdr flags */ 3507c478bd9Sstevel@tonic-gate unsigned ed_uflags; /* elf descriptor flags */ 3517c478bd9Sstevel@tonic-gate }; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate NOTE(RWLOCK_PROTECTS_DATA(Elf::ed_rwlock, Elf)) 3547c478bd9Sstevel@tonic-gate NOTE(RWLOCK_COVERS_LOCKS(Elf::ed_rwlock, Elf_Scn::s_mutex)) 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate #ifdef __lock_lint 3577c478bd9Sstevel@tonic-gate #define ELFRLOCK(e) (void) rw_rdlock(&((Elf *)e)->ed_rwlock); 3587c478bd9Sstevel@tonic-gate #else 3597c478bd9Sstevel@tonic-gate #define ELFRLOCK(e) \ 3607c478bd9Sstevel@tonic-gate if (elf_threaded) \ 3617c478bd9Sstevel@tonic-gate (void) rw_rdlock(&((Elf *)e)->ed_rwlock); 3627c478bd9Sstevel@tonic-gate #endif 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate #ifdef __lock_lint 3657c478bd9Sstevel@tonic-gate #define ELFWLOCK(e) (void) rw_wrlock(&((Elf *)e)->ed_rwlock); 3667c478bd9Sstevel@tonic-gate #else 3677c478bd9Sstevel@tonic-gate #define ELFWLOCK(e) \ 3687c478bd9Sstevel@tonic-gate if (elf_threaded) \ 3697c478bd9Sstevel@tonic-gate (void) rw_wrlock(&((Elf *)e)->ed_rwlock); 3707c478bd9Sstevel@tonic-gate #endif 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate #ifdef __lock_lint 3737c478bd9Sstevel@tonic-gate #define ELFUNLOCK(e) (void) rw_unlock(&((Elf *)e)->ed_rwlock); 3747c478bd9Sstevel@tonic-gate #else 3757c478bd9Sstevel@tonic-gate #define ELFUNLOCK(e) \ 3767c478bd9Sstevel@tonic-gate if (elf_threaded) \ 3777c478bd9Sstevel@tonic-gate (void) rw_unlock(&((Elf *)e)->ed_rwlock); 3787c478bd9Sstevel@tonic-gate #endif 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate #define EDF_ASALLOC 0x1 /* applies to ed_arsym */ 3817c478bd9Sstevel@tonic-gate #define EDF_EHALLOC 0x2 /* applies to ed_ehdr */ 3827c478bd9Sstevel@tonic-gate #define EDF_PHALLOC 0x4 /* applies to ed_phdr */ 3837c478bd9Sstevel@tonic-gate #define EDF_SHALLOC 0x8 /* applies to ed_shdr */ 3847c478bd9Sstevel@tonic-gate #define EDF_COFFAOUT 0x10 /* original file was coff a.out */ 3857c478bd9Sstevel@tonic-gate #define EDF_RAWALLOC 0x20 /* applies to ed_raw */ 3867c478bd9Sstevel@tonic-gate #define EDF_READ 0x40 /* file can be read */ 3877c478bd9Sstevel@tonic-gate #define EDF_WRITE 0x80 /* file can be written */ 3887c478bd9Sstevel@tonic-gate #define EDF_MEMORY 0x100 /* file opened via elf_memory() */ 3897c478bd9Sstevel@tonic-gate #define EDF_ASTRALLOC 0x200 /* applies to ed_arstr */ 3907c478bd9Sstevel@tonic-gate #define EDF_MPROTECT 0x400 /* applies to slideable archives */ 3917c478bd9Sstevel@tonic-gate #define EDF_IMALLOC 0x800 /* wrimage dynamically allocated */ 3927c478bd9Sstevel@tonic-gate #define EDF_WRALLOC 0x1000 /* wrimage is to by dyn allocated */ 393*ba7866cdSAli Bahrami #define EDF_ARSYM64 0x2000 /* archive symbol table is 64-bit format */ 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate typedef enum 3977c478bd9Sstevel@tonic-gate { 3987c478bd9Sstevel@tonic-gate OK_YES = 0, 3997c478bd9Sstevel@tonic-gate OK_NO = ~0 4007c478bd9Sstevel@tonic-gate } Okay; 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate #define _(a) a 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * Max size for an Elf error message string 4067c478bd9Sstevel@tonic-gate */ 4077c478bd9Sstevel@tonic-gate #define MAXELFERR 1024 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate /* 4107c478bd9Sstevel@tonic-gate * General thread management macros 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate #ifdef __lock_lint 4137c478bd9Sstevel@tonic-gate #define ELFACCESSDATA(a, b) \ 4147c478bd9Sstevel@tonic-gate (void) mutex_lock(&_elf_globals_mutex); \ 4157c478bd9Sstevel@tonic-gate a = b; \ 4167c478bd9Sstevel@tonic-gate (void) mutex_unlock(&_elf_globals_mutex); 4177c478bd9Sstevel@tonic-gate #else 4187c478bd9Sstevel@tonic-gate #define ELFACCESSDATA(a, b) \ 4197c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 4207c478bd9Sstevel@tonic-gate (void) mutex_lock(&_elf_globals_mutex); \ 4217c478bd9Sstevel@tonic-gate a = b; \ 4227c478bd9Sstevel@tonic-gate (void) mutex_unlock(&_elf_globals_mutex); \ 4237c478bd9Sstevel@tonic-gate } else \ 4247c478bd9Sstevel@tonic-gate a = b; 4257c478bd9Sstevel@tonic-gate #endif 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate #ifdef __lock_lint 4287c478bd9Sstevel@tonic-gate #define ELFRWLOCKINIT(lock) \ 4297c478bd9Sstevel@tonic-gate (void) rwlock_init((lock), USYNC_THREAD, 0); 4307c478bd9Sstevel@tonic-gate #else 4317c478bd9Sstevel@tonic-gate #define ELFRWLOCKINIT(lock) \ 4327c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 4337c478bd9Sstevel@tonic-gate (void) rwlock_init((lock), USYNC_THREAD, 0); \ 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate #endif 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate #ifdef __lock_lint 4387c478bd9Sstevel@tonic-gate #define ELFMUTEXINIT(lock) \ 4397c478bd9Sstevel@tonic-gate (void) mutex_init(lock, USYNC_THREAD, 0); 4407c478bd9Sstevel@tonic-gate #else 4417c478bd9Sstevel@tonic-gate #define ELFMUTEXINIT(lock) \ 4427c478bd9Sstevel@tonic-gate if (elf_threaded) { \ 4437c478bd9Sstevel@tonic-gate (void) mutex_init(lock, USYNC_THREAD, 0); \ 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate #endif 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate extern Member *_elf_armem(Elf *, char *, size_t); 4497c478bd9Sstevel@tonic-gate extern void _elf_arinit(Elf *); 4507c478bd9Sstevel@tonic-gate extern Okay _elf_cook(Elf *); 4517c478bd9Sstevel@tonic-gate extern Okay _elf_cookscn(Elf_Scn * s); 4527c478bd9Sstevel@tonic-gate extern Okay _elf32_cookscn(Elf_Scn * s); 4537c478bd9Sstevel@tonic-gate extern Okay _elf64_cookscn(Elf_Scn * s); 4547c478bd9Sstevel@tonic-gate extern Dnode *_elf_dnode(void); 4557c478bd9Sstevel@tonic-gate extern Elf_Data *_elf_locked_getdata(Elf_Scn *, Elf_Data *); 4567a5d89c4Sab196087 extern size_t _elf32_entsz(Elf *elf, Elf32_Word, unsigned); 4577a5d89c4Sab196087 extern size_t _elf64_entsz(Elf *elf, Elf64_Word, unsigned); 4587c478bd9Sstevel@tonic-gate extern Okay _elf_inmap(Elf *); 4597c478bd9Sstevel@tonic-gate extern char *_elf_outmap(int, size_t, unsigned *); 4607c478bd9Sstevel@tonic-gate extern size_t _elf_outsync(int, char *, size_t, unsigned); 4617c478bd9Sstevel@tonic-gate extern size_t _elf32_msize(Elf_Type, unsigned); 4627c478bd9Sstevel@tonic-gate extern size_t _elf64_msize(Elf_Type, unsigned); 4637c478bd9Sstevel@tonic-gate extern Elf_Type _elf32_mtype(Elf *, Elf32_Word, unsigned); 4647c478bd9Sstevel@tonic-gate extern Elf_Type _elf64_mtype(Elf *, Elf64_Word, unsigned); 4657c478bd9Sstevel@tonic-gate extern char *_elf_read(int, off_t, size_t); 4667c478bd9Sstevel@tonic-gate extern Snode32 *_elf32_snode(void); 4677c478bd9Sstevel@tonic-gate extern Snode64 *_elf64_snode(void); 4687c478bd9Sstevel@tonic-gate extern void _elf_unmap(char *, size_t); 4697c478bd9Sstevel@tonic-gate extern Okay _elf_vm(Elf *, size_t, size_t); 4707c478bd9Sstevel@tonic-gate extern int _elf32_ehdr(Elf *, int); 4717c478bd9Sstevel@tonic-gate extern int _elf32_phdr(Elf *, int); 4727c478bd9Sstevel@tonic-gate extern int _elf32_shdr(Elf *, int); 4737c478bd9Sstevel@tonic-gate extern int _elf64_ehdr(Elf *, int); 4747c478bd9Sstevel@tonic-gate extern int _elf64_phdr(Elf *, int); 4757c478bd9Sstevel@tonic-gate extern int _elf64_shdr(Elf *, int); 4767c478bd9Sstevel@tonic-gate extern int _elf_byte; 4777c478bd9Sstevel@tonic-gate extern const Elf32_Ehdr _elf32_ehdr_init; 4787c478bd9Sstevel@tonic-gate extern const Elf64_Ehdr _elf64_ehdr_init; 4797c478bd9Sstevel@tonic-gate extern unsigned _elf_encode; 4803c573fccSAli Bahrami extern _elf_execfill_func_t *_elf_execfill_func; 4817c478bd9Sstevel@tonic-gate extern void _elf_seterr(Msg, int); 4827c478bd9Sstevel@tonic-gate extern const Snode32 _elf32_snode_init; 4837c478bd9Sstevel@tonic-gate extern const Snode64 _elf64_snode_init; 4847c478bd9Sstevel@tonic-gate extern const Dnode _elf_dnode_init; 4857c478bd9Sstevel@tonic-gate extern unsigned _elf_work; 4867c478bd9Sstevel@tonic-gate extern mutex_t _elf_globals_mutex; 4877c478bd9Sstevel@tonic-gate extern off_t _elf64_update(Elf * elf, Elf_Cmd cmd); 488ba2be530Sab196087 extern int _elf64_swap_wrimage(Elf *elf); 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate /* CSTYLED */ 4917c478bd9Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \ 4927c478bd9Sstevel@tonic-gate _elf_byte _elf32_ehdr_init _elf64_ehdr_init _elf_encode \ 4937c478bd9Sstevel@tonic-gate _elf_snode_init _elf_work)) 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate #ifdef __cplusplus 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate #endif 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate #endif /* _DECL_H */ 500