xref: /minix3/usr.bin/ldd/ldd.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: ldd.c,v 1.22 2014/03/02 03:55:19 matt Exp $	*/
24b999f19SBen Gras 
34b999f19SBen Gras /*-
44b999f19SBen Gras  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
54b999f19SBen Gras  * All rights reserved.
64b999f19SBen Gras  *
74b999f19SBen Gras  * This code is derived from software contributed to The NetBSD Foundation
84b999f19SBen Gras  * by Paul Kranenburg.
94b999f19SBen Gras  *
104b999f19SBen Gras  * Redistribution and use in source and binary forms, with or without
114b999f19SBen Gras  * modification, are permitted provided that the following conditions
124b999f19SBen Gras  * are met:
134b999f19SBen Gras  * 1. Redistributions of source code must retain the above copyright
144b999f19SBen Gras  *    notice, this list of conditions and the following disclaimer.
154b999f19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
164b999f19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
174b999f19SBen Gras  *    documentation and/or other materials provided with the distribution.
184b999f19SBen Gras  *
194b999f19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
204b999f19SBen Gras  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
214b999f19SBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
224b999f19SBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
234b999f19SBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
244b999f19SBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
254b999f19SBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
264b999f19SBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
274b999f19SBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
284b999f19SBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
294b999f19SBen Gras  * POSSIBILITY OF SUCH DAMAGE.
304b999f19SBen Gras  */
314b999f19SBen Gras 
324b999f19SBen Gras /*
334b999f19SBen Gras  * Copyright 1996 John D. Polstra.
344b999f19SBen Gras  * Copyright 1996 Matt Thomas <matt@3am-software.com>
354b999f19SBen Gras  * All rights reserved.
364b999f19SBen Gras  *
374b999f19SBen Gras  * Redistribution and use in source and binary forms, with or without
384b999f19SBen Gras  * modification, are permitted provided that the following conditions
394b999f19SBen Gras  * are met:
404b999f19SBen Gras  * 1. Redistributions of source code must retain the above copyright
414b999f19SBen Gras  *    notice, this list of conditions and the following disclaimer.
424b999f19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
434b999f19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
444b999f19SBen Gras  *    documentation and/or other materials provided with the distribution.
454b999f19SBen Gras  * 3. All advertising materials mentioning features or use of this software
464b999f19SBen Gras  *    must display the following acknowledgement:
474b999f19SBen Gras  *      This product includes software developed by John Polstra.
484b999f19SBen Gras  * 4. The name of the author may not be used to endorse or promote products
494b999f19SBen Gras  *    derived from this software without specific prior written permission.
504b999f19SBen Gras  *
514b999f19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
524b999f19SBen Gras  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
534b999f19SBen Gras  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
544b999f19SBen Gras  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
554b999f19SBen Gras  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
564b999f19SBen Gras  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
574b999f19SBen Gras  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
584b999f19SBen Gras  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
594b999f19SBen Gras  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
604b999f19SBen Gras  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
614b999f19SBen Gras  */
624b999f19SBen Gras 
634b999f19SBen Gras #include <sys/cdefs.h>
644b999f19SBen Gras #ifndef lint
65*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: ldd.c,v 1.22 2014/03/02 03:55:19 matt Exp $");
664b999f19SBen Gras #endif /* not lint */
674b999f19SBen Gras 
684b999f19SBen Gras #include <sys/types.h>
694b999f19SBen Gras #include <sys/mman.h>
704b999f19SBen Gras #include <sys/wait.h>
714b999f19SBen Gras 
724b999f19SBen Gras #include <dirent.h>
734b999f19SBen Gras #include <err.h>
744b999f19SBen Gras #include <errno.h>
754b999f19SBen Gras #include <fcntl.h>
764b999f19SBen Gras #include <stdarg.h>
774b999f19SBen Gras #include <stdio.h>
784b999f19SBen Gras #include <stdlib.h>
794b999f19SBen Gras #include <string.h>
804b999f19SBen Gras #include <unistd.h>
814b999f19SBen Gras #include <ctype.h>
824b999f19SBen Gras 
834b999f19SBen Gras #include "debug.h"
844b999f19SBen Gras #include "rtld.h"
854b999f19SBen Gras #include "ldd.h"
864b999f19SBen Gras 
874b999f19SBen Gras /*
884b999f19SBen Gras  * Data declarations.
894b999f19SBen Gras  */
904b999f19SBen Gras static char *error_message;	/* Message for dlopen(), or NULL */
914b999f19SBen Gras bool _rtld_trust;		/* False for setuid and setgid programs */
9284d9c625SLionel Sambuc /*
9384d9c625SLionel Sambuc  * This may be ELF64 or ELF32 but since they are used opaquely it doesn't
9484d9c625SLionel Sambuc  * really matter.
9584d9c625SLionel Sambuc  */
964b999f19SBen Gras Obj_Entry *_rtld_objlist;	/* Head of linked list of shared objects */
974b999f19SBen Gras Obj_Entry **_rtld_objtail = &_rtld_objlist;
984b999f19SBen Gras 				/* Link field of last object in list */
994b999f19SBen Gras u_int _rtld_objcount;		/* Number of shared objects */
1004b999f19SBen Gras u_int _rtld_objloads;		/* Number of objects loaded */
1014b999f19SBen Gras 
1024b999f19SBen Gras Obj_Entry *_rtld_objmain;	/* The main program shared object */
1034b999f19SBen Gras size_t _rtld_pagesz;
1044b999f19SBen Gras 
1054b999f19SBen Gras Search_Path *_rtld_default_paths;
1064b999f19SBen Gras Search_Path *_rtld_paths;
1074b999f19SBen Gras Library_Xform *_rtld_xforms;
1084b999f19SBen Gras 
1094b999f19SBen Gras static void usage(void) __dead;
1104b999f19SBen Gras char *main_local;
1114b999f19SBen Gras char *main_progname;
1124b999f19SBen Gras 
1134b999f19SBen Gras static void
usage(void)1144b999f19SBen Gras usage(void)
1154b999f19SBen Gras {
1164b999f19SBen Gras 	fprintf(stderr, "Usage: %s [-f <format 1>] [-f <format 2>] <filename>"
1174b999f19SBen Gras 		" ...\n", getprogname());
1184b999f19SBen Gras 	exit(1);
1194b999f19SBen Gras }
1204b999f19SBen Gras 
1214b999f19SBen Gras int
main(int argc,char ** argv)1224b999f19SBen Gras main(int argc, char **argv)
1234b999f19SBen Gras {
1244b999f19SBen Gras 	const char *fmt1 = NULL, *fmt2 = NULL;
1254b999f19SBen Gras 	int c;
1264b999f19SBen Gras 
1274b999f19SBen Gras #ifdef DEBUG
1284b999f19SBen Gras 	debug = 1;
1294b999f19SBen Gras #endif
1304b999f19SBen Gras 	while ((c = getopt(argc, argv, "f:o")) != -1) {
1314b999f19SBen Gras 		switch (c) {
1324b999f19SBen Gras 		case 'f':
1334b999f19SBen Gras 			if (fmt1) {
1344b999f19SBen Gras 				if (fmt2)
1354b999f19SBen Gras 					errx(1, "Too many formats");
1364b999f19SBen Gras 				fmt2 = optarg;
1374b999f19SBen Gras 			} else
1384b999f19SBen Gras 				fmt1 = optarg;
1394b999f19SBen Gras 			break;
1404b999f19SBen Gras 		case 'o':
1414b999f19SBen Gras 			if (fmt1 || fmt2)
1424b999f19SBen Gras 				errx(1, "Cannot use -o and -f together");
1434b999f19SBen Gras 			fmt1 = "%a:-l%o.%m => %p\n";
1444b999f19SBen Gras 			break;
1454b999f19SBen Gras 		default:
1464b999f19SBen Gras 			usage();
1474b999f19SBen Gras 			/*NOTREACHED*/
1484b999f19SBen Gras 		}
1494b999f19SBen Gras 	}
1504b999f19SBen Gras 	argc -= optind;
1514b999f19SBen Gras 	argv += optind;
1524b999f19SBen Gras 
1534b999f19SBen Gras 	if (argc <= 0) {
1544b999f19SBen Gras 		usage();
1554b999f19SBen Gras 		/*NOTREACHED*/
1564b999f19SBen Gras 	}
1574b999f19SBen Gras 
1584b999f19SBen Gras 	for (; argc != 0; argc--, argv++) {
1594b999f19SBen Gras 		int fd;
1604b999f19SBen Gras 
1614b999f19SBen Gras 		fd = open(*argv, O_RDONLY);
1624b999f19SBen Gras 		if (fd == -1) {
1634b999f19SBen Gras 			warn("%s", *argv);
1644b999f19SBen Gras 			continue;
1654b999f19SBen Gras 		}
1664b999f19SBen Gras 		if (elf_ldd(fd, *argv, fmt1, fmt2) == -1
1674b999f19SBen Gras 		    /* Alpha never had 32 bit support. */
168*0a6a1f1dSLionel Sambuc #if (defined(_LP64) && !defined(ELF64_ONLY)) || defined(MIPS_N32)
1694b999f19SBen Gras 		    && elf32_ldd(fd, *argv, fmt1, fmt2) == -1
17084d9c625SLionel Sambuc #if defined(__mips__) && 0 /* XXX this is still hosed for some reason */
1714b999f19SBen Gras 		    && elf32_ldd_compat(fd, *argv, fmt1, fmt2) == -1
1724b999f19SBen Gras #endif
1734b999f19SBen Gras #endif
1744b999f19SBen Gras 		    )
1754b999f19SBen Gras 			warnx("%s", error_message);
1764b999f19SBen Gras 		close(fd);
1774b999f19SBen Gras 	}
1784b999f19SBen Gras 
1794b999f19SBen Gras 	return 0;
1804b999f19SBen Gras }
1814b999f19SBen Gras 
1824b999f19SBen Gras /*
1834b999f19SBen Gras  * Error reporting function.  Use it like printf.  If formats the message
1844b999f19SBen Gras  * into a buffer, and sets things up so that the next call to dlerror()
1854b999f19SBen Gras  * will return the message.
1864b999f19SBen Gras  */
1874b999f19SBen Gras void
_rtld_error(const char * fmt,...)1884b999f19SBen Gras _rtld_error(const char *fmt, ...)
1894b999f19SBen Gras {
1904b999f19SBen Gras 	static char buf[512];
1914b999f19SBen Gras 	va_list ap;
1924b999f19SBen Gras 	va_start(ap, fmt);
1934b999f19SBen Gras 	xvsnprintf(buf, sizeof buf, fmt, ap);
1944b999f19SBen Gras 	error_message = buf;
1954b999f19SBen Gras 	va_end(ap);
1964b999f19SBen Gras }
1974b999f19SBen Gras 
1984b999f19SBen Gras char *
dlerror()1994b999f19SBen Gras dlerror()
2004b999f19SBen Gras {
2014b999f19SBen Gras 	char *msg = error_message;
2024b999f19SBen Gras 	error_message = NULL;
2034b999f19SBen Gras 	return msg;
2044b999f19SBen Gras }
2054b999f19SBen Gras 
2064b999f19SBen Gras void
_rtld_die(void)20784d9c625SLionel Sambuc _rtld_die(void)
2084b999f19SBen Gras {
20984d9c625SLionel Sambuc 	const char *msg = dlerror();
2104b999f19SBen Gras 
21184d9c625SLionel Sambuc 	if (msg == NULL)
21284d9c625SLionel Sambuc 		msg = "Fatal error";
21384d9c625SLionel Sambuc 	xerrx(1, "%s", msg);
2144b999f19SBen Gras }
2154b999f19SBen Gras 
2164b999f19SBen Gras void
_rtld_shared_enter(void)21784d9c625SLionel Sambuc _rtld_shared_enter(void)
2184b999f19SBen Gras {
21984d9c625SLionel Sambuc }
2204b999f19SBen Gras 
22184d9c625SLionel Sambuc void
_rtld_shared_exit(void)22284d9c625SLionel Sambuc _rtld_shared_exit(void)
22384d9c625SLionel Sambuc {
22484d9c625SLionel Sambuc }
2254b999f19SBen Gras 
22684d9c625SLionel Sambuc void
_rtld_exclusive_enter(sigset_t * mask)22784d9c625SLionel Sambuc _rtld_exclusive_enter(sigset_t *mask)
22884d9c625SLionel Sambuc {
2294b999f19SBen Gras }
23084d9c625SLionel Sambuc 
23184d9c625SLionel Sambuc void
_rtld_exclusive_exit(sigset_t * mask)23284d9c625SLionel Sambuc _rtld_exclusive_exit(sigset_t *mask)
23384d9c625SLionel Sambuc {
2344b999f19SBen Gras }
235