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