1 /* Load the dependencies of a mapped object.
2 Copyright (C) 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
26 _dl_map_object_deps (struct link_map
*map
,
27 struct link_map
**preloads
, unsigned int npreloads
,
35 struct list head
[1 + npreloads
], *tailp
, *scanp
;
36 struct list duphead
, *duptailp
;
38 unsigned int nduplist
;
40 /* Start the search list with one element: MAP itself. */
43 /* We use `l_reserved' as a mark bit to detect objects we have already
44 put in the search list and avoid adding duplicate elements later in
48 /* Add the preloaded items after MAP but before any of its dependencies. */
49 for (nlist
= 0; nlist
< npreloads
; ++nlist
)
51 head
[nlist
].next
= &head
[nlist
+ 1];
52 head
[nlist
+ 1].map
= preloads
[nlist
];
53 preloads
[nlist
]->l_reserved
= 1;
56 /* Terminate the lists. */
57 head
[nlist
].next
= NULL
;
60 /* Start here for adding dependencies to the list. */
61 tailp
= &head
[nlist
++];
63 /* Until now we have the same number of libraries in the normal and
64 the list with duplicates. */
68 /* Process each element of the search list, loading each of its immediate
69 dependencies and appending them to the list as we step through it.
70 This produces a flat, ordered list that represents a breadth-first
71 search of the dependency tree. */
72 for (scanp
= head
; scanp
; scanp
= scanp
->next
)
74 struct link_map
*l
= scanp
->map
;
76 if (l
->l_info
[DT_NEEDED
])
79 = ((void *) l
->l_addr
+ l
->l_info
[DT_STRTAB
]->d_un
.d_ptr
);
81 for (d
= l
->l_ld
; d
->d_tag
!= DT_NULL
; ++d
)
82 if (d
->d_tag
== DT_NEEDED
)
84 /* Map in the needed object. */
86 = _dl_map_object (l
, strtab
+ d
->d_un
.d_val
,
87 l
->l_type
== lt_executable
? lt_library
:
88 l
->l_type
, trace_mode
);
91 /* This object is already in the search list we are
92 building. Don't add a duplicate pointer. Release the
93 reference just added by _dl_map_object. */
97 /* Append DEP to the search list. */
98 tailp
->next
= alloca (sizeof *tailp
);
103 /* Set the mark bit that says it's already in the list. */
107 /* In any case Append DEP to the duplicates search list. */
108 duptailp
->next
= alloca (sizeof *duptailp
);
109 duptailp
= duptailp
->next
;
111 duptailp
->next
= NULL
;
117 /* Store the search list we built in the object. It will be used for
118 searches in the scope of this object. */
119 map
->l_searchlist
= malloc (nlist
* sizeof (struct link_map
*));
120 map
->l_nsearchlist
= nlist
;
123 for (scanp
= head
; scanp
; scanp
= scanp
->next
)
125 map
->l_searchlist
[nlist
++] = scanp
->map
;
127 /* Now clear all the mark bits we set in the objects on the search list
128 to avoid duplicates, so the next call starts fresh. */
129 scanp
->map
->l_reserved
= 0;
132 map
->l_dupsearchlist
= malloc (nduplist
* sizeof (struct link_map
*));
133 map
->l_ndupsearchlist
= nduplist
;
135 for (nlist
= 0; nlist
< npreloads
+ 1; ++nlist
)
136 map
->l_dupsearchlist
[nlist
] = head
[nlist
].map
;
137 for (scanp
= duphead
.next
; scanp
; scanp
= scanp
->next
)
138 map
->l_dupsearchlist
[nlist
++] = scanp
->map
;