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