#ifndef _DECL_H
#define _DECL_H
#pragma ident "@(#)decl.h 1.23 08/03/18 SMI"
#if !defined(__APPLE__)
#include <thread.h>
#include <note.h>
#include <_libelf.h>
#include <sys/machelf.h>
#include <msg.h>
#else
#define SEG_CTF "__CTF"
#define SECT_CTF "__ctf"
#include <pthread.h>
#define USYNC_THREAD IGNORED
#define DEFAULTMUTEX PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t mutex_t;
typedef pthread_rwlock_t rwlock_t;
typedef pthread_key_t thread_key_t;
#define RW_LOCK_HELD(x) 1
#define MUTEX_HELD(x) 1
#define rwlock_init(x,y,z) pthread_rwlock_init(x,((const pthread_rwlockattr_t *)NULL))
#define rw_rdlock(x) pthread_rwlock_rdlock(x)
#define rw_wrlock(x) pthread_rwlock_wrlock(x)
#define rw_unlock(x) pthread_rwlock_unlock(x)
#define mutex_init(x,y,z) pthread_mutex_init(x,((const pthread_mutexattr_t *)NULL))
#define mutex_lock(x) pthread_mutex_lock(x)
#define mutex_unlock(x) pthread_mutex_unlock(x)
#define NOTE(x)
#include <libelf.h>
#include "machelf.h"
#include <gelf.h>
#include <msg.h>
#include <unistd.h>
#define PAGESIZE getpagesize()
#define SHT_SPARC_GOTDATA -1
#define SHT_AMD64_UNWIND -1
#define SWAP16(v) v = OSSwapInt16(v)
#define SWAP32(v) v = OSSwapInt32(v)
#define SWAP64(v) v = OSSwapInt64(v)
#include <mach-o/loader.h>
extern void __swap_mach_header(struct mach_header *);
extern void __swap_mach_header_64(struct mach_header_64 *);
extern void __swap_segment_command(struct segment_command *);
extern void __swap_segment_command_64(struct segment_command_64 *);
extern void __swap_section(struct section *);
extern void __swap_section_64(struct section_64 *);
extern void __swap_symtab_command(struct symtab_command *);
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Member Member;
typedef struct Memlist Memlist;
typedef struct Memident Memident;
typedef struct Dnode Dnode;
typedef struct Snode32 Snode32;
typedef struct Snode64 Snode64;
typedef union
{
Elf32_Word w;
Elf32_Addr a;
Elf32_Off o;
} Elf32;
typedef union {
Elf64_Xword x;
Elf64_Word w;
Elf64_Addr a;
Elf64_Off o;
Elf_Void *p;
} Elf64;
struct Dnode
{
Elf_Data db_data;
Elf_Scn *db_scn;
Dnode *db_next;
Dnode *db_raw;
off_t db_off;
size_t db_fsz;
size_t db_shsz;
size_t db_osz;
Elf_Void *db_buf;
unsigned db_uflags;
unsigned db_myflags;
Elf64_Off db_xoff;
};
#define DBF_ALLOC 0x1
#define DBF_READY 0x2
struct Elf_Scn
{
mutex_t s_mutex;
Elf_Scn *s_next;
Elf *s_elf;
Dnode *s_hdnode;
Dnode *s_tlnode;
Elf_Void *s_shdr;
size_t s_index;
int s_err;
unsigned s_shflags;
unsigned s_uflags;
unsigned s_myflags;
Dnode s_dnode;
};
NOTE(MUTEX_PROTECTS_DATA(Elf_Scn::s_mutex, Elf_Scn Dnode Elf_Data))
NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf_Data))
NOTE(SCHEME_PROTECTS_DATA("Scn lock held", Elf32_Shdr Elf32_Sym))
NOTE(READ_ONLY_DATA(Elf_Scn::s_elf))
NOTE(READ_ONLY_DATA(Dnode::db_scn))
extern int *_elf_libc_threaded;
#define elf_threaded (_elf_libc_threaded && *_elf_libc_threaded)
#ifdef __lock_lint
#define SCNLOCK(x) (void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
#else
#define SCNLOCK(x) \
if (elf_threaded) \
(void) mutex_lock(&((Elf_Scn *)x)->s_mutex);
#endif
#ifdef __lock_lint
#define SCNUNLOCK(x) (void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
#else
#define SCNUNLOCK(x) \
if (elf_threaded) \
(void) mutex_unlock(&((Elf_Scn *)x)->s_mutex);
#endif
#ifdef __lock_lint
#define UPGRADELOCKS(e, s)\
(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
#else
#define UPGRADELOCKS(e, s)\
if (elf_threaded) { \
(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
(void) rw_wrlock(&((Elf *)e)->ed_rwlock); \
}
#endif
#ifdef __lock_lint
#define DOWNGRADELOCKS(e, s)\
(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
#else
#define DOWNGRADELOCKS(e, s)\
if (elf_threaded) { \
(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
}
#endif
#ifdef __lock_lint
#define READLOCKS(e, s) \
(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
(void) mutex_lock(&((Elf_Scn *)s)->s_mutex);
#else
#define READLOCKS(e, s) \
if (elf_threaded) { \
(void) rw_rdlock(&((Elf *)e)->ed_rwlock); \
(void) mutex_lock(&((Elf_Scn *)s)->s_mutex); \
}
#endif
#ifdef __lock_lint
#define READUNLOCKS(e, s) \
(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
(void) rw_unlock(&((Elf *)e)->ed_rwlock);
#else
#define READUNLOCKS(e, s) \
if (elf_threaded) { \
(void) mutex_unlock(&((Elf_Scn *)s)->s_mutex); \
(void) rw_unlock(&((Elf *)e)->ed_rwlock); \
}
#endif
#define SF_ALLOC 0x1
#define SF_READY 0x2
struct Snode32
{
Elf_Scn sb_scn;
Elf32_Shdr sb_shdr;
};
struct Snode64
{
Elf_Scn sb_scn;
Elf64_Shdr sb_shdr;
};
typedef enum
{
ES_FRESH = 0,
ES_COOKED,
ES_FROZEN
} Status;
struct Elf
{
rwlock_t ed_rwlock;
Elf *ed_parent;
int ed_activ;
int ed_fd;
Status ed_status;
off_t ed_baseoff;
size_t ed_memoff;
size_t ed_siboff;
size_t ed_nextoff;
char *ed_image;
size_t ed_imagesz;
char *ed_wrimage;
size_t ed_wrimagesz;
char *ed_ident;
size_t ed_identsz;
char *ed_raw;
size_t ed_fsz;
unsigned *ed_vm;
size_t ed_vmsz;
unsigned ed_encode;
unsigned ed_version;
int ed_class;
Elf_Kind ed_kind;
Elf_Void *ed_ehdr;
Elf_Void *ed_phdr;
size_t ed_phdrsz;
Elf_Void *ed_shdr;
Elf_Scn *ed_hdscn;
Elf_Scn *ed_tlscn;
size_t ed_scntabsz;
Memlist *ed_memlist;
Member *ed_armem;
Elf_Void *ed_arsym;
size_t ed_arsymsz;
size_t ed_arsymoff;
char *ed_arstr;
size_t ed_arstrsz;
size_t ed_arstroff;
unsigned ed_myflags;
unsigned ed_ehflags;
unsigned ed_phflags;
unsigned ed_uflags;
};
NOTE(RWLOCK_PROTECTS_DATA(Elf::ed_rwlock, Elf))
NOTE(RWLOCK_COVERS_LOCKS(Elf::ed_rwlock, Elf_Scn::s_mutex))
#ifdef __lock_lint
#define ELFRLOCK(e) (void) rw_rdlock(&((Elf *)e)->ed_rwlock);
#else
#define ELFRLOCK(e) \
if (elf_threaded) \
(void) rw_rdlock(&((Elf *)e)->ed_rwlock);
#endif
#ifdef __lock_lint
#define ELFWLOCK(e) (void) rw_wrlock(&((Elf *)e)->ed_rwlock);
#else
#define ELFWLOCK(e) \
if (elf_threaded) \
(void) rw_wrlock(&((Elf *)e)->ed_rwlock);
#endif
#ifdef __lock_lint
#define ELFUNLOCK(e) (void) rw_unlock(&((Elf *)e)->ed_rwlock);
#else
#define ELFUNLOCK(e) \
if (elf_threaded) \
(void) rw_unlock(&((Elf *)e)->ed_rwlock);
#endif
#define EDF_ASALLOC 0x1
#define EDF_EHALLOC 0x2
#define EDF_PHALLOC 0x4
#define EDF_SHALLOC 0x8
#define EDF_COFFAOUT 0x10
#define EDF_RAWALLOC 0x20
#define EDF_READ 0x40
#define EDF_WRITE 0x80
#define EDF_MEMORY 0x100
#define EDF_ASTRALLOC 0x200
#define EDF_MPROTECT 0x400
#define EDF_IMALLOC 0x800
#define EDF_WRALLOC 0x1000
#if defined(__APPLE__)
#define EDF_RDKERNTYPE 0x2000
#endif
typedef enum
{
OK_YES = 0,
OK_NO = ~0
} Okay;
#define _(a) a
#define MAXELFERR 1024
#ifdef __lock_lint
#define ELFACCESSDATA(a, b) \
(void) mutex_lock(&_elf_globals_mutex); \
a = b; \
(void) mutex_unlock(&_elf_globals_mutex);
#else
#define ELFACCESSDATA(a, b) \
if (elf_threaded) { \
(void) mutex_lock(&_elf_globals_mutex); \
a = b; \
(void) mutex_unlock(&_elf_globals_mutex); \
} else \
a = b;
#endif
#ifdef __lock_lint
#define ELFRWLOCKINIT(lock) \
(void) rwlock_init((lock), USYNC_THREAD, 0);
#else
#define ELFRWLOCKINIT(lock) \
if (elf_threaded) { \
(void) rwlock_init((lock), USYNC_THREAD, 0); \
}
#endif
#ifdef __lock_lint
#define ELFMUTEXINIT(lock) \
(void) mutex_init(lock, USYNC_THREAD, 0);
#else
#define ELFMUTEXINIT(lock) \
if (elf_threaded) { \
(void) mutex_init(lock, USYNC_THREAD, 0); \
}
#endif
extern Member *_elf_armem(Elf *, char *, size_t);
extern void _elf_arinit(Elf *);
extern Okay _elf_cook(Elf *);
extern Okay _elf_cookscn(Elf_Scn * s);
extern Okay _elf32_cookscn(Elf_Scn * s);
extern Okay _elf64_cookscn(Elf_Scn * s);
extern Dnode *_elf_dnode(void);
extern Elf_Data *_elf_locked_getdata(Elf_Scn *, Elf_Data *);
extern size_t _elf32_entsz(Elf *elf, Elf32_Word, unsigned);
extern size_t _elf64_entsz(Elf *elf, Elf64_Word, unsigned);
extern Okay _elf_inmap(Elf *);
extern char *_elf_outmap(int, size_t, unsigned *);
extern size_t _elf_outsync(int, char *, size_t, unsigned);
extern size_t _elf32_msize(Elf_Type, unsigned);
extern size_t _elf64_msize(Elf_Type, unsigned);
extern Elf_Type _elf32_mtype(Elf *, Elf32_Word, unsigned);
extern Elf_Type _elf64_mtype(Elf *, Elf64_Word, unsigned);
extern char *_elf_read(int, off_t, size_t);
extern Snode32 *_elf32_snode(void);
extern Snode64 *_elf64_snode(void);
extern void _elf_unmap(char *, size_t);
extern Okay _elf_vm(Elf *, size_t, size_t);
extern int _elf32_ehdr(Elf *, int);
extern int _elf32_phdr(Elf *, int);
extern int _elf32_shdr(Elf *, int);
extern int _elf64_ehdr(Elf *, int);
extern int _elf64_phdr(Elf *, int);
extern int _elf64_shdr(Elf *, int);
extern int _elf_byte;
extern const Elf32_Ehdr _elf32_ehdr_init;
extern const Elf64_Ehdr _elf64_ehdr_init;
extern unsigned _elf_encode;
extern void _elf_seterr(Msg, int);
extern const Snode32 _elf32_snode_init;
extern const Snode64 _elf64_snode_init;
extern const Dnode _elf_dnode_init;
extern unsigned _elf_work;
extern mutex_t _elf_globals_mutex;
extern off_t _elf64_update(Elf * elf, Elf_Cmd cmd);
extern int _elf64_swap_wrimage(Elf *elf);
NOTE(MUTEX_PROTECTS_DATA(_elf_globals_mutex, \
_elf_byte _elf32_ehdr_init _elf64_ehdr_init _elf_encode \
_elf_snode_init _elf_work))
#ifdef __cplusplus
}
#endif
#endif