[BZ #77]
[platform/upstream/glibc.git] / elf / dl-open.c
1 /* Load a shared object at runtime, relocate it, and run its initializer.
2    Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <assert.h>
21 #include <dlfcn.h>
22 #include <errno.h>
23 #include <libintl.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/mman.h>           /* Check whether MAP_COPY is defined.  */
29 #include <sys/param.h>
30 #include <bits/libc-lock.h>
31 #include <ldsodefs.h>
32 #include <bp-sym.h>
33 #include <caller.h>
34
35 #include <dl-dst.h>
36
37
38 #ifndef SHARED
39 /* Giving this initialized value preallocates some surplus bytes in the
40    static TLS area, see __libc_setup_tls (libc-tls.c).  */
41 size_t _dl_tls_static_size = 2048;
42 #endif
43
44 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
45                                     void (*dl_main) (const ElfW(Phdr) *phdr,
46                                                      ElfW(Word) phnum,
47                                                      ElfW(Addr) *user_entry));
48 weak_extern (BP_SYM (_dl_sysdep_start))
49
50 extern int __libc_multiple_libcs;       /* Defined in init-first.c.  */
51
52 extern int __libc_argc attribute_hidden;
53 extern char **__libc_argv attribute_hidden;
54
55 extern char **__environ;
56
57 /* Undefine the following for debugging.  */
58 /* #define SCOPE_DEBUG 1 */
59 #ifdef SCOPE_DEBUG
60 static void show_scope (struct link_map *new);
61 #endif
62
63 /* We must be carefull not to leave us in an inconsistent state.  Thus we
64    catch any error and re-raise it after cleaning up.  */
65
66 struct dl_open_args
67 {
68   const char *file;
69   int mode;
70   /* This is the caller of the dlopen() function.  */
71   const void *caller_dlopen;
72   /* This is the caller if _dl_open().  */
73   const void *caller_dl_open;
74   struct link_map *map;
75   /* Namespace ID.  */
76   Lmid_t nsid;
77 };
78
79
80 static int
81 add_to_global (struct link_map *new)
82 {
83   struct link_map **new_global;
84   unsigned int to_add = 0;
85   unsigned int cnt;
86
87   /* Count the objects we have to put in the global scope.  */
88   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
89     if (new->l_searchlist.r_list[cnt]->l_global == 0)
90       ++to_add;
91
92   /* The symbols of the new objects and its dependencies are to be
93      introduced into the global scope that will be used to resolve
94      references from other dynamically-loaded objects.
95
96      The global scope is the searchlist in the main link map.  We
97      extend this list if necessary.  There is one problem though:
98      since this structure was allocated very early (before the libc
99      is loaded) the memory it uses is allocated by the malloc()-stub
100      in the ld.so.  When we come here these functions are not used
101      anymore.  Instead the malloc() implementation of the libc is
102      used.  But this means the block from the main map cannot be used
103      in an realloc() call.  Therefore we allocate a completely new
104      array the first time we have to add something to the locale scope.  */
105
106   if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0)
107     {
108       /* This is the first dynamic object given global scope.  */
109       GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
110         = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8;
111       new_global = (struct link_map **)
112         malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
113                 * sizeof (struct link_map *));
114       if (new_global == NULL)
115         {
116           GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
117         nomem:
118           GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
119                                  N_("cannot extend global scope"));
120           return 1;
121         }
122
123       /* Copy over the old entries.  */
124       GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list
125         = memcpy (new_global,
126                   GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
127                   (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
128                    * sizeof (struct link_map *)));
129     }
130   else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add
131            > GL(dl_ns)[new->l_ns]._ns_global_scope_alloc)
132     {
133       /* We have to extend the existing array of link maps in the
134          main map.  */
135       new_global = (struct link_map **)
136         realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
137                  ((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
138                   * sizeof (struct link_map *)));
139       if (new_global == NULL)
140         goto nomem;
141
142       GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8;
143       GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global;
144     }
145
146   /* Now add the new entries.  */
147   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
148     {
149       struct link_map *map = new->l_searchlist.r_list[cnt];
150
151       if (map->l_global == 0)
152         {
153           map->l_global = 1;
154           GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist]
155             = map;
156           ++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
157         }
158     }
159
160   return 0;
161 }
162
163
164 static void
165 dl_open_worker (void *a)
166 {
167   struct dl_open_args *args = a;
168   const char *file = args->file;
169   int mode = args->mode;
170   struct link_map *new, *l;
171   int lazy;
172   unsigned int i;
173 #ifdef USE_TLS
174   bool any_tls;
175 #endif
176   struct link_map *call_map = NULL;
177
178   /* Check whether _dl_open() has been called from a valid DSO.  */
179   if (__check_caller (args->caller_dl_open, allow_libc|allow_libdl) != 0)
180     GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
181
182   /* Determine the caller's map if necessary.  This is needed in case
183      we have a DST, when we don't know the namespace ID we have to put
184      the new object in, or when the file name has no path in which
185      case we need to look along the RUNPATH/RPATH of the caller.  */
186   const char *dst = strchr (file, '$');
187   if (dst != NULL || args->nsid == __LM_ID_CALLER
188       || strchr (file, '/') == NULL)
189     {
190       const void *caller_dlopen = args->caller_dlopen;
191
192       /* We have to find out from which object the caller is calling.
193          By default we assume this is the main application.  */
194       call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
195
196       for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
197         for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
198           if (caller_dlopen >= (const void *) l->l_map_start
199               && caller_dlopen < (const void *) l->l_map_end)
200             {
201               /* There must be exactly one DSO for the range of the virtual
202                  memory.  Otherwise something is really broken.  */
203               assert (ns == l->l_ns);
204               call_map = l;
205               goto found_caller;
206             }
207
208     found_caller:
209       if (args->nsid == __LM_ID_CALLER)
210         args->nsid = call_map->l_ns;
211     }
212
213   /* Maybe we have to expand a DST.  */
214   if (__builtin_expect (dst != NULL, 0))
215     {
216       size_t len = strlen (file);
217       size_t required;
218       char *new_file;
219
220       /* DSTs must not appear in SUID/SGID programs.  */
221       if (__libc_enable_secure)
222         /* This is an error.  */
223         GLRO(dl_signal_error) (0, "dlopen", NULL,
224                                N_("DST not allowed in SUID/SGID programs"));
225
226
227       /* Determine how much space we need.  We have to allocate the
228          memory locally.  */
229       required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0));
230
231       /* Get space for the new file name.  */
232       new_file = (char *) alloca (required + 1);
233
234       /* Generate the new file name.  */
235       _dl_dst_substitute (call_map, file, new_file, 0);
236
237       /* If the substitution failed don't try to load.  */
238       if (*new_file == '\0')
239         GLRO(dl_signal_error) (0, "dlopen", NULL,
240                                N_("empty dynamic string token substitution"));
241
242       /* Now we have a new file name.  */
243       file = new_file;
244
245       /* It does not matter whether call_map is set even if we
246          computed it only because of the DST.  Since the path contains
247          a slash the value is not used.  See dl-load.c.  */
248     }
249
250   /* Load the named object.  */
251   args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
252                                          mode | __RTLD_CALLMAP, args->nsid);
253
254   /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
255      set and the object is not already loaded.  */
256   if (new == NULL)
257     {
258       assert (mode & RTLD_NOLOAD);
259       return;
260     }
261
262   if (__builtin_expect (mode & __RTLD_SPROF, 0))
263     /* This happens only if we load a DSO for 'sprof'.  */
264     return;
265
266   /* This object is directly loaded.  */
267   ++new->l_direct_opencount;
268
269   /* It was already open.  */
270   if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
271     {
272       /* Let the user know about the opencount.  */
273       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
274         GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
275                                new->l_name, new->l_ns, new->l_opencount);
276
277       /* If the user requested the object to be in the global namespace
278          but it is not so far, add it now.  */
279       if ((mode & RTLD_GLOBAL) && new->l_global == 0)
280         (void) add_to_global (new);
281
282       if (new->l_direct_opencount == 1)
283         /* This is the only direct reference.  Increment all the
284            dependencies' reference counter.  */
285         for (i = 0; i < new->l_searchlist.r_nlist; ++i)
286           ++new->l_searchlist.r_list[i]->l_opencount;
287       else
288         /* Increment just the reference counter of the object.  */
289         ++new->l_opencount;
290
291       return;
292     }
293
294   /* Load that object's dependencies.  */
295   GLRO(dl_map_object_deps) (new, NULL, 0, 0,
296                             mode & (__RTLD_DLOPEN | RTLD_DEEPBIND));
297
298   /* So far, so good.  Now check the versions.  */
299   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
300     if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
301       (void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i]->l_real,
302                                           0, 0);
303
304 #ifdef SCOPE_DEBUG
305   show_scope (new);
306 #endif
307
308   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */
309   lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GLRO(dl_lazy);
310
311   /* Relocate the objects loaded.  We do this in reverse order so that copy
312      relocs of earlier objects overwrite the data written by later objects.  */
313
314   l = new;
315   while (l->l_next)
316     l = l->l_next;
317   while (1)
318     {
319       if (! l->l_real->l_relocated)
320         {
321 #ifdef SHARED
322           if (GLRO(dl_profile) != NULL)
323             {
324               /* If this here is the shared object which we want to profile
325                  make sure the profile is started.  We can find out whether
326                  this is necessary or not by observing the `_dl_profile_map'
327                  variable.  If was NULL but is not NULL afterwars we must
328                  start the profiling.  */
329               struct link_map *old_profile_map = GL(dl_profile_map);
330
331               GLRO(dl_relocate_object) (l, l->l_scope, 1, 1);
332
333               if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
334                 {
335                   /* We must prepare the profiling.  */
336                   GLRO(dl_start_profile) ();
337
338                   /* Prevent unloading the object.  */
339                   GL(dl_profile_map)->l_flags_1 |= DF_1_NODELETE;
340                 }
341             }
342           else
343 #endif
344             GLRO(dl_relocate_object) (l, l->l_scope, lazy, 0);
345         }
346
347       if (l == new)
348         break;
349       l = l->l_prev;
350     }
351
352 #ifdef USE_TLS
353   /* Do static TLS initialization now if it has been delayed because
354      the TLS template might not be fully relocated at _dl_allocate_static_tls
355      time.  */
356   for (l = new; l; l = l->l_next)
357     if (l->l_need_tls_init)
358       {
359         l->l_need_tls_init = 0;
360         GL(dl_init_static_tls) (l);
361       }
362
363   /* We normally don't bump the TLS generation counter.  There must be
364      actually a need to do this.  */
365   any_tls = false;
366 #endif
367
368   /* Increment the open count for all dependencies.  If the file is
369      not loaded as a dependency here add the search list of the newly
370      loaded object to the scope.  */
371   for (i = 0; i < new->l_searchlist.r_nlist; ++i)
372     if (++new->l_searchlist.r_list[i]->l_opencount > 1
373         && new->l_real->l_searchlist.r_list[i]->l_type == lt_loaded)
374       {
375         struct link_map *imap = new->l_searchlist.r_list[i];
376         struct r_scope_elem **runp = imap->l_scope;
377         size_t cnt = 0;
378
379         while (*runp != NULL)
380           {
381             /* This can happen if imap was just loaded, but during
382                relocation had l_opencount bumped because of relocation
383                dependency.  Avoid duplicates in l_scope.  */
384             if (__builtin_expect (*runp == &new->l_searchlist, 0))
385               break;
386
387             ++cnt;
388             ++runp;
389           }
390
391         if (*runp != NULL)
392           /* Avoid duplicates.  */
393           continue;
394
395         if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
396           {
397             /* The 'r_scope' array is too small.  Allocate a new one
398                dynamically.  */
399             struct r_scope_elem **newp;
400             size_t new_size = imap->l_scope_max * 2;
401
402             if (imap->l_scope == imap->l_scope_mem)
403               {
404                 newp = (struct r_scope_elem **)
405                   malloc (new_size * sizeof (struct r_scope_elem *));
406                 if (newp == NULL)
407                   GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL,
408                                          N_("cannot create scope list"));
409                 imap->l_scope = memcpy (newp, imap->l_scope,
410                                         cnt * sizeof (imap->l_scope[0]));
411               }
412             else
413               {
414                 newp = (struct r_scope_elem **)
415                   realloc (imap->l_scope,
416                            new_size * sizeof (struct r_scope_elem *));
417                 if (newp == NULL)
418                   GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL,
419                                          N_("cannot create scope list"));
420                 imap->l_scope = newp;
421               }
422
423             imap->l_scope_max = new_size;
424           }
425
426         imap->l_scope[cnt++] = &new->l_searchlist;
427         imap->l_scope[cnt] = NULL;
428       }
429 #if USE_TLS
430     else if (new->l_searchlist.r_list[i]->l_opencount == 1
431              /* Only if the module defines thread local data.  */
432              && __builtin_expect (new->l_searchlist.r_list[i]->l_tls_blocksize
433                                   > 0, 0))
434       {
435         /* Now that we know the object is loaded successfully add
436            modules containing TLS data to the dtv info table.  We
437            might have to increase its size.  */
438         struct dtv_slotinfo_list *listp;
439         struct dtv_slotinfo_list *prevp;
440         size_t idx = new->l_searchlist.r_list[i]->l_tls_modid;
441
442         assert (new->l_searchlist.r_list[i]->l_type == lt_loaded);
443
444         /* Find the place in the dtv slotinfo list.  */
445         listp = GL(dl_tls_dtv_slotinfo_list);
446         prevp = NULL;           /* Needed to shut up gcc.  */
447         do
448           {
449             /* Does it fit in the array of this list element?  */
450             if (idx < listp->len)
451               break;
452             idx -= listp->len;
453             prevp = listp;
454             listp = listp->next;
455           }
456         while (listp != NULL);
457
458         if (listp == NULL)
459           {
460             /* When we come here it means we have to add a new element
461                to the slotinfo list.  And the new module must be in
462                the first slot.  */
463             assert (idx == 0);
464
465             listp = prevp->next = (struct dtv_slotinfo_list *)
466               malloc (sizeof (struct dtv_slotinfo_list)
467                       + TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
468             if (listp == NULL)
469               {
470                 /* We ran out of memory.  We will simply fail this
471                    call but don't undo anything we did so far.  The
472                    application will crash or be terminated anyway very
473                    soon.  */
474
475                 /* We have to do this since some entries in the dtv
476                    slotinfo array might already point to this
477                    generation.  */
478                 ++GL(dl_tls_generation);
479
480                 GLRO(dl_signal_error) (ENOMEM, "dlopen", NULL, N_("\
481 cannot create TLS data structures"));
482               }
483
484             listp->len = TLS_SLOTINFO_SURPLUS;
485             listp->next = NULL;
486             memset (listp->slotinfo, '\0',
487                     TLS_SLOTINFO_SURPLUS * sizeof (struct dtv_slotinfo));
488           }
489
490         /* Add the information into the slotinfo data structure.  */
491         listp->slotinfo[idx].map = new->l_searchlist.r_list[i];
492         listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
493
494         /* We have to bump the generation counter.  */
495         any_tls = true;
496       }
497
498   /* Bump the generation number if necessary.  */
499   if (any_tls)
500     if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
501       __libc_fatal (_("TLS generation counter wrapped!  Please send report with the 'glibcbug' script."));
502 #endif
503
504   /* Run the initializer functions of new objects.  */
505   GLRO(dl_init) (new, __libc_argc, __libc_argv, __environ);
506
507   /* Now we can make the new map available in the global scope.  */
508   if (mode & RTLD_GLOBAL)
509     /* Move the object in the global namespace.  */
510     if (add_to_global (new) != 0)
511       /* It failed.  */
512       return;
513
514   /* Mark the object as not deletable if the RTLD_NODELETE flags was
515      passed.  */
516   if (__builtin_expect (mode & RTLD_NODELETE, 0))
517     new->l_flags_1 |= DF_1_NODELETE;
518
519 #ifndef SHARED
520   /* We must be the static _dl_open in libc.a.  A static program that
521      has loaded a dynamic object now has competition.  */
522   __libc_multiple_libcs = 1;
523 #endif
524
525   /* Let the user know about the opencount.  */
526   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
527     GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
528                            new->l_name, new->l_ns, new->l_opencount);
529 }
530
531
532 void *
533 internal_function
534 _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
535 {
536   struct dl_open_args args;
537   const char *objname;
538   const char *errstring;
539   int errcode;
540
541   if ((mode & RTLD_BINDING_MASK) == 0)
542     /* One of the flags must be set.  */
543     GLRO(dl_signal_error) (EINVAL, file, NULL,
544                            N_("invalid mode for dlopen()"));
545
546   /* Make sure we are alone.  */
547   __rtld_lock_lock_recursive (GL(dl_load_lock));
548
549   if (nsid == LM_ID_NEWLM)
550     {
551       /* Find a new namespace.  */
552       for (nsid = 1; nsid < DL_NNS; ++nsid)
553         if (GL(dl_ns)[nsid]._ns_loaded == NULL)
554           break;
555
556       if (nsid == DL_NNS)
557         {
558           /* No more namespace available.  */
559           __rtld_lock_unlock_recursive (GL(dl_load_lock));
560
561           GLRO(dl_signal_error) (EINVAL, file, NULL, N_("\
562 no more namespaces available for dlmopen()"));
563         }
564     }
565
566   args.file = file;
567   args.mode = mode;
568   args.caller_dlopen = caller_dlopen;
569   args.caller_dl_open = RETURN_ADDRESS (0);
570   args.map = NULL;
571   args.nsid = nsid;
572   errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
573
574 #ifndef MAP_COPY
575   /* We must munmap() the cache file.  */
576   GLRO(dl_unload_cache) ();
577 #endif
578
579   /* Release the lock.  */
580   __rtld_lock_unlock_recursive (GL(dl_load_lock));
581
582   if (__builtin_expect (errstring != NULL, 0))
583     {
584       /* Some error occurred during loading.  */
585       char *local_errstring;
586       size_t len_errstring;
587
588       /* Remove the object from memory.  It may be in an inconsistent
589          state if relocation failed, for example.  */
590       if (args.map)
591         {
592           unsigned int i;
593
594           /* Increment open counters for all objects since this
595              sometimes has not happened yet.  */
596           if (args.map->l_searchlist.r_list[0]->l_opencount == 0)
597             for (i = 0; i < args.map->l_searchlist.r_nlist; ++i)
598               ++args.map->l_searchlist.r_list[i]->l_opencount;
599
600 #ifdef USE_TLS
601           /* Maybe some of the modules which were loaded uses TLS.
602              Since it will be removed in the following _dl_close call
603              we have to mark the dtv array as having gaps to fill
604              the holes.  This is a pessimistic assumption which won't
605              hurt if not true.  */
606           GL(dl_tls_dtv_gaps) = true;
607 #endif
608
609           _dl_close (args.map);
610         }
611
612       /* Make a local copy of the error string so that we can release the
613          memory allocated for it.  */
614       len_errstring = strlen (errstring) + 1;
615       if (objname == errstring + len_errstring)
616         {
617           size_t total_len = len_errstring + strlen (objname) + 1;
618           local_errstring = alloca (total_len);
619           memcpy (local_errstring, errstring, total_len);
620           objname = local_errstring + len_errstring;
621         }
622       else
623         {
624           local_errstring = alloca (len_errstring);
625           memcpy (local_errstring, errstring, len_errstring);
626         }
627
628       if (errstring != _dl_out_of_memory)
629         free ((char *) errstring);
630
631       /* Reraise the error.  */
632       GLRO(dl_signal_error) (errcode, objname, NULL, local_errstring);
633     }
634
635 #ifndef SHARED
636   DL_STATIC_INIT (args.map);
637 #endif
638
639   return args.map;
640 }
641 libc_hidden_def (_dl_open)
642
643
644 #ifdef SCOPE_DEBUG
645 #include <unistd.h>
646
647 static void
648 show_scope (struct link_map *new)
649 {
650   int scope_cnt;
651
652   for (scope_cnt = 0; new->l_scope[scope_cnt] != NULL; ++scope_cnt)
653     {
654       char numbuf[2];
655       unsigned int cnt;
656
657       numbuf[0] = '0' + scope_cnt;
658       numbuf[1] = '\0';
659       _dl_printf ("scope %s:", numbuf);
660
661       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt)
662         if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name)
663           _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name);
664         else
665           _dl_printf (" <main>");
666
667       _dl_printf ("\n");
668     }
669 }
670 #endif