From owner-p4-projects@FreeBSD.ORG Tue Apr 25 15:47:00 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 846C116A40A; Tue, 25 Apr 2006 15:47:00 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C9D716A403 for ; Tue, 25 Apr 2006 15:47:00 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id BFA0043D6B for ; Tue, 25 Apr 2006 15:46:59 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k3PFkx5C082566 for ; Tue, 25 Apr 2006 15:46:59 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k3PFkxSb082560 for perforce@freebsd.org; Tue, 25 Apr 2006 15:46:59 GMT (envelope-from jhb@freebsd.org) Date: Tue, 25 Apr 2006 15:46:59 GMT Message-Id: <200604251546.k3PFkxSb082560@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 96064 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 Apr 2006 15:47:00 -0000 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