Make sure stuff using Obj_Entry is compiled correctly for ELF32 or ELF64.diff -r1.19 -r1.20 src/usr.bin/ldd/ldd.c
(matt)
--- src/usr.bin/ldd/ldd.c 2011/05/24 12:27:29 1.19
+++ src/usr.bin/ldd/ldd.c 2012/07/08 00:53:44 1.20
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ldd.c,v 1.19 2011/05/24 12:27:29 joerg Exp $ */ | 1 | /* $NetBSD: ldd.c,v 1.20 2012/07/08 00:53:44 matt 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. | |
@@ -52,53 +52,57 @@ | @@ -52,53 +52,57 @@ | |||
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.19 2011/05/24 12:27:29 joerg Exp $"); | 65 | __RCSID("$NetBSD: ldd.c,v 1.20 2012/07/08 00:53:44 matt 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 | /* | |||
93 | * This may be ELF64 or ELF32 but since they are used opaquely it doesn't | |||
94 | * really matter. | |||
95 | */ | |||
92 | Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ | 96 | Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ | |
93 | Obj_Entry **_rtld_objtail = &_rtld_objlist; | 97 | Obj_Entry **_rtld_objtail = &_rtld_objlist; | |
94 | /* Link field of last object in list */ | 98 | /* Link field of last object in list */ | |
95 | u_int _rtld_objcount; /* Number of shared objects */ | 99 | u_int _rtld_objcount; /* Number of shared objects */ | |
96 | u_int _rtld_objloads; /* Number of objects loaded */ | 100 | u_int _rtld_objloads; /* Number of objects loaded */ | |
97 | 101 | |||
98 | Obj_Entry *_rtld_objmain; /* The main program shared object */ | 102 | Obj_Entry *_rtld_objmain; /* The main program shared object */ | |
99 | size_t _rtld_pagesz; | 103 | size_t _rtld_pagesz; | |
100 | 104 | |||
101 | Search_Path *_rtld_default_paths; | 105 | Search_Path *_rtld_default_paths; | |
102 | Search_Path *_rtld_paths; | 106 | Search_Path *_rtld_paths; | |
103 | Library_Xform *_rtld_xforms; | 107 | Library_Xform *_rtld_xforms; | |
104 | 108 | |||
@@ -190,131 +194,26 @@ _rtld_error(const char *fmt, ...) | @@ -190,131 +194,26 @@ _rtld_error(const char *fmt, ...) | |||
190 | error_message = buf; | 194 | error_message = buf; | |
191 | va_end(ap); | 195 | va_end(ap); | |
192 | } | 196 | } | |
193 | 197 | |||
194 | char * | 198 | char * | |
195 | dlerror() | 199 | dlerror() | |
196 | { | 200 | { | |
197 | char *msg = error_message; | 201 | char *msg = error_message; | |
198 | error_message = NULL; | 202 | error_message = NULL; | |
199 | return msg; | 203 | return msg; | |
200 | } | 204 | } | |
201 | 205 | |||
202 | void | 206 | void | |
203 | fmtprint(const char *libname, Obj_Entry *obj, const char *fmt1, | |||
204 | const char *fmt2) | |||
205 | { | |||
206 | const char *libpath = obj ? obj->path : "not found"; | |||
207 | char libnamebuf[200]; | |||
208 | char *libmajor = NULL; | |||
209 | const char *fmt; | |||
210 | char *cp; | |||
211 | int c; | |||
212 | ||||
213 | if (strncmp(libname, "lib", 3) == 0 && | |||
214 | (cp = strstr(libname, ".so")) != NULL) { | |||
215 | size_t i = cp - (libname + 3); | |||
216 | ||||
217 | if (i >= sizeof(libnamebuf)) | |||
218 | i = sizeof(libnamebuf) - 1; | |||
219 | (void)memcpy(libnamebuf, libname + 3, i); | |||
220 | libnamebuf[i] = '\0'; | |||
221 | if (cp[3] && isdigit((unsigned char)cp[4])) | |||
222 | libmajor = &cp[4]; | |||
223 | libname = libnamebuf; | |||
224 | } | |||
225 | ||||
226 | if (fmt1 == NULL) | |||
227 | fmt1 = libmajor != NULL ? | |||
228 | "\t-l%o.%m => %p\n" : | |||
229 | "\t-l%o => %p\n"; | |||
230 | if (fmt2 == NULL) | |||
231 | fmt2 = "\t%o => %p\n"; | |||
232 | ||||
233 | fmt = libname == libnamebuf ? fmt1 : fmt2; | |||
234 | while ((c = *fmt++) != '\0') { | |||
235 | switch (c) { | |||
236 | default: | |||
237 | putchar(c); | |||
238 | continue; | |||
239 | case '\\': | |||
240 | switch (c = *fmt) { | |||
241 | case '\0': | |||
242 | continue; | |||
243 | case 'n': | |||
244 | putchar('\n'); | |||
245 | break; | |||
246 | case 't': | |||
247 | putchar('\t'); | |||
248 | break; | |||
249 | } | |||
250 | break; | |||
251 | case '%': | |||
252 | switch (c = *fmt) { | |||
253 | case '\0': | |||
254 | continue; | |||
255 | case '%': | |||
256 | default: | |||
257 | putchar(c); | |||
258 | break; | |||
259 | case 'A': | |||
260 | printf("%s", main_local); | |||
261 | break; | |||
262 | case 'a': | |||
263 | printf("%s", main_progname); | |||
264 | break; | |||
265 | case 'o': | |||
266 | printf("%s", libname); | |||
267 | break; | |||
268 | case 'm': | |||
269 | printf("%s", libmajor); | |||
270 | break; | |||
271 | case 'n': | |||
272 | /* XXX: not supported for elf */ | |||
273 | break; | |||
274 | case 'p': | |||
275 | printf("%s", libpath); | |||
276 | break; | |||
277 | case 'x': | |||
278 | printf("%p", obj ? obj->mapbase : 0); | |||
279 | break; | |||
280 | } | |||
281 | break; | |||
282 | } | |||
283 | ++fmt; | |||
284 | } | |||
285 | } | |||
286 | ||||
287 | void | |||
288 | print_needed(Obj_Entry *obj, const char *fmt1, const char *fmt2) | |||
289 | { | |||
290 | const Needed_Entry *needed; | |||
291 | ||||
292 | for (needed = obj->needed; needed != NULL; needed = needed->next) { | |||
293 | const char *libname = obj->strtab + needed->name; | |||
294 | ||||
295 | if (needed->obj != NULL) { | |||
296 | if (!needed->obj->printed) { | |||
297 | fmtprint(libname, needed->obj, fmt1, fmt2); | |||
298 | needed->obj->printed = 1; | |||
299 | print_needed(needed->obj, fmt1, fmt2); | |||
300 | } | |||
301 | } else { | |||
302 | fmtprint(libname, needed->obj, fmt1, fmt2); | |||
303 | } | |||
304 | } | |||
305 | } | |||
306 | ||||
307 | void | |||
308 | _rtld_die(void) | 207 | _rtld_die(void) | |
309 | { | 208 | { | |
310 | const char *msg = dlerror(); | 209 | const char *msg = dlerror(); | |
311 | 210 | |||
312 | if (msg == NULL) | 211 | if (msg == NULL) | |
313 | msg = "Fatal error"; | 212 | msg = "Fatal error"; | |
314 | xerrx(1, "%s", msg); | 213 | xerrx(1, "%s", msg); | |
315 | } | 214 | } | |
316 | 215 | |||
317 | void | 216 | void | |
318 | _rtld_shared_enter(void) | 217 | _rtld_shared_enter(void) | |
319 | { | 218 | { | |
320 | } | 219 | } |
--- src/usr.bin/ldd/ldd.h 2009/12/15 04:06:43 1.6
+++ src/usr.bin/ldd/ldd.h 2012/07/08 00:53:44 1.7
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ldd.h,v 1.6 2009/12/15 04:06:43 mrg Exp $ */ | 1 | /* $NetBSD: ldd.h,v 1.7 2012/07/08 00:53:44 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2008 Matthew R. Green | 4 | * Copyright (c) 2008 Matthew R. Green | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -33,18 +33,15 @@ int elf32_ldd(int, char *, const char *, | @@ -33,18 +33,15 @@ int elf32_ldd(int, char *, const char *, | |||
33 | #ifdef _LP64 | 33 | #ifdef _LP64 | |
34 | #define LDD_ELF64 | 34 | #define LDD_ELF64 | |
35 | #endif | 35 | #endif | |
36 | 36 | |||
37 | #ifdef LDD_ELF64 | 37 | #ifdef LDD_ELF64 | |
38 | int elf64_ldd(int, char *, const char *, const char *); | 38 | int elf64_ldd(int, char *, const char *, const char *); | |
39 | #define elf_ldd elf64_ldd | 39 | #define elf_ldd elf64_ldd | |
40 | #elif defined(ELF32_COMPAT) | 40 | #elif defined(ELF32_COMPAT) | |
41 | #define elf_ldd elf32_compat_ldd | 41 | #define elf_ldd elf32_compat_ldd | |
42 | #else | 42 | #else | |
43 | #define elf_ldd elf32_ldd | 43 | #define elf_ldd elf32_ldd | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | void fmtprint(const char *, Obj_Entry *, const char *, const char *); | |||
47 | void print_needed(Obj_Entry *, const char *, const char *); | |||
48 | ||||
49 | extern char *main_local; | 46 | extern char *main_local; | |
50 | extern char *main_progname; | 47 | extern char *main_progname; |
--- src/usr.bin/ldd/ldd_elfxx.c 2011/06/30 20:09:41 1.5
+++ src/usr.bin/ldd/ldd_elfxx.c 2012/07/08 00:53:44 1.6
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ldd_elfxx.c,v 1.5 2011/06/30 20:09:41 wiz Exp $ */ | 1 | /* $NetBSD: ldd_elfxx.c,v 1.6 2012/07/08 00:53:44 matt 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. | |
@@ -52,48 +52,51 @@ | @@ -52,48 +52,51 @@ | |||
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_elfxx.c,v 1.5 2011/06/30 20:09:41 wiz Exp $"); | 65 | __RCSID("$NetBSD: ldd_elfxx.c,v 1.6 2012/07/08 00:53:44 matt 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 | static void print_needed(Obj_Entry *, const char *, const char *); | |||
88 | static void fmtprint(const char *, Obj_Entry *, const char *, const char *); | |||
89 | ||||
87 | /* | 90 | /* | |
88 | * elfxx_ldd() - bit-size independent ELF ldd implementation. | 91 | * elfxx_ldd() - bit-size independent ELF ldd implementation. | |
89 | * returns 0 on success and -1 on failure. | 92 | * returns 0 on success and -1 on failure. | |
90 | */ | 93 | */ | |
91 | int | 94 | int | |
92 | ELFNAME(ldd)(int fd, char *path, const char *fmt1, const char *fmt2) | 95 | ELFNAME(ldd)(int fd, char *path, const char *fmt1, const char *fmt2) | |
93 | { | 96 | { | |
94 | struct stat st; | 97 | struct stat st; | |
95 | 98 | |||
96 | if (lseek(fd, 0, SEEK_SET) < 0 || | 99 | if (lseek(fd, 0, SEEK_SET) < 0 || | |
97 | fstat(fd, &st) < 0) { | 100 | fstat(fd, &st) < 0) { | |
98 | _rtld_error("%s: %s", path, strerror(errno)); | 101 | _rtld_error("%s: %s", path, strerror(errno)); | |
99 | return -1; | 102 | return -1; | |
@@ -148,13 +151,118 @@ ELFNAME(ldd)(int fd, char *path, const c | @@ -148,13 +151,118 @@ ELFNAME(ldd)(int fd, char *path, const c | |||
148 | xfree(__UNCONST(needed)); | 151 | xfree(__UNCONST(needed)); | |
149 | } | 152 | } | |
150 | (void) munmap(obj->mapbase, obj->mapsize); | 153 | (void) munmap(obj->mapbase, obj->mapsize); | |
151 | xfree(obj->path); | 154 | xfree(obj->path); | |
152 | xfree(obj); | 155 | xfree(obj); | |
153 | } | 156 | } | |
154 | 157 | |||
155 | _rtld_objmain = NULL; | 158 | _rtld_objmain = NULL; | |
156 | _rtld_objtail = &_rtld_objlist; | 159 | _rtld_objtail = &_rtld_objlist; | |
157 | /* Need to free _rtld_paths? */ | 160 | /* Need to free _rtld_paths? */ | |
158 | 161 | |||
159 | return 0; | 162 | return 0; | |
160 | } | 163 | } | |
164 | ||||
165 | void | |||
166 | fmtprint(const char *libname, Obj_Entry *obj, const char *fmt1, | |||
167 | const char *fmt2) | |||
168 | { | |||
169 | const char *libpath = obj ? obj->path : "not found"; | |||
170 | char libnamebuf[200]; | |||
171 | char *libmajor = NULL; | |||
172 | const char *fmt; | |||
173 | char *cp; | |||
174 | int c; | |||
175 | ||||
176 | if (strncmp(libname, "lib", 3) == 0 && | |||
177 | (cp = strstr(libname, ".so")) != NULL) { | |||
178 | size_t i = cp - (libname + 3); | |||
179 | ||||
180 | if (i >= sizeof(libnamebuf)) | |||
181 | i = sizeof(libnamebuf) - 1; | |||
182 | (void)memcpy(libnamebuf, libname + 3, i); | |||
183 | libnamebuf[i] = '\0'; | |||
184 | if (cp[3] && isdigit((unsigned char)cp[4])) | |||
185 | libmajor = &cp[4]; | |||
186 | libname = libnamebuf; | |||
187 | } | |||
188 | ||||
189 | if (fmt1 == NULL) | |||
190 | fmt1 = libmajor != NULL ? | |||
191 | "\t-l%o.%m => %p\n" : | |||
192 | "\t-l%o => %p\n"; | |||
193 | if (fmt2 == NULL) | |||
194 | fmt2 = "\t%o => %p\n"; | |||
195 | ||||
196 | fmt = libname == libnamebuf ? fmt1 : fmt2; | |||
197 | while ((c = *fmt++) != '\0') { | |||
198 | switch (c) { | |||
199 | default: | |||
200 | putchar(c); | |||
201 | continue; | |||
202 | case '\\': | |||
203 | switch (c = *fmt) { | |||
204 | case '\0': | |||
205 | continue; | |||
206 | case 'n': | |||
207 | putchar('\n'); | |||
208 | break; | |||
209 | case 't': | |||
210 | putchar('\t'); | |||
211 | break; | |||
212 | } | |||
213 | break; | |||
214 | case '%': | |||
215 | switch (c = *fmt) { | |||
216 | case '\0': | |||
217 | continue; | |||
218 | case '%': | |||
219 | default: | |||
220 | putchar(c); | |||
221 | break; | |||
222 | case 'A': | |||
223 | printf("%s", main_local); | |||
224 | break; | |||
225 | case 'a': | |||
226 | printf("%s", main_progname); | |||
227 | break; | |||
228 | case 'o': | |||
229 | printf("%s", libname); | |||
230 | break; | |||
231 | case 'm': | |||
232 | printf("%s", libmajor); | |||
233 | break; | |||
234 | case 'n': | |||
235 | /* XXX: not supported for elf */ | |||
236 | break; | |||
237 | case 'p': | |||
238 | printf("%s", libpath); | |||
239 | break; | |||
240 | case 'x': | |||
241 | printf("%p", obj ? obj->mapbase : 0); | |||
242 | break; | |||
243 | } | |||
244 | break; | |||
245 | } | |||
246 | ++fmt; | |||
247 | } | |||
248 | } | |||
249 | ||||
250 | void | |||
251 | print_needed(Obj_Entry *obj, const char *fmt1, const char *fmt2) | |||
252 | { | |||
253 | const Needed_Entry *needed; | |||
254 | ||||
255 | for (needed = obj->needed; needed != NULL; needed = needed->next) { | |||
256 | const char *libname = obj->strtab + needed->name; | |||
257 | ||||
258 | if (needed->obj != NULL) { | |||
259 | if (!needed->obj->printed) { | |||
260 | fmtprint(libname, needed->obj, fmt1, fmt2); | |||
261 | needed->obj->printed = 1; | |||
262 | print_needed(needed->obj, fmt1, fmt2); | |||
263 | } | |||
264 | } else { | |||
265 | fmtprint(libname, needed->obj, fmt1, fmt2); | |||
266 | } | |||
267 | } | |||
268 | } |