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