summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-06-20 20:37:17 +0000
committerjhb <jhb@FreeBSD.org>2006-06-20 20:37:17 +0000
commitc9fac30209a97fdedf9aeac93688911025f77170 (patch)
tree752b02bb55e8f018b0e29243b2f03c751e56ee9f /sys/compat
parenteef5a2aec40c3dd5f042fede5cc8566d82c27c0d (diff)
downloadFreeBSD-src-c9fac30209a97fdedf9aeac93688911025f77170.zip
FreeBSD-src-c9fac30209a97fdedf9aeac93688911025f77170.tar.gz
- Add a new linker_file_foreach() function that walks the list of linker
file objects calling a user-specified predicate function on each object. The iteration terminates either when the entire list has been iterated over or the predicate function returns a non-zero value. linker_file_foreach() returns the value returned by the last invocation of the predicate function. It also accepts a void * context pointer that is passed to the predicate function as well. Using an iterator function avoids exposing linker internals to the rest of the kernel making locking simpler. - Use linker_file_foreach() instead of walking the list of linker files manually to lookup ndis files in ndis(4). - Use linker_file_foreach() to implement linker_hwpmc_list_objects().
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/ndis/subr_ndis.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index ee8a0f9..40ff543 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -2886,6 +2886,32 @@ ndis_find_sym(lf, filename, suffix, sym)
return(0);
}
+struct ndis_checkmodule {
+ char *afilename;
+ ndis_fh *fh;
+};
+
+/*
+ * See if a single module contains the symbols for a specified file.
+ */
+static int
+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;
+ nc->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,7 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
struct vattr *vap = &vat;
ndis_fh *fh;
char *path;
- linker_file_t head, lf;
- caddr_t kldstart, kldend;
+ struct ndis_checkmodule nc;
if (RtlUnicodeStringToAnsiString(&as, filename, TRUE)) {
*status = NDIS_STATUS_RESOURCES;
@@ -2943,23 +2968,10 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
* 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;
OpenPOWER on IntegriCloud