rtld.h revision 62801
150476Speter/*-
21802Sphk * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
31802Sphk * All rights reserved.
444290Swollman *
544301Swollman * Redistribution and use in source and binary forms, with or without
644290Swollman * modification, are permitted provided that the following conditions
755955Srgrimes * are met:
855955Srgrimes * 1. Redistributions of source code must retain the above copyright
944301Swollman *    notice, this list of conditions and the following disclaimer.
109488Sphk * 2. Redistributions in binary form must reproduce the above copyright
1174385Sphk *    notice, this list of conditions and the following disclaimer in the
1274385Sphk *    documentation and/or other materials provided with the distribution.
139488Sphk *
1474385Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1574385Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
169488Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1774385Sphk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1874385Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1944437Sache * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2044437Sache * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2144437Sache * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2274385Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2344437Sache * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2474385Sphk *
2574385Sphk * $FreeBSD: head/libexec/rtld-elf/rtld.h 62801 2000-07-08 04:10:38Z jdp $
2644437Sache */
2774385Sphk
2874385Sphk#ifndef RTLD_H /* { */
2944290Swollman#define RTLD_H 1
3044301Swollman
3144290Swollman#include <sys/types.h>
321846Swollman#include <sys/queue.h>
3344301Swollman
341802Sphk#include <link.h>
3544356Swollman#include <elf.h>
3644290Swollman#include <stddef.h>
3744301Swollman
3844290Swollman#include "rtld_machdep.h"
3944290Swollman
4044301Swollman#ifndef STANDARD_LIBRARY_PATH
4144301Swollman#define STANDARD_LIBRARY_PATH	"/usr/lib/elf:/usr/lib"
4244301Swollman#endif
4344301Swollman
4444356Swollman#define NEW(type)	((type *) xmalloc(sizeof(type)))
4544290Swollman#define CNEW(type)	((type *) xcalloc(sizeof(type)))
462848Sphk
472577Sbde/* We might as well do booleans like C++. */
481802Sphktypedef unsigned char bool;
4944290Swollman#define false	0
5044290Swollman#define true	1
511802Sphk
521802Sphkstruct stat;
5344290Swollmanstruct Struct_Obj_Entry;
5444290Swollman
551802Sphk/* Lists of shared objects */
561802Sphktypedef struct Struct_Objlist_Entry {
5744290Swollman    STAILQ_ENTRY(Struct_Objlist_Entry) link;
5844290Swollman    struct Struct_Obj_Entry *obj;
591802Sphk} Objlist_Entry;
6044290Swollman
6144290Swollmantypedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
6244290Swollman
6344290Swollman/* Lists of init or fini functions */
6444290Swollmantypedef void (*InitFunc)(void);
6544290Swollman
6644290Swollmantypedef struct Struct_Funclist_Entry {
6744290Swollman    STAILQ_ENTRY(Struct_Funclist_Entry) link;
6844290Swollman    InitFunc func;
6944290Swollman} Funclist_Entry;
7044301Swollman
7144301Swollmantypedef STAILQ_HEAD(Struct_Funclist, Struct_Funclist_Entry) Funclist;
7244301Swollman
7344301Swollman/* Lists of shared object dependencies */
7444301Swollmantypedef struct Struct_Needed_Entry {
7544301Swollman    struct Struct_Needed_Entry *next;
762274Spaul    struct Struct_Obj_Entry *obj;
7739063Simp    unsigned long name;		/* Offset of name in string table */
7839063Simp} Needed_Entry;
791802Sphk
802274Spaul/* Lock object */
8139063Simptypedef struct Struct_LockInfo {
8239063Simp    void *context;		/* Client context for creating locks */
831802Sphk    void *thelock;		/* The one big lock */
842274Spaul    /* Debugging aids. */
8539063Simp    volatile int rcount;	/* Number of readers holding lock */
8639063Simp    volatile int wcount;	/* Number of writers holding lock */
875820Sjkh    /* Methods */
881802Sphk    void *(*lock_create)(void *context);
8939063Simp    void (*rlock_acquire)(void *lock);
9039063Simp    void (*wlock_acquire)(void *lock);
9139063Simp    void (*rlock_release)(void *lock);
9239063Simp    void (*wlock_release)(void *lock);
9339063Simp    void (*lock_destroy)(void *lock);
9439063Simp    void (*context_destroy)(void *context);
9539063Simp} LockInfo;
9639063Simp
971802Sphk/*
981802Sphk * Shared object descriptor.
9939063Simp *
10039063Simp * Items marked with "(%)" are dynamically allocated, and must be freed
10139063Simp * when the structure is destroyed.
10239063Simp *
10339063Simp * CAUTION: It appears that the JDK port peeks into these structures.
10439063Simp * It looks at "next" and "mapbase" at least.  Don't add new members
10539063Simp * near the front, until this can be straightened out.
10639063Simp */
1071802Sphktypedef struct Struct_Obj_Entry {
1081802Sphk    /*
10939063Simp     * These two items have to be set right for compatibility with the
11039063Simp     * original ElfKit crt1.o.
11139063Simp     */
11239063Simp    Elf_Word magic;		/* Magic number (sanity check) */
11339063Simp    Elf_Word version;		/* Version number of struct format */
11439063Simp
11539063Simp    struct Struct_Obj_Entry *next;
11639063Simp    char *path;			/* Pathname of underlying file (%) */
1171802Sphk    int refcount;
11844290Swollman    int dl_refcount;		/* Number of times loaded by dlopen */
11944290Swollman
12044290Swollman    /* These items are computed by map_object() or by digest_phdr(). */
12144290Swollman    caddr_t mapbase;		/* Base address of mapped region */
12244290Swollman    size_t mapsize;		/* Size of mapped region in bytes */
12344290Swollman    size_t textsize;		/* Size of text segment in bytes */
12444290Swollman    Elf_Addr vaddrbase;		/* Base address in shared object file */
12544290Swollman    caddr_t relocbase;		/* Relocation constant = mapbase - vaddrbase */
12644290Swollman    const Elf_Dyn *dynamic;	/* Dynamic section */
12744290Swollman    caddr_t entry;		/* Entry point */
12844290Swollman    const Elf_Phdr *phdr;	/* Program header if it is mapped, else NULL */
12944290Swollman    size_t phsize;		/* Size of program header in bytes */
13044290Swollman    const char *interp;		/* Pathname of the interpreter, if any */
13144290Swollman
13244290Swollman    /* Items from the dynamic section. */
13344290Swollman    Elf_Addr *pltgot;		/* PLT or GOT, depending on architecture */
13444290Swollman    const Elf_Rel *rel;		/* Relocation entries */
13544290Swollman    unsigned long relsize;	/* Size in bytes of relocation info */
13644290Swollman    const Elf_Rela *rela;	/* Relocation entries with addend */
13744290Swollman    unsigned long relasize;	/* Size in bytes of addend relocation info */
13844290Swollman    const Elf_Rel *pltrel;	/* PLT relocation entries */
13944290Swollman    unsigned long pltrelsize;	/* Size in bytes of PLT relocation info */
14044290Swollman    const Elf_Rela *pltrela;	/* PLT relocation entries with addend */
14144290Swollman    unsigned long pltrelasize;	/* Size in bytes of PLT addend reloc info */
14244290Swollman    const Elf_Sym *symtab;	/* Symbol table */
14344290Swollman    const char *strtab;		/* String table */
14444301Swollman    unsigned long strsize;	/* Size in bytes of string table */
14544301Swollman
14644301Swollman    const Elf_Addr *buckets;	/* Hash table buckets array */
14744301Swollman    unsigned long nbuckets;	/* Number of buckets */
14844301Swollman    const Elf_Addr *chains;	/* Hash table chain array */
14944301Swollman    unsigned long nchains;	/* Number of chains */
15044301Swollman
15144301Swollman    const char *rpath;		/* Search path specified in object */
15244301Swollman    Needed_Entry *needed;	/* Shared objects needed by this one (%) */
15344301Swollman
15444301Swollman    InitFunc init;		/* Initialization function to call */
15544301Swollman    InitFunc fini;		/* Termination function to call */
15644301Swollman
15744301Swollman    bool mainprog;		/* True if this is the main program */
1582368Sbde    bool rtld;			/* True if this is the dynamic linker */
1592368Sbde    bool textrel;		/* True if there are relocations to text seg */
1602487Sjkh    bool symbolic;		/* True if generated with "-Bsymbolic" */
1611964Sjkh    bool traced;		/* Already printed in ldd trace output */
1622368Sbde    bool jmpslots_done;		/* Already have relocated the jump slots */
1632487Sjkh
1641964Sjkh    struct link_map linkmap;	/* for GDB */
1652368Sbde    Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */
1662487Sjkh    Objlist dagmembers;		/* DAG has these members (%) */
1671964Sjkh    dev_t dev;			/* Object's filesystem's device */
1682368Sbde    ino_t ino;			/* Object's inode number */
1691802Sphk} Obj_Entry;
17044301Swollman
17144301Swollman#define RTLD_MAGIC	0xd550b87a
17244301Swollman#define RTLD_VERSION	1
17344301Swollman
17444290Swollmanextern void _rtld_error(const char *, ...) __printflike(1, 2);
17544290Swollmanextern Obj_Entry *map_object(int, const char *, const struct stat *);
17644290Swollmanextern void *xcalloc(size_t);
17744290Swollmanextern void *xmalloc(size_t);
17844290Swollmanextern char *xstrdup(const char *);
17944290Swollmanextern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
18044290Swollman
1811802Sphk/*
1821802Sphk * Function declarations.
183 */
184int do_copy_relocations(Obj_Entry *);
185unsigned long elf_hash(const char *);
186const Elf_Sym *find_symdef(unsigned long, Obj_Entry *, const Obj_Entry **,
187  bool);
188void init_pltgot(Obj_Entry *);
189void lockdflt_init(LockInfo *);
190void obj_free(Obj_Entry *);
191Obj_Entry *obj_new(void);
192int reloc_non_plt(Obj_Entry *, Obj_Entry *);
193int reloc_plt(Obj_Entry *);
194int reloc_jmpslots(Obj_Entry *);
195void _rtld_bind_start(void);
196const Elf_Sym *symlook_obj(const char *, unsigned long,
197  const Obj_Entry *, bool);
198
199#endif /* } */
200