| @@ -1,244 +1,247 @@ | | | @@ -1,244 +1,247 @@ |
1 | /* $NetBSD: ldd.c,v 1.24 2021/07/22 17:39:52 christos Exp $ */ | | 1 | /* $NetBSD: ldd.c,v 1.25 2021/07/23 04:20:05 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Paul Kranenburg. | | 8 | * by Paul Kranenburg. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright | | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the | | 16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. | | 17 | * documentation and/or other materials provided with the distribution. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Copyright 1996 John D. Polstra. | | 33 | * Copyright 1996 John D. Polstra. |
34 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | | 34 | * Copyright 1996 Matt Thomas <matt@3am-software.com> |
35 | * All rights reserved. | | 35 | * All rights reserved. |
36 | * | | 36 | * |
37 | * Redistribution and use in source and binary forms, with or without | | 37 | * Redistribution and use in source and binary forms, with or without |
38 | * modification, are permitted provided that the following conditions | | 38 | * modification, are permitted provided that the following conditions |
39 | * are met: | | 39 | * are met: |
40 | * 1. Redistributions of source code must retain the above copyright | | 40 | * 1. Redistributions of source code must retain the above copyright |
41 | * notice, this list of conditions and the following disclaimer. | | 41 | * notice, this list of conditions and the following disclaimer. |
42 | * 2. Redistributions in binary form must reproduce the above copyright | | 42 | * 2. Redistributions in binary form must reproduce the above copyright |
43 | * notice, this list of conditions and the following disclaimer in the | | 43 | * notice, this list of conditions and the following disclaimer in the |
44 | * documentation and/or other materials provided with the distribution. | | 44 | * documentation and/or other materials provided with the distribution. |
45 | * 3. All advertising materials mentioning features or use of this software | | 45 | * 3. All advertising materials mentioning features or use of this software |
46 | * must display the following acknowledgement: | | 46 | * must display the following acknowledgement: |
47 | * This product includes software developed by John Polstra. | | 47 | * This product includes software developed by John Polstra. |
48 | * 4. The name of the author may not be used to endorse or promote products | | 48 | * 4. The name of the author may not be used to endorse or promote products |
49 | * derived from this software without specific prior written permission. | | 49 | * derived from this software without specific prior written permission. |
50 | * | | 50 | * |
51 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 51 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
52 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 52 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
53 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 53 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
54 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 54 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
55 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 55 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
60 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 60 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | #ifndef lint | | 64 | #ifndef lint |
65 | __RCSID("$NetBSD: ldd.c,v 1.24 2021/07/22 17:39:52 christos Exp $"); | | 65 | __RCSID("$NetBSD: ldd.c,v 1.25 2021/07/23 04:20:05 martin Exp $"); |
66 | #endif /* not lint */ | | 66 | #endif /* not lint */ |
67 | | | 67 | |
68 | #include <sys/types.h> | | 68 | #include <sys/types.h> |
69 | #include <sys/mman.h> | | 69 | #include <sys/mman.h> |
70 | #include <sys/wait.h> | | 70 | #include <sys/wait.h> |
71 | | | 71 | |
72 | #include <dirent.h> | | 72 | #include <dirent.h> |
73 | #include <err.h> | | 73 | #include <err.h> |
74 | #include <errno.h> | | 74 | #include <errno.h> |
75 | #include <fcntl.h> | | 75 | #include <fcntl.h> |
76 | #include <stdarg.h> | | 76 | #include <stdarg.h> |
77 | #include <stdio.h> | | 77 | #include <stdio.h> |
78 | #include <stdlib.h> | | 78 | #include <stdlib.h> |
79 | #include <string.h> | | 79 | #include <string.h> |
80 | #include <unistd.h> | | 80 | #include <unistd.h> |
81 | #include <ctype.h> | | 81 | #include <ctype.h> |
82 | | | 82 | |
83 | #include "debug.h" | | 83 | #include "debug.h" |
84 | #include "rtld.h" | | 84 | #include "rtld.h" |
85 | #include "ldd.h" | | 85 | #include "ldd.h" |
86 | | | 86 | |
87 | /* | | 87 | /* |
88 | * Data declarations. | | 88 | * Data declarations. |
89 | */ | | 89 | */ |
90 | static char *error_message; /* Message for dlopen(), or NULL */ | | 90 | static char *error_message; /* Message for dlopen(), or NULL */ |
91 | bool _rtld_trust; /* False for setuid and setgid programs */ | | 91 | bool _rtld_trust; /* False for setuid and setgid programs */ |
92 | /* | | 92 | /* |
93 | * This may be ELF64 or ELF32 but since they are used opaquely it doesn't | | 93 | * This may be ELF64 or ELF32 but since they are used opaquely it doesn't |
94 | * really matter. | | 94 | * really matter. |
95 | */ | | 95 | */ |
96 | Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ | | 96 | Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ |
97 | Obj_Entry **_rtld_objtail = &_rtld_objlist; | | 97 | Obj_Entry **_rtld_objtail = &_rtld_objlist; |
98 | /* Link field of last object in list */ | | 98 | /* Link field of last object in list */ |
99 | u_int _rtld_objcount; /* Number of shared objects */ | | 99 | u_int _rtld_objcount; /* Number of shared objects */ |
100 | u_int _rtld_objloads; /* Number of objects loaded */ | | 100 | u_int _rtld_objloads; /* Number of objects loaded */ |
101 | | | 101 | |
102 | Obj_Entry *_rtld_objmain; /* The main program shared object */ | | 102 | Obj_Entry *_rtld_objmain; /* The main program shared object */ |
103 | size_t _rtld_pagesz; | | 103 | size_t _rtld_pagesz; |
104 | | | 104 | |
105 | Search_Path *_rtld_default_paths; | | 105 | Search_Path *_rtld_default_paths; |
106 | Search_Path *_rtld_paths; | | 106 | Search_Path *_rtld_paths; |
107 | Library_Xform *_rtld_xforms; | | 107 | Library_Xform *_rtld_xforms; |
108 | | | 108 | |
109 | static void usage(void) __dead; | | 109 | static void usage(void) __dead; |
110 | char *main_local; | | 110 | char *main_local; |
111 | char *main_progname; | | 111 | char *main_progname; |
112 | | | 112 | |
113 | static void | | 113 | static void |
114 | usage(void) | | 114 | usage(void) |
115 | { | | 115 | { |
116 | fprintf(stderr, "Usage: %s [-f <format 1>] [-f <format 2>] <filename>" | | 116 | fprintf(stderr, "Usage: %s [-f <format 1>] [-f <format 2>] <filename>" |
117 | " ...\n", getprogname()); | | 117 | " ...\n", getprogname()); |
118 | exit(1); | | 118 | exit(1); |
119 | } | | 119 | } |
120 | | | 120 | |
121 | int | | 121 | int |
122 | main(int argc, char **argv) | | 122 | main(int argc, char **argv) |
123 | { | | 123 | { |
124 | const char *fmt1 = NULL, *fmt2 = NULL; | | 124 | const char *fmt1 = NULL, *fmt2 = NULL; |
125 | int c, exit_status = EXIT_SUCCESS; | | 125 | int c, exit_status = EXIT_SUCCESS; |
126 | char cwd[MAXPATHLEN], path[MAXPATHLEN]; | | 126 | char cwd[MAXPATHLEN], path[MAXPATHLEN]; |
127 | | | 127 | |
128 | #ifdef DEBUG | | 128 | #ifdef DEBUG |
129 | debug = 1; | | 129 | debug = 1; |
130 | #endif | | 130 | #endif |
131 | while ((c = getopt(argc, argv, "f:o")) != -1) { | | 131 | while ((c = getopt(argc, argv, "f:o")) != -1) { |
132 | switch (c) { | | 132 | switch (c) { |
133 | case 'f': | | 133 | case 'f': |
134 | if (fmt1) { | | 134 | if (fmt1) { |
135 | if (fmt2) | | 135 | if (fmt2) |
136 | errx(1, "Too many formats"); | | 136 | errx(1, "Too many formats"); |
137 | fmt2 = optarg; | | 137 | fmt2 = optarg; |
138 | } else | | 138 | } else |
139 | fmt1 = optarg; | | 139 | fmt1 = optarg; |
140 | break; | | 140 | break; |
141 | case 'o': | | 141 | case 'o': |
142 | if (fmt1 || fmt2) | | 142 | if (fmt1 || fmt2) |
143 | errx(1, "Cannot use -o and -f together"); | | 143 | errx(1, "Cannot use -o and -f together"); |
144 | fmt1 = "%a:-l%o.%m => %p\n"; | | 144 | fmt1 = "%a:-l%o.%m => %p\n"; |
145 | break; | | 145 | break; |
146 | default: | | 146 | default: |
147 | usage(); | | 147 | usage(); |
148 | /*NOTREACHED*/ | | 148 | /*NOTREACHED*/ |
149 | } | | 149 | } |
150 | } | | 150 | } |
151 | argc -= optind; | | 151 | argc -= optind; |
152 | argv += optind; | | 152 | argv += optind; |
153 | | | 153 | |
154 | if (argc <= 0) { | | 154 | if (argc <= 0) { |
155 | usage(); | | 155 | usage(); |
156 | /*NOTREACHED*/ | | 156 | /*NOTREACHED*/ |
157 | } | | 157 | } |
158 | if (getcwd(cwd, sizeof(cwd)) == NULL) | | 158 | if (getcwd(cwd, sizeof(cwd)) == NULL) |
159 | err(EXIT_FAILURE, "Can't get working directory"); | | 159 | err(EXIT_FAILURE, "Can't get working directory"); |
160 | | | 160 | |
161 | for (; argc != 0; argc--, argv++) { | | 161 | for (; argc != 0; argc--, argv++) { |
162 | int fd; | | 162 | int fd; |
163 | | | 163 | |
164 | if (**argv != '/') | | 164 | if (**argv != '/') { |
165 | snprintf(path, sizeof(path), "%s/%s", cwd, *argv); | | 165 | strcpy(path, cwd); |
166 | else | | 166 | strlcat(path, "/", sizeof(path)); |
| | | 167 | strlcat(path, *argv, sizeof(path)); |
| | | 168 | } else { |
167 | strlcpy(path, *argv, sizeof(path)); | | 169 | strlcpy(path, *argv, sizeof(path)); |
| | | 170 | } |
168 | fd = open(*argv, O_RDONLY); | | 171 | fd = open(*argv, O_RDONLY); |
169 | if (fd == -1) { | | 172 | if (fd == -1) { |
170 | exit_status = EXIT_FAILURE; | | 173 | exit_status = EXIT_FAILURE; |
171 | warn("%s", *argv); | | 174 | warn("%s", *argv); |
172 | continue; | | 175 | continue; |
173 | } | | 176 | } |
174 | if (elf_ldd(fd, *argv, path, fmt1, fmt2) == -1 | | 177 | if (elf_ldd(fd, *argv, path, fmt1, fmt2) == -1 |
175 | /* Alpha never had 32 bit support. */ | | 178 | /* Alpha never had 32 bit support. */ |
176 | #if (defined(_LP64) && !defined(ELF64_ONLY)) || defined(MIPS_N32) | | 179 | #if (defined(_LP64) && !defined(ELF64_ONLY)) || defined(MIPS_N32) |
177 | && elf32_ldd(fd, *argv, path, fmt1, fmt2) == -1 | | 180 | && elf32_ldd(fd, *argv, path, fmt1, fmt2) == -1 |
178 | #if defined(__mips__) && 0 /* XXX this is still hosed for some reason */ | | 181 | #if defined(__mips__) && 0 /* XXX this is still hosed for some reason */ |
179 | && elf32_ldd_compat(fd, *argv, path, fmt1, fmt2) == -1 | | 182 | && elf32_ldd_compat(fd, *argv, path, fmt1, fmt2) == -1 |
180 | #endif | | 183 | #endif |
181 | #endif | | 184 | #endif |
182 | ) { | | 185 | ) { |
183 | exit_status = EXIT_FAILURE; | | 186 | exit_status = EXIT_FAILURE; |
184 | warnx("%s", error_message); | | 187 | warnx("%s", error_message); |
185 | } | | 188 | } |
186 | close(fd); | | 189 | close(fd); |
187 | } | | 190 | } |
188 | | | 191 | |
189 | return exit_status; | | 192 | return exit_status; |
190 | } | | 193 | } |
191 | | | 194 | |
192 | /* | | 195 | /* |
193 | * Error reporting function. Use it like printf. If formats the message | | 196 | * Error reporting function. Use it like printf. If formats the message |
194 | * into a buffer, and sets things up so that the next call to dlerror() | | 197 | * into a buffer, and sets things up so that the next call to dlerror() |
195 | * will return the message. | | 198 | * will return the message. |
196 | */ | | 199 | */ |
197 | void | | 200 | void |
198 | _rtld_error(const char *fmt, ...) | | 201 | _rtld_error(const char *fmt, ...) |
199 | { | | 202 | { |
200 | static char buf[512]; | | 203 | static char buf[512]; |
201 | va_list ap; | | 204 | va_list ap; |
202 | va_start(ap, fmt); | | 205 | va_start(ap, fmt); |
203 | xvsnprintf(buf, sizeof buf, fmt, ap); | | 206 | xvsnprintf(buf, sizeof buf, fmt, ap); |
204 | error_message = buf; | | 207 | error_message = buf; |
205 | va_end(ap); | | 208 | va_end(ap); |
206 | } | | 209 | } |
207 | | | 210 | |
208 | char * | | 211 | char * |
209 | dlerror() | | 212 | dlerror() |
210 | { | | 213 | { |
211 | char *msg = error_message; | | 214 | char *msg = error_message; |
212 | error_message = NULL; | | 215 | error_message = NULL; |
213 | return msg; | | 216 | return msg; |
214 | } | | 217 | } |
215 | | | 218 | |
216 | void | | 219 | void |
217 | _rtld_die(void) | | 220 | _rtld_die(void) |
218 | { | | 221 | { |
219 | const char *msg = dlerror(); | | 222 | const char *msg = dlerror(); |
220 | | | 223 | |
221 | if (msg == NULL) | | 224 | if (msg == NULL) |
222 | msg = "Fatal error"; | | 225 | msg = "Fatal error"; |
223 | xerrx(1, "%s", msg); | | 226 | xerrx(1, "%s", msg); |
224 | } | | 227 | } |
225 | | | 228 | |
226 | void | | 229 | void |
227 | _rtld_shared_enter(void) | | 230 | _rtld_shared_enter(void) |
228 | { | | 231 | { |
229 | } | | 232 | } |
230 | | | 233 | |
231 | void | | 234 | void |
232 | _rtld_shared_exit(void) | | 235 | _rtld_shared_exit(void) |
233 | { | | 236 | { |
234 | } | | 237 | } |
235 | | | 238 | |
236 | void | | 239 | void |
237 | _rtld_exclusive_enter(sigset_t *mask) | | 240 | _rtld_exclusive_enter(sigset_t *mask) |
238 | { | | 241 | { |
239 | } | | 242 | } |
240 | | | 243 | |
241 | void | | 244 | void |
242 | _rtld_exclusive_exit(sigset_t *mask) | | 245 | _rtld_exclusive_exit(sigset_t *mask) |
243 | { | | 246 | { |
244 | } | | 247 | } |