rtld.h revision 116563
11541Srgrimes/*-
21541Srgrimes * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
31541Srgrimes * All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes *
141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
151541Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
161541Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
171541Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
181541Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
191541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
201541Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
211541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
221541Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
231541Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
241541Srgrimes *
251541Srgrimes * $FreeBSD: head/libexec/rtld-elf/rtld.h 116563 2003-06-19 03:55:38Z mdodd $
261541Srgrimes */
271541Srgrimes
281541Srgrimes#ifndef RTLD_H /* { */
291541Srgrimes#define RTLD_H 1
301541Srgrimes
311541Srgrimes#include <machine/elf.h>
321541Srgrimes#include <sys/types.h>
331541Srgrimes#include <sys/queue.h>
3422521Sdyson
3550477Speter#include <elf-hints.h>
361541Srgrimes#include <link.h>
371541Srgrimes#include <stddef.h>
381541Srgrimes
391541Srgrimes#include "rtld_lock.h"
401541Srgrimes#include "rtld_machdep.h"
411541Srgrimes
421541Srgrimes#ifndef STANDARD_LIBRARY_PATH
431541Srgrimes#define STANDARD_LIBRARY_PATH	"/usr/lib"
445651Sjoerg#endif
455651Sjoerg
465651Sjoerg#define NEW(type)	((type *) xmalloc(sizeof(type)))
475651Sjoerg#define CNEW(type)	((type *) xcalloc(sizeof(type)))
485651Sjoerg
491541Srgrimes/* We might as well do booleans like C++. */
501541Srgrimestypedef unsigned char bool;
511541Srgrimes#define false	0
521541Srgrimes#define true	1
5345773Sdcs
541541Srgrimesstruct stat;
551541Srgrimesstruct Struct_Obj_Entry;
561541Srgrimes
575651Sjoerg/* Lists of shared objects */
581541Srgrimestypedef struct Struct_Objlist_Entry {
595651Sjoerg    STAILQ_ENTRY(Struct_Objlist_Entry) link;
605651Sjoerg    struct Struct_Obj_Entry *obj;
611541Srgrimes} Objlist_Entry;
625651Sjoerg
635651Sjoergtypedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
645651Sjoerg
655651Sjoerg/* Types of init and fini functions */
661541Srgrimestypedef void (*InitFunc)(void);
671541Srgrimes
681541Srgrimes/* Lists of shared object dependencies */
691541Srgrimestypedef struct Struct_Needed_Entry {
701541Srgrimes    struct Struct_Needed_Entry *next;
711541Srgrimes    struct Struct_Obj_Entry *obj;
721541Srgrimes    unsigned long name;		/* Offset of name in string table */
731541Srgrimes} Needed_Entry;
741541Srgrimes
751541Srgrimes/* Lock object */
761541Srgrimestypedef struct Struct_LockInfo {
771541Srgrimes    void *context;		/* Client context for creating locks */
781541Srgrimes    void *thelock;		/* The one big lock */
791541Srgrimes    /* Debugging aids. */
801541Srgrimes    volatile int rcount;	/* Number of readers holding lock */
811541Srgrimes    volatile int wcount;	/* Number of writers holding lock */
821541Srgrimes    /* Methods */
831541Srgrimes    void *(*lock_create)(void *context);
841541Srgrimes    void (*rlock_acquire)(void *lock);
851541Srgrimes    void (*wlock_acquire)(void *lock);
861541Srgrimes    void (*rlock_release)(void *lock);
871541Srgrimes    void (*wlock_release)(void *lock);
881541Srgrimes    void (*lock_destroy)(void *lock);
891541Srgrimes    void (*context_destroy)(void *context);
901541Srgrimes} LockInfo;
911541Srgrimes
921541Srgrimes/*
931541Srgrimes * Shared object descriptor.
941541Srgrimes *
951541Srgrimes * Items marked with "(%)" are dynamically allocated, and must be freed
96332955Sbenno * when the structure is destroyed.
97332955Sbenno *
981541Srgrimes * CAUTION: It appears that the JDK port peeks into these structures.
9945773Sdcs * It looks at "next" and "mapbase" at least.  Don't add new members
10045773Sdcs * near the front, until this can be straightened out.
10145773Sdcs */
10245773Sdcstypedef struct Struct_Obj_Entry {
10345773Sdcs    /*
10445773Sdcs     * These two items have to be set right for compatibility with the
10545773Sdcs     * original ElfKit crt1.o.
10645773Sdcs     */
10745773Sdcs    Elf_Word magic;		/* Magic number (sanity check) */
10845773Sdcs    Elf_Word version;		/* Version number of struct format */
10945773Sdcs
11045773Sdcs    struct Struct_Obj_Entry *next;
11145773Sdcs    char *path;			/* Pathname of underlying file (%) */
11245773Sdcs    char *origin_path;		/* Directory path of origin file */
11345773Sdcs    int refcount;
11445773Sdcs    int dl_refcount;		/* Number of times loaded by dlopen */
11545773Sdcs
11645773Sdcs    /* These items are computed by map_object() or by digest_phdr(). */
11745773Sdcs    caddr_t mapbase;		/* Base address of mapped region */
11845773Sdcs    size_t mapsize;		/* Size of mapped region in bytes */
11945773Sdcs    size_t textsize;		/* Size of text segment in bytes */
12045773Sdcs    Elf_Addr vaddrbase;		/* Base address in shared object file */
12145773Sdcs    caddr_t relocbase;		/* Relocation constant = mapbase - vaddrbase */
12245773Sdcs    const Elf_Dyn *dynamic;	/* Dynamic section */
12345773Sdcs    caddr_t entry;		/* Entry point */
12445773Sdcs    const Elf_Phdr *phdr;	/* Program header if it is mapped, else NULL */
12545773Sdcs    size_t phsize;		/* Size of program header in bytes */
12645773Sdcs    const char *interp;		/* Pathname of the interpreter, if any */
12745773Sdcs
12845773Sdcs    /* Items from the dynamic section. */
12945773Sdcs    Elf_Addr *pltgot;		/* PLT or GOT, depending on architecture */
13045773Sdcs    const Elf_Rel *rel;		/* Relocation entries */
13145773Sdcs    unsigned long relsize;	/* Size in bytes of relocation info */
13245773Sdcs    const Elf_Rela *rela;	/* Relocation entries with addend */
13345773Sdcs    unsigned long relasize;	/* Size in bytes of addend relocation info */
13445773Sdcs    const Elf_Rel *pltrel;	/* PLT relocation entries */
13545773Sdcs    unsigned long pltrelsize;	/* Size in bytes of PLT relocation info */
13645773Sdcs    const Elf_Rela *pltrela;	/* PLT relocation entries with addend */
13745773Sdcs    unsigned long pltrelasize;	/* Size in bytes of PLT addend reloc info */
13845773Sdcs    const Elf_Sym *symtab;	/* Symbol table */
13945773Sdcs    const char *strtab;		/* String table */
1405651Sjoerg    unsigned long strsize;	/* Size in bytes of string table */
1415651Sjoerg
1425651Sjoerg    const Elf_Hashelt *buckets;	/* Hash table buckets array */
1435651Sjoerg    unsigned long nbuckets;	/* Number of buckets */
1445651Sjoerg    const Elf_Hashelt *chains;	/* Hash table chain array */
1455651Sjoerg    unsigned long nchains;	/* Number of chains */
1465651Sjoerg
1475651Sjoerg    const char *rpath;		/* Search path specified in object */
1485651Sjoerg    Needed_Entry *needed;	/* Shared objects needed by this one (%) */
1495651Sjoerg
1505651Sjoerg    Elf_Addr init;		/* Initialization function to call */
1515651Sjoerg    Elf_Addr fini;		/* Termination function to call */
1525651Sjoerg
1535651Sjoerg    bool mainprog;		/* True if this is the main program */
1545651Sjoerg    bool rtld;			/* True if this is the dynamic linker */
1555651Sjoerg    bool textrel;		/* True if there are relocations to text seg */
1565651Sjoerg    bool symbolic;		/* True if generated with "-Bsymbolic" */
1575651Sjoerg    bool bind_now;		/* True if all relocations should be made first */
1585651Sjoerg    bool traced;		/* Already printed in ldd trace output */
1595651Sjoerg    bool jmpslots_done;		/* Already have relocated the jump slots */
1605651Sjoerg    bool init_done;		/* Already have added object to init list */
1615651Sjoerg
1625651Sjoerg    struct link_map linkmap;	/* for GDB and dlinfo() */
1635651Sjoerg    Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */
1645651Sjoerg    Objlist dagmembers;		/* DAG has these members (%) */
1655651Sjoerg    dev_t dev;			/* Object's filesystem's device */
1665651Sjoerg    ino_t ino;			/* Object's inode number */
1675651Sjoerg    void *priv;			/* Platform-dependant */
1685651Sjoerg} Obj_Entry;
1695651Sjoerg
1705651Sjoerg#define RTLD_MAGIC	0xd550b87a
1715651Sjoerg#define RTLD_VERSION	1
1725651Sjoerg
1735651Sjoerg/*
1745651Sjoerg * Symbol cache entry used during relocation to avoid multiple lookups
1755651Sjoerg * of the same symbol.
1765651Sjoerg */
1771541Srgrimestypedef struct Struct_SymCache {
1781541Srgrimes    const Elf_Sym *sym;		/* Symbol table entry */
1791541Srgrimes    const Obj_Entry *obj;	/* Shared object which defines it */
18022521Sdyson} SymCache;
18122521Sdyson
1821541Srgrimesextern void _rtld_error(const char *, ...) __printflike(1, 2);
1831541Srgrimesextern Obj_Entry *map_object(int, const char *, const struct stat *);
1841541Srgrimesextern void *xcalloc(size_t);
1851541Srgrimesextern void *xmalloc(size_t);
1861541Srgrimesextern char *xstrdup(const char *);
1871541Srgrimesextern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
18822521Sdyson
1891541Srgrimesextern void dump_relocations (Obj_Entry *);
1901541Srgrimesextern void dump_obj_relocations (Obj_Entry *);
1911541Srgrimesextern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long);
1921541Srgrimesextern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long);
1931541Srgrimes
1941541Srgrimes/*
19522521Sdyson * Function declarations.
19622521Sdyson */
19722521Sdysonunsigned long elf_hash(const char *);
1981541Srgrimesconst Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
1991541Srgrimes  const Obj_Entry **, bool, SymCache *);
2001541Srgrimesvoid init_pltgot(Obj_Entry *);
2011541Srgrimesvoid lockdflt_init(void);
2021541Srgrimesvoid obj_free(Obj_Entry *);
2031541SrgrimesObj_Entry *obj_new(void);
20422521Sdysonvoid _rtld_bind_start(void);
2051541Srgrimesconst Elf_Sym *symlook_obj(const char *, unsigned long,
2061541Srgrimes  const Obj_Entry *, bool);
2071541Srgrimes
2081541Srgrimes/*
2091541Srgrimes * MD function declarations.
21022521Sdyson */
2111541Srgrimesint do_copy_relocations(Obj_Entry *);
2121541Srgrimesint reloc_non_plt(Obj_Entry *, Obj_Entry *);
21355206Speterint reloc_plt(Obj_Entry *);
21425531Sjoergint reloc_jmpslots(Obj_Entry *);
2151541Srgrimes
2165651Sjoerg#endif /* } */
21745773Sdcs