* Lookup KLD which contains requested module in the "linker.hints" file. If * version specification is available, then try to find the best KLD. * Otherwise just find the latest one. */
| 1829 | * Otherwise just find the latest one. |
| 1830 | */ |
| 1831 | static char * |
| 1832 | linker_hints_lookup(const char *path, int pathlen, const char *modname, |
| 1833 | int modnamelen, const struct mod_depend *verinfo) |
| 1834 | { |
| 1835 | struct thread *td = curthread; /* XXX */ |
| 1836 | struct ucred *cred = td ? td->td_ucred : NULL; |
| 1837 | struct nameidata nd; |
| 1838 | struct vattr vattr, mattr; |
| 1839 | const char *best, *sep; |
| 1840 | u_char *hints = NULL; |
| 1841 | u_char *cp, *recptr, *bufend, *result, *pathbuf; |
| 1842 | int error, ival, bestver, *intp, found, flags, clen, blen; |
| 1843 | ssize_t reclen; |
| 1844 | |
| 1845 | result = NULL; |
| 1846 | bestver = found = 0; |
| 1847 | |
| 1848 | sep = (path[pathlen - 1] != '/') ? "/" : ""; |
| 1849 | reclen = imax(modnamelen, strlen(linker_hintfile)) + pathlen + |
| 1850 | strlen(sep) + 1; |
| 1851 | pathbuf = malloc(reclen, M_LINKER, M_WAITOK); |
| 1852 | snprintf(pathbuf, reclen, "%.*s%s%s", pathlen, path, sep, |
| 1853 | linker_hintfile); |
| 1854 | |
| 1855 | NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, td); |
| 1856 | flags = FREAD; |
| 1857 | error = vn_open(&nd, &flags, 0, NULL); |
| 1858 | if (error) |
| 1859 | goto bad; |
| 1860 | NDFREE(&nd, NDF_ONLY_PNBUF); |
| 1861 | if (nd.ni_vp->v_type != VREG) |
| 1862 | goto bad; |
| 1863 | best = cp = NULL; |
| 1864 | error = VOP_GETATTR(nd.ni_vp, &vattr, cred); |
| 1865 | #ifdef FSTACK |
| 1866 | if (error || vattr.va_size == 0) |
| 1867 | #else |
| 1868 | if (error) |
| 1869 | #endif |
| 1870 | goto bad; |
| 1871 | /* |
| 1872 | * XXX: we need to limit this number to some reasonable value |
| 1873 | */ |
| 1874 | if (vattr.va_size > LINKER_HINTS_MAX) { |
| 1875 | printf("linker.hints file too large %ld\n", (long)vattr.va_size); |
| 1876 | goto bad; |
| 1877 | } |
| 1878 | hints = malloc(vattr.va_size, M_TEMP, M_WAITOK); |
| 1879 | error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)hints, vattr.va_size, 0, |
| 1880 | UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td); |
| 1881 | if (error) |
| 1882 | goto bad; |
| 1883 | VOP_UNLOCK(nd.ni_vp); |
| 1884 | vn_close(nd.ni_vp, FREAD, cred, td); |
| 1885 | nd.ni_vp = NULL; |
| 1886 | if (reclen != 0) { |
| 1887 | printf("can't read %zd\n", reclen); |
| 1888 | goto bad; |
no test coverage detected