xref: /freebsd/libexec/rtld-elf/rtld.c (revision d74e86d9e30043893d6b308468008b65640ddcae)
1 /*-
2  * Copyright 1996-1998 John D. Polstra.
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  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *      $Id: rtld.c,v 1.9 1998/09/15 21:07:52 jdp Exp $
26  */
27 
28 /*
29  * Dynamic linker for ELF.
30  *
31  * John Polstra <jdp@polstra.com>.
32  */
33 
34 #ifndef __GNUC__
35 #error "GCC is needed to compile this file"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/mman.h>
40 
41 #include <dlfcn.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50 
51 #include "debug.h"
52 #include "rtld.h"
53 
54 /*
55  * Debugging support.
56  */
57 
58 #define assert(cond)	((cond) ? (void) 0 :\
59     (msg("oops: " __XSTRING(__LINE__) "\n"), abort()))
60 #define msg(s)		(write(1, s, strlen(s)))
61 #define trace()		msg("trace: " __XSTRING(__LINE__) "\n");
62 
63 #define END_SYM		"end"
64 
65 /* Types. */
66 typedef void (*func_ptr_type)();
67 
68 /*
69  * Function declarations.
70  */
71 static void call_fini_functions(Obj_Entry *);
72 static void call_init_functions(Obj_Entry *);
73 static void die(void);
74 static void digest_dynamic(Obj_Entry *);
75 static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t);
76 static Obj_Entry *dlcheck(void *);
77 static char *find_library(const char *, const Obj_Entry *);
78 static const char *gethints(void);
79 static void init_rtld(caddr_t);
80 static bool is_exported(const Elf_Sym *);
81 static void linkmap_add(Obj_Entry *);
82 static void linkmap_delete(Obj_Entry *);
83 static int load_needed_objects(Obj_Entry *);
84 static Obj_Entry *load_object(char *);
85 static Obj_Entry *obj_from_addr(const void *);
86 static int relocate_objects(Obj_Entry *, bool);
87 static void rtld_exit(void);
88 static char *search_library_path(const char *, const char *);
89 static void unref_object_dag(Obj_Entry *);
90 static void trace_loaded_objects(Obj_Entry *obj);
91 
92 void r_debug_state(void);
93 void xprintf(const char *, ...);
94 
95 #ifdef DEBUG
96 static const char *basename(const char *);
97 #endif
98 
99 /* Assembly language entry point for lazy binding. */
100 extern void _rtld_bind_start(void);
101 
102 /*
103  * Assembly language macro for getting the GOT pointer.
104  */
105 #ifdef __i386__
106 #define get_got_address()				\
107     ({ Elf_Addr *thegot;				\
108        __asm__("movl %%ebx,%0" : "=rm"(thegot));	\
109        thegot; })
110 #elif __alpha__
111 #define get_got_address()	NULL
112 #else
113 #error "This file only supports the i386 and alpha architectures"
114 #endif
115 
116 /*
117  * Data declarations.
118  */
119 static char *error_message;	/* Message for dlerror(), or NULL */
120 struct r_debug r_debug;	/* for GDB; */
121 static bool trust;		/* False for setuid and setgid programs */
122 static char *ld_bind_now;	/* Environment variable for immediate binding */
123 static char *ld_debug;		/* Environment variable for debugging */
124 static char *ld_library_path;	/* Environment variable for search path */
125 static char *ld_tracing;	/* Called from ldd to print libs */
126 static Obj_Entry **main_tail;	/* Value of obj_tail after loading main and
127 				   its needed shared libraries */
128 static Obj_Entry *obj_list;	/* Head of linked list of shared objects */
129 static Obj_Entry **obj_tail;	/* Link field of last object in list */
130 static Obj_Entry *obj_main;	/* The main program shared object */
131 static Obj_Entry obj_rtld;	/* The dynamic linker shared object */
132 
133 #define GDB_STATE(s)	r_debug.r_state = s; r_debug_state();
134 
135 extern Elf_Dyn _DYNAMIC;
136 
137 /*
138  * These are the functions the dynamic linker exports to application
139  * programs.  They are the only symbols the dynamic linker is willing
140  * to export from itself.
141  */
142 static func_ptr_type exports[] = {
143     (func_ptr_type) &_rtld_error,
144     (func_ptr_type) &dlclose,
145     (func_ptr_type) &dlerror,
146     (func_ptr_type) &dlopen,
147     (func_ptr_type) &dlsym,
148     NULL
149 };
150 
151 /*
152  * Global declarations normally provided by crt1.  The dynamic linker is
153  * not build with crt1, so we have to provide them ourselves.
154  */
155 char *__progname;
156 char **environ;
157 
158 /*
159  * Main entry point for dynamic linking.  The first argument is the
160  * stack pointer.  The stack is expected to be laid out as described
161  * in the SVR4 ABI specification, Intel 386 Processor Supplement.
162  * Specifically, the stack pointer points to a word containing
163  * ARGC.  Following that in the stack is a null-terminated sequence
164  * of pointers to argument strings.  Then comes a null-terminated
165  * sequence of pointers to environment strings.  Finally, there is a
166  * sequence of "auxiliary vector" entries.
167  *
168  * The second argument points to a place to store the dynamic linker's
169  * exit procedure pointer and the third to a place to store the main
170  * program's object.
171  *
172  * The return value is the main program's entry point.
173  */
174 func_ptr_type
175 _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
176 {
177     Elf_Auxinfo *aux_info[AT_COUNT];
178     int i;
179     int argc;
180     char **argv;
181     char **env;
182     Elf_Auxinfo *aux;
183     Elf_Auxinfo *auxp;
184 
185     /*
186      * On entry, the dynamic linker itself has not been relocated yet.
187      * Be very careful not to reference any global data until after
188      * init_rtld has returned.  It is OK to reference file-scope statics
189      * and string constants, and to call static and global functions.
190      */
191 
192     /* Find the auxiliary vector on the stack. */
193     argc = *sp++;
194     argv = (char **) sp;
195     sp += argc + 1;	/* Skip over arguments and NULL terminator */
196     env = (char **) sp;
197     while (*sp++ != 0)	/* Skip over environment, and NULL terminator */
198 	;
199     aux = (Elf_Auxinfo *) sp;
200 
201     /* Digest the auxiliary vector. */
202     for (i = 0;  i < AT_COUNT;  i++)
203 	aux_info[i] = NULL;
204     for (auxp = aux;  auxp->a_type != AT_NULL;  auxp++) {
205 	if (auxp->a_type < AT_COUNT)
206 	    aux_info[auxp->a_type] = auxp;
207     }
208 
209     /* Initialize and relocate ourselves. */
210     assert(aux_info[AT_BASE] != NULL);
211     init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
212 
213     __progname = obj_rtld.path;
214     environ = env;
215 
216     trust = geteuid() == getuid() && getegid() == getgid();
217 
218     ld_bind_now = getenv("LD_BIND_NOW");
219     if (trust) {
220 	ld_debug = getenv("LD_DEBUG");
221 	ld_library_path = getenv("LD_LIBRARY_PATH");
222     }
223     ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS");
224 
225     if (ld_debug != NULL && *ld_debug != '\0')
226 	debug = 1;
227     dbg("%s is initialized, base address = %p", __progname,
228 	(caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
229 
230     /*
231      * Load the main program, or process its program header if it is
232      * already loaded.
233      */
234     if (aux_info[AT_EXECFD] != NULL) {	/* Load the main program. */
235 	int fd = aux_info[AT_EXECFD]->a_un.a_val;
236 	dbg("loading main program");
237 	obj_main = map_object(fd);
238 	close(fd);
239 	if (obj_main == NULL)
240 	    die();
241     } else {				/* Main program already loaded. */
242 	const Elf_Phdr *phdr;
243 	int phnum;
244 	caddr_t entry;
245 
246 	dbg("processing main program's program header");
247 	assert(aux_info[AT_PHDR] != NULL);
248 	phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr;
249 	assert(aux_info[AT_PHNUM] != NULL);
250 	phnum = aux_info[AT_PHNUM]->a_un.a_val;
251 	assert(aux_info[AT_PHENT] != NULL);
252 	assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr));
253 	assert(aux_info[AT_ENTRY] != NULL);
254 	entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr;
255 	obj_main = digest_phdr(phdr, phnum, entry);
256     }
257 
258     obj_main->path = xstrdup(argv[0]);
259     obj_main->mainprog = true;
260     digest_dynamic(obj_main);
261 
262     linkmap_add(obj_main);
263     linkmap_add(&obj_rtld);
264 
265     /* Link the main program into the list of objects. */
266     *obj_tail = obj_main;
267     obj_tail = &obj_main->next;
268     obj_main->refcount++;
269 
270     dbg("loading needed objects");
271     if (load_needed_objects(obj_main) == -1)
272 	die();
273     main_tail = obj_tail;
274 
275     if (ld_tracing) {		/* We're done */
276 	trace_loaded_objects(obj_main);
277 	exit(0);
278     }
279 
280     dbg("relocating objects");
281     if (relocate_objects(obj_main,
282 	ld_bind_now != NULL && *ld_bind_now != '\0') == -1)
283 	die();
284 
285     dbg("doing copy relocations");
286     if (do_copy_relocations(obj_main) == -1)
287 	die();
288 
289     dbg("calling _init functions");
290     call_init_functions(obj_main->next);
291 
292     dbg("transferring control to program entry point = %p", obj_main->entry);
293 
294     r_debug_state();		/* say hello to gdb! */
295 
296     /* Return the exit procedure and the program entry point. */
297     *exit_proc = rtld_exit;
298     *objp = obj_main;
299     return (func_ptr_type) obj_main->entry;
300 }
301 
302 caddr_t
303 _rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
304 {
305     const Elf_Rel *rel;
306     const Elf_Sym *def;
307     const Obj_Entry *defobj;
308     Elf_Addr *where;
309     caddr_t target;
310 
311     if (obj->pltrel)
312 	rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
313     else
314 	rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
315 
316     where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
317     def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true);
318     if (def == NULL)
319 	die();
320 
321     target = (caddr_t) (defobj->relocbase + def->st_value);
322 
323     dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
324       defobj->strtab + def->st_name, basename(obj->path),
325       target, basename(defobj->path));
326 
327     *where = (Elf_Addr) target;
328     return target;
329 }
330 
331 /*
332  * Error reporting function.  Use it like printf.  If formats the message
333  * into a buffer, and sets things up so that the next call to dlerror()
334  * will return the message.
335  */
336 void
337 _rtld_error(const char *fmt, ...)
338 {
339     static char buf[512];
340     va_list ap;
341 
342     va_start(ap, fmt);
343     vsnprintf(buf, sizeof buf, fmt, ap);
344     error_message = buf;
345     va_end(ap);
346 }
347 
348 #ifdef DEBUG
349 static const char *
350 basename(const char *name)
351 {
352     const char *p = strrchr(name, '/');
353     return p != NULL ? p + 1 : name;
354 }
355 #endif
356 
357 static void
358 call_fini_functions(Obj_Entry *first)
359 {
360     Obj_Entry *obj;
361 
362     for (obj = first;  obj != NULL;  obj = obj->next)
363 	if (obj->fini != NULL)
364 	    (*obj->fini)();
365 }
366 
367 static void
368 call_init_functions(Obj_Entry *first)
369 {
370     if (first != NULL) {
371 	call_init_functions(first->next);
372 	if (first->init != NULL)
373 	    (*first->init)();
374     }
375 }
376 
377 static void
378 die(void)
379 {
380     const char *msg = dlerror();
381 
382     if (msg == NULL)
383 	msg = "Fatal error";
384     errx(1, "%s", msg);
385 }
386 
387 /*
388  * Process a shared object's DYNAMIC section, and save the important
389  * information in its Obj_Entry structure.
390  */
391 static void
392 digest_dynamic(Obj_Entry *obj)
393 {
394     const Elf_Dyn *dynp;
395     Needed_Entry **needed_tail = &obj->needed;
396     const Elf_Dyn *dyn_rpath = NULL;
397     int plttype = DT_REL;
398 
399     for (dynp = obj->dynamic;  dynp->d_tag != DT_NULL;  dynp++) {
400 	switch (dynp->d_tag) {
401 
402 	case DT_REL:
403 	    obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr);
404 	    break;
405 
406 	case DT_RELSZ:
407 	    obj->relsize = dynp->d_un.d_val;
408 	    break;
409 
410 	case DT_RELENT:
411 	    assert(dynp->d_un.d_val == sizeof(Elf_Rel));
412 	    break;
413 
414 	case DT_JMPREL:
415 	    obj->pltrel = (const Elf_Rel *)
416 	      (obj->relocbase + dynp->d_un.d_ptr);
417 	    break;
418 
419 	case DT_PLTRELSZ:
420 	    obj->pltrelsize = dynp->d_un.d_val;
421 	    break;
422 
423 	case DT_RELA:
424 	    obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr);
425 	    break;
426 
427 	case DT_RELASZ:
428 	    obj->relasize = dynp->d_un.d_val;
429 	    break;
430 
431 	case DT_RELAENT:
432 	    assert(dynp->d_un.d_val == sizeof(Elf_Rela));
433 	    break;
434 
435 	case DT_PLTREL:
436 	    plttype = dynp->d_un.d_val;
437 	    assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA);
438 	    break;
439 
440 	case DT_SYMTAB:
441 	    obj->symtab = (const Elf_Sym *)
442 	      (obj->relocbase + dynp->d_un.d_ptr);
443 	    break;
444 
445 	case DT_SYMENT:
446 	    assert(dynp->d_un.d_val == sizeof(Elf_Sym));
447 	    break;
448 
449 	case DT_STRTAB:
450 	    obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr);
451 	    break;
452 
453 	case DT_STRSZ:
454 	    obj->strsize = dynp->d_un.d_val;
455 	    break;
456 
457 	case DT_HASH:
458 	    {
459 		const Elf_Addr *hashtab = (const Elf_Addr *)
460 		  (obj->relocbase + dynp->d_un.d_ptr);
461 		obj->nbuckets = hashtab[0];
462 		obj->nchains = hashtab[1];
463 		obj->buckets = hashtab + 2;
464 		obj->chains = obj->buckets + obj->nbuckets;
465 	    }
466 	    break;
467 
468 	case DT_NEEDED:
469 	    assert(!obj->rtld);
470 	    {
471 		Needed_Entry *nep = NEW(Needed_Entry);
472 		nep->name = dynp->d_un.d_val;
473 		nep->obj = NULL;
474 		nep->next = NULL;
475 
476 		*needed_tail = nep;
477 		needed_tail = &nep->next;
478 	    }
479 	    break;
480 
481 	case DT_PLTGOT:
482 	    obj->got = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
483 	    break;
484 
485 	case DT_TEXTREL:
486 	    obj->textrel = true;
487 	    break;
488 
489 	case DT_SYMBOLIC:
490 	    obj->symbolic = true;
491 	    break;
492 
493 	case DT_RPATH:
494 	    /*
495 	     * We have to wait until later to process this, because we
496 	     * might not have gotten the address of the string table yet.
497 	     */
498 	    dyn_rpath = dynp;
499 	    break;
500 
501 	case DT_SONAME:
502 	    /* Not used by the dynamic linker. */
503 	    break;
504 
505 	case DT_INIT:
506 	    obj->init = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr);
507 	    break;
508 
509 	case DT_FINI:
510 	    obj->fini = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr);
511 	    break;
512 
513 	case DT_DEBUG:
514 	    /* XXX - not implemented yet */
515 	    dbg("Filling in DT_DEBUG entry");
516 	    ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
517 	    break;
518 
519 	default:
520 	    xprintf("Ignored d_tag %d\n",dynp->d_tag);
521             break;
522 	}
523     }
524 
525     obj->traced = false;
526 
527     if (plttype == DT_RELA) {
528 	obj->pltrela = (const Elf_Rela *) obj->pltrel;
529 	obj->pltrel = NULL;
530 	obj->pltrelasize = obj->pltrelsize;
531 	obj->pltrelsize = 0;
532     }
533 
534     if (dyn_rpath != NULL)
535 	obj->rpath = obj->strtab + dyn_rpath->d_un.d_val;
536 }
537 
538 /*
539  * Process a shared object's program header.  This is used only for the
540  * main program, when the kernel has already loaded the main program
541  * into memory before calling the dynamic linker.  It creates and
542  * returns an Obj_Entry structure.
543  */
544 static Obj_Entry *
545 digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry)
546 {
547     Obj_Entry *obj = CNEW(Obj_Entry);
548     const Elf_Phdr *phlimit = phdr + phnum;
549     const Elf_Phdr *ph;
550     int nsegs = 0;
551 
552     for (ph = phdr;  ph < phlimit;  ph++) {
553 	switch (ph->p_type) {
554 
555 	case PT_PHDR:
556 	    assert((const Elf_Phdr *) ph->p_vaddr == phdr);
557 	    obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
558 	    obj->phsize = ph->p_memsz;
559 	    break;
560 
561 	case PT_LOAD:
562 	    assert(nsegs < 2);
563 	    if (nsegs == 0) {	/* First load segment */
564 		obj->vaddrbase = trunc_page(ph->p_vaddr);
565 		obj->mapbase = (caddr_t) obj->vaddrbase;
566 		obj->relocbase = obj->mapbase - obj->vaddrbase;
567 		obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
568 		  obj->vaddrbase;
569 	    } else {		/* Last load segment */
570 		obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
571 		  obj->vaddrbase;
572 	    }
573 	    nsegs++;
574 	    break;
575 
576 	case PT_DYNAMIC:
577 	    obj->dynamic = (const Elf_Dyn *) ph->p_vaddr;
578 	    break;
579 	}
580     }
581     assert(nsegs == 2);
582 
583     obj->entry = entry;
584     return obj;
585 }
586 
587 static Obj_Entry *
588 dlcheck(void *handle)
589 {
590     Obj_Entry *obj;
591 
592     for (obj = obj_list;  obj != NULL;  obj = obj->next)
593 	if (obj == (Obj_Entry *) handle)
594 	    break;
595 
596     if (obj == NULL || obj->dl_refcount == 0) {
597 	_rtld_error("Invalid shared object handle %p", handle);
598 	return NULL;
599     }
600     return obj;
601 }
602 
603 /*
604  * Hash function for symbol table lookup.  Don't even think about changing
605  * this.  It is specified by the System V ABI.
606  */
607 unsigned long
608 elf_hash(const char *name)
609 {
610     const unsigned char *p = (const unsigned char *) name;
611     unsigned long h = 0;
612     unsigned long g;
613 
614     while (*p != '\0') {
615 	h = (h << 4) + *p++;
616 	if ((g = h & 0xf0000000) != 0)
617 	    h ^= g >> 24;
618 	h &= ~g;
619     }
620     return h;
621 }
622 
623 /*
624  * Find the library with the given name, and return its full pathname.
625  * The returned string is dynamically allocated.  Generates an error
626  * message and returns NULL if the library cannot be found.
627  *
628  * If the second argument is non-NULL, then it refers to an already-
629  * loaded shared object, whose library search path will be searched.
630  *
631  * The search order is:
632  *   LD_LIBRARY_PATH
633  *   ldconfig hints
634  *   rpath in the referencing file
635  *   /usr/lib
636  */
637 static char *
638 find_library(const char *name, const Obj_Entry *refobj)
639 {
640     char *pathname;
641 
642     if (strchr(name, '/') != NULL) {	/* Hard coded pathname */
643 	if (name[0] != '/' && !trust) {
644 	    _rtld_error("Absolute pathname required for shared object \"%s\"",
645 	      name);
646 	    return NULL;
647 	}
648 	return xstrdup(name);
649     }
650 
651     dbg(" Searching for \"%s\"", name);
652 
653     if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
654       (pathname = search_library_path(name, gethints())) != NULL ||
655       (refobj != NULL &&
656       (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
657       (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
658 	return pathname;
659 
660     _rtld_error("Shared object \"%s\" not found", name);
661     return NULL;
662 }
663 
664 /*
665  * Given a symbol number in a referencing object, find the corresponding
666  * definition of the symbol.  Returns a pointer to the symbol, or NULL if
667  * no definition was found.  Returns a pointer to the Obj_Entry of the
668  * defining object via the reference parameter DEFOBJ_OUT.
669  */
670 const Elf_Sym *
671 find_symdef(unsigned long symnum, const Obj_Entry *refobj,
672     const Obj_Entry **defobj_out, bool in_plt)
673 {
674     const Elf_Sym *ref;
675     const Elf_Sym *strongdef;
676     const Elf_Sym *weakdef;
677     const Obj_Entry *obj;
678     const Obj_Entry *strongobj;
679     const Obj_Entry *weakobj;
680     const char *name;
681     unsigned long hash;
682 
683     ref = refobj->symtab + symnum;
684     name = refobj->strtab + ref->st_name;
685     hash = elf_hash(name);
686 
687     if (refobj->symbolic) {	/* Look first in the referencing object */
688 	const Elf_Sym *def = symlook_obj(name, hash, refobj, in_plt);
689 	if (def != NULL) {
690 	    *defobj_out = refobj;
691 	    return def;
692 	}
693     }
694 
695     /*
696      * Look in all loaded objects.  Skip the referencing object, if
697      * we have already searched it.  We keep track of the first weak
698      * definition and the first strong definition we encounter.  If
699      * we find a strong definition we stop searching, because there
700      * won't be anything better than that.
701      */
702     strongdef = weakdef = NULL;
703     strongobj = weakobj = NULL;
704     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
705 	if (obj != refobj || !refobj->symbolic) {
706 	    const Elf_Sym *def = symlook_obj(name, hash, obj, in_plt);
707 	    if (def != NULL) {
708 		if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
709 		    if (weakdef == NULL) {
710 			weakdef = def;
711 			weakobj = obj;
712 		    }
713 		} else {
714 		    strongdef = def;
715 		    strongobj = obj;
716 		    break;	/* We are done. */
717 		}
718 	    }
719 	}
720     }
721 
722     /*
723      * If we still don't have a strong definition, search the dynamic
724      * linker itself, and possibly resolve the symbol from there.
725      * This is how the application links to dynamic linker services
726      * such as dlopen.  Only the values listed in the "exports" array
727      * can be resolved from the dynamic linker.
728      */
729     if (strongdef == NULL) {
730 	const Elf_Sym *def = symlook_obj(name, hash, &obj_rtld, in_plt);
731 	if (def != NULL && is_exported(def)) {
732 	    if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
733 		if (weakdef == NULL) {
734 		    weakdef = def;
735 		    weakobj = &obj_rtld;
736 		}
737 	    } else {
738 		strongdef = def;
739 		strongobj = &obj_rtld;
740 	    }
741 	}
742     }
743 
744     if (strongdef != NULL) {
745 	*defobj_out = strongobj;
746 	return strongdef;
747     }
748     if (weakdef != NULL) {
749 	*defobj_out = weakobj;
750 	return weakdef;
751     }
752 
753     _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name);
754     return NULL;
755 }
756 
757 /*
758  * Return the search path from the ldconfig hints file, reading it if
759  * necessary.  Returns NULL if there are problems with the hints file,
760  * or if the search path there is empty.
761  */
762 static const char *
763 gethints(void)
764 {
765     static char *hints;
766 
767     if (hints == NULL) {
768 	int fd;
769 	struct elfhints_hdr hdr;
770 	char *p;
771 
772 	/* Keep from trying again in case the hints file is bad. */
773 	hints = "";
774 
775 	if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
776 	    return NULL;
777 	if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
778 	  hdr.magic != ELFHINTS_MAGIC ||
779 	  hdr.version != 1) {
780 	    close(fd);
781 	    return NULL;
782 	}
783 	p = xmalloc(hdr.dirlistlen + 1);
784 	if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
785 	  read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) {
786 	    free(p);
787 	    close(fd);
788 	    return NULL;
789 	}
790 	hints = p;
791 	close(fd);
792     }
793     return hints[0] != '\0' ? hints : NULL;
794 }
795 
796 /*
797  * Initialize the dynamic linker.  The argument is the address at which
798  * the dynamic linker has been mapped into memory.  The primary task of
799  * this function is to relocate the dynamic linker.
800  */
801 static void
802 init_rtld(caddr_t mapbase)
803 {
804     /*
805      * Conjure up an Obj_Entry structure for the dynamic linker.
806      *
807      * The "path" member is supposed to be dynamically-allocated, but we
808      * aren't yet initialized sufficiently to do that.  Below we will
809      * replace the static version with a dynamically-allocated copy.
810      */
811     obj_rtld.path = "/usr/libexec/ld-elf.so.1";
812     obj_rtld.rtld = true;
813     obj_rtld.mapbase = mapbase;
814     obj_rtld.relocbase = mapbase;
815     obj_rtld.got = get_got_address();
816 #ifdef	__alpha__
817     obj_rtld.dynamic = (const Elf_Dyn *) &_DYNAMIC;
818 #else
819     obj_rtld.dynamic = (const Elf_Dyn *) (obj_rtld.mapbase + obj_rtld.got[0]);
820 #endif
821 
822     digest_dynamic(&obj_rtld);
823 #ifdef __alpha__
824 /* XXX XXX XXX */
825 obj_rtld.got = NULL;
826 #endif
827     assert(obj_rtld.needed == NULL);
828     assert(!obj_rtld.textrel);
829 
830     /*
831      * Temporarily put the dynamic linker entry into the object list, so
832      * that symbols can be found.
833      */
834     obj_list = &obj_rtld;
835     obj_tail = &obj_rtld.next;
836 
837     relocate_objects(&obj_rtld, true);
838 
839     /* Make the object list empty again. */
840     obj_list = NULL;
841     obj_tail = &obj_list;
842 
843     /* Replace the path with a dynamically allocated copy. */
844     obj_rtld.path = xstrdup(obj_rtld.path);
845 
846     r_debug.r_brk = r_debug_state;
847     r_debug.r_state = RT_CONSISTENT;
848 }
849 
850 static bool
851 is_exported(const Elf_Sym *def)
852 {
853     func_ptr_type value;
854     const func_ptr_type *p;
855 
856     value = (func_ptr_type)(obj_rtld.relocbase + def->st_value);
857     for (p = exports;  *p != NULL;  p++)
858 	if (*p == value)
859 	    return true;
860     return false;
861 }
862 
863 /*
864  * Given a shared object, traverse its list of needed objects, and load
865  * each of them.  Returns 0 on success.  Generates an error message and
866  * returns -1 on failure.
867  */
868 static int
869 load_needed_objects(Obj_Entry *first)
870 {
871     Obj_Entry *obj;
872 
873     for (obj = first;  obj != NULL;  obj = obj->next) {
874 	Needed_Entry *needed;
875 
876 	for (needed = obj->needed;  needed != NULL;  needed = needed->next) {
877 	    const char *name = obj->strtab + needed->name;
878 	    char *path = find_library(name, obj);
879 
880 	    needed->obj = NULL;
881 	    if (path == NULL && !ld_tracing)
882 		return -1;
883 
884 	    if (path) {
885 		needed->obj = load_object(path);
886 		if (needed->obj == NULL && !ld_tracing)
887 		    return -1;		/* XXX - cleanup */
888 	    }
889 	}
890     }
891 
892     return 0;
893 }
894 
895 /*
896  * Load a shared object into memory, if it is not already loaded.  The
897  * argument must be a string allocated on the heap.  This function assumes
898  * responsibility for freeing it when necessary.
899  *
900  * Returns a pointer to the Obj_Entry for the object.  Returns NULL
901  * on failure.
902  */
903 static Obj_Entry *
904 load_object(char *path)
905 {
906     Obj_Entry *obj;
907 
908     for (obj = obj_list->next;  obj != NULL;  obj = obj->next)
909 	if (strcmp(obj->path, path) == 0)
910 	    break;
911 
912     if (obj == NULL) {	/* First use of this object, so we must map it in */
913 	int fd;
914 
915 	if ((fd = open(path, O_RDONLY)) == -1) {
916 	    _rtld_error("Cannot open \"%s\"", path);
917 	    return NULL;
918 	}
919 	obj = map_object(fd);
920 	close(fd);
921 	if (obj == NULL) {
922 	    free(path);
923 	    return NULL;
924 	}
925 
926 	obj->path = path;
927 	digest_dynamic(obj);
928 
929 	*obj_tail = obj;
930 	obj_tail = &obj->next;
931 	linkmap_add(obj);	/* for GDB */
932 
933 	dbg("  %p .. %p: %s", obj->mapbase,
934 	  obj->mapbase + obj->mapsize - 1, obj->path);
935 	if (obj->textrel)
936 	    dbg("  WARNING: %s has impure text", obj->path);
937     } else
938 	free(path);
939 
940     obj->refcount++;
941     return obj;
942 }
943 
944 static Obj_Entry *
945 obj_from_addr(const void *addr)
946 {
947     unsigned long endhash;
948     Obj_Entry *obj;
949 
950     endhash = elf_hash(END_SYM);
951     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
952 	const Elf_Sym *endsym;
953 
954 	if (addr < (void *) obj->mapbase)
955 	    continue;
956 	if ((endsym = symlook_obj(END_SYM, endhash, obj, true)) == NULL)
957 	    continue;	/* No "end" symbol?! */
958 	if (addr < (void *) (obj->relocbase + endsym->st_value))
959 	    return obj;
960     }
961     return NULL;
962 }
963 
964 /*
965  * Relocate newly-loaded shared objects.  The argument is a pointer to
966  * the Obj_Entry for the first such object.  All objects from the first
967  * to the end of the list of objects are relocated.  Returns 0 on success,
968  * or -1 on failure.
969  */
970 static int
971 relocate_objects(Obj_Entry *first, bool bind_now)
972 {
973     Obj_Entry *obj;
974 
975     for (obj = first;  obj != NULL;  obj = obj->next) {
976 	if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
977 	    obj->symtab == NULL || obj->strtab == NULL) {
978 	    _rtld_error("%s: Shared object has no run-time symbol table",
979 	      obj->path);
980 	    return -1;
981 	}
982 
983 	if (obj->textrel) {
984 	    /* There are relocations to the write-protected text segment. */
985 	    if (mprotect(obj->mapbase, obj->textsize,
986 	      PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
987 		_rtld_error("%s: Cannot write-enable text segment: %s",
988 		  obj->path, strerror(errno));
989 		return -1;
990 	    }
991 	}
992 
993 	/* Process the non-PLT relocations. */
994 	if (reloc_non_plt(obj, &obj_rtld))
995 		return -1;
996 
997 	if (obj->textrel) {	/* Re-protected the text segment. */
998 	    if (mprotect(obj->mapbase, obj->textsize,
999 	      PROT_READ|PROT_EXEC) == -1) {
1000 		_rtld_error("%s: Cannot write-protect text segment: %s",
1001 		  obj->path, strerror(errno));
1002 		return -1;
1003 	    }
1004 	}
1005 
1006 	/* Process the PLT relocations. */
1007 	if (reloc_plt(obj, bind_now))
1008 		return -1;
1009 
1010 	/*
1011 	 * Set up the magic number and version in the Obj_Entry.  These
1012 	 * were checked in the crt1.o from the original ElfKit, so we
1013 	 * set them for backward compatibility.
1014 	 */
1015 	obj->magic = RTLD_MAGIC;
1016 	obj->version = RTLD_VERSION;
1017 
1018 	/* Set the special GOT entries. */
1019 	if (obj->got) {
1020 #ifdef __i386__
1021 	    obj->got[1] = (Elf_Addr) obj;
1022 	    obj->got[2] = (Elf_Addr) &_rtld_bind_start;
1023 #endif
1024 #ifdef __alpha__
1025 	    /* This function will be called to perform the relocation.  */
1026 	    obj->got[2] = (Elf_Addr) &_rtld_bind_start;
1027 	    /* Identify this shared object */
1028 	    obj->got[3] = (Elf_Addr) obj;
1029 #endif
1030 	}
1031     }
1032 
1033     return 0;
1034 }
1035 
1036 /*
1037  * Cleanup procedure.  It will be called (by the atexit mechanism) just
1038  * before the process exits.
1039  */
1040 static void
1041 rtld_exit(void)
1042 {
1043     dbg("rtld_exit()");
1044     call_fini_functions(obj_list->next);
1045 }
1046 
1047 static char *
1048 search_library_path(const char *name, const char *path)
1049 {
1050     size_t namelen = strlen(name);
1051     const char *p = path;
1052 
1053     if (p == NULL)
1054 	return NULL;
1055 
1056     p += strspn(p, ":;");
1057     while (*p != '\0') {
1058 	size_t len = strcspn(p, ":;");
1059 
1060 	if (*p == '/' || trust) {
1061 	    char *pathname;
1062 	    const char *dir = p;
1063 	    size_t dirlen = len;
1064 
1065 	    pathname = xmalloc(dirlen + 1 + namelen + 1);
1066 	    strncpy(pathname, dir, dirlen);
1067 	    pathname[dirlen] = '/';
1068 	    strcpy(pathname + dirlen + 1, name);
1069 
1070 	    dbg("  Trying \"%s\"", pathname);
1071 	    if (access(pathname, F_OK) == 0)		/* We found it */
1072 		return pathname;
1073 
1074 	    free(pathname);
1075 	}
1076 	p += len;
1077 	p += strspn(p, ":;");
1078     }
1079 
1080     return NULL;
1081 }
1082 
1083 int
1084 dlclose(void *handle)
1085 {
1086     Obj_Entry *root = dlcheck(handle);
1087 
1088     if (root == NULL)
1089 	return -1;
1090 
1091     GDB_STATE(RT_DELETE);
1092 
1093     root->dl_refcount--;
1094     unref_object_dag(root);
1095     if (root->refcount == 0) {	/* We are finished with some objects. */
1096 	Obj_Entry *obj;
1097 	Obj_Entry **linkp;
1098 
1099 	/* Finalize objects that are about to be unmapped. */
1100 	for (obj = obj_list->next;  obj != NULL;  obj = obj->next)
1101 	    if (obj->refcount == 0 && obj->fini != NULL)
1102 		(*obj->fini)();
1103 
1104 	/* Unmap all objects that are no longer referenced. */
1105 	linkp = &obj_list->next;
1106 	while ((obj = *linkp) != NULL) {
1107 	    if (obj->refcount == 0) {
1108 		munmap(obj->mapbase, obj->mapsize);
1109 		free(obj->path);
1110 		while (obj->needed != NULL) {
1111 		    Needed_Entry *needed = obj->needed;
1112 		    obj->needed = needed->next;
1113 		    free(needed);
1114 		}
1115 		linkmap_delete(obj);
1116 		*linkp = obj->next;
1117 		free(obj);
1118 	    } else
1119 		linkp = &obj->next;
1120 	}
1121     }
1122 
1123     GDB_STATE(RT_CONSISTENT);
1124 
1125     return 0;
1126 }
1127 
1128 const char *
1129 dlerror(void)
1130 {
1131     char *msg = error_message;
1132     error_message = NULL;
1133     return msg;
1134 }
1135 
1136 void *
1137 dlopen(const char *name, int mode)
1138 {
1139     Obj_Entry **old_obj_tail = obj_tail;
1140     Obj_Entry *obj = NULL;
1141 
1142     GDB_STATE(RT_ADD);
1143 
1144     if (name == NULL)
1145 	obj = obj_main;
1146     else {
1147 	char *path = find_library(name, NULL);
1148 	if (path != NULL)
1149 	    obj = load_object(path);
1150     }
1151 
1152     if (obj) {
1153 	obj->dl_refcount++;
1154 	if (*old_obj_tail != NULL) {		/* We loaded something new. */
1155 	    assert(*old_obj_tail == obj);
1156 
1157 	    /* XXX - Clean up properly after an error. */
1158 	    if (load_needed_objects(obj) == -1) {
1159 		obj->dl_refcount--;
1160 		obj = NULL;
1161 	    } else if (relocate_objects(obj, mode == RTLD_NOW) == -1) {
1162 		obj->dl_refcount--;
1163 		obj = NULL;
1164 	    } else
1165 		call_init_functions(obj);
1166 	}
1167     }
1168 
1169     GDB_STATE(RT_CONSISTENT);
1170 
1171     return obj;
1172 }
1173 
1174 void *
1175 dlsym(void *handle, const char *name)
1176 {
1177     const Obj_Entry *obj;
1178     unsigned long hash;
1179     const Elf_Sym *def;
1180 
1181     hash = elf_hash(name);
1182     def = NULL;
1183 
1184     if (handle == NULL || handle == RTLD_NEXT) {
1185 	void *retaddr;
1186 
1187 	retaddr = __builtin_return_address(0);	/* __GNUC__ only */
1188 	if ((obj = obj_from_addr(retaddr)) == NULL) {
1189 	    _rtld_error("Cannot determine caller's shared object");
1190 	    return NULL;
1191 	}
1192 	if (handle == NULL)	/* Just the caller's shared object. */
1193 	    def = symlook_obj(name, hash, obj, true);
1194 	else {			/* All the shared objects after the caller's */
1195 	    while ((obj = obj->next) != NULL)
1196 		if ((def = symlook_obj(name, hash, obj, true)) != NULL)
1197 		    break;
1198 	}
1199     } else {
1200 	if ((obj = dlcheck(handle)) == NULL)
1201 	    return NULL;
1202 
1203 	if (obj->mainprog) {
1204 	    /* Search main program and all libraries loaded by it. */
1205 	    for ( ;  obj != *main_tail;  obj = obj->next)
1206 		if ((def = symlook_obj(name, hash, obj, true)) != NULL)
1207 		    break;
1208 	} else {
1209 	    /*
1210 	     * XXX - This isn't correct.  The search should include the whole
1211 	     * DAG rooted at the given object.
1212 	     */
1213 	    def = symlook_obj(name, hash, obj, true);
1214 	}
1215     }
1216 
1217     if (def != NULL)
1218 	return obj->relocbase + def->st_value;
1219 
1220     _rtld_error("Undefined symbol \"%s\"", name);
1221     return NULL;
1222 }
1223 
1224 static void
1225 linkmap_add(Obj_Entry *obj)
1226 {
1227     struct link_map *l = &obj->linkmap;
1228     struct link_map *prev;
1229 
1230     obj->linkmap.l_name = obj->path;
1231     obj->linkmap.l_addr = obj->mapbase;
1232     obj->linkmap.l_ld = obj->dynamic;
1233 #ifdef __mips__
1234     /* GDB needs load offset on MIPS to use the symbols */
1235     obj->linkmap.l_offs = obj->relocbase;
1236 #endif
1237 
1238     if (r_debug.r_map == NULL) {
1239 	r_debug.r_map = l;
1240 	return;
1241     }
1242 
1243     /*
1244      * Scan to the end of the list, but not past the entry for the
1245      * dynamic linker, which we want to keep at the very end.
1246      */
1247     for (prev = r_debug.r_map;
1248       prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
1249       prev = prev->l_next)
1250 	;
1251 
1252     /* Link in the new entry. */
1253     l->l_prev = prev;
1254     l->l_next = prev->l_next;
1255     if (l->l_next != NULL)
1256 	l->l_next->l_prev = l;
1257     prev->l_next = l;
1258 }
1259 
1260 static void
1261 linkmap_delete(Obj_Entry *obj)
1262 {
1263     struct link_map *l = &obj->linkmap;
1264 
1265     if (l->l_prev == NULL) {
1266 	if ((r_debug.r_map = l->l_next) != NULL)
1267 	    l->l_next->l_prev = NULL;
1268 	return;
1269     }
1270 
1271     if ((l->l_prev->l_next = l->l_next) != NULL)
1272 	l->l_next->l_prev = l->l_prev;
1273 }
1274 
1275 /*
1276  * Function for the debugger to set a breakpoint on to gain control.
1277  */
1278 void
1279 r_debug_state(void)
1280 {
1281 }
1282 
1283 /*
1284  * Search the symbol table of a single shared object for a symbol of
1285  * the given name.  Returns a pointer to the symbol, or NULL if no
1286  * definition was found.
1287  *
1288  * The symbol's hash value is passed in for efficiency reasons; that
1289  * eliminates many recomputations of the hash value.
1290  */
1291 const Elf_Sym *
1292 symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
1293   bool in_plt)
1294 {
1295     unsigned long symnum = obj->buckets[hash % obj->nbuckets];
1296 
1297     while (symnum != STN_UNDEF) {
1298 	const Elf_Sym *symp;
1299 	const char *strp;
1300 
1301 	assert(symnum < obj->nchains);
1302 	symp = obj->symtab + symnum;
1303 	assert(symp->st_name != 0);
1304 	strp = obj->strtab + symp->st_name;
1305 
1306 	if (strcmp(name, strp) == 0)
1307 	    return symp->st_shndx != SHN_UNDEF ||
1308 	      (!in_plt && symp->st_value != 0 &&
1309 	      ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL;
1310 
1311 	symnum = obj->chains[symnum];
1312     }
1313 
1314     return NULL;
1315 }
1316 
1317 static void
1318 trace_loaded_objects(Obj_Entry *obj)
1319 {
1320     char	*fmt1, *fmt2, *fmt, *main_local;
1321     int		c;
1322 
1323     if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
1324 	main_local = "";
1325 
1326     if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL)
1327 	fmt1 = "\t%o => %p (%x)\n";
1328 
1329     if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
1330 	fmt2 = "\t%o (%x)\n";
1331 
1332     for (; obj; obj = obj->next) {
1333 	Needed_Entry		*needed;
1334 	char			*name, *path;
1335 	bool			is_lib;
1336 
1337 	for (needed = obj->needed; needed; needed = needed->next) {
1338 	    if (needed->obj != NULL) {
1339 		if (needed->obj->traced)
1340 		    continue;
1341 		needed->obj->traced = true;
1342 		path = needed->obj->path;
1343 	    } else
1344 		path = "not found";
1345 
1346 	    name = (char *)obj->strtab + needed->name;
1347 	    is_lib = strncmp(name, "lib", 3) == 0;	/* XXX - bogus */
1348 
1349 	    fmt = is_lib ? fmt1 : fmt2;
1350 	    while ((c = *fmt++) != '\0') {
1351 		switch (c) {
1352 		default:
1353 		    putchar(c);
1354 		    continue;
1355 		case '\\':
1356 		    switch (c = *fmt) {
1357 		    case '\0':
1358 			continue;
1359 		    case 'n':
1360 			putchar('\n');
1361 			break;
1362 		    case 't':
1363 			putchar('\t');
1364 			break;
1365 		    }
1366 		    break;
1367 		case '%':
1368 		    switch (c = *fmt) {
1369 		    case '\0':
1370 			continue;
1371 		    case '%':
1372 		    default:
1373 			putchar(c);
1374 			break;
1375 		    case 'A':
1376 			printf("%s", main_local);
1377 			break;
1378 		    case 'a':
1379 			printf("%s", obj_main->path);
1380 			break;
1381 		    case 'o':
1382 			printf("%s", name);
1383 			break;
1384 #if 0
1385 		    case 'm':
1386 			printf("%d", sodp->sod_major);
1387 			break;
1388 		    case 'n':
1389 			printf("%d", sodp->sod_minor);
1390 			break;
1391 #endif
1392 		    case 'p':
1393 			printf("%s", path);
1394 			break;
1395 		    case 'x':
1396 			printf("%p", needed->obj ? needed->obj->mapbase : 0);
1397 			break;
1398 		    }
1399 		    break;
1400 		}
1401 		++fmt;
1402 	    }
1403 	}
1404     }
1405 }
1406 
1407 static void
1408 unref_object_dag(Obj_Entry *root)
1409 {
1410     assert(root->refcount != 0);
1411     root->refcount--;
1412     if (root->refcount == 0) {
1413 	const Needed_Entry *needed;
1414 
1415 	for (needed = root->needed;  needed != NULL;  needed = needed->next)
1416 	    unref_object_dag(needed->obj);
1417     }
1418 }
1419 
1420 /*
1421  * Non-mallocing printf, for use by malloc itself.
1422  * XXX - This doesn't belong in this module.
1423  */
1424 void
1425 xprintf(const char *fmt, ...)
1426 {
1427     char buf[256];
1428     va_list ap;
1429 
1430     va_start(ap, fmt);
1431     vsprintf(buf, fmt, ap);
1432     (void)write(1, buf, strlen(buf));
1433     va_end(ap);
1434 }
1435