xref: /freebsd/libexec/rtld-elf/rtld.h (revision 48fd084579af7604e934b827ef473194d3d5e3ba)
13124c3e0SJohn Polstra /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3e6209940SPedro F. Giffuni  *
49bfb1dfcSJohn Polstra  * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
53124c3e0SJohn Polstra  * All rights reserved.
63124c3e0SJohn Polstra  *
73124c3e0SJohn Polstra  * Redistribution and use in source and binary forms, with or without
83124c3e0SJohn Polstra  * modification, are permitted provided that the following conditions
93124c3e0SJohn Polstra  * are met:
103124c3e0SJohn Polstra  * 1. Redistributions of source code must retain the above copyright
113124c3e0SJohn Polstra  *    notice, this list of conditions and the following disclaimer.
123124c3e0SJohn Polstra  * 2. Redistributions in binary form must reproduce the above copyright
133124c3e0SJohn Polstra  *    notice, this list of conditions and the following disclaimer in the
143124c3e0SJohn Polstra  *    documentation and/or other materials provided with the distribution.
153124c3e0SJohn Polstra  *
163124c3e0SJohn Polstra  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
173124c3e0SJohn Polstra  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
183124c3e0SJohn Polstra  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
193124c3e0SJohn Polstra  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
203124c3e0SJohn Polstra  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
213124c3e0SJohn Polstra  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
223124c3e0SJohn Polstra  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
233124c3e0SJohn Polstra  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
243124c3e0SJohn Polstra  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
253124c3e0SJohn Polstra  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
263124c3e0SJohn Polstra  */
273124c3e0SJohn Polstra 
283124c3e0SJohn Polstra #ifndef RTLD_H /* { */
293124c3e0SJohn Polstra #define RTLD_H 1
303124c3e0SJohn Polstra 
315e6220d9SDavid E. O'Brien #include <machine/elf.h>
323124c3e0SJohn Polstra #include <sys/types.h>
33926ea445SJohn Polstra #include <sys/queue.h>
343124c3e0SJohn Polstra 
355e6220d9SDavid E. O'Brien #include <elf-hints.h>
362001f720SDoug Rabson #include <link.h>
370e9a2605SKonstantin Belousov #include <stdarg.h>
38168bbfa7SConrad Meyer #include <stdbool.h>
398569deafSKonstantin Belousov #include <setjmp.h>
403124c3e0SJohn Polstra #include <stddef.h>
413124c3e0SJohn Polstra 
426d5d786fSAlexander Kabaev #include "rtld_lock.h"
43d5b537d0SJohn Polstra #include "rtld_machdep.h"
44d5b537d0SJohn Polstra 
453124c3e0SJohn Polstra #define NEW(type)	((type *) xmalloc(sizeof(type)))
46758ffbfaSKonstantin Belousov #define CNEW(type)	((type *) xcalloc(1, sizeof(type)))
473124c3e0SJohn Polstra 
48017246d0SDoug Rabson extern size_t tls_last_offset;
49017246d0SDoug Rabson extern size_t tls_last_size;
50017246d0SDoug Rabson extern size_t tls_static_space;
5178b64846SAlex Richardson extern Elf_Addr tls_dtv_generation;
52017246d0SDoug Rabson extern int tls_max_index;
5395335dd3SStephen J. Kiernan extern size_t ld_static_tls_extra;
54017246d0SDoug Rabson 
55ea8577c7SAlan Cox extern int npagesizes;
56ea8577c7SAlan Cox extern size_t *pagesizes;
57e85eaa93SAndrew Turner extern size_t page_size;
58ea8577c7SAlan Cox 
5983aa9cc0SKonstantin Belousov extern int main_argc;
6083aa9cc0SKonstantin Belousov extern char **main_argv;
6183aa9cc0SKonstantin Belousov extern char **environ;
6283aa9cc0SKonstantin Belousov 
637360ae0fSJohn Polstra struct stat;
643124c3e0SJohn Polstra struct Struct_Obj_Entry;
653124c3e0SJohn Polstra 
669bfb1dfcSJohn Polstra /* Lists of shared objects */
67926ea445SJohn Polstra typedef struct Struct_Objlist_Entry {
68e3975643SJake Burkholder     STAILQ_ENTRY(Struct_Objlist_Entry) link;
69926ea445SJohn Polstra     struct Struct_Obj_Entry *obj;
70926ea445SJohn Polstra } Objlist_Entry;
71926ea445SJohn Polstra 
72e3975643SJake Burkholder typedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
73926ea445SJohn Polstra 
7444a028c3SJohn Polstra /* Types of init and fini functions */
759bfb1dfcSJohn Polstra typedef void (*InitFunc)(void);
7683aa9cc0SKonstantin Belousov typedef void (*InitArrFunc)(int, char **, char **);
779bfb1dfcSJohn Polstra 
789bfb1dfcSJohn Polstra /* Lists of shared object dependencies */
793124c3e0SJohn Polstra typedef struct Struct_Needed_Entry {
803124c3e0SJohn Polstra     struct Struct_Needed_Entry *next;
813124c3e0SJohn Polstra     struct Struct_Obj_Entry *obj;
823124c3e0SJohn Polstra     unsigned long name;		/* Offset of name in string table */
833124c3e0SJohn Polstra } Needed_Entry;
843124c3e0SJohn Polstra 
850eb88f20SAlexander Kabaev typedef struct Struct_Name_Entry {
860eb88f20SAlexander Kabaev     STAILQ_ENTRY(Struct_Name_Entry) link;
870eb88f20SAlexander Kabaev     char   name[1];
880eb88f20SAlexander Kabaev } Name_Entry;
890eb88f20SAlexander Kabaev 
90630df077SJohn Polstra /* Lock object */
91630df077SJohn Polstra typedef struct Struct_LockInfo {
92630df077SJohn Polstra     void *context;		/* Client context for creating locks */
93630df077SJohn Polstra     void *thelock;		/* The one big lock */
94630df077SJohn Polstra     /* Debugging aids. */
95630df077SJohn Polstra     volatile int rcount;	/* Number of readers holding lock */
96630df077SJohn Polstra     volatile int wcount;	/* Number of writers holding lock */
97630df077SJohn Polstra     /* Methods */
98630df077SJohn Polstra     void *(*lock_create)(void *context);
99630df077SJohn Polstra     void (*rlock_acquire)(void *lock);
100630df077SJohn Polstra     void (*wlock_acquire)(void *lock);
101630df077SJohn Polstra     void (*rlock_release)(void *lock);
102630df077SJohn Polstra     void (*wlock_release)(void *lock);
103630df077SJohn Polstra     void (*lock_destroy)(void *lock);
104630df077SJohn Polstra     void (*context_destroy)(void *context);
105630df077SJohn Polstra } LockInfo;
106630df077SJohn Polstra 
1070eb88f20SAlexander Kabaev typedef struct Struct_Ver_Entry {
1080eb88f20SAlexander Kabaev 	Elf_Word     hash;
1090eb88f20SAlexander Kabaev 	unsigned int flags;
1100eb88f20SAlexander Kabaev 	const char  *name;
1110eb88f20SAlexander Kabaev 	const char  *file;
1120eb88f20SAlexander Kabaev } Ver_Entry;
1130eb88f20SAlexander Kabaev 
11434cb87baSKonstantin Belousov typedef struct Struct_Sym_Match_Result {
11534cb87baSKonstantin Belousov     const Elf_Sym *sym_out;
11634cb87baSKonstantin Belousov     const Elf_Sym *vsymp;
11734cb87baSKonstantin Belousov     int vcount;
11834cb87baSKonstantin Belousov } Sym_Match_Result;
11934cb87baSKonstantin Belousov 
1200eb88f20SAlexander Kabaev #define VER_INFO_HIDDEN	0x01
1210eb88f20SAlexander Kabaev 
1223124c3e0SJohn Polstra /*
1233124c3e0SJohn Polstra  * Shared object descriptor.
1243124c3e0SJohn Polstra  *
1253124c3e0SJohn Polstra  * Items marked with "(%)" are dynamically allocated, and must be freed
1263124c3e0SJohn Polstra  * when the structure is destroyed.
12782531605SJohn Polstra  *
12882531605SJohn Polstra  * CAUTION: It appears that the JDK port peeks into these structures.
12982531605SJohn Polstra  * It looks at "next" and "mapbase" at least.  Don't add new members
13082531605SJohn Polstra  * near the front, until this can be straightened out.
1313124c3e0SJohn Polstra  */
1323124c3e0SJohn Polstra typedef struct Struct_Obj_Entry {
1333124c3e0SJohn Polstra     /*
1343124c3e0SJohn Polstra      * These two items have to be set right for compatibility with the
1353124c3e0SJohn Polstra      * original ElfKit crt1.o.
1363124c3e0SJohn Polstra      */
137757686b1SMarcel Moolenaar     Elf_Size magic;		/* Magic number (sanity check) */
138757686b1SMarcel Moolenaar     Elf_Size version;		/* Version number of struct format */
1393124c3e0SJohn Polstra 
1409fee0541SKonstantin Belousov     TAILQ_ENTRY(Struct_Obj_Entry) next;
1413124c3e0SJohn Polstra     char *path;			/* Pathname of underlying file (%) */
142da9f2454SMatthew N. Dodd     char *origin_path;		/* Directory path of origin file */
143c0274175SMark Johnston     int refcount;		/* DAG references */
144c0274175SMark Johnston     int holdcount;		/* Count of transient references */
1453124c3e0SJohn Polstra     int dl_refcount;		/* Number of times loaded by dlopen */
1463124c3e0SJohn Polstra 
1473124c3e0SJohn Polstra     /* These items are computed by map_object() or by digest_phdr(). */
1483124c3e0SJohn Polstra     caddr_t mapbase;		/* Base address of mapped region */
1493124c3e0SJohn Polstra     size_t mapsize;		/* Size of mapped region in bytes */
1501eab1be0SJohn Birrell     Elf_Addr vaddrbase;		/* Base address in shared object file */
1513124c3e0SJohn Polstra     caddr_t relocbase;		/* Relocation constant = mapbase - vaddrbase */
1521eab1be0SJohn Birrell     const Elf_Dyn *dynamic;	/* Dynamic section */
1533124c3e0SJohn Polstra     caddr_t entry;		/* Entry point */
1541eab1be0SJohn Birrell     const Elf_Phdr *phdr;	/* Program header if it is mapped, else NULL */
1553124c3e0SJohn Polstra     size_t phsize;		/* Size of program header in bytes */
156a607e5d7SJohn Polstra     const char *interp;		/* Pathname of the interpreter, if any */
157212f264cSKonstantin Belousov     Elf_Word stack_flags;
1583124c3e0SJohn Polstra 
159017246d0SDoug Rabson     /* TLS information */
160017246d0SDoug Rabson     int tlsindex;		/* Index in DTV for this module */
161017246d0SDoug Rabson     void *tlsinit;		/* Base address of TLS init block */
162017246d0SDoug Rabson     size_t tlsinitsize;		/* Size of TLS init block for this module */
163017246d0SDoug Rabson     size_t tlssize;		/* Size of TLS block for this module */
164017246d0SDoug Rabson     size_t tlsoffset;		/* Offset of static TLS block for this module */
165017246d0SDoug Rabson     size_t tlsalign;		/* Alignment of static TLS block */
1662f06c66aSKonstantin Belousov     size_t tlspoffset;		/* p_offset of the static TLS block */
167017246d0SDoug Rabson 
1683124c3e0SJohn Polstra     /* Items from the dynamic section. */
169d5b537d0SJohn Polstra     Elf_Addr *pltgot;		/* PLT or GOT, depending on architecture */
1701eab1be0SJohn Birrell     const Elf_Rel *rel;		/* Relocation entries */
1713124c3e0SJohn Polstra     unsigned long relsize;	/* Size in bytes of relocation info */
17213575fc4SDoug Rabson     const Elf_Rela *rela;	/* Relocation entries with addend */
17313575fc4SDoug Rabson     unsigned long relasize;	/* Size in bytes of addend relocation info */
174a7d137fcSFangrui Song     const Elf_Relr *relr;	/* RELR relocation entries */
175a7d137fcSFangrui Song     unsigned long relrsize;	/* Size in bytes of RELR relocations */
1761eab1be0SJohn Birrell     const Elf_Rel *pltrel;	/* PLT relocation entries */
1773124c3e0SJohn Polstra     unsigned long pltrelsize;	/* Size in bytes of PLT relocation info */
17813575fc4SDoug Rabson     const Elf_Rela *pltrela;	/* PLT relocation entries with addend */
17913575fc4SDoug Rabson     unsigned long pltrelasize;	/* Size in bytes of PLT addend reloc info */
1801eab1be0SJohn Birrell     const Elf_Sym *symtab;	/* Symbol table */
1813124c3e0SJohn Polstra     const char *strtab;		/* String table */
1823124c3e0SJohn Polstra     unsigned long strsize;	/* Size in bytes of string table */
1833124c3e0SJohn Polstra 
1840eb88f20SAlexander Kabaev     const Elf_Verneed *verneed; /* Required versions. */
1850eb88f20SAlexander Kabaev     Elf_Word verneednum;	/* Number of entries in verneed table */
1860eb88f20SAlexander Kabaev     const Elf_Verdef  *verdef;	/* Provided versions. */
1870eb88f20SAlexander Kabaev     Elf_Word verdefnum;		/* Number of entries in verdef table */
1880eb88f20SAlexander Kabaev     const Elf_Versym *versyms;  /* Symbol versions table */
1890eb88f20SAlexander Kabaev 
190b5393d9fSDoug Rabson     const Elf_Hashelt *buckets;	/* Hash table buckets array */
1913124c3e0SJohn Polstra     unsigned long nbuckets;	/* Number of buckets */
192b5393d9fSDoug Rabson     const Elf_Hashelt *chains;	/* Hash table chain array */
193f6265192SKonstantin Belousov     unsigned long nchains;	/* Number of entries in chain array */
194f6265192SKonstantin Belousov 
195f6265192SKonstantin Belousov     Elf32_Word nbuckets_gnu;		/* Number of GNU hash buckets*/
196f6265192SKonstantin Belousov     Elf32_Word symndx_gnu;		/* 1st accessible symbol on dynsym table */
197f6265192SKonstantin Belousov     Elf32_Word maskwords_bm_gnu;  	/* Bloom filter words - 1 (bitmask) */
198f6265192SKonstantin Belousov     Elf32_Word shift2_gnu;		/* Bloom filter shift count */
199f6265192SKonstantin Belousov     Elf32_Word dynsymcount;		/* Total entries in dynsym table */
200903e0ffdSAlex Richardson     const Elf_Addr *bloom_gnu;		/* Bloom filter used by GNU hash func */
201f6265192SKonstantin Belousov     const Elf_Hashelt *buckets_gnu;	/* GNU hash table bucket array */
202f6265192SKonstantin Belousov     const Elf_Hashelt *chain_zero_gnu;	/* GNU hash table value array (Zeroed) */
2033124c3e0SJohn Polstra 
204903e0ffdSAlex Richardson     const char *rpath;		/* Search path specified in object */
205903e0ffdSAlex Richardson     const char *runpath;	/* Search path with different priority */
2063124c3e0SJohn Polstra     Needed_Entry *needed;	/* Shared objects needed by this one (%) */
2078569deafSKonstantin Belousov     Needed_Entry *needed_filtees;
2088569deafSKonstantin Belousov     Needed_Entry *needed_aux_filtees;
2093124c3e0SJohn Polstra 
2100eb88f20SAlexander Kabaev     STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we
2110eb88f20SAlexander Kabaev 					       know about. */
2120eb88f20SAlexander Kabaev     Ver_Entry *vertab;		/* Versions required /defined by this object */
2130eb88f20SAlexander Kabaev     int vernum;			/* Number of entries in vertab */
2140eb88f20SAlexander Kabaev 
21514a55adfSPeter Wemm     Elf_Addr init;		/* Initialization function to call */
21614a55adfSPeter Wemm     Elf_Addr fini;		/* Termination function to call */
21783aa9cc0SKonstantin Belousov     Elf_Addr preinit_array;	/* Pre-initialization array of functions */
21883aa9cc0SKonstantin Belousov     Elf_Addr init_array;	/* Initialization array of functions */
21983aa9cc0SKonstantin Belousov     Elf_Addr fini_array;	/* Termination array of functions */
22083aa9cc0SKonstantin Belousov     int preinit_array_num;	/* Number of entries in preinit_array */
22183aa9cc0SKonstantin Belousov     int init_array_num; 	/* Number of entries in init_array */
22283aa9cc0SKonstantin Belousov     int fini_array_num; 	/* Number of entries in fini_array */
22383aa9cc0SKonstantin Belousov 
22483aa9cc0SKonstantin Belousov     int32_t osrel;		/* OSREL note value */
225e8927aa6SKonstantin Belousov     uint32_t fctl0;		/* FEATURE_CONTROL note desc[0] value */
2263124c3e0SJohn Polstra 
22749f90ad2SAlexander Kabaev     bool mainprog : 1;		/* True if this is the main program */
22849f90ad2SAlexander Kabaev     bool rtld : 1;		/* True if this is the dynamic linker */
229082f959aSKonstantin Belousov     bool relocated : 1;		/* True if processed by relocate_objects() */
230ff17bc61SKonstantin Belousov     bool ver_checked : 1;	/* True if processed by rtld_verify_object_versions */
23149f90ad2SAlexander Kabaev     bool textrel : 1;		/* True if there are relocations to text seg */
23249f90ad2SAlexander Kabaev     bool symbolic : 1;		/* True if generated with "-Bsymbolic" */
2339daf6cd0SKonstantin Belousov     bool deepbind : 1;		/* True if loaded with RTLD_DEEPBIND" */
23449f90ad2SAlexander Kabaev     bool bind_now : 1;		/* True if all relocations should be made first */
23549f90ad2SAlexander Kabaev     bool traced : 1;		/* Already printed in ldd trace output */
23649f90ad2SAlexander Kabaev     bool jmpslots_done : 1;	/* Already have relocated the jump slots */
23749f90ad2SAlexander Kabaev     bool init_done : 1;		/* Already have added object to init list */
238283a4f40SKonstantin Belousov     bool tls_static : 1;	/* Already allocated offset for static TLS */
23991880e07SKonstantin Belousov     bool tls_dynamic : 1;	/* A non-static DTV entry has been allocated */
24049f90ad2SAlexander Kabaev     bool phdr_alloc : 1;	/* Phdr is allocated and needs to be freed. */
24128551690SKonstantin Belousov     bool z_origin : 1;		/* Process rpath and soname tokens */
2422b0b4ee3SKonstantin Belousov     bool z_nodelete : 1;	/* Do not unload the object and dependencies */
2430d3bc8a9SKonstantin Belousov     bool z_noopen : 1;		/* Do not load on dlopen */
2448569deafSKonstantin Belousov     bool z_loadfltr : 1;	/* Immediately load filtees */
2453cf98c19SKonstantin Belousov     bool z_interpose : 1;	/* Interpose all objects but main */
246bca2f623SKonstantin Belousov     bool z_nodeflib : 1;	/* Don't search default library path */
2473de38154SKonstantin Belousov     bool z_global : 1;		/* Make the object global */
248c1a81320SKonstantin Belousov     bool z_pie : 1;		/* Object proclaimed itself PIE executable */
24978aaab9fSKonstantin Belousov     bool z_initfirst : 1;	/* Proceed initializers before other objects */
2505d00c5a6SKonstantin Belousov     bool static_tls : 1;	/* Needs static TLS allocation */
2515d00c5a6SKonstantin Belousov     bool static_tls_copied : 1;	/* Needs static TLS copying */
2526c3154f6SAlexander Kabaev     bool ref_nodel : 1;		/* Refcount increased to prevent dlclose */
2536c3154f6SAlexander Kabaev     bool init_scanned: 1;	/* Object is already on init list. */
2546c3154f6SAlexander Kabaev     bool on_fini_list: 1;	/* Object is already on fini list. */
255b8fc1b23SKonstantin Belousov     bool dag_inited : 1;	/* Object has its DAG initialized. */
2568569deafSKonstantin Belousov     bool filtees_loaded : 1;	/* Filtees loaded */
257968a1897SKonstantin Belousov     bool filtees_loading : 1;	/* In process of filtees loading */
2586be4b697SKonstantin Belousov     bool irelative : 1;		/* Object has R_MACHDEP_IRELATIVE relocs */
259c5ca0d11SKonstantin Belousov     bool irelative_nonplt : 1;	/* Object has R_MACHDEP_IRELATIVE non-plt relocs */
2606be4b697SKonstantin Belousov     bool gnu_ifunc : 1;		/* Object has references to STT_GNU_IFUNC */
26174b0daf4SKonstantin Belousov     bool non_plt_gnu_ifunc : 1;	/* Object has non-plt IFUNC references */
2624903c73fSKonstantin Belousov     bool ifuncs_resolved : 1;	/* Object ifuncs were already resolved */
26383aa9cc0SKonstantin Belousov     bool crt_no_init : 1;	/* Object' crt does not call _init/_fini */
264f6265192SKonstantin Belousov     bool valid_hash_sysv : 1;	/* A valid System V hash hash tag is available */
265f6265192SKonstantin Belousov     bool valid_hash_gnu : 1;	/* A valid GNU hash tag is available */
2660e521992SKonstantin Belousov     bool dlopened : 1;		/* dlopen()-ed (vs. load statically) */
2679fee0541SKonstantin Belousov     bool marker : 1;		/* marker on the global obj list */
268c0274175SMark Johnston     bool unholdfree : 1;	/* unmap upon last unhold */
269510fe58cSMark Johnston     bool doomed : 1;		/* Object cannot be referenced */
2702001f720SDoug Rabson 
27106db20ffSAndrew Turner     MD_OBJ_ENTRY;
27206db20ffSAndrew Turner 
2736c3154f6SAlexander Kabaev     struct link_map linkmap;	/* For GDB and dlinfo() */
27482531605SJohn Polstra     Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */
27582531605SJohn Polstra     Objlist dagmembers;		/* DAG has these members (%) */
27682531605SJohn Polstra     dev_t dev;			/* Object's filesystem's device */
27782531605SJohn Polstra     ino_t ino;			/* Object's inode number */
2781acf0dbaSUlrich Spörlein     void *priv;			/* Platform-dependent */
2793124c3e0SJohn Polstra } Obj_Entry;
2803124c3e0SJohn Polstra 
2813124c3e0SJohn Polstra #define RTLD_MAGIC	0xd550b87a
2823124c3e0SJohn Polstra #define RTLD_VERSION	1
2833124c3e0SJohn Polstra 
2849fee0541SKonstantin Belousov TAILQ_HEAD(obj_entry_q, Struct_Obj_Entry);
2859fee0541SKonstantin Belousov 
28622a91927SDoug Rabson #define RTLD_STATIC_TLS_EXTRA	128
287017246d0SDoug Rabson 
2880eb88f20SAlexander Kabaev /* Flags to be passed into symlook_ family of functions. */
2890eb88f20SAlexander Kabaev #define SYMLOOK_IN_PLT	0x01	/* Lookup for PLT symbol */
2905b646fa1SKonstantin Belousov #define SYMLOOK_DLSYM	0x02	/* Return newest versioned symbol. Used by
2910eb88f20SAlexander Kabaev 				   dlsym. */
292082f959aSKonstantin Belousov #define	SYMLOOK_EARLY	0x04	/* Symlook is done during initialization. */
29314c35647SKonstantin Belousov #define	SYMLOOK_IFUNC	0x08	/* Allow IFUNC processing in
29414c35647SKonstantin Belousov 				   reloc_non_plt(). */
2950eb88f20SAlexander Kabaev 
2960d3bc8a9SKonstantin Belousov /* Flags for load_object(). */
297abf48e83SKonstantin Belousov #define	RTLD_LO_NOLOAD	0x01	/* dlopen() specified RTLD_NOLOAD. */
298abf48e83SKonstantin Belousov #define	RTLD_LO_DLOPEN	0x02	/* Load_object() called from dlopen(). */
299abf48e83SKonstantin Belousov #define	RTLD_LO_TRACE	0x04	/* Only tracing. */
3008569deafSKonstantin Belousov #define	RTLD_LO_NODELETE 0x08	/* Loaded object cannot be closed. */
3018569deafSKonstantin Belousov #define	RTLD_LO_FILTEES 0x10	/* Loading filtee. */
302082f959aSKonstantin Belousov #define	RTLD_LO_EARLY	0x20	/* Do not call ctors, postpone it to the
303082f959aSKonstantin Belousov 				   initialization during the image start. */
30462af2dc3SKonstantin Belousov #define	RTLD_LO_IGNSTLS 0x40	/* Do not allocate static TLS */
3051659238aSKonstantin Belousov #define	RTLD_LO_DEEPBIND 0x80	/* Force symbolic for this object */
3060d3bc8a9SKonstantin Belousov 
307c15e7faaSJohn Polstra /*
308c15e7faaSJohn Polstra  * Symbol cache entry used during relocation to avoid multiple lookups
309c15e7faaSJohn Polstra  * of the same symbol.
310c15e7faaSJohn Polstra  */
311c15e7faaSJohn Polstra typedef struct Struct_SymCache {
312c15e7faaSJohn Polstra     const Elf_Sym *sym;		/* Symbol table entry */
313c15e7faaSJohn Polstra     const Obj_Entry *obj;	/* Shared object which defines it */
314c15e7faaSJohn Polstra } SymCache;
315c15e7faaSJohn Polstra 
3168569deafSKonstantin Belousov /*
3178569deafSKonstantin Belousov  * This structure provides a reentrant way to keep a list of objects and
3188569deafSKonstantin Belousov  * check which ones have already been processed in some way.
3198569deafSKonstantin Belousov  */
3208569deafSKonstantin Belousov typedef struct Struct_DoneList {
3218569deafSKonstantin Belousov     const Obj_Entry **objs;		/* Array of object pointers */
3228569deafSKonstantin Belousov     unsigned int num_alloc;		/* Allocated size of the array */
3238569deafSKonstantin Belousov     unsigned int num_used;		/* Number of array slots used */
3248569deafSKonstantin Belousov } DoneList;
3258569deafSKonstantin Belousov 
3268569deafSKonstantin Belousov struct Struct_RtldLockState {
3278569deafSKonstantin Belousov 	int lockstate;
328a7bc470aSKonstantin Belousov 	sigjmp_buf env;
3298569deafSKonstantin Belousov };
3308569deafSKonstantin Belousov 
331bca2f623SKonstantin Belousov struct fill_search_info_args {
332bca2f623SKonstantin Belousov 	int request;
333bca2f623SKonstantin Belousov 	unsigned int flags;
334bca2f623SKonstantin Belousov 	struct dl_serinfo *serinfo;
335bca2f623SKonstantin Belousov 	struct dl_serpath *serpath;
336bca2f623SKonstantin Belousov 	char *strspace;
337bca2f623SKonstantin Belousov };
338bca2f623SKonstantin Belousov 
3398569deafSKonstantin Belousov /*
3408569deafSKonstantin Belousov  * The pack of arguments and results for the symbol lookup functions.
3418569deafSKonstantin Belousov  */
3428569deafSKonstantin Belousov typedef struct Struct_SymLook {
3438569deafSKonstantin Belousov     const char *name;
3448569deafSKonstantin Belousov     unsigned long hash;
345f6265192SKonstantin Belousov     uint32_t hash_gnu;
3468569deafSKonstantin Belousov     const Ver_Entry *ventry;
3478569deafSKonstantin Belousov     int flags;
3488569deafSKonstantin Belousov     const Obj_Entry *defobj_out;
3498569deafSKonstantin Belousov     const Elf_Sym *sym_out;
3508569deafSKonstantin Belousov     struct Struct_RtldLockState *lockstate;
3518569deafSKonstantin Belousov } SymLook;
3528569deafSKonstantin Belousov 
35347315d6dSKonstantin Belousov enum {
35447315d6dSKonstantin Belousov 	LD_BIND_NOW = 0,
35547315d6dSKonstantin Belousov 	LD_PRELOAD,
35647315d6dSKonstantin Belousov 	LD_LIBMAP,
35747315d6dSKonstantin Belousov 	LD_LIBRARY_PATH,
35847315d6dSKonstantin Belousov 	LD_LIBRARY_PATH_FDS,
35947315d6dSKonstantin Belousov 	LD_LIBMAP_DISABLE,
36047315d6dSKonstantin Belousov 	LD_BIND_NOT,
36147315d6dSKonstantin Belousov 	LD_DEBUG,
36247315d6dSKonstantin Belousov 	LD_ELF_HINTS_PATH,
36347315d6dSKonstantin Belousov 	LD_LOADFLTR,
36447315d6dSKonstantin Belousov 	LD_LIBRARY_PATH_RPATH,
36547315d6dSKonstantin Belousov 	LD_PRELOAD_FDS,
36647315d6dSKonstantin Belousov 	LD_DYNAMIC_WEAK,
36747315d6dSKonstantin Belousov 	LD_TRACE_LOADED_OBJECTS,
36847315d6dSKonstantin Belousov 	LD_UTRACE,
36947315d6dSKonstantin Belousov 	LD_DUMP_REL_PRE,
37047315d6dSKonstantin Belousov 	LD_DUMP_REL_POST,
37147315d6dSKonstantin Belousov 	LD_TRACE_LOADED_OBJECTS_PROGNAME,
37247315d6dSKonstantin Belousov 	LD_TRACE_LOADED_OBJECTS_FMT1,
37347315d6dSKonstantin Belousov 	LD_TRACE_LOADED_OBJECTS_FMT2,
37447315d6dSKonstantin Belousov 	LD_TRACE_LOADED_OBJECTS_ALL,
37547315d6dSKonstantin Belousov 	LD_SHOW_AUXV,
37647315d6dSKonstantin Belousov 	LD_STATIC_TLS_EXTRA,
377860c4d94SKonstantin Belousov 	LD_NO_DL_ITERATE_PHDR_AFTER_FORK,
37847315d6dSKonstantin Belousov };
37947315d6dSKonstantin Belousov 
3800c4f9ecdSKonstantin Belousov void _rtld_error(const char *, ...) __printflike(1, 2) __exported;
38129f36d0bSEd Maste void rtld_die(void) __dead2;
382e24348dfSKonstantin Belousov const char *rtld_strerror(int);
383a08d92deSJessica Clarke Obj_Entry *map_object(int, const char *, const struct stat *, bool);
384e24348dfSKonstantin Belousov void *xcalloc(size_t, size_t);
385e24348dfSKonstantin Belousov void *xmalloc(size_t);
386e24348dfSKonstantin Belousov char *xstrdup(const char *);
387feaae6baSKonstantin Belousov void *xmalloc_aligned(size_t size, size_t align, size_t offset);
38813575fc4SDoug Rabson extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
389d48dde6fSNathan Whitehorn extern Elf_Sym sym_zero;	/* For resolving undefined weak refs. */
390e35ddbe4SKonstantin Belousov extern bool ld_bind_not;
391aef199e5SKonstantin Belousov extern bool ld_fast_sigblock;
39213575fc4SDoug Rabson 
393e24348dfSKonstantin Belousov void dump_relocations(Obj_Entry *);
394e24348dfSKonstantin Belousov void dump_obj_relocations(Obj_Entry *);
395e24348dfSKonstantin Belousov void dump_Elf_Rel(Obj_Entry *, const Elf_Rel *, u_long);
396e24348dfSKonstantin Belousov void dump_Elf_Rela(Obj_Entry *, const Elf_Rela *, u_long);
397c5d061c1SMatthew N. Dodd 
39813575fc4SDoug Rabson /*
39913575fc4SDoug Rabson  * Function declarations.
40013575fc4SDoug Rabson  */
40147315d6dSKonstantin Belousov const char *ld_get_env_var(int idx);
402e85eaa93SAndrew Turner uintptr_t rtld_round_page(uintptr_t);
403e85eaa93SAndrew Turner uintptr_t rtld_trunc_page(uintptr_t);
40429e3a065SEd Maste Elf32_Word elf_hash(const char *);
405185db83cSJohn Polstra const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
4068569deafSKonstantin Belousov   const Obj_Entry **, int, SymCache *, struct Struct_RtldLockState *);
4072c297acbSMatthew N. Dodd void lockdflt_init(void);
40883aa9cc0SKonstantin Belousov void digest_notes(Obj_Entry *, Elf_Addr, Elf_Addr);
4099fee0541SKonstantin Belousov Obj_Entry *globallist_curr(const Obj_Entry *obj);
4109fee0541SKonstantin Belousov Obj_Entry *globallist_next(const Obj_Entry *obj);
411926ea445SJohn Polstra void obj_free(Obj_Entry *);
412926ea445SJohn Polstra Obj_Entry *obj_new(void);
4134d7f08c8SKonstantin Belousov Obj_Entry *obj_from_addr(const void *);
414d5b537d0SJohn Polstra void _rtld_bind_start(void);
4156be4b697SKonstantin Belousov void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def);
4168569deafSKonstantin Belousov void symlook_init(SymLook *, const char *);
4178569deafSKonstantin Belousov int symlook_obj(SymLook *, const Obj_Entry *);
418960f40b8SJessica Clarke void *tls_get_addr_common(struct tcb *tcb, int index, size_t offset);
419017246d0SDoug Rabson void *allocate_tls(Obj_Entry *, void *, size_t, size_t);
420017246d0SDoug Rabson void free_tls(void *, size_t, size_t);
421*48fd0845SJessica Clarke void *allocate_module_tls(struct tcb *tcb, int index);
422017246d0SDoug Rabson bool allocate_tls_offset(Obj_Entry *obj);
423ddab7ee8SDoug Rabson void free_tls_offset(Obj_Entry *obj);
4240eb88f20SAlexander Kabaev const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
425ca8c8dc3SKonstantin Belousov int convert_prot(int elfflags);
42663fc4e82SKonstantin Belousov bool check_elf_headers(const Elf_Ehdr *hdr, const char *path);
4273124c3e0SJohn Polstra 
42894040887SMatthew N. Dodd /*
42994040887SMatthew N. Dodd  * MD function declarations.
43094040887SMatthew N. Dodd  */
43194040887SMatthew N. Dodd int do_copy_relocations(Obj_Entry *);
432082f959aSKonstantin Belousov int reloc_non_plt(Obj_Entry *, Obj_Entry *, int flags,
433082f959aSKonstantin Belousov     struct Struct_RtldLockState *);
4344849c3a5SMichal Meloun int reloc_plt(Obj_Entry *, int flags, struct Struct_RtldLockState *);
435082f959aSKonstantin Belousov int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *);
4366be4b697SKonstantin Belousov int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *);
437c5ca0d11SKonstantin Belousov int reloc_iresolve_nonplt(Obj_Entry *, struct Struct_RtldLockState *);
438082f959aSKonstantin Belousov int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *);
43933658afdSJessica Clarke void ifunc_init(Elf_Auxinfo *[__min_size(AT_COUNT)]);
44041fc6f68SMarius Strobl void init_pltgot(Obj_Entry *);
441017246d0SDoug Rabson void allocate_initial_tls(Obj_Entry *);
44294040887SMatthew N. Dodd 
4433124c3e0SJohn Polstra #endif /* } */
444