rtld.h revision 127250
1219820Sjeff/*-
2219820Sjeff * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3219820Sjeff * All rights reserved.
4219820Sjeff *
5219820Sjeff * Redistribution and use in source and binary forms, with or without
6219820Sjeff * modification, are permitted provided that the following conditions
7219820Sjeff * are met:
8219820Sjeff * 1. Redistributions of source code must retain the above copyright
9219820Sjeff *    notice, this list of conditions and the following disclaimer.
10219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
11219820Sjeff *    notice, this list of conditions and the following disclaimer in the
12219820Sjeff *    documentation and/or other materials provided with the distribution.
13219820Sjeff *
14219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24219820Sjeff *
25219820Sjeff * $FreeBSD: head/libexec/rtld-elf/rtld.h 127250 2004-03-21 01:21:26Z peter $
26219820Sjeff */
27219820Sjeff
28219820Sjeff#ifndef RTLD_H /* { */
29219820Sjeff#define RTLD_H 1
30219820Sjeff
31219820Sjeff#include <machine/elf.h>
32219820Sjeff#include <sys/types.h>
33219820Sjeff#include <sys/queue.h>
34219820Sjeff
35219820Sjeff#include <elf-hints.h>
36219820Sjeff#include <link.h>
37219820Sjeff#include <stddef.h>
38219820Sjeff
39219820Sjeff#include "rtld_lock.h"
40219820Sjeff#include "rtld_machdep.h"
41219820Sjeff
42219820Sjeff#ifdef COMPAT_32BIT
43219820Sjeff#undef STANDARD_LIBRARY_PATH
44219820Sjeff#undef _PATH_ELF_HINTS
45219820Sjeff#define	_PATH_ELF_HINTS		"/var/run/ld-elf32.so.hints"
46219820Sjeff/* For running 32 bit binaries  */
47219820Sjeff#define	STANDARD_LIBRARY_PATH	"/lib32:/usr/lib32"
48219820Sjeff#define LD_ "LD_32_"
49219820Sjeff#endif
50219820Sjeff
51219820Sjeff#ifndef STANDARD_LIBRARY_PATH
52219820Sjeff#define STANDARD_LIBRARY_PATH	"/lib:/usr/lib"
53219820Sjeff#endif
54219820Sjeff#ifndef LD_
55219820Sjeff#define LD_ "LD_"
56219820Sjeff#endif
57219820Sjeff
58219820Sjeff#define NEW(type)	((type *) xmalloc(sizeof(type)))
59219820Sjeff#define CNEW(type)	((type *) xcalloc(sizeof(type)))
60219820Sjeff
61219820Sjeff/* We might as well do booleans like C++. */
62219820Sjefftypedef unsigned char bool;
63219820Sjeff#define false	0
64219820Sjeff#define true	1
65219820Sjeff
66219820Sjeffstruct stat;
67219820Sjeffstruct Struct_Obj_Entry;
68219820Sjeff
69219820Sjeff/* Lists of shared objects */
70219820Sjefftypedef struct Struct_Objlist_Entry {
71219820Sjeff    STAILQ_ENTRY(Struct_Objlist_Entry) link;
72219820Sjeff    struct Struct_Obj_Entry *obj;
73219820Sjeff} Objlist_Entry;
74219820Sjeff
75219820Sjefftypedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
76219820Sjeff
77219820Sjeff/* Types of init and fini functions */
78219820Sjefftypedef void (*InitFunc)(void);
79219820Sjeff
80219820Sjeff/* Lists of shared object dependencies */
81219820Sjefftypedef struct Struct_Needed_Entry {
82219820Sjeff    struct Struct_Needed_Entry *next;
83219820Sjeff    struct Struct_Obj_Entry *obj;
84219820Sjeff    unsigned long name;		/* Offset of name in string table */
85219820Sjeff} Needed_Entry;
86219820Sjeff
87219820Sjeff/* Lock object */
88219820Sjefftypedef struct Struct_LockInfo {
89219820Sjeff    void *context;		/* Client context for creating locks */
90219820Sjeff    void *thelock;		/* The one big lock */
91219820Sjeff    /* Debugging aids. */
92219820Sjeff    volatile int rcount;	/* Number of readers holding lock */
93219820Sjeff    volatile int wcount;	/* Number of writers holding lock */
94219820Sjeff    /* Methods */
95219820Sjeff    void *(*lock_create)(void *context);
96219820Sjeff    void (*rlock_acquire)(void *lock);
97219820Sjeff    void (*wlock_acquire)(void *lock);
98219820Sjeff    void (*rlock_release)(void *lock);
99219820Sjeff    void (*wlock_release)(void *lock);
100219820Sjeff    void (*lock_destroy)(void *lock);
101219820Sjeff    void (*context_destroy)(void *context);
102} LockInfo;
103
104/*
105 * Shared object descriptor.
106 *
107 * Items marked with "(%)" are dynamically allocated, and must be freed
108 * when the structure is destroyed.
109 *
110 * CAUTION: It appears that the JDK port peeks into these structures.
111 * It looks at "next" and "mapbase" at least.  Don't add new members
112 * near the front, until this can be straightened out.
113 */
114typedef struct Struct_Obj_Entry {
115    /*
116     * These two items have to be set right for compatibility with the
117     * original ElfKit crt1.o.
118     */
119    Elf_Word magic;		/* Magic number (sanity check) */
120    Elf_Word version;		/* Version number of struct format */
121
122    struct Struct_Obj_Entry *next;
123    char *path;			/* Pathname of underlying file (%) */
124    char *origin_path;		/* Directory path of origin file */
125    int refcount;
126    int dl_refcount;		/* Number of times loaded by dlopen */
127
128    /* These items are computed by map_object() or by digest_phdr(). */
129    caddr_t mapbase;		/* Base address of mapped region */
130    size_t mapsize;		/* Size of mapped region in bytes */
131    size_t textsize;		/* Size of text segment in bytes */
132    Elf_Addr vaddrbase;		/* Base address in shared object file */
133    caddr_t relocbase;		/* Relocation constant = mapbase - vaddrbase */
134    const Elf_Dyn *dynamic;	/* Dynamic section */
135    caddr_t entry;		/* Entry point */
136    const Elf_Phdr *phdr;	/* Program header if it is mapped, else NULL */
137    size_t phsize;		/* Size of program header in bytes */
138    const char *interp;		/* Pathname of the interpreter, if any */
139
140    /* Items from the dynamic section. */
141    Elf_Addr *pltgot;		/* PLT or GOT, depending on architecture */
142    const Elf_Rel *rel;		/* Relocation entries */
143    unsigned long relsize;	/* Size in bytes of relocation info */
144    const Elf_Rela *rela;	/* Relocation entries with addend */
145    unsigned long relasize;	/* Size in bytes of addend relocation info */
146    const Elf_Rel *pltrel;	/* PLT relocation entries */
147    unsigned long pltrelsize;	/* Size in bytes of PLT relocation info */
148    const Elf_Rela *pltrela;	/* PLT relocation entries with addend */
149    unsigned long pltrelasize;	/* Size in bytes of PLT addend reloc info */
150    const Elf_Sym *symtab;	/* Symbol table */
151    const char *strtab;		/* String table */
152    unsigned long strsize;	/* Size in bytes of string table */
153
154    const Elf_Hashelt *buckets;	/* Hash table buckets array */
155    unsigned long nbuckets;	/* Number of buckets */
156    const Elf_Hashelt *chains;	/* Hash table chain array */
157    unsigned long nchains;	/* Number of chains */
158
159    const char *rpath;		/* Search path specified in object */
160    Needed_Entry *needed;	/* Shared objects needed by this one (%) */
161
162    Elf_Addr init;		/* Initialization function to call */
163    Elf_Addr fini;		/* Termination function to call */
164
165    bool mainprog;		/* True if this is the main program */
166    bool rtld;			/* True if this is the dynamic linker */
167    bool textrel;		/* True if there are relocations to text seg */
168    bool symbolic;		/* True if generated with "-Bsymbolic" */
169    bool bind_now;		/* True if all relocations should be made first */
170    bool traced;		/* Already printed in ldd trace output */
171    bool jmpslots_done;		/* Already have relocated the jump slots */
172    bool init_done;		/* Already have added object to init list */
173
174    struct link_map linkmap;	/* for GDB and dlinfo() */
175    Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */
176    Objlist dagmembers;		/* DAG has these members (%) */
177    dev_t dev;			/* Object's filesystem's device */
178    ino_t ino;			/* Object's inode number */
179    void *priv;			/* Platform-dependant */
180} Obj_Entry;
181
182#define RTLD_MAGIC	0xd550b87a
183#define RTLD_VERSION	1
184
185/*
186 * Symbol cache entry used during relocation to avoid multiple lookups
187 * of the same symbol.
188 */
189typedef struct Struct_SymCache {
190    const Elf_Sym *sym;		/* Symbol table entry */
191    const Obj_Entry *obj;	/* Shared object which defines it */
192} SymCache;
193
194extern void _rtld_error(const char *, ...) __printflike(1, 2);
195extern Obj_Entry *map_object(int, const char *, const struct stat *);
196extern void *xcalloc(size_t);
197extern void *xmalloc(size_t);
198extern char *xstrdup(const char *);
199extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
200
201extern void dump_relocations (Obj_Entry *);
202extern void dump_obj_relocations (Obj_Entry *);
203extern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long);
204extern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long);
205
206/*
207 * Function declarations.
208 */
209unsigned long elf_hash(const char *);
210const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
211  const Obj_Entry **, bool, SymCache *);
212void init_pltgot(Obj_Entry *);
213void lockdflt_init(void);
214void obj_free(Obj_Entry *);
215Obj_Entry *obj_new(void);
216void _rtld_bind_start(void);
217const Elf_Sym *symlook_obj(const char *, unsigned long,
218  const Obj_Entry *, bool);
219
220/*
221 * MD function declarations.
222 */
223int do_copy_relocations(Obj_Entry *);
224int reloc_non_plt(Obj_Entry *, Obj_Entry *);
225int reloc_plt(Obj_Entry *);
226int reloc_jmpslots(Obj_Entry *);
227
228#endif /* } */
229