Date: Tue, 25 Apr 2006 15:46:59 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 96064 for review Message-ID: <200604251546.k3PFkxSb082560@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=96064 Change 96064 by jhb@jhb_slimer on 2006/04/25 15:46:50 - Make linker_find_file_by_name() and linker_find_file_by_id() private to the linker. Add a new linker_file_foreach() function to iterate over the list of linker files calling a predicate function with the linker lock held. - Change ndis to use linker_file_foreach() instead of fondling the list of linker files directly. Affected files ... .. //depot/projects/smpng/sys/compat/ndis/subr_ndis.c#37 edit .. //depot/projects/smpng/sys/kern/kern_linker.c#55 edit .. //depot/projects/smpng/sys/sys/linker.h#20 edit Differences ... ==== //depot/projects/smpng/sys/compat/ndis/subr_ndis.c#37 (text+ko) ==== @@ -2886,6 +2886,32 @@ return(0); } +struct ndis_checkmodule { + char *afilename; + ndis_fh *fh; +}; + +/* + * See if a single module contains the symbols for a specified file. + */ +static void +NdisCheckModule(linker_file_t lf, void *context) +{ + struct ndis_checkmodule *nc; + caddr_t kldstart, kldend; + + nc = (struct ndis_checkmodule *)context; + if (ndis_find_sym(lf, nc->afilename, "_start", &kldstart)) + return (0); + if (ndis_find_sym(lf, nc->afilename, "_end", &kldend)) + return (0); + nc->fh->nf_vp = lf; + nc->fh->nf_map = NULL; + nc->fh->nf_type = NDIS_FH_TYPE_MODULE; + cn->fh->nf_maplen = (kldend - kldstart) & 0xFFFFFFFF; + return (1); +} + /* can also return NDIS_STATUS_RESOURCES/NDIS_STATUS_ERROR_READING_FILE */ static void NdisOpenFile(status, filehandle, filelength, filename, highestaddr) @@ -2904,8 +2930,8 @@ struct vattr *vap = &vat; ndis_fh *fh; char *path; + struct ndis_checkmodule nc; linker_file_t head, lf; - caddr_t kldstart, kldend; if (RtlUnicodeStringToAnsiString(&as, filename, TRUE)) { *status = NDIS_STATUS_RESOURCES; @@ -2943,23 +2969,10 @@ * us since the kernel appears to us as just another module. */ - /* - * This is an evil trick for getting the head of the linked - * file list, which is not exported from kern_linker.o. It - * happens that linker file #1 is always the kernel, and is - * always the first element in the list. - */ - - head = linker_find_file_by_id(1); - for (lf = head; lf != NULL; lf = TAILQ_NEXT(lf, link)) { - if (ndis_find_sym(lf, afilename, "_start", &kldstart)) - continue; - if (ndis_find_sym(lf, afilename, "_end", &kldend)) - continue; - fh->nf_vp = lf; - fh->nf_map = NULL; - fh->nf_type = NDIS_FH_TYPE_MODULE; - *filelength = fh->nf_maplen = (kldend - kldstart) & 0xFFFFFFFF; + nc.afilename = afilename; + nc.fh = fh; + if (linker_file_foreach(NdisCheckModule, &nc)) { + *filelength = fh->nf_maplen; *filehandle = fh; *status = NDIS_STATUS_SUCCESS; return; ==== //depot/projects/smpng/sys/kern/kern_linker.c#55 (text+ko) ==== @@ -72,6 +72,16 @@ */ static const char *linker_basename(const char *path); +/* + * Find a currently loaded file given its filename. + */ +static linker_file_t linker_find_file_by_name(const char* _filename); + +/* + * Find a currently loaded file given its file id. + */ +static linker_file_t linker_find_file_by_id(int _fileid); + /* Metadata from the static kernel */ SET_DECLARE(modmetadata_set, struct mod_metadata); @@ -434,7 +444,7 @@ return (error); } -linker_file_t +static linker_file_t linker_find_file_by_name(const char *filename) { linker_file_t lf; @@ -454,7 +464,7 @@ return (lf); } -linker_file_t +static linker_file_t linker_find_file_by_id(int fileid) { linker_file_t lf; @@ -466,6 +476,22 @@ return (lf); } +int +linker_file_foreach(linker_predicate_t *predicate, void *context) +{ + linker_file_t lf; + int retval = 0; + + KLD_LOCK(); + TAILQ_FOREACH(lf, &linker_files, link) { + retval = predicate(lf, context); + if (retval != 0) + break; + } + KLD_UNLOCK(); + return (retval); +} + linker_file_t linker_make_file(const char *pathname, linker_class_t lc) { ==== //depot/projects/smpng/sys/sys/linker.h#20 (text+ko) ==== @@ -95,6 +95,11 @@ }; /* + * Function type used when iterating over the list of linker files. + */ +typedef int linker_predicate_t(linker_file_t, void *); + +/* * The "file" for the kernel. */ extern linker_file_t linker_kernel_file; @@ -113,19 +118,16 @@ linker_file_t* _result); /* - * Find a currently loaded file given its filename. + * Unload a file, freeing up memory. */ -linker_file_t linker_find_file_by_name(const char* _filename); +int linker_file_unload(linker_file_t _file, int flags); /* - * Find a currently loaded file given its file id. + * Iterate over all of the currently loaded linker files calling the + * predicate function while the function returns 0. Returns the value + * returned by the last predicate function. */ -linker_file_t linker_find_file_by_id(int _fileid); - -/* - * Unload a file, freeing up memory. - */ -int linker_file_unload(linker_file_t _file, int flags); +int linker_file_foreach(linker_predicate_t *_predicate, void *_context); /* * Lookup a symbol in a file. If deps is TRUE, look in dependencies
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604251546.k3PFkxSb082560>