PERFORCE change 96064 for review
John Baldwin
jhb at FreeBSD.org
Tue Apr 25 15:47:00 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=96064
Change 96064 by jhb at 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
More information about the p4-projects
mailing list