Merge from vendor branch OPENSSL:
[dragonfly.git] / libexec / rtld-aout / rtld.c
1 /*
2  * Copyright (c) 1993 Paul Kranenburg
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Paul Kranenburg.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $FreeBSD: src/libexec/rtld-aout/rtld.c,v 1.58.2.2 2002/03/04 12:00:31 dwmalone Exp $
31  * $DragonFly: src/libexec/rtld-aout/Attic/rtld.c,v 1.3 2003/11/14 03:54:31 dillon Exp $
32  */
33
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/file.h>
38 #include <sys/time.h>
39 #include <sys/resource.h>
40 #include <sys/errno.h>
41 #include <sys/mman.h>
42 #ifndef MAP_COPY
43 #define MAP_COPY        MAP_PRIVATE
44 #endif
45 #include <dlfcn.h>
46 #include <err.h>
47 #include <fcntl.h>
48 #include <a.out.h>
49 #include <paths.h>
50 #include <stab.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55 #if __STDC__
56 #include <stdarg.h>
57 #else
58 #include <varargs.h>
59 #endif
60
61 #include <link.h>
62
63 #include "md.h"
64 #include "shlib.h"
65 #include "support.h"
66 #include "dynamic.h"
67
68 #ifndef MAP_ANON
69 #define MAP_ANON        0
70 #define anon_open() do {                                        \
71         if ((anon_fd = open(_PATH_DEVZERO, O_RDWR, 0)) == -1)   \
72                 err("open: %s", _PATH_DEVZERO);                 \
73 } while (0)
74 #define anon_close() do {       \
75         (void)close(anon_fd);   \
76         anon_fd = -1;           \
77 } while (0)
78 #else
79 #define anon_open()
80 #define anon_close()
81 #endif
82
83 /*
84  * Structure for building a list of shared objects.
85  */
86 struct so_list {
87         struct so_map   *sol_map;       /* Link map for shared object */
88         struct so_list  *sol_next;      /* Next entry in the list */
89 };
90
91 /*
92  * Loader private data, hung off <so_map>->som_spd
93  */
94 struct somap_private {
95         int             spd_version;
96         struct so_map   *spd_parent;
97         struct so_list  *spd_children;
98         struct so_map   *spd_prev;
99         dev_t           spd_dev;
100         ino_t           spd_ino;
101         int             spd_refcount;
102         int             spd_flags;
103 #define RTLD_MAIN       0x01
104 #define RTLD_RTLD       0x02
105 #define RTLD_DL         0x04
106 #define RTLD_INIT       0x08
107         unsigned long   a_text;    /* text size, if known     */
108         unsigned long   a_data;    /* initialized data size   */
109         unsigned long   a_bss;     /* uninitialized data size */
110
111 #ifdef SUN_COMPAT
112         long            spd_offset;     /* Correction for Sun main programs */
113 #endif
114 };
115
116 #define LM_PRIVATE(smp) ((struct somap_private *)(smp)->som_spd)
117
118 #ifdef SUN_COMPAT
119 #define LM_OFFSET(smp)  (LM_PRIVATE(smp)->spd_offset)
120 #else
121 #define LM_OFFSET(smp)  (0)
122 #endif
123
124 /* Base address for section_dispatch_table entries */
125 #define LM_LDBASE(smp)  (smp->som_addr + LM_OFFSET(smp))
126
127 /* Start of text segment */
128 #define LM_TXTADDR(smp) (smp->som_addr == (caddr_t)0 ? PAGSIZ : 0)
129
130 /* Start of run-time relocation_info */
131 #define LM_REL(smp)     ((struct relocation_info *) \
132         (smp->som_addr + LM_OFFSET(smp) + LD_REL((smp)->som_dynamic)))
133
134 /* Start of symbols */
135 #define LM_SYMBOL(smp, i)       ((struct nzlist *) \
136         (smp->som_addr + LM_OFFSET(smp) + LD_SYMBOL((smp)->som_dynamic) + \
137                 i * (LD_VERSION_NZLIST_P(smp->som_dynamic->d_version) ? \
138                         sizeof(struct nzlist) : sizeof(struct nlist))))
139
140 /* Start of hash table */
141 #define LM_HASH(smp)    ((struct rrs_hash *) \
142         ((smp)->som_addr + LM_OFFSET(smp) + LD_HASH((smp)->som_dynamic)))
143
144 /* Start of strings */
145 #define LM_STRINGS(smp) ((char *) \
146         ((smp)->som_addr + LM_OFFSET(smp) + LD_STRINGS((smp)->som_dynamic)))
147
148 /* Start of search paths */
149 #define LM_PATHS(smp)   ((char *) \
150         ((smp)->som_addr + LM_OFFSET(smp) + LD_PATHS((smp)->som_dynamic)))
151
152 /* End of text */
153 #define LM_ETEXT(smp)   ((char *) \
154         ((smp)->som_addr + LM_TXTADDR(smp) + LD_TEXTSZ((smp)->som_dynamic)))
155
156 /* Needed shared objects */
157 #define LM_NEED(smp)    ((struct sod *) \
158         ((smp)->som_addr + LM_TXTADDR(smp) + LD_NEED((smp)->som_dynamic)))
159
160 /* PLT is in data segment, so don't use LM_OFFSET here */
161 #define LM_PLT(smp)     ((jmpslot_t *) \
162         ((smp)->som_addr + LD_PLT((smp)->som_dynamic)))
163
164 /* Parent of link map */
165 #define LM_PARENT(smp)  (LM_PRIVATE(smp)->spd_parent)
166
167 #ifndef RELOC_EXTERN_P
168 #define RELOC_EXTERN_P(s) ((s)->r_extern)
169 #endif
170
171 #ifndef RELOC_SYMBOL
172 #define RELOC_SYMBOL(s) ((s)->r_symbolnum)
173 #endif
174
175 #ifndef RELOC_PCREL_P
176 #define RELOC_PCREL_P(s) ((s)->r_pcrel)
177 #endif
178
179 #define END_SYM         "_end"
180
181 static char             __main_progname[] = "main";
182 static char             *main_progname = __main_progname;
183 static char             us[] = "/usr/libexec/ld.so";
184
185 char                    **environ;
186 char                    *__progname;
187 int                     errno;
188
189 static uid_t            uid, euid;
190 static gid_t            gid, egid;
191 static int              careful;
192 static int              anon_fd = -1;
193
194 static char             *ld_bind_now;
195 static char             *ld_ignore_missing_objects;
196 static char             *ld_library_path;
197 static char             *ld_preload;
198 static char             *ld_tracing;
199 static char             *ld_suppress_warnings;
200 static char             *ld_warn_non_pure_code;
201
202 struct so_map           *link_map_head;
203 struct so_map           *link_map_tail;
204 struct rt_symbol        *rt_symbol_head;
205
206 static void             *__dlopen (const char *, int);
207 static int              __dlclose (void *);
208 static void             *__dlsym (void *, const char *);
209 static const char       *__dlerror (void);
210 static void             __dlexit (void);
211 static void             *__dlsym3 (void *, const char *, void *);
212 static int              __dladdr (const void *, Dl_info *);
213
214 static struct ld_entry  ld_entry = {
215         __dlopen, __dlclose, __dlsym, __dlerror, __dlexit, __dlsym3, __dladdr
216 };
217
218        void             xprintf (char *, ...);
219 static struct so_map    *map_object (   const char *,
220                                                 struct sod *,
221                                                 struct so_map *);
222 static int              map_preload (void);
223 static int              map_sods (struct so_map *);
224 static int              reloc_dag (struct so_map *, int);
225 static void             unmap_object (struct so_map     *, int);
226 static struct so_map    *alloc_link_map (       const char *, struct sod *,
227                                                 struct so_map *, caddr_t,
228                                                 struct _dynamic *);
229 static void             init_link_map ( struct so_map *,
230                                                 struct somap_private *,
231                                                 const char *, struct sod *,
232                                                 struct so_map *, caddr_t,
233                                                 struct _dynamic *);
234 static void             free_link_map (struct so_map *);
235 static inline int       check_text_reloc (      struct relocation_info *,
236                                                 struct so_map *,
237                                                 caddr_t);
238 static int              reloc_map (struct so_map *, int);
239 static void             reloc_copy (struct so_map *);
240 static void             init_dag (struct so_map *);
241 static void             init_sods (struct so_list *);
242 static void             init_internal_malloc (void);
243 static void             init_external_malloc (void);
244 static int              call_map (struct so_map *, char *);
245 static char             *findhint (char *, int, int *);
246 static char             *rtfindlib (char *, int, int, int);
247 static char             *rtfindfile (const char *);
248 void                    binder_entry (void);
249 long                    binder (jmpslot_t *);
250 static struct nzlist    *lookup (char *, struct so_map **, int);
251 static inline struct rt_symbol  *lookup_rts (char *, unsigned long);
252 static struct nzlist    *lookup_in_obj (char *, unsigned long,
253     struct so_map *, int);
254 static struct rt_symbol *enter_rts (char *, unsigned long, long, int,
255     caddr_t, long, struct so_map *);
256 static void             *sym_addr (char *);
257 static struct nzlist *  lookup_errno_hack(char *, struct so_map **, int);
258 static void             die (void);
259 static void             generror (char *, ...);
260 static int              maphints (void);
261 static void             unmaphints (void);
262 static void             ld_trace (struct so_map *);
263 static void             rt_readenv (void);
264 static int              hinthash (char *, int);
265 int                     rtld (int, struct crt_ldso *, struct _dynamic *);
266
267 /*
268  * Compute a hash value for symbol tables.  Don't change this -- the
269  * algorithm is dictated by the way the linker builds the symbol
270  * tables in the shared objects.
271  */
272 static inline unsigned long
273 sym_hash(s)
274         const char      *s;
275 {
276         unsigned long    h;
277
278         h = 0;
279         while (*s != '\0')
280                 h = (h << 1) + *s++;
281         return h & 0x7fffffffUL;
282 }
283
284 static inline int
285 strcmp (register const char *s1, register const char *s2)
286 {
287         while (*s1 == *s2++)
288                 if (*s1++ == 0)
289                         return (0);
290         return (*(unsigned char *)s1 - *(unsigned char *)--s2);
291 }
292
293 #include "md-static-funcs.c"
294
295 /*
296  * Called from assembler stub that has set up crtp (passed from crt0)
297  * and dp (our __DYNAMIC).
298  */
299 int
300 rtld(version, crtp, dp)
301 int                     version;
302 struct crt_ldso         *crtp;
303 struct _dynamic         *dp;
304 {
305         struct relocation_info  *reloc;
306         struct relocation_info  *reloc_limit;   /* End+1 of relocation */
307         struct so_debug         *ddp;
308         struct so_map           *main_map;
309         struct so_map           *smp;
310         char                    *add_paths;
311         char                    *main_path;
312
313         /* Check version */
314         if (version != CRT_VERSION_BSD_2 &&
315             version != CRT_VERSION_BSD_3 &&
316             version != CRT_VERSION_BSD_4 &&
317             version != CRT_VERSION_BSD_5 &&
318             version != CRT_VERSION_SUN)
319                 return -1;
320
321         /* Fixup __DYNAMIC structure */
322         (long)dp->d_un.d_sdt += crtp->crt_ba;
323
324         /* Relocate ourselves */
325         reloc = (struct relocation_info *) (LD_REL(dp) + crtp->crt_ba);
326         reloc_limit =
327                 (struct relocation_info *) ((char *) reloc + LD_RELSZ(dp));
328         while(reloc < reloc_limit) {
329                 /*
330                  * Objects linked with "-Bsymbolic" (in particular, ld.so
331                  * itself) can end up having unused relocation entries at
332                  * the end.  These can be detected by the fact that they
333                  * have an address of 0.
334                  */
335                 if(reloc->r_address == 0)       /* We're done */
336                     break;
337                 md_relocate_simple(reloc, crtp->crt_ba,
338                         reloc->r_address + crtp->crt_ba);
339                 ++reloc;
340         }
341
342         if (version >= CRT_VERSION_BSD_4)
343                 __progname = crtp->crt_ldso;
344         if (version >= CRT_VERSION_BSD_3)
345                 main_progname = crtp->crt_prog;
346         main_path = version >= CRT_VERSION_BSD_5 ? crtp->crt_argv[0] :
347             main_progname;
348
349         /* Some buggy versions of crt0.o have crt_ldso filled in as NULL. */
350         if (__progname == NULL)
351                 __progname = us;
352
353         /* Fill in some fields in _DYNAMIC or crt structure */
354         if (version >= CRT_VERSION_BSD_4)
355                 crtp->crt_ldentry = &ld_entry;          /* crt */
356         else
357                 crtp->crt_dp->d_entry = &ld_entry;      /* _DYNAMIC */
358
359         /* Initialize our internal malloc package. */
360         init_internal_malloc();
361
362         /* Setup out (private) environ variable */
363         environ = crtp->crt_ep;
364
365         /* Get user and group identifiers */
366         uid = getuid(); euid = geteuid();
367         gid = getgid(); egid = getegid();
368
369         careful = (uid != euid) || (gid != egid);
370
371         rt_readenv();
372
373         anon_open();
374
375         /* Make a link map entry for the main program */
376         main_map = alloc_link_map(main_path,
377                              (struct sod *) NULL, (struct so_map *) NULL,
378                              (caddr_t) 0, crtp->crt_dp);
379         LM_PRIVATE(main_map)->spd_refcount++;
380         LM_PRIVATE(main_map)->spd_flags |= RTLD_MAIN;
381
382         /* Make a link map entry for ourselves */
383         smp = alloc_link_map(us,
384                              (struct sod *) NULL, (struct so_map *) NULL,
385                              (caddr_t) crtp->crt_ba, dp);
386         LM_PRIVATE(smp)->spd_refcount++;
387         LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
388
389         /*
390          * Setup the executable's run path
391          */
392         if (version >= CRT_VERSION_BSD_4) {
393                 add_paths = LM_PATHS(main_map);
394                 if (add_paths)
395                         add_search_path(add_paths);
396         }
397
398         /*
399          * Setup the directory search list for findshlib.  We use only
400          * the standard search path.  Any extra directories from
401          * LD_LIBRARY_PATH are searched explicitly, in rtfindlib.
402          */
403         std_search_path();
404
405         /* Map in LD_PRELOADs before the main program's shared objects so we
406            can intercept those calls */
407         if (ld_preload != NULL) {
408                 if(map_preload() == -1)                 /* Failed */
409                         die();
410         }
411
412         /* Map all the shared objects that the main program depends upon */
413         if(map_sods(main_map) == -1)
414                 die();
415
416         if(ld_tracing) {        /* We're done */
417                 ld_trace(link_map_head);
418                 exit(0);
419         }
420
421         crtp->crt_dp->d_un.d_sdt->sdt_loaded = link_map_head->som_next;
422
423         /* Relocate all mapped objects. */
424         if(reloc_dag(main_map, ld_bind_now != NULL) == -1)      /* Failed */
425                 die();
426
427         /*
428          * Switch to the same malloc that the program uses.  We do
429          * this before initializing the loaded objects, because their
430          * initialization functions may well call malloc, and it won't
431          * work right until we have set it up.
432          */
433         init_external_malloc();
434
435         /* Initialize all mapped objects. */
436         init_dag(main_map);
437
438         ddp = crtp->crt_dp->d_debug;
439         ddp->dd_cc = rt_symbol_head;
440         if (ddp->dd_in_debugger) {
441                 caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
442
443                 /* Set breakpoint for the benefit of debuggers */
444                 if (mprotect(addr, PAGSIZ,
445                                 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
446                         err(1, "Cannot set breakpoint (%s)", main_progname);
447                 }
448                 md_set_breakpoint((long)crtp->crt_bp, (long *)&ddp->dd_bpt_shadow);
449                 if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
450                         err(1, "Cannot re-protect breakpoint (%s)",
451                                 main_progname);
452                 }
453
454                 ddp->dd_bpt_addr = crtp->crt_bp;
455                 if (link_map_head)
456                         ddp->dd_sym_loaded = 1;
457         }
458
459         /* Close the hints file */
460         unmaphints();
461
462         /* Close our file descriptor */
463         (void)close(crtp->crt_ldfd);
464         anon_close();
465
466         return LDSO_VERSION_HAS_DLADDR;
467 }
468
469 void
470 ld_trace(smp)
471         struct so_map *smp;
472 {
473         char    *fmt1, *fmt2, *fmt, *main_local;
474         int     c;
475
476         if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
477                 main_local = "";
478
479         if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL)
480                 fmt1 = "\t-l%o.%m => %p (%x)\n";
481
482         if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
483                 fmt2 = "\t%o (%x)\n";
484
485         for (; smp; smp = smp->som_next) {
486                 struct sod      *sodp;
487                 char            *name, *path;
488
489                 if ((sodp = smp->som_sod) == NULL)
490                         continue;
491
492                 name = (char *)sodp->sod_name;
493                 if (LM_PARENT(smp))
494                         name += (long)LM_LDBASE(LM_PARENT(smp));
495
496                 if ((path = smp->som_path) == NULL)
497                         path = "not found";
498
499                 fmt = sodp->sod_library ? fmt1 : fmt2;
500                 while ((c = *fmt++) != '\0') {
501                         switch (c) {
502                         default:
503                                 putchar(c);
504                                 continue;
505                         case '\\':
506                                 switch (c = *fmt) {
507                                 case '\0':
508                                         continue;
509                                 case 'n':
510                                         putchar('\n');
511                                         break;
512                                 case 't':
513                                         putchar('\t');
514                                         break;
515                                 }
516                                 break;
517                         case '%':
518                                 switch (c = *fmt) {
519                                 case '\0':
520                                         continue;
521                                 case '%':
522                                 default:
523                                         putchar(c);
524                                         break;
525                                 case 'A':
526                                         printf("%s", main_local);
527                                         break;
528                                 case 'a':
529                                         printf("%s", main_progname);
530                                         break;
531                                 case 'o':
532                                         printf("%s", name);
533                                         break;
534                                 case 'm':
535                                         printf("%d", sodp->sod_major);
536                                         break;
537                                 case 'n':
538                                         printf("%d", sodp->sod_minor);
539                                         break;
540                                 case 'p':
541                                         printf("%s", path);
542                                         break;
543                                 case 'x':
544                                         printf("%p", smp->som_addr);
545                                         break;
546                                 }
547                                 break;
548                         }
549                         ++fmt;
550                 }
551         }
552 }
553
554 /*
555  * Allocate a new link map and return a pointer to it.
556  *
557  * PATH is the pathname of the shared object.
558  *
559  * SODP is a pointer to the shared object dependency structure responsible
560  * for causing the new object to be loaded.  PARENT is the shared object
561  * into which SODP points.  Both can be NULL if the new object is not
562  * being loaded as a result of a shared object dependency.
563  *
564  * ADDR is the address at which the object has been mapped.  DP is a pointer
565  * to its _dynamic structure.
566  */
567 static struct so_map *
568 alloc_link_map(path, sodp, parent, addr, dp)
569         const char      *path;
570         struct sod      *sodp;
571         struct so_map   *parent;
572         caddr_t         addr;
573         struct _dynamic *dp;
574 {
575         struct so_map           *smp;
576         struct somap_private    *smpp;
577
578 #ifdef DEBUG /* { */
579         xprintf("alloc_link_map: \"%s\" at %p\n", path, addr);
580 #endif /* } */
581
582         smp = (struct so_map *)xmalloc(sizeof(struct so_map));
583         smpp = (struct somap_private *)xmalloc(sizeof(struct somap_private));
584         init_link_map(smp, smpp, path, sodp, parent, addr, dp);
585
586         /* Link the new entry into the list of link maps */
587         smpp->spd_prev = link_map_tail;
588         if(link_map_tail == NULL)       /* First link map entered into list */
589                 link_map_head = link_map_tail = smp;
590         else {                          /* Append to end of list */
591                 link_map_tail->som_next = smp;
592                 link_map_tail = smp;
593         }
594
595         return smp;
596 }
597
598 /*
599  * Initialize a link map entry that has already been allocated.
600  */
601 static void
602 init_link_map(smp, smpp, path, sodp, parent, addr, dp)
603         struct so_map           *smp;
604         struct somap_private    *smpp;
605         const char              *path;
606         struct sod              *sodp;
607         struct so_map           *parent;
608         caddr_t                  addr;
609         struct _dynamic         *dp;
610 {
611         memset(smp, 0, sizeof *smp);
612         memset(smpp, 0, sizeof *smpp);
613         smp->som_spd = (caddr_t)smpp;
614         smp->som_addr = addr;
615         smp->som_path = path ? strdup(path) : NULL;
616         smp->som_sod = sodp;
617         smp->som_dynamic = dp;
618         smpp->spd_parent = parent;
619 #ifdef SUN_COMPAT
620         smpp->spd_offset =
621                 (addr==0 && dp && dp->d_version==LD_VERSION_SUN) ? PAGSIZ : 0;
622 #endif
623 }
624
625 /*
626  * Remove the specified link map entry from the list of link maps, and free
627  * the associated storage.
628  */
629 static void
630 free_link_map(smp)
631         struct so_map   *smp;
632 {
633         struct somap_private    *smpp = LM_PRIVATE(smp);
634
635 #ifdef DEBUG /* { */
636         xprintf("free_link_map: \"%s\"\n", smp->som_path);
637 #endif /* } */
638
639         if(smpp->spd_prev == NULL)      /* Removing first entry in list */
640                 link_map_head = smp->som_next;
641         else                            /* Update link of previous entry */
642                 smpp->spd_prev->som_next = smp->som_next;
643
644         if(smp->som_next == NULL)       /* Removing last entry in list */
645                 link_map_tail = smpp->spd_prev;
646         else                            /* Update back link of next entry */
647                 LM_PRIVATE(smp->som_next)->spd_prev = smpp->spd_prev;
648
649         if (smp->som_path != NULL)
650                 free(smp->som_path);
651         free(smpp);
652         free(smp);
653 }
654
655 /*
656  * Map the shared object specified by PATH into memory, if it is not
657  * already mapped.  Increment the object's reference count, and return a
658  * pointer to its link map.
659  *
660  * As a special case, if PATH is NULL, it is taken to refer to the main
661  * program.
662  *
663  * SODP is a pointer to the shared object dependency structure that caused
664  * this object to be requested.  PARENT is a pointer to the link map of
665  * the shared object containing that structure.  For a shared object not
666  * being mapped as a result of a shared object dependency, these pointers
667  * should be NULL.  An example of this is a shared object that is explicitly
668  * loaded via dlopen().
669  *
670  * The return value is a pointer to the link map for the requested object.
671  * If the operation failed, the return value is NULL.  In that case, an
672  * error message can be retrieved by calling dlerror().
673  */
674 static struct so_map *
675 map_object(path, sodp, parent)
676         const char      *path;
677         struct sod      *sodp;
678         struct so_map   *parent;
679 {
680         struct so_map   *smp;
681         struct stat     statbuf;
682
683         if(path == NULL)        /* Special case for the main program itself */
684                 smp = link_map_head;
685         else {
686                 /*
687                  * Check whether the shared object is already mapped.
688                  * We check first for an exact match by pathname.  That
689                  * will detect the usual case.  If no match is found by
690                  * pathname, then stat the file, and check for a match by
691                  * device and inode.  That will detect the less common case
692                  * involving multiple links to the same library.
693                  */
694                 for(smp = link_map_head;  smp != NULL;  smp = smp->som_next) {
695                         if(!(LM_PRIVATE(smp)->spd_flags & (RTLD_MAIN|RTLD_RTLD))
696                         && smp->som_path != NULL
697                         && strcmp(smp->som_path, path) == 0)
698                                 break;
699                 }
700                 if(smp == NULL) {  /* Check for a match by device and inode */
701                         if (stat(path, &statbuf) == -1) {
702                                 generror ("cannot stat \"%s\" : %s",
703                                         path, strerror(errno));
704                                 return NULL;
705                         }
706                         for (smp = link_map_head;  smp != NULL;
707                              smp = smp->som_next) {
708                                 struct somap_private *smpp = LM_PRIVATE(smp);
709
710                                 if (!(smpp->spd_flags & (RTLD_MAIN | RTLD_RTLD))
711                                 && smpp->spd_ino == statbuf.st_ino
712                                 && smpp->spd_dev == statbuf.st_dev)
713                                         break;
714                         }
715                 }
716         }
717
718         if (smp == NULL) {      /* We must map the object */
719                 struct _dynamic *dp;
720                 int             fd;
721                 caddr_t         addr;
722                 struct exec     hdr;
723                 struct somap_private *smpp;
724
725                 if ((fd = open(path, O_RDONLY, 0)) == -1) {
726                         generror ("open failed for \"%s\" : %s",
727                                   path, strerror (errno));
728                         return NULL;
729                 }
730
731                 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
732                         generror ("header read failed for \"%s\"", path);
733                         (void)close(fd);
734                         return NULL;
735                 }
736
737                 if (N_BADMAG(hdr)) {
738                         generror ("bad magic number in \"%s\"", path);
739                         (void)close(fd);
740                         return NULL;
741                 }
742
743                 /*
744                  * Map the entire address space of the object.  It is
745                  * tempting to map just the text segment at first, in
746                  * order to avoid having to use mprotect to change the
747                  * protections of the data segment.  But that would not
748                  * be correct.  Mmap might find a group of free pages
749                  * large enough to hold the text segment, but not large
750                  * enough for the entire object.  When we then mapped
751                  * in the data and BSS segments, they would either be
752                  * non-contiguous with the text segment (if we didn't
753                  * specify MAP_FIXED), or they would map over some
754                  * previously mapped region (if we did use MAP_FIXED).
755                  * The only way we can be sure of getting a contigous
756                  * region that is large enough is to map the entire
757                  * region at once.
758                  */
759                 if ((addr = mmap(0, hdr.a_text + hdr.a_data + hdr.a_bss,
760                          PROT_READ|PROT_EXEC,
761                          MAP_COPY, fd, 0)) == (caddr_t)-1) {
762                         generror ("mmap failed for \"%s\" : %s",
763                                   path, strerror (errno));
764                         (void)close(fd);
765                         return NULL;
766                 }
767
768                 (void)close(fd);
769
770                 /* Change the data segment to writable */
771                 if (mprotect(addr + hdr.a_text, hdr.a_data,
772                     PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
773                         generror ("mprotect failed for \"%s\" : %s",
774                                   path, strerror (errno));
775                         (void)munmap(addr, hdr.a_text + hdr.a_data + hdr.a_bss);
776                         return NULL;
777                 }
778
779                 /* Map in pages of zeros for the BSS segment */
780                 if (mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
781                          PROT_READ|PROT_WRITE|PROT_EXEC,
782                          MAP_ANON|MAP_COPY|MAP_FIXED,
783                          anon_fd, 0) == (caddr_t)-1) {
784                         generror ("mmap failed for \"%s\" : %s",
785                                   path, strerror (errno));
786                         (void)munmap(addr, hdr.a_text + hdr.a_data + hdr.a_bss);
787                         return NULL;
788                 }
789
790                 /* Assume _DYNAMIC is the first data item */
791                 dp = (struct _dynamic *)(addr+hdr.a_text);
792
793                 /* Fixup __DYNAMIC structure */
794                 (long)dp->d_un.d_sdt += (long)addr;
795
796                 smp = alloc_link_map(path, sodp, parent, addr, dp);
797
798                 /* save segment sizes for unmap. */
799                 smpp = LM_PRIVATE(smp);
800                 smpp->a_text = hdr.a_text;
801                 smpp->a_data = hdr.a_data;
802                 smpp->a_bss = hdr.a_bss;
803
804                 /*
805                  * Save the device and inode, so we can detect multiple links
806                  * to the same library.  Note, if we reach this point, then
807                  * statbuf is guaranteed to have been filled in.
808                  */
809                 smpp->spd_dev = statbuf.st_dev;
810                 smpp->spd_ino = statbuf.st_ino;
811         }
812
813         LM_PRIVATE(smp)->spd_refcount++;
814         if(LM_PRIVATE(smp)->spd_refcount == 1) {  /* First use of object */
815                 /*
816                  * Recursively map all of the shared objects that this
817                  * one depends upon.
818                  */
819                 if(map_sods(smp) == -1) {               /* Failed */
820                         unmap_object(smp, 0);           /* Clean up */
821                         return NULL;
822                 }
823         }
824
825         return smp;
826 }
827
828 /*
829  * Map all the shared libraries named in the LD_PRELOAD environment
830  * variable.
831  *
832  * Returns 0 on success, -1 on failure.  On failure, an error message can
833  * be gotten via dlerror().
834  */
835         static int
836 map_preload (void) {
837         char    *ld_name = ld_preload;
838         char    *name;
839
840         while ((name = strsep(&ld_name, ":")) != NULL) {
841                 char            *path = NULL;
842                 struct so_map   *smp = NULL;
843
844                 if (*name != '\0') {
845                         path = (strchr(name, '/') != NULL) ?  strdup(name) :
846                                 rtfindfile(name);
847                 }
848                 if (path == NULL) {
849                         generror("Can't find LD_PRELOAD shared"
850                                 " library \"%s\"", name);
851                 } else {
852                         smp = map_object(path, (struct sod *) NULL,
853                                 (struct so_map *) NULL);
854                         free(path);
855                 }
856                 if (ld_name != NULL)
857                         *(ld_name - 1) = ':';
858                 if (smp == NULL) {
859                         /*
860                          * We don't bother to unmap already-loaded libraries
861                          * on failure, because in that case the program is
862                          * about to die anyway.
863                          */
864                         return -1;
865                 }
866         }
867         return 0;
868 }
869
870 /*
871  * Map all of the shared objects that a given object depends upon.  PARENT is
872  * a pointer to the link map for the shared object whose dependencies are
873  * to be mapped.
874  *
875  * Returns 0 on success.  Returns -1 on failure.  In that case, an error
876  * message can be retrieved by calling dlerror().
877  */
878 static int
879 map_sods(parent)
880         struct so_map   *parent;
881 {
882         struct somap_private    *parpp = LM_PRIVATE(parent);
883         struct so_list          **soltail = &parpp->spd_children;
884         long                    next = LD_NEED(parent->som_dynamic);
885
886         while(next != 0) {
887                 struct sod      *sodp =
888                         (struct sod *) (LM_LDBASE(parent) + next);
889                 char            *name =
890                         (char *) (LM_LDBASE(parent) + sodp->sod_name);
891                 char            *path = NULL;
892                 struct so_map   *smp = NULL;
893
894                 if(sodp->sod_library) {
895                         /*
896                          * First try for a match with an adequate minor
897                          * number.
898                          */
899                         path = rtfindlib(name, sodp->sod_major,
900                                          sodp->sod_minor, 1);
901                         /*
902                          * If none was found, try for just a major version
903                          * match.  A warning is issued by rtfindlib in
904                          * this case, since the minor version number isn't
905                          * really high enough.
906                          */
907                         if (path == NULL)
908                                 path = rtfindlib(name, sodp->sod_major,
909                                                  sodp->sod_minor, 0);
910                         if(path == NULL && !ld_tracing) {
911                                 generror ("Can't find shared library"
912                                           " \"lib%s.so.%d.%d\"", name,
913                                           sodp->sod_major, sodp->sod_minor);
914                         }
915                 } else {
916                         if(careful && name[0] != '/') {
917                                 generror("Shared library path must start"
918                                          " with \"/\" for \"%s\"", name);
919                         } else
920                                 path = strdup(name);
921                 }
922
923                 if(path != NULL) {
924                         smp = map_object(path, sodp, parent);
925                         free(path);
926                 }
927
928                 if(smp != NULL) {
929                         struct so_list  *solp = (struct so_list *)
930                                 xmalloc(sizeof(struct so_list));
931                         solp->sol_map = smp;
932                         solp->sol_next = NULL;
933                         *soltail = solp;
934                         soltail = &solp->sol_next;
935                 } else if(ld_tracing) {
936                         /*
937                          * Allocate a dummy map entry so that we will get the
938                          * "not found" message.
939                          */
940                         (void)alloc_link_map(NULL, sodp, parent, 0, 0);
941                 } else if (ld_ignore_missing_objects) {
942                         const char *msg;
943                         /*
944                          * Call __dlerror() even it we're not going to use
945                          * the message, in order to clear the saved message.
946                          */
947                         msg = __dlerror();  /* Should never be NULL */
948                         if (!ld_suppress_warnings)
949                                 warnx("warning: %s", msg);
950                 } else  /* Give up */
951                         break;
952
953                 next = sodp->sod_next;
954         }
955
956         if(next != 0) {
957                 /*
958                  * Oh drat, we have to clean up a mess.
959                  *
960                  * We failed to load a shared object that we depend upon.
961                  * So now we have to unload any dependencies that we had
962                  * already successfully loaded prior to the error.
963                  *
964                  * Cleaning up doesn't matter so much for the initial
965                  * loading of the program, since any failure is going to
966                  * terminate the program anyway.  But it is very important
967                  * to clean up properly when something is being loaded
968                  * via dlopen().
969                  */
970                 struct so_list          *solp;
971
972                 while((solp = parpp->spd_children) != NULL) {
973                         unmap_object(solp->sol_map, 0);
974                         parpp->spd_children = solp->sol_next;
975                         free(solp);
976                 }
977
978                 return -1;
979         }
980
981         return 0;
982 }
983
984 /*
985  * Relocate the DAG of shared objects rooted at the given link map
986  * entry.  Returns 0 on success, or -1 on failure.  On failure, an
987  * error message can be retrieved via dlerror().
988  */
989 static int
990 reloc_dag(root, bind_now)
991         struct so_map   *root;
992         int             bind_now;
993 {
994         struct so_map   *smp;
995
996         /*
997          * Relocate all newly-loaded objects.  We avoid recursion for this
998          * step by taking advantage of a few facts.  This function is called
999          * only when there are in fact some newly-loaded objects to process.
1000          * Furthermore, all newly-loaded objects will have their link map
1001          * entries at the end of the link map list.  And, the root of the
1002          * tree of objects just loaded will have been the first to be loaded
1003          * and therefore the first new object in the link map list.  Finally,
1004          * we take advantage of the fact that we can relocate the newly-loaded
1005          * objects in any order.
1006          *
1007          * All these facts conspire to let us simply loop over the tail
1008          * portion of the link map list, relocating each object so
1009          * encountered.
1010          */
1011         for(smp = root;  smp != NULL;  smp = smp->som_next) {
1012                 if(!(LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)) {
1013                         if(reloc_map(smp, bind_now) < 0)
1014                                 return -1;
1015                 }
1016         }
1017
1018         /*
1019          * Copy any relocated initialized data.  Again, we can just loop
1020          * over the appropriate portion of the link map list.
1021          */
1022         for(smp = root;  smp != NULL;  smp = smp->som_next) {
1023                 if(!(LM_PRIVATE(smp)->spd_flags & RTLD_RTLD))
1024                         reloc_copy(smp);
1025         }
1026
1027         return 0;
1028 }
1029
1030 /*
1031  * Remove a reference to the shared object specified by SMP.  If no
1032  * references remain, unmap the object and, recursively, its descendents.
1033  * This function also takes care of calling the finalization routines for
1034  * objects that are removed.
1035  *
1036  * If KEEP is true, then the actual calls to munmap() are skipped,
1037  * and the object is kept in memory.  That is used only for finalization,
1038  * from dlexit(), when the program is exiting.  There are two reasons
1039  * for it.  First, the program is exiting and there is no point in
1040  * spending the time to explicitly unmap its shared objects.  Second,
1041  * even after dlexit() has been called, there are still a couple of
1042  * calls that are made to functions in libc.  (This is really a bug
1043  * in crt0.)  So libc and the main program, at least, must remain
1044  * mapped in that situation.
1045  *
1046  * Under no reasonable circumstances should this function fail.  If
1047  * anything goes wrong, we consider it an internal error, and report
1048  * it with err().
1049  */
1050 static void
1051 unmap_object(smp, keep)
1052         struct so_map   *smp;
1053         int             keep;
1054 {
1055         struct somap_private    *smpp = LM_PRIVATE(smp);
1056
1057         smpp->spd_refcount--;
1058         if(smpp->spd_refcount == 0) {           /* Finished with this object */
1059                 struct so_list  *solp;
1060
1061                 if(smpp->spd_flags & RTLD_INIT) {       /* Was initialized */
1062                         /*
1063                          * Call the object's finalization routine.  For
1064                          * backward compatibility, we first try to call
1065                          * ".fini".  If that does not exist, we call
1066                          * "__fini".
1067                          */
1068                         if(call_map(smp, ".fini") == -1)
1069                                 call_map(smp, "__fini");
1070                 }
1071
1072                 /* Recursively unreference the object's descendents */
1073                 while((solp = smpp->spd_children) != NULL) {
1074                         unmap_object(solp->sol_map, keep);
1075                         smpp->spd_children = solp->sol_next;
1076                         free(solp);
1077                 }
1078
1079                 if(!keep) {     /* Unmap the object from memory */
1080                         if(munmap(smp->som_addr,
1081                         smpp->a_text + smpp->a_data + smpp->a_bss) < 0)
1082                                 err(1, "internal error 1: munmap failed");
1083
1084                         /* Unlink and free the object's link map entry */
1085                         free_link_map(smp);
1086                 }
1087         }
1088 }
1089
1090 static inline int
1091 check_text_reloc(r, smp, addr)
1092 struct relocation_info  *r;
1093 struct so_map           *smp;
1094 caddr_t                 addr;
1095 {
1096         char    *sym;
1097
1098         if (addr >= LM_ETEXT(smp))
1099                 return 0;
1100
1101         if (RELOC_EXTERN_P(r))
1102                 sym = LM_STRINGS(smp) +
1103                                 LM_SYMBOL(smp, RELOC_SYMBOL(r))->nz_strx;
1104         else
1105                 sym = "";
1106
1107         if (!ld_suppress_warnings && ld_warn_non_pure_code)
1108                 warnx("warning: non pure code in %s at %x (%s)",
1109                                 smp->som_path, r->r_address, sym);
1110
1111         if (smp->som_write == 0 &&
1112                 mprotect(smp->som_addr + LM_TXTADDR(smp),
1113                                 LD_TEXTSZ(smp->som_dynamic),
1114                                 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1115                 generror ("mprotect failed for \"%s\" : %s",
1116                           smp->som_path, strerror (errno));
1117                 return -1;
1118         }
1119
1120         smp->som_write = 1;
1121         return 0;
1122 }
1123
1124 static int
1125 reloc_map(smp, bind_now)
1126         struct so_map           *smp;
1127         int                     bind_now;
1128 {
1129         /*
1130          * Caching structure for reducing the number of calls to
1131          * lookup() during relocation.
1132          *
1133          * While relocating a given shared object, the dynamic linker
1134          * maintains a caching vector that is directly indexed by
1135          * the symbol number in the relocation entry.  The first time
1136          * a given symbol is looked up, the caching vector is
1137          * filled in with a pointer to the symbol table entry, and
1138          * a pointer to the so_map of the shared object in which the
1139          * symbol was defined.  On subsequent uses of the same symbol,
1140          * that information is retrieved directly from the caching
1141          * vector, without calling lookup() again.
1142          *
1143          * A symbol that is referenced in a relocation entry is
1144          * typically referenced in many relocation entries, so this
1145          * caching reduces the number of calls to lookup()
1146          * dramatically.  The overall improvement in the speed of
1147          * dynamic linking is also dramatic -- as much as a factor
1148          * of three for programs that use many shared libaries.
1149          */
1150         struct cacheent {
1151                 struct nzlist *np;      /* Pointer to symbol entry */
1152                 struct so_map *src_map; /* Shared object that defined symbol */
1153         };
1154
1155         struct _dynamic         *dp = smp->som_dynamic;
1156         struct relocation_info  *r = LM_REL(smp);
1157         struct relocation_info  *rend = r + LD_RELSZ(dp)/sizeof(*r);
1158         long                    symbolbase = (long)LM_SYMBOL(smp, 0);
1159         char                    *stringbase = LM_STRINGS(smp);
1160         int symsize             = LD_VERSION_NZLIST_P(dp->d_version) ?
1161                                         sizeof(struct nzlist) :
1162                                         sizeof(struct nlist);
1163         long                    numsyms = LD_STABSZ(dp) / symsize;
1164         size_t                  cachebytes = numsyms * sizeof(struct cacheent);
1165         struct cacheent         *symcache =
1166                                         (struct cacheent *) alloca(cachebytes);
1167
1168         if(symcache == NULL) {
1169                 generror("Cannot allocate symbol caching vector for %s",
1170                         smp->som_path);
1171                 return -1;
1172         }
1173         bzero(symcache, cachebytes);
1174
1175         if (LD_PLTSZ(dp))
1176                 md_fix_jmpslot(LM_PLT(smp),
1177                                 (long)LM_PLT(smp), (long)binder_entry);
1178
1179         for (; r < rend; r++) {
1180                 char    *sym;
1181                 caddr_t addr;
1182
1183                 /*
1184                  * Objects linked with "-Bsymbolic" can end up having unused
1185                  * relocation entries at the end.  These can be detected by
1186                  * the fact that they have an address of 0.
1187                  */
1188                 if(r->r_address == 0)   /* Finished relocating this object */
1189                         break;
1190
1191                 addr = smp->som_addr + r->r_address;
1192                 if (check_text_reloc(r, smp, addr) < 0)
1193                         return -1;
1194
1195                 if (RELOC_EXTERN_P(r)) {
1196                         struct so_map   *src_map = NULL;
1197                         struct nzlist   *p, *np;
1198                         long    relocation;
1199
1200                         if (RELOC_JMPTAB_P(r) && !bind_now)
1201                                 continue;
1202
1203                         p = (struct nzlist *)
1204                                 (symbolbase + symsize * RELOC_SYMBOL(r));
1205
1206                         if (p->nz_type == (N_SETV + N_EXT))
1207                                 src_map = smp;
1208
1209                         sym = stringbase + p->nz_strx;
1210
1211                         /*
1212                          * Look up the symbol, checking the caching
1213                          * vector first.
1214                          */
1215                         np = symcache[RELOC_SYMBOL(r)].np;
1216                         if(np != NULL)  /* Symbol already cached */
1217                                 src_map = symcache[RELOC_SYMBOL(r)].src_map;
1218                         else {  /* Symbol not cached yet */
1219                                 np = lookup(sym, &src_map, RELOC_JMPTAB_P(r));
1220                                 /*
1221                                  * Record the needed information about
1222                                  * the symbol in the caching vector,
1223                                  * so that we won't have to call
1224                                  * lookup the next time we encounter
1225                                  * the symbol.
1226                                  */
1227                                 symcache[RELOC_SYMBOL(r)].np = np;
1228                                 symcache[RELOC_SYMBOL(r)].src_map = src_map;
1229                         }
1230
1231                         if (np == NULL) {
1232                                 generror ("Undefined symbol \"%s\" in %s:%s",
1233                                         sym, main_progname, smp->som_path);
1234                                 return -1;
1235                         }
1236
1237                         /*
1238                          * Found symbol definition.
1239                          * If it's in a link map, adjust value
1240                          * according to the load address of that map.
1241                          * Otherwise it's a run-time allocated common
1242                          * whose value is already up-to-date.
1243                          */
1244                         relocation = np->nz_value;
1245                         if (src_map)
1246                                 relocation += (long)src_map->som_addr;
1247
1248                         if (RELOC_JMPTAB_P(r)) {
1249                                 md_bind_jmpslot(relocation, addr);
1250                                 continue;
1251                         }
1252
1253                         relocation += md_get_addend(r, addr);
1254
1255                         if (RELOC_PCREL_P(r))
1256                                 relocation -= (long)smp->som_addr;
1257
1258                         if (RELOC_COPY_P(r) && src_map) {
1259                                 (void)enter_rts(sym, sym_hash(sym),
1260                                         (long)addr,
1261                                         N_DATA + N_EXT,
1262                                         src_map->som_addr + np->nz_value,
1263                                         np->nz_size, src_map);
1264                                 continue;
1265                         }
1266
1267                         md_relocate(r, relocation, addr, 0);
1268                 } else {
1269                         md_relocate(r,
1270 #ifdef SUN_COMPAT
1271                                 md_get_rt_segment_addend(r, addr)
1272 #else
1273                                 md_get_addend(r, addr)
1274 #endif
1275                                         + (long)smp->som_addr, addr, 0);
1276                 }
1277
1278         }
1279
1280         if (smp->som_write) {
1281                 if (mprotect(smp->som_addr + LM_TXTADDR(smp),
1282                                 LD_TEXTSZ(smp->som_dynamic),
1283                                 PROT_READ|PROT_EXEC) == -1) {
1284                         generror ("mprotect failed for \"%s\" : %s",
1285                                   smp->som_path, strerror (errno));
1286                         return -1;
1287                 }
1288                 smp->som_write = 0;
1289         }
1290         return 0;
1291 }
1292
1293 static void
1294 reloc_copy(smp)
1295         struct so_map           *smp;
1296 {
1297         struct rt_symbol        *rtsp;
1298
1299         for (rtsp = rt_symbol_head; rtsp; rtsp = rtsp->rt_next)
1300                 if ((rtsp->rt_smp == NULL || rtsp->rt_smp == smp) &&
1301                                 rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
1302                         bcopy(rtsp->rt_srcaddr, (caddr_t)rtsp->rt_sp->nz_value,
1303                                                         rtsp->rt_sp->nz_size);
1304                 }
1305 }
1306
1307 /*
1308  * Initialize the DAG of shared objects rooted at the given object.
1309  */
1310 static void
1311 init_dag(smp)
1312         struct so_map           *smp;
1313 {
1314         struct somap_private    *smpp = LM_PRIVATE(smp);
1315
1316         if(!(smpp->spd_flags & RTLD_INIT)) {    /* Not initialized yet */
1317                 smpp->spd_flags |= RTLD_INIT;
1318
1319                 /* Make sure all the children are initialized */
1320                 if(smpp->spd_children != NULL)
1321                         init_sods(smpp->spd_children);
1322
1323                 if(call_map(smp, ".init") == -1)
1324                         call_map(smp, "__init");
1325         }
1326 }
1327
1328 static void
1329 init_sods(solp)
1330         struct so_list  *solp;
1331 {
1332         /* Recursively initialize the rest of the list */
1333         if(solp->sol_next != NULL)
1334                 init_sods(solp->sol_next);
1335
1336         /* Initialize the first element of the list */
1337         init_dag(solp->sol_map);
1338 }
1339
1340
1341 /*
1342  * Call a function in a given shared object.  SMP is the shared object, and
1343  * SYM is the name of the function.
1344  *
1345  * Returns 0 on success, or -1 if the symbol was not found.  Failure is not
1346  * necessarily an error condition, so no error message is generated.
1347  */
1348 static int
1349 call_map(smp, sym)
1350         struct so_map           *smp;
1351         char                    *sym;
1352 {
1353         struct so_map           *src_map = smp;
1354         struct nzlist           *np;
1355
1356         np = lookup(sym, &src_map, 1);
1357         if (np) {
1358                 (*(void (*)())(src_map->som_addr + np->nz_value))();
1359                 return 0;
1360         }
1361
1362         return -1;
1363 }
1364
1365 /*
1366  * Run-time common symbol table.
1367  */
1368
1369 #define RTC_TABSIZE             57
1370 static struct rt_symbol         *rt_symtab[RTC_TABSIZE];
1371
1372 /*
1373  * Look up a symbol in the run-time common symbol table.  For efficiency,
1374  * the symbol's hash value must be passed in too.
1375  */
1376 static inline struct rt_symbol *
1377 lookup_rts(name, hash)
1378         char            *name;
1379         unsigned long    hash;
1380 {
1381         register struct rt_symbol       *rtsp;
1382
1383         for (rtsp = rt_symtab[hash % RTC_TABSIZE]; rtsp; rtsp = rtsp->rt_link)
1384                 if (strcmp(name, rtsp->rt_sp->nz_name) == 0)
1385                         return rtsp;
1386
1387         return NULL;
1388 }
1389
1390 /*
1391  * Enter a symbol into the run-time common symbol table.  For efficiency,
1392  * the symbol's hash value must be passed in too.
1393  */
1394 static struct rt_symbol *
1395 enter_rts(name, hash, value, type, srcaddr, size, smp)
1396         char            *name;
1397         unsigned long    hash;
1398         long             value;
1399         int              type;
1400         caddr_t          srcaddr;
1401         long             size;
1402         struct so_map   *smp;
1403 {
1404         register struct rt_symbol       *rtsp, **rpp;
1405
1406         /* Find end of bucket */
1407         for (rpp = &rt_symtab[hash % RTC_TABSIZE]; *rpp; rpp = &(*rpp)->rt_link)
1408                 continue;
1409
1410         /* Allocate new common symbol */
1411         rtsp = (struct rt_symbol *)xmalloc(sizeof(struct rt_symbol));
1412         rtsp->rt_sp = (struct nzlist *)xmalloc(sizeof(struct nzlist));
1413         rtsp->rt_sp->nz_name = strdup(name);
1414         rtsp->rt_sp->nz_value = value;
1415         rtsp->rt_sp->nz_type = type;
1416         rtsp->rt_sp->nz_size = size;
1417         rtsp->rt_srcaddr = srcaddr;
1418         rtsp->rt_smp = smp;
1419         rtsp->rt_link = NULL;
1420
1421         /* Link onto linear list as well */
1422         rtsp->rt_next = rt_symbol_head;
1423         rt_symbol_head = rtsp;
1424
1425         *rpp = rtsp;
1426
1427         return rtsp;
1428 }
1429
1430
1431 /*
1432  * Lookup NAME in the link maps. The link map producing a definition
1433  * is returned in SRC_MAP. If SRC_MAP is not NULL on entry the search
1434  * is confined to that map.
1435  *
1436  * REAL_DEF_ONLY is a boolean which specifies whether certain special
1437  * symbols for functions should satisfy the lookup or not.  The
1438  * reasons behind it are somewhat complicated.  They are motivated
1439  * by the scenario in which the address of a single function is
1440  * taken from several shared objects.  The address should come out
1441  * the same in all cases, because the application code might decide
1442  * to use it in comparisons.  To make this work, the linker creates
1443  * a symbol entry for the function in the main executable, with a
1444  * type of N_UNDF+N_EXT, an N_AUX of AUX_FUNC, and a value that
1445  * refers to the PLT entry for the function in the main executable.
1446  * If REAL_DEF_ONLY is false, then this kind of special symbol is
1447  * considered a "definition" when lookup up the symbol.  Since the
1448  * main executable is at the beginning of the shared object search
1449  * list, the result is that references from all shared objects will
1450  * resolve to the main program's PLT entry, and thus the function
1451  * addresses will compare equal as they should.
1452  *
1453  * When relocating the PLT entry itself, we obviously must match
1454  * only the true defining symbol for the function.  In that case, we
1455  * set REAL_DEF_ONLY to true, which disables matching the special
1456  * N_UNDF+N_EXT entries.
1457  *
1458  * It is not so clear how to set this flag for a lookup done from
1459  * dlsym.  If the lookup specifies a particular shared object other
1460  * than the main executable, the flag makes no difference -- only the
1461  * true definition will be matched.  (That is because the special
1462  * symbols are only present in the main executable, which will not
1463  * be searched.)  But when the lookup is over all the shared objects
1464  * (i.e., dlsym's "fd" parameter is NULL), then the flag does have an
1465  * effect.  We elect to match only the true definition even in that
1466  * case.
1467  *
1468  * The upshot of all this is the following rule of thumb: Set
1469  * REAL_DEF_ONLY in all cases except when processing a non-PLT
1470  * relocation.
1471  */
1472 static struct nzlist *
1473 lookup(name, src_map, real_def_only)
1474         char            *name;
1475         struct so_map   **src_map;      /* IN/OUT */
1476         int             real_def_only;
1477 {
1478         unsigned long            hash;
1479
1480         hash = sym_hash(name);
1481
1482         if (*src_map != NULL)   /* Look in just one specific object */
1483                 return lookup_in_obj(name, hash, *src_map, real_def_only);
1484         else {  /* Search runtime symbols and all loaded objects */
1485                 unsigned long            common_size;
1486                 struct so_map           *smp;
1487                 struct rt_symbol        *rtsp;
1488                 struct nzlist           *np;
1489
1490                 if ((rtsp = lookup_rts(name, hash)) != NULL)
1491                         return rtsp->rt_sp;
1492
1493                 common_size = 0;
1494                 for (smp = link_map_head; smp; smp = smp->som_next) {
1495                         if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
1496                                 continue;
1497                         np = lookup_in_obj(name, hash, smp, real_def_only);
1498                         if (np == NULL)
1499                                 continue;
1500                         /* We know that np->nz_value > 0 at this point. */
1501                         if (np->nz_type == N_UNDF+N_EXT &&
1502                             N_AUX(&np->nlist) != AUX_FUNC) {    /* Common */
1503                                 if (common_size < np->nz_value)
1504                                         common_size = np->nz_value;
1505                                 continue;
1506                         }
1507
1508                         /* We found the symbol definition. */
1509                         *src_map = smp;
1510                         return np;
1511                 }
1512                 if (common_size > 0) {  /* It is a common symbol. */
1513                         void    *mem;
1514
1515                         mem = memset(xmalloc(common_size), 0, common_size);
1516                         rtsp = enter_rts(name, hash, (long)mem, N_UNDF + N_EXT,
1517                             0, common_size, NULL);
1518                         return rtsp->rt_sp;
1519                 }
1520
1521                 /*
1522                  * Just before giving up, check for the __error() hack.
1523                  */
1524                 np = lookup_errno_hack(name, src_map, real_def_only);
1525                 if (np != NULL)
1526                         return np;
1527
1528                 /* No definition was found for the symbol. */
1529                 return NULL;
1530         }
1531 }
1532
1533 /*
1534  * Lookup a symbol in one specific shared object.  The hash
1535  * value is passed in for efficiency.  For an explanation of the
1536  * "real_def_only" flag, see the comment preceding the "lookup"
1537  * function.
1538  */
1539 static struct nzlist *
1540 lookup_in_obj(name, hash, smp, real_def_only)
1541         char            *name;
1542         unsigned long    hash;
1543         struct so_map   *smp;
1544         int              real_def_only;
1545 {
1546         unsigned long    buckets;
1547         struct rrs_hash *hp;
1548         char            *cp;
1549         struct nzlist   *np;
1550         char            *symbolbase;
1551         struct rrs_hash *hashbase;
1552         char            *stringbase;
1553         size_t          symsize;
1554
1555         if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
1556                 return NULL;
1557
1558         hashbase = LM_HASH(smp);
1559
1560 restart:
1561         hp = &hashbase[hash % buckets];
1562         if (hp->rh_symbolnum == -1)
1563                 return NULL;
1564
1565         symbolbase = (char *)LM_SYMBOL(smp, 0);
1566         stringbase = LM_STRINGS(smp);
1567         symsize = LD_VERSION_NZLIST_P(smp->som_dynamic->d_version)?
1568             sizeof(struct nzlist) : sizeof(struct nlist);
1569         for ( ; ; ) {
1570                 np = (struct nzlist *)(symbolbase + hp->rh_symbolnum*symsize);
1571                 cp = stringbase + np->nz_strx;
1572                 if (strcmp(cp, name) == 0)
1573                         break;
1574                 if (hp->rh_next == 0)   /* End of hash chain */
1575                         return NULL;
1576                 hp = hashbase + hp->rh_next;
1577         }
1578
1579         /*
1580          * We have a symbol with the name we're looking for.
1581          */
1582         if (np->nz_type == N_INDR+N_EXT) {
1583                 /*
1584                  * Next symbol gives the aliased name. Restart
1585                  * search with new name.
1586                  */
1587                 name = stringbase + (++np)->nz_strx;
1588                 hash = sym_hash(name);
1589                 goto restart;
1590         }
1591
1592         if (np->nz_value == 0)  /* It's not a definition */
1593                 return NULL;
1594
1595         if (real_def_only)      /* Don't match special function symbols. */
1596                 if (np->nz_type == N_UNDF+N_EXT &&
1597                     N_AUX(&np->nlist) == AUX_FUNC)
1598                         return NULL;
1599
1600         return np;
1601 }
1602
1603 /*
1604  * Return the value of a symbol in the user's program.  This is used
1605  * internally for a few symbols which must exist.  If the requested
1606  * symbol is not found, this simply exits with a fatal error.
1607  */
1608 static void *
1609 sym_addr(name)
1610         char            *name;
1611 {
1612         struct so_map   *smp;
1613         struct nzlist   *np;
1614
1615         smp = NULL;
1616         np = lookup(name, &smp, 1);
1617         if (np == NULL)
1618                 errx(1, "Program has no symbol \"%s\"", name);
1619         return ((smp == NULL) ? NULL : smp->som_addr) + np->nz_value;
1620 }
1621
1622
1623 static int *p_errno;    /* Pointer to errno variable in main program. */
1624
1625 /*
1626  * Help old a.out binaries that are broken by the new errno macro.  They
1627  * can be missing __error() through no fault of their own.  In particular,
1628  * old a.out binaries can link against an old libc that does not contain
1629  * __error(), yet still require __error() because of other libraries that
1630  * have been recompiled since the errno change.  This locates the backward
1631  * compatible work-alike we have hidden here in ld.so.
1632  */
1633 static struct nzlist *
1634 lookup_errno_hack(sym, src_map, real_def_only)
1635         char            *sym;
1636         struct so_map   **src_map;
1637         int              real_def_only;
1638 {
1639         struct so_map   *smp;
1640         struct nzlist   *np;
1641
1642         if (strcmp(sym, "___error") != 0)
1643                 return NULL;
1644
1645         /*
1646          * Locate errno in the main program.  If it's not there, NULL
1647          * will be returned by our __error() substitute, and a core dump
1648          * will follow.  That's impossible, of course, since crt0.o always
1649          * supplies errno.
1650          */
1651         smp = NULL;
1652         np = lookup("_errno", &smp, 1);
1653         if (np != NULL && smp != NULL) {
1654                 p_errno = (int *)(smp->som_addr + np->nz_value);
1655 #ifdef DEBUG
1656                 xprintf(" HACK: _errno at %p in %s\n", p_errno, smp->som_path);
1657 #endif
1658         }
1659
1660         /*
1661          * Specifically find the ld.so link map because most routines
1662          * skip over it during normal operation.
1663          */
1664         for (smp = link_map_head; ; smp = smp->som_next)
1665                 if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
1666                         break;
1667
1668         /*
1669          * Find our __error() substitute stashed here in ld.so.
1670          */
1671         np = lookup("___error_unthreaded_hack", &smp, real_def_only);
1672         if (np != NULL)
1673                 *src_map = smp;
1674
1675 #ifdef DEBUG
1676         if (np == NULL)
1677                 xprintf(" HACK: %s fudge not found, oops\n", sym);
1678         else
1679                 xprintf(" HACK: %s fudge in %s\n", sym, smp->som_path);
1680 #endif
1681
1682         return np;
1683 }
1684
1685
1686 /*
1687  * Just like __error_unthreaded(), but for those poor orphaned a.out
1688  * binaries from way back that are bamboozled by the new errno macro.
1689  */
1690 int *
1691 __error_unthreaded_hack()
1692 {
1693         return p_errno;
1694 }
1695
1696
1697 /*
1698  * This routine is called from the jumptable to resolve
1699  * procedure calls to shared objects.
1700  */
1701 long
1702 binder(jsp)
1703         jmpslot_t       *jsp;
1704 {
1705         struct so_map   *smp, *src_map = NULL;
1706         long            addr;
1707         char            *sym;
1708         struct nzlist   *np;
1709         int             index;
1710
1711         /*
1712          * Find the PLT map that contains JSP.
1713          */
1714         for (smp = link_map_head; smp; smp = smp->som_next) {
1715                 if (LM_PLT(smp) < jsp &&
1716                         jsp < LM_PLT(smp) + LD_PLTSZ(smp->som_dynamic)/sizeof(*jsp))
1717                         break;
1718         }
1719
1720         if (smp == NULL)
1721                 errx(1, "Call to binder from unknown location: %p\n", jsp);
1722
1723         index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
1724
1725         /* Get the local symbol this jmpslot refers to */
1726         sym = LM_STRINGS(smp) +
1727                 LM_SYMBOL(smp,RELOC_SYMBOL(&LM_REL(smp)[index]))->nz_strx;
1728
1729         np = lookup(sym, &src_map, 1);
1730         if (np == NULL)
1731                 errx(1, "Undefined symbol \"%s\" called from %s:%s at %p",
1732                                 sym, main_progname, smp->som_path, jsp);
1733
1734         /* Fixup jmpslot so future calls transfer directly to target */
1735         addr = np->nz_value;
1736         if (src_map)
1737                 addr += (long)src_map->som_addr;
1738
1739         md_fix_jmpslot(jsp, (long)jsp, addr);
1740
1741 #if DEBUG
1742         xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr,
1743                 src_map->som_path);
1744 #endif
1745         return addr;
1746 }
1747
1748 static struct hints_header      *hheader;       /* NULL means not mapped */
1749 static struct hints_bucket      *hbuckets;
1750 static char                     *hstrtab;
1751
1752 /*
1753  * Map the hints file into memory, if it is not already mapped.  Returns
1754  * 0 on success, or -1 on failure.
1755  */
1756 static int
1757 maphints (void)
1758 {
1759         static int              hints_bad;      /* TRUE if hints are unusable */
1760         static int              paths_added;
1761         int                     hfd;
1762         struct hints_header     hdr;
1763         caddr_t                 addr;
1764
1765         if (hheader != NULL)    /* Already mapped */
1766                 return 0;
1767
1768         if (hints_bad)          /* Known to be corrupt or unavailable */
1769                 return -1;
1770
1771         if ((hfd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
1772                 hints_bad = 1;
1773                 return -1;
1774         }
1775
1776         /* Read the header and check it */
1777
1778         if (read(hfd, &hdr, sizeof hdr) != sizeof hdr ||
1779             HH_BADMAG(hdr) ||
1780             (hdr.hh_version != LD_HINTS_VERSION_1 &&
1781              hdr.hh_version != LD_HINTS_VERSION_2)) {
1782                 close(hfd);
1783                 hints_bad = 1;
1784                 return -1;
1785         }
1786
1787         /* Map the hints into memory */
1788
1789         addr = mmap(0, hdr.hh_ehints, PROT_READ, MAP_SHARED, hfd, 0);
1790         if (addr == (caddr_t)-1) {
1791                 close(hfd);
1792                 hints_bad = 1;
1793                 return -1;
1794         }
1795
1796         close(hfd);
1797
1798         hheader = (struct hints_header *)addr;
1799         hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab);
1800         hstrtab = (char *)(addr + hheader->hh_strtab);
1801         /* pluck out the system ldconfig path */
1802         if (hheader->hh_version >= LD_HINTS_VERSION_2 && !paths_added) {
1803                 add_search_path(hstrtab + hheader->hh_dirlist);
1804                 paths_added = 1;
1805         }
1806
1807         return 0;
1808 }
1809
1810 /*
1811  * Unmap the hints file, if it is currently mapped.
1812  */
1813 static void
1814 unmaphints()
1815 {
1816         if (hheader != NULL) {
1817                 munmap((caddr_t)hheader, hheader->hh_ehints);
1818                 hheader = NULL;
1819         }
1820 }
1821
1822 int
1823 hinthash(cp, vmajor)
1824         char    *cp;
1825         int     vmajor;
1826 {
1827         int     k = 0;
1828
1829         while (*cp)
1830                 k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
1831
1832         k = (((k << 1) + (k >> 14)) ^ (vmajor*257)) & 0x3fff;
1833
1834         return k;
1835 }
1836
1837 #undef major
1838 #undef minor
1839
1840 /*
1841  * Search for a library in the hints generated by ldconfig.  On success,
1842  * returns the full pathname of the matching library.  This string is
1843  * always dynamically allocated on the heap.
1844  *
1845  * MINORP is an in/out parameter.  If the incoming value of *MINORP is
1846  * >= 0, then no library will be considered a match unless its minor
1847  * version number is at least that large.  Otherwise, only the major
1848  * version number is checked.  In any case, the minor number of the
1849  * matching library is stored into *MINORP.
1850  *
1851  * Returns NULL if the library cannot be found.
1852  */
1853 static char *
1854 findhint(name, major, minorp)
1855         char    *name;
1856         int     major;
1857         int     *minorp;
1858 {
1859         struct hints_bucket     *bp =
1860                 hbuckets + (hinthash(name, major) % hheader->hh_nbucket);
1861
1862         while (1) {
1863                 /* Sanity check */
1864                 if (bp->hi_namex >= hheader->hh_strtab_sz) {
1865                         warnx("Bad name index: %#x\n", bp->hi_namex);
1866                         break;
1867                 }
1868                 if (bp->hi_pathx >= hheader->hh_strtab_sz) {
1869                         warnx("Bad path index: %#x\n", bp->hi_pathx);
1870                         break;
1871                 }
1872                 /*
1873                  * For a given major number, the hints file has only one
1874                  * entry -- namely, the one with the highest minor number.
1875                  * If we find an entry with a matching major number, we
1876                  * know it is the best one.
1877                  */
1878                 if (strcmp(name, hstrtab + bp->hi_namex) == 0 &&
1879                     bp->hi_major == major) {
1880                         struct stat s;
1881                         int realminor;
1882
1883                         realminor = bp->hi_ndewey >= 2 ? bp->hi_minor : 0;
1884                         if (realminor < *minorp)        /* Not good enough */
1885                                 return NULL;
1886                         if (stat(hstrtab + bp->hi_pathx, &s) == -1)
1887                                 return NULL;  /* Doesn't actually exist */
1888                         *minorp = realminor;
1889                         return strdup(hstrtab + bp->hi_pathx);
1890                 }
1891
1892                 if (bp->hi_next == -1)
1893                         break;
1894
1895                 /* Move on to next in bucket */
1896                 bp = &hbuckets[bp->hi_next];
1897         }
1898
1899         /* No hints available for name */
1900         return NULL;
1901 }
1902
1903 /*
1904  * Search for the given shared library.  On success, returns a string
1905  * containing the full pathname for the library.  This string is always
1906  * dynamically allocated on the heap.
1907  *
1908  * Returns NULL if the library cannot be found.
1909  */
1910 static char *
1911 rtfindlib(name, major, minor, strictminor)
1912         char    *name;
1913         int     major, minor;
1914         int     strictminor;
1915 {
1916         char    *ld_path = ld_library_path;
1917         char    *path = NULL;
1918         int     realminor;
1919
1920         realminor = strictminor ? minor : -1;
1921         if (ld_path != NULL) {  /* First, search the directories in ld_path */
1922                 /*
1923                  * There is no point in trying to use the hints file for this.
1924                  */
1925                 char    *dir;
1926
1927                 while (path == NULL && (dir = strsep(&ld_path, ":")) != NULL) {
1928                         path = search_lib_dir(dir, name, &major, &realminor, 0);
1929                         if (ld_path != NULL)
1930                                 *(ld_path - 1) = ':';
1931                 }
1932         }
1933
1934         if (path == NULL && maphints() == 0)    /* Search the hints file */
1935                 path = findhint(name, major, &realminor);
1936
1937         if (path == NULL)       /* Search the standard directories */
1938                 path = findshlib(name, &major, &realminor, 0);
1939
1940         if (path != NULL && realminor < minor && !ld_suppress_warnings) {
1941                 warnx("warning: %s: minor version %d"
1942                       " older than expected %d, using it anyway",
1943                       path, realminor, minor);
1944         }
1945
1946         return path;
1947 }
1948
1949 /*
1950  * Search for the given shared library file.  This is similar to rtfindlib,
1951  * except that the argument is the actual name of the desired library file.
1952  * Thus there is no need to worry about version numbers.  The return value
1953  * is a string containing the full pathname for the library.  This string
1954  * is always dynamically allocated on the heap.
1955  *
1956  * Returns NULL if the library cannot be found.
1957  */
1958 static char *
1959 rtfindfile(name)
1960         const char      *name;
1961 {
1962         char    *ld_path = ld_library_path;
1963         char    *path = NULL;
1964
1965         if (ld_path != NULL) {  /* First, search the directories in ld_path */
1966                 char    *dir;
1967
1968                 while (path == NULL && (dir = strsep(&ld_path, ":")) != NULL) {
1969                         struct stat     sb;
1970
1971                         path = concat(dir, "/", name);
1972                         if (lstat(path, &sb) == -1) {   /* Does not exist */
1973                                 free(path);
1974                                 path = NULL;
1975                         }
1976                         if (ld_path != NULL)
1977                                 *(ld_path - 1) = ':';
1978                 }
1979         }
1980
1981         /*
1982          * We don't search the hints file.  It is organized around major
1983          * and minor version numbers, so it is not suitable for finding
1984          * a specific file name.
1985          */
1986
1987         if (path == NULL)       /* Search the standard directories */
1988                 path = find_lib_file(name);
1989
1990         return path;
1991 }
1992
1993 /*
1994  * Buffer for error messages and a pointer that is set to point to the buffer
1995  * when a error occurs.  It acts as a last error flag, being set to NULL
1996  * after an error is returned.
1997  */
1998 #define DLERROR_BUF_SIZE 512
1999 static char  dlerror_buf [DLERROR_BUF_SIZE];
2000 static char *dlerror_msg = NULL;
2001
2002
2003 static void *
2004 __dlopen(path, mode)
2005         const char      *path;
2006         int              mode;
2007 {
2008         struct so_map   *old_tail = link_map_tail;
2009         struct so_map   *smp;
2010         int             bind_now = mode == RTLD_NOW;
2011         char            *name;
2012
2013         /*
2014          * path == NULL is handled by map_object()
2015          */
2016
2017         anon_open();
2018
2019         name = (path && strchr(path, '/') == NULL) ? rtfindfile(path) : (char *)path;
2020
2021         /* Map the object, and the objects on which it depends */
2022         smp = map_object(name, (struct sod *) NULL, (struct so_map *) NULL);
2023         if (name != path)
2024                 free(name);
2025         if(smp == NULL)         /* Failed */
2026                 return NULL;
2027         LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
2028
2029         /* Relocate and initialize all newly-mapped objects */
2030         if(link_map_tail != old_tail) {  /* We have mapped some new objects */
2031                 if(reloc_dag(smp, bind_now) == -1)      /* Failed */
2032                         return NULL;
2033                 init_dag(smp);
2034         }
2035
2036         unmaphints();
2037         anon_close();
2038
2039         return smp;
2040 }
2041
2042 static int
2043 __dlclose(fd)
2044         void    *fd;
2045 {
2046         struct so_map   *smp = (struct so_map *)fd;
2047         struct so_map   *scanp;
2048
2049 #ifdef DEBUG
2050         xprintf("dlclose(%s): refcount = %d\n", smp->som_path,
2051                 LM_PRIVATE(smp)->spd_refcount);
2052 #endif
2053         /* Check the argument for validity */
2054         for(scanp = link_map_head;  scanp != NULL;  scanp = scanp->som_next)
2055                 if(scanp == smp)        /* We found the map in the list */
2056                         break;
2057         if(scanp == NULL || !(LM_PRIVATE(smp)->spd_flags & RTLD_DL)) {
2058                 generror("Invalid argument to dlclose");
2059                 return -1;
2060         }
2061
2062         unmap_object(smp, 0);
2063
2064         return 0;
2065 }
2066
2067 /*
2068  * This form of dlsym is obsolete.  Current versions of crt0 don't call
2069  * it.  It can still be called by old executables that were linked with
2070  * old versions of crt0.
2071  */
2072 static void *
2073 __dlsym(fd, sym)
2074         void            *fd;
2075         const char      *sym;
2076 {
2077         if (fd == RTLD_NEXT) {
2078                 generror("RTLD_NEXT not supported by this version of"
2079                     " crt0.o");
2080                 return NULL;
2081         }
2082         return __dlsym3(fd, sym, NULL);
2083 }
2084
2085 static void *
2086 resolvesym(fd, sym, retaddr)
2087         void    *fd;
2088         char    *sym;
2089         void    *retaddr;
2090 {
2091         struct so_map   *smp;
2092         struct so_map   *src_map;
2093         struct nzlist   *np;
2094         long            addr;
2095
2096         if (fd == RTLD_NEXT) {
2097                 /* Find the shared object that contains the caller. */
2098                 for (smp = link_map_head;  smp != NULL;  smp = smp->som_next) {
2099                         void *textbase = smp->som_addr + LM_TXTADDR(smp);
2100                         void *textlimit = LM_ETEXT(smp);
2101
2102                         if (textbase <= retaddr && retaddr < textlimit)
2103                                 break;
2104                 }
2105                 if (smp == NULL) {
2106                         generror("Cannot determine caller's shared object");
2107                         return NULL;
2108                 }
2109                 smp = smp->som_next;
2110                 if (smp != NULL && LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
2111                         smp = smp->som_next;
2112                 if (smp == NULL) {
2113                         generror("No next shared object for RTLD_NEXT");
2114                         return NULL;
2115                 }
2116                 do {
2117                         src_map = smp;
2118                         np = lookup(sym, &src_map, 1);
2119                 } while (np == NULL && (smp = smp->som_next) != NULL);
2120         } else {
2121                 smp = (struct so_map *)fd;
2122                 src_map = NULL;
2123
2124                 /*
2125                  * Restrict search to passed map if dlopen()ed.
2126                  */
2127                 if (smp != NULL && LM_PRIVATE(smp)->spd_flags & RTLD_DL)
2128                         src_map = smp;
2129
2130                 np = lookup(sym, &src_map, 1);
2131         }
2132
2133         if (np == NULL) {
2134                 generror("Undefined symbol");
2135                 return NULL;
2136         }
2137
2138         addr = np->nz_value;
2139         if (src_map)
2140                 addr += (long)src_map->som_addr;
2141
2142         return (void *)addr;
2143 }
2144
2145 static int
2146 __dladdr(addr, dlip)
2147         const void      *addr;
2148         Dl_info         *dlip;
2149 {
2150         struct _dynamic *dp;
2151         struct so_map   *smp;
2152         char            *stringbase;
2153         long             numsyms;
2154         int              symsize;
2155         int              i;
2156
2157         /* Find the shared object that contains the address. */
2158         for (smp = link_map_head;  smp != NULL;  smp = smp->som_next) {
2159                 struct so_map           *src_map;
2160                 struct somap_private    *smpp;
2161                 struct nzlist           *np;
2162
2163                 smpp = LM_PRIVATE(smp);
2164                 if (smpp->spd_flags & RTLD_RTLD)
2165                         continue;
2166
2167                 if ((void *)smp->som_addr > addr)
2168                         continue;
2169
2170                 src_map = smp;
2171                 if ((np = lookup(END_SYM, &src_map, 1)) == NULL)
2172                         continue;       /* No "_end" symbol?! */
2173                 if (addr < (void *)(smp->som_addr + np->nz_value))
2174                         break;
2175         }
2176         if (smp == NULL) {
2177                 generror("No shared object contains address");
2178                 return 0;
2179         }
2180         dlip->dli_fname = smp->som_path;
2181         dlip->dli_fbase = smp->som_addr;
2182         dlip->dli_saddr = (void *) 0;
2183         dlip->dli_sname = NULL;
2184
2185         dp = smp->som_dynamic;
2186         symsize = LD_VERSION_NZLIST_P(dp->d_version) ?
2187             sizeof(struct nzlist) : sizeof(struct nlist);
2188         numsyms = LD_STABSZ(dp) / symsize;
2189         stringbase = LM_STRINGS(smp);
2190
2191         for (i = 0;  i < numsyms;  i++) {
2192                 struct nzlist   *symp = LM_SYMBOL(smp, i);
2193                 unsigned long    value;
2194
2195                 /* Reject all except definitions. */
2196                 if (symp->nz_type != N_EXT + N_ABS &&
2197                     symp->nz_type != N_EXT + N_TEXT &&
2198                     symp->nz_type != N_EXT + N_DATA &&
2199                     symp->nz_type != N_EXT + N_BSS)
2200                         continue;
2201
2202                 /*
2203                  * If the symbol is greater than the specified address, or
2204                  * if it is further away from addr than the current nearest
2205                  * symbol, then reject it.
2206                  */
2207                 value = (unsigned long) (smp->som_addr + symp->nz_value);
2208                 if (value > (unsigned long) addr ||
2209                     value < (unsigned long) dlip->dli_saddr)
2210                         continue;
2211
2212                 /* Update our idea of the nearest symbol. */
2213                 dlip->dli_sname = stringbase + symp->nz_strx;
2214                 dlip->dli_saddr = (void *) value;
2215
2216                 if (dlip->dli_saddr == addr)    /* Can't get any closer. */
2217                     break;
2218         }
2219         /*
2220          * Remove any leading underscore from the symbol name, to hide
2221          * our a.out-ness.
2222          */
2223         if (dlip->dli_sname != NULL && dlip->dli_sname[0] == '_')
2224                 dlip->dli_sname++;
2225         return 1;
2226 }
2227
2228 static void *
2229 __dlsym3(fd, sym, retaddr)
2230         void            *fd;
2231         const char      *sym;
2232         void            *retaddr;
2233 {
2234         void *result;
2235
2236         result = resolvesym(fd, sym, retaddr);
2237         /*
2238          * XXX - Ugly, but it makes the least impact on the run-time loader
2239          * sources.  We assume that most of the time the error is a
2240          * undefined symbol error from above, so we try again.  If it's
2241          * not an undefined symbol we end up getting the same error twice,
2242          * but that's acceptable.
2243          */
2244         if (result == NULL) {
2245                 /* Prepend an underscore and try again */
2246                 char *newsym = xmalloc(strlen(sym) + 2);
2247
2248                 newsym[0] = '_';
2249                 strcpy(&newsym[1], sym);
2250                 result = resolvesym(fd, newsym, retaddr);
2251                 free(newsym);
2252         }
2253         return result;
2254 }
2255
2256 static const char *
2257 __dlerror (void)
2258 {
2259         const char      *err;
2260
2261         err = dlerror_msg;
2262         dlerror_msg = NULL;  /* Next call will return NULL */
2263
2264         return err;
2265 }
2266
2267 static void
2268 __dlexit (void)
2269 {
2270 #ifdef DEBUG
2271 xprintf("__dlexit called\n");
2272 #endif
2273
2274         unmap_object(link_map_head, 1);
2275 }
2276
2277 /*
2278  * Print the current error message and exit with failure status.
2279  */
2280 static void
2281 die (void)
2282 {
2283         const char      *msg;
2284
2285         fprintf(stderr, "ld.so failed");
2286         if ((msg = __dlerror()) != NULL)
2287                 fprintf(stderr, ": %s", msg);
2288         putc('\n', stderr);
2289         _exit(1);
2290 }
2291
2292
2293 /*
2294  * Generate an error message that can be later be retrieved via dlerror.
2295  */
2296 static void
2297 #if __STDC__
2298 generror(char *fmt, ...)
2299 #else
2300 generror(fmt, va_alist)
2301 char    *fmt;
2302 #endif
2303 {
2304         va_list ap;
2305 #if __STDC__
2306         va_start(ap, fmt);
2307 #else
2308         va_start(ap);
2309 #endif
2310         vsnprintf (dlerror_buf, DLERROR_BUF_SIZE, fmt, ap);
2311         dlerror_msg = dlerror_buf;
2312
2313         va_end(ap);
2314 }
2315
2316 void
2317 #if __STDC__
2318 xprintf(char *fmt, ...)
2319 #else
2320 xprintf(fmt, va_alist)
2321 char    *fmt;
2322 #endif
2323 {
2324         char buf[256];
2325         va_list ap;
2326 #if __STDC__
2327         va_start(ap, fmt);
2328 #else
2329         va_start(ap);
2330 #endif
2331
2332         vsnprintf(buf, sizeof(buf), fmt, ap);
2333         (void)write(1, buf, strlen(buf));
2334         va_end(ap);
2335 }
2336
2337 /*
2338  * rt_readenv() etc.
2339  *
2340  * Do a sweep over the environment once only, pick up what
2341  * looks interesting.
2342  *
2343  * This is pretty obscure, but is relatively simple.  Simply
2344  * look at each environment variable, if it starts with "LD_" then
2345  * look closer at it.  If it's in our table, set the variable
2346  * listed.  effectively, this is like:
2347  *    ld_preload = careful ? NULL : getenv("LD_PRELOAD");
2348  * except that the environment is scanned once only to pick up all
2349  * known variables, rather than scanned multiple times for each
2350  * variable.
2351  *
2352  * If an environment variable of interest is set to the empty string, we
2353  * treat it as if it were unset.
2354  */
2355
2356 #define L(n, u, v) { n, sizeof(n) - 1, u, v },
2357 struct env_scan_tab {
2358         char    *name;
2359         int     len;
2360         int     unsafe;
2361         char    **value;
2362 } scan_tab[] = {
2363         L("LD_LIBRARY_PATH=",           1, &ld_library_path)
2364         L("LD_PRELOAD=",                1, &ld_preload)
2365         L("LD_IGNORE_MISSING_OBJECTS=", 1, &ld_ignore_missing_objects)
2366         L("LD_TRACE_LOADED_OBJECTS=",   0, &ld_tracing)
2367         L("LD_BIND_NOW=",               0, &ld_bind_now)
2368         L("LD_SUPPRESS_WARNINGS=",      0, &ld_suppress_warnings)
2369         L("LD_WARN_NON_PURE_CODE=",     0, &ld_warn_non_pure_code)
2370         { NULL, 0, 0, NULL }
2371 };
2372 #undef L
2373
2374 static void
2375 rt_readenv()
2376 {
2377         char **p = environ;
2378         char *v;
2379         struct env_scan_tab *t;
2380
2381         /* for each string in the environment... */
2382         while ((v = *p++)) {
2383
2384                 /* check for LD_xxx */
2385                 if (v[0] != 'L' || v[1] != 'D' || v[2] != '_')
2386                         continue;
2387
2388                 for (t = scan_tab; t->name; t++) {
2389                         if (careful && t->unsafe)
2390                                 continue;       /* skip for set[ug]id */
2391                         if (strncmp(t->name, v, t->len) == 0) {
2392                                 if (*(v + t->len) != '\0')      /* Not empty */
2393                                         *t->value = v + t->len;
2394                                 break;
2395                         }
2396                 }
2397         }
2398 }
2399
2400 /*
2401  * Malloc implementation for use within the dynamic linker.  At first
2402  * we do a simple allocation using sbrk.  After the user's program
2403  * has been loaded, we switch to using whatever malloc functions are
2404  * defined there.
2405  */
2406
2407 /* Symbols related to the sbrk and brk implementations. */
2408 #define CURBRK_SYM      "curbrk"
2409 #define MINBRK_SYM      "minbrk"
2410 #define END_SYM         "_end"
2411
2412 /* Symbols related to malloc. */
2413 #define FREE_SYM        "_free"
2414 #define MALLOC_SYM      "_malloc"
2415 #define REALLOC_SYM     "_realloc"
2416
2417 /* Hooks into the implementation of sbrk and brk. */
2418 extern char *curbrk __asm__(CURBRK_SYM);
2419 extern char *minbrk __asm__(MINBRK_SYM);
2420
2421 /* Pointers to the user program's malloc functions. */
2422 static void     *(*p_malloc) (size_t);
2423 static void     *(*p_realloc) (void *, size_t);
2424 static void      (*p_free) (void *);
2425
2426 /* Upper limit of the memory allocated by our internal malloc. */
2427 static char     *rtld_alloc_lev;
2428
2429 /*
2430  * Set up the internal malloc so that it will take its memory from the
2431  * main program's sbrk arena.
2432  */
2433 static void
2434 init_internal_malloc (void)
2435 {
2436         const struct exec *hdr;
2437
2438         /*
2439          * Before anything calls sbrk or brk, we have to initialize
2440          * its idea of the current break level to just beyond the main
2441          * program's address space.  Strictly speaking, the right
2442          * way to do that is to look up the value of "_end" in the
2443          * application's run time symbol table.
2444          *
2445          * That is what we used to do, and it works correctly for
2446          * every valid program.  Unfortunately, it doesn't work right
2447          * for "unexec"ed versions of emacs.  They are incorrectly
2448          * generated with a wrong value for "_end".  (xemacs gets it
2449          * right.)
2450          *
2451          * To work around this, we peek at the exec header to get the
2452          * sizes of the text, data, and bss segments.  Luckily, the
2453          * header is in memory at the start of the first mapped page.
2454          * From the segment sizes, we can calculate a proper initial
2455          * value for the break level.
2456          */
2457         hdr = (const struct exec *)PAGSIZ;
2458         if (N_BADMAG(*hdr))     /* Sanity check */
2459                 errx(1, "Cannot find program's a.out header");
2460         rtld_alloc_lev = curbrk = minbrk =
2461                 (char *)hdr + hdr->a_text + hdr->a_data + hdr->a_bss;
2462 }
2463
2464 /*
2465  * Set things up so that the dynamic linker can use the program's
2466  * malloc functions.
2467  */
2468 static void
2469 init_external_malloc (void)
2470 {
2471         /*
2472          * Patch the program's idea of the current break address to
2473          * what it really is as a result of the allocations we have
2474          * already done.
2475          */
2476         *(char **)(sym_addr(CURBRK_SYM)) = curbrk;
2477
2478         /*
2479          * Set the minimum break level too.  Otherwise, "unexec"ed
2480          * emacs sets the break too low and wipes out our tables of
2481          * shared objects.
2482          */
2483         *(char **)(sym_addr(MINBRK_SYM)) = curbrk;
2484
2485         /*
2486          * Set up pointers to the program's allocation functions, so
2487          * that we can use them from now on.
2488          */
2489         p_malloc = (void *(*)(size_t))(sym_addr(MALLOC_SYM));
2490         p_free = (void (*)(void *))(sym_addr(FREE_SYM));
2491         p_realloc = (void *(*)(void *, size_t))(sym_addr(REALLOC_SYM));
2492 }
2493
2494 void *
2495 malloc(size)
2496         size_t   size;
2497 {
2498         char            *p;
2499
2500         /* If we are far enough along, we can use the system malloc. */
2501         if (p_malloc != NULL)
2502                 return (*p_malloc)(size);
2503
2504         /*
2505          * Otherwise we use our simple built-in malloc.  We get the
2506          * memory from brk() in increments of one page.  We store the
2507          * allocated size in the first word, so that realloc can be
2508          * made to work.
2509          */
2510         if (rtld_alloc_lev == NULL)
2511                 errx(1, "Internal error: internal malloc called before"
2512                     " being initialized");
2513
2514         p = (char *)ALIGN(rtld_alloc_lev);
2515         rtld_alloc_lev = p + sizeof(size_t) + size;
2516
2517         if (rtld_alloc_lev > curbrk) {  /* Get memory from system */
2518                 char    *newbrk;
2519
2520                 newbrk = (char *)
2521                     roundup2((unsigned long)rtld_alloc_lev, PAGSIZ);
2522                 if (brk(newbrk) == -1)
2523                         return NULL;
2524         }
2525
2526         *(size_t *)p = size;
2527         return p + sizeof(size_t);
2528 }
2529
2530 void *
2531 realloc(ptr, size)
2532         void    *ptr;
2533         size_t   size;
2534 {
2535         size_t   old_size;
2536         void    *new_ptr;
2537
2538         if (ptr == NULL)
2539                 return malloc(size);
2540
2541         /*
2542          * If we are far enough along, and if the memory originally came
2543          * from the system malloc, we can use the system realloc.
2544          */
2545         if (p_realloc != NULL && (char *)ptr >= rtld_alloc_lev)
2546                 return (*p_realloc)(ptr, size);
2547
2548         old_size = *((size_t *)ptr - 1);
2549         if (old_size >= size)   /* Not expanding the region */
2550                 return ptr;
2551
2552         new_ptr = malloc(size);
2553         if (new_ptr != NULL)
2554                 memcpy(new_ptr, ptr, old_size);
2555         return new_ptr;
2556 }
2557
2558 void
2559 free(ptr)
2560         void    *ptr;
2561 {
2562         if (ptr == NULL)
2563                 return;
2564
2565         /*
2566          * If we are far enough along, and if the memory originally came
2567          * from the system malloc, we can use the system free.  Otherwise
2568          * we can't free the memory and we just let it go to waste.
2569          */
2570         if (p_free != NULL && (char *)ptr >= rtld_alloc_lev)
2571                 (*p_free)(ptr);
2572 }