* This routine is responsible for finding dependencies of userland initiated * kldload(2)'s of files. */
| 2156 | * kldload(2)'s of files. |
| 2157 | */ |
| 2158 | int |
| 2159 | linker_load_dependencies(linker_file_t lf) |
| 2160 | { |
| 2161 | linker_file_t lfdep; |
| 2162 | struct mod_metadata **start, **stop, **mdp, **nmdp; |
| 2163 | struct mod_metadata *mp, *nmp; |
| 2164 | const struct mod_depend *verinfo; |
| 2165 | modlist_t mod; |
| 2166 | const char *modname, *nmodname; |
| 2167 | int ver, error = 0; |
| 2168 | |
| 2169 | /* |
| 2170 | * All files are dependent on /kernel. |
| 2171 | */ |
| 2172 | sx_assert(&kld_sx, SA_XLOCKED); |
| 2173 | if (linker_kernel_file) { |
| 2174 | linker_kernel_file->refs++; |
| 2175 | error = linker_file_add_dependency(lf, linker_kernel_file); |
| 2176 | if (error) |
| 2177 | return (error); |
| 2178 | } |
| 2179 | if (linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, |
| 2180 | NULL) != 0) |
| 2181 | return (0); |
| 2182 | for (mdp = start; mdp < stop; mdp++) { |
| 2183 | mp = *mdp; |
| 2184 | if (mp->md_type != MDT_VERSION) |
| 2185 | continue; |
| 2186 | modname = mp->md_cval; |
| 2187 | ver = ((const struct mod_version *)mp->md_data)->mv_version; |
| 2188 | mod = modlist_lookup(modname, ver); |
| 2189 | if (mod != NULL) { |
| 2190 | printf("interface %s.%d already present in the KLD" |
| 2191 | " '%s'!\n", modname, ver, |
| 2192 | mod->container->filename); |
| 2193 | return (EEXIST); |
| 2194 | } |
| 2195 | } |
| 2196 | |
| 2197 | for (mdp = start; mdp < stop; mdp++) { |
| 2198 | mp = *mdp; |
| 2199 | if (mp->md_type != MDT_DEPEND) |
| 2200 | continue; |
| 2201 | modname = mp->md_cval; |
| 2202 | verinfo = mp->md_data; |
| 2203 | nmodname = NULL; |
| 2204 | for (nmdp = start; nmdp < stop; nmdp++) { |
| 2205 | nmp = *nmdp; |
| 2206 | if (nmp->md_type != MDT_VERSION) |
| 2207 | continue; |
| 2208 | nmodname = nmp->md_cval; |
| 2209 | if (strcmp(modname, nmodname) == 0) |
| 2210 | break; |
| 2211 | } |
| 2212 | if (nmdp < stop)/* early exit, it's a self reference */ |
| 2213 | continue; |
| 2214 | mod = modlist_lookup2(modname, verinfo); |
| 2215 | if (mod) { /* woohoo, it's loaded already */ |
no test coverage detected