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