LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] fix verify_export_symbols()
@ 2008-03-13  9:04 Jan Beulich
  2008-03-17 22:36 ` Rusty Russell
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Beulich @ 2008-03-13  9:04 UTC (permalink / raw)
  To: linux-kernel

When the newer export flavors were added, it was apparently forgotten
to add respective code here.
In order to not double the (source) size of the function, add some
abstraction to reduce code duplication.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

---
 kernel/module.c |   39 +++++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 20 deletions(-)

--- linux-2.6.25-rc5/kernel/module.c	2008-03-10 13:24:35.000000000 +0100
+++ 2.6.25-rc5-verify-export-symbols/kernel/module.c	2008-03-04 11:23:05.000000000 +0100
@@ -1383,33 +1383,32 @@ EXPORT_SYMBOL_GPL(__symbol_get);
  */
 static int verify_export_symbols(struct module *mod)
 {
-	const char *name = NULL;
-	unsigned long i, ret = 0;
+	const char *name;
+	unsigned int i;
 	struct module *owner;
 	const unsigned long *crc;
 
-	for (i = 0; i < mod->num_syms; i++)
-		if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name,
-							&owner, &crc, 1))) {
-			name = mod->syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
-		}
+#define VERIFY(syms) \
+	for (i = 0; i < mod->num_##syms; i++) { \
+		name = mod->syms[i].name; \
+		if (!IS_ERR_VALUE(__find_symbol(name, &owner, &crc, 1))) \
+			goto dup; \
+	}
 
-	for (i = 0; i < mod->num_gpl_syms; i++)
-		if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name,
-							&owner, &crc, 1))) {
-			name = mod->gpl_syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
-		}
+	VERIFY(syms);
+	VERIFY(gpl_syms);
+	VERIFY(gpl_future_syms);
+	VERIFY(unused_syms);
+	VERIFY(unused_gpl_syms);
+#undef VERIFY
+
+	return 0;
 
 dup:
-	if (ret)
-		printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
-			mod->name, name, module_name(owner));
+	printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
+		mod->name, name, module_name(owner));
 
-	return ret;
+	return -ENOEXEC;
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] fix verify_export_symbols()
  2008-03-13  9:04 [PATCH] fix verify_export_symbols() Jan Beulich
@ 2008-03-17 22:36 ` Rusty Russell
  2008-03-18  0:29   ` Rusty Russell
  0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2008-03-17 22:36 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, Andrew Morton

On Thursday 13 March 2008 20:04:17 you wrote:
> When the newer export flavors were added, it was apparently forgotten
> to add respective code here.
> In order to not double the (source) size of the function, add some
> abstraction to reduce code duplication.

Hi Jan,

   Actually, the others did exist, they just weren't checked.

I've taken this patch and your two other module patches.  Please cc me on 
module patches in future.

Thanks!
Rusty.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] fix verify_export_symbols()
  2008-03-17 22:36 ` Rusty Russell
@ 2008-03-18  0:29   ` Rusty Russell
  2008-03-20  5:25     ` [PATCH 1/2] module: neaten __find_symbol, rename to find_symbol Rusty Russell
  0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2008-03-18  0:29 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, Andrew Morton

On Tuesday 18 March 2008 09:36:04 Rusty Russell wrote:
> On Thursday 13 March 2008 20:04:17 you wrote:
> > When the newer export flavors were added, it was apparently forgotten
> > to add respective code here.
> > In order to not double the (source) size of the function, add some
> > abstraction to reduce code duplication.
>
> Hi Jan,
>
>    Actually, the others did exist, they just weren't checked.

No, my bad, you're right (GPL-only existed, but they were covered already).  
The problem with this is that we'll get a bogus unused warning in the case of 
doing a __find_symbol on an unused symbol.

It's time for a general cleanup of the __find_symbol logic.  I'll post when 
it's done.

Thanks!
Rusty.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] module: neaten __find_symbol, rename to find_symbol.
  2008-03-18  0:29   ` Rusty Russell
@ 2008-03-20  5:25     ` Rusty Russell
  2008-03-20  5:27       ` [PATCH 2/2] module: Enhance verify_export_symbols Rusty Russell
  0 siblings, 1 reply; 6+ messages in thread
From: Rusty Russell @ 2008-03-20  5:25 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

__find_symbol() has grown over time: there are now 5 different arrays
of symbols it traverses.  It also shouldn't print out a warning on
some calls (ie. verify_symbol which simply checks for name clashes,
and __symbol_put which checks for bugs).

1) Rename to find_symbol: no need for underscores.
2) Use bool and add "warn" parameter to suppress warnings.
3) Make table-driven rather than open coded.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 kernel/module.c |  244 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 122 insertions(+), 122 deletions(-)

diff -r 08e60e418777 kernel/module.c
--- a/kernel/module.c	Tue Mar 18 11:30:06 2008 +1100
+++ b/kernel/module.c	Tue Mar 18 14:15:32 2008 +1100
@@ -165,131 +165,136 @@ static const struct kernel_symbol *looku
 	return NULL;
 }
 
-static void printk_unused_warning(const char *name)
+static bool always_ok(bool gplok, bool warn, const char *name)
 {
-	printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
-		"however this module is using it.\n", name);
-	printk(KERN_WARNING "This symbol will go away in the future.\n");
-	printk(KERN_WARNING "Please evalute if this is the right api to use, "
-		"and if it really is, submit a report the linux kernel "
-		"mailinglist together with submitting your code for "
-		"inclusion.\n");
+	return true;
 }
 
-/* Find a symbol, return value, crc and module which owns it */
-static unsigned long __find_symbol(const char *name,
-				   struct module **owner,
-				   const unsigned long **crc,
-				   int gplok)
+static bool printk_unused_warning(bool gplok, bool warn, const char *name)
+{
+	if (warn) {
+		printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
+		       "however this module is using it.\n", name);
+		printk(KERN_WARNING
+		       "This symbol will go away in the future.\n");
+		printk(KERN_WARNING
+		       "Please evalute if this is the right api to use and if "
+		       "it really is, submit a report the linux kernel "
+		       "mailinglist together with submitting your code for "
+		       "inclusion.\n");
+	}
+	return true;
+}
+
+static bool gpl_only_unused_warning(bool gplok, bool warn, const char *name)
+{
+	if (!gplok)
+		return false;
+	return printk_unused_warning(gplok, warn, name);
+}
+
+static bool gpl_only(bool gplok, bool warn, const char *name)
+{
+	return gplok;
+}
+
+static bool warn_if_not_gpl(bool gplok, bool warn, const char *name)
+{
+	if (!gplok && warn) {
+		printk(KERN_WARNING "Symbol %s is being used "
+		       "by a non-GPL module, which will not "
+		       "be allowed in the future\n", name);
+		printk(KERN_WARNING "Please see the file "
+		       "Documentation/feature-removal-schedule.txt "
+		       "in the kernel source tree for more details.\n");
+	}
+	return true;
+}
+
+struct symsearch {
+	const struct kernel_symbol *start, *stop;
+	bool (*check)(bool gplok, bool warn, const char *name);
+};
+
+/* Look through this array of symbol tables for a symbol match which
+ * passes the check function. */
+static const struct kernel_symbol *search_symarrays(const struct symsearch *arr,
+						    unsigned int num,
+						    const char *name,
+						    bool gplok,
+						    bool warn,
+						    const unsigned long **crc)
+{
+	unsigned int i;
+	const struct kernel_symbol *ks;
+
+	for (i = 0; i < num; i++) {
+		ks = lookup_symbol(name, arr[i].start, arr[i].stop);
+		if (!ks || !arr[i].check(gplok, warn, name))
+			continue;
+
+		if (crc)
+			*crc = symversion(arr[i].start, ks - arr[i].start);
+		return ks;
+	}
+	return NULL;
+}
+
+/* Find a symbol, return value, (optional) crc and (optional) module
+ * which owns it */
+static unsigned long find_symbol(const char *name,
+				 struct module **owner,
+				 const unsigned long **crc,
+				 bool gplok,
+				 bool warn)
 {
 	struct module *mod;
 	const struct kernel_symbol *ks;
+	const struct symsearch arr[] = {
+		{ __start___ksymtab, __stop___ksymtab, always_ok },
+		{ __start___ksymtab_gpl, __stop___ksymtab_gpl, gpl_only },
+		{ __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,
+		  warn_if_not_gpl },
+		{ __start___ksymtab_unused, __stop___ksymtab_unused,
+		  printk_unused_warning },
+		{ __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,
+		  gpl_only_unused_warning },
+	};
 
 	/* Core kernel first. */
-	*owner = NULL;
-	ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
+	ks = search_symarrays(arr, ARRAY_SIZE(arr), name, gplok, warn, crc);
 	if (ks) {
-		*crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
-		return ks->value;
-	}
-	if (gplok) {
-		ks = lookup_symbol(name, __start___ksymtab_gpl,
-					 __stop___ksymtab_gpl);
-		if (ks) {
-			*crc = symversion(__start___kcrctab_gpl,
-					  (ks - __start___ksymtab_gpl));
-			return ks->value;
-		}
-	}
-	ks = lookup_symbol(name, __start___ksymtab_gpl_future,
-				 __stop___ksymtab_gpl_future);
-	if (ks) {
-		if (!gplok) {
-			printk(KERN_WARNING "Symbol %s is being used "
-			       "by a non-GPL module, which will not "
-			       "be allowed in the future\n", name);
-			printk(KERN_WARNING "Please see the file "
-			       "Documentation/feature-removal-schedule.txt "
-			       "in the kernel source tree for more "
-			       "details.\n");
-		}
-		*crc = symversion(__start___kcrctab_gpl_future,
-				  (ks - __start___ksymtab_gpl_future));
-		return ks->value;
-	}
-
-	ks = lookup_symbol(name, __start___ksymtab_unused,
-				 __stop___ksymtab_unused);
-	if (ks) {
-		printk_unused_warning(name);
-		*crc = symversion(__start___kcrctab_unused,
-				  (ks - __start___ksymtab_unused));
-		return ks->value;
-	}
-
-	if (gplok)
-		ks = lookup_symbol(name, __start___ksymtab_unused_gpl,
-				 __stop___ksymtab_unused_gpl);
-	if (ks) {
-		printk_unused_warning(name);
-		*crc = symversion(__start___kcrctab_unused_gpl,
-				  (ks - __start___ksymtab_unused_gpl));
+		if (owner)
+			*owner = NULL;
 		return ks->value;
 	}
 
 	/* Now try modules. */
 	list_for_each_entry(mod, &modules, list) {
-		*owner = mod;
-		ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
+		struct symsearch arr[] = {
+			{ mod->syms, mod->syms + mod->num_syms, always_ok },
+			{ mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
+			  gpl_only },
+			{ mod->gpl_future_syms,
+			  mod->gpl_future_syms + mod->num_gpl_future_syms,
+			  warn_if_not_gpl },
+			{ mod->unused_syms,
+			  mod->unused_syms + mod->num_unused_syms,
+			  printk_unused_warning },
+			{ mod->unused_gpl_syms,
+			  mod->unused_gpl_syms + mod->num_unused_gpl_syms,
+			  gpl_only_unused_warning },
+		};
+
+		ks = search_symarrays(arr, ARRAY_SIZE(arr),
+				      name, gplok, warn, crc);
 		if (ks) {
-			*crc = symversion(mod->crcs, (ks - mod->syms));
-			return ks->value;
-		}
-
-		if (gplok) {
-			ks = lookup_symbol(name, mod->gpl_syms,
-					   mod->gpl_syms + mod->num_gpl_syms);
-			if (ks) {
-				*crc = symversion(mod->gpl_crcs,
-						  (ks - mod->gpl_syms));
-				return ks->value;
-			}
-		}
-		ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms);
-		if (ks) {
-			printk_unused_warning(name);
-			*crc = symversion(mod->unused_crcs, (ks - mod->unused_syms));
-			return ks->value;
-		}
-
-		if (gplok) {
-			ks = lookup_symbol(name, mod->unused_gpl_syms,
-					   mod->unused_gpl_syms + mod->num_unused_gpl_syms);
-			if (ks) {
-				printk_unused_warning(name);
-				*crc = symversion(mod->unused_gpl_crcs,
-						  (ks - mod->unused_gpl_syms));
-				return ks->value;
-			}
-		}
-		ks = lookup_symbol(name, mod->gpl_future_syms,
-				   (mod->gpl_future_syms +
-				    mod->num_gpl_future_syms));
-		if (ks) {
-			if (!gplok) {
-				printk(KERN_WARNING "Symbol %s is being used "
-				       "by a non-GPL module, which will not "
-				       "be allowed in the future\n", name);
-				printk(KERN_WARNING "Please see the file "
-				       "Documentation/feature-removal-schedule.txt "
-				       "in the kernel source tree for more "
-				       "details.\n");
-			}
-			*crc = symversion(mod->gpl_future_crcs,
-					  (ks - mod->gpl_future_syms));
+			if (owner)
+				*owner = mod;
 			return ks->value;
 		}
 	}
+
 	DEBUGP("Failed to find symbol %s\n", name);
 	return -ENOENT;
 }
@@ -778,10 +783,9 @@ void __symbol_put(const char *symbol)
 void __symbol_put(const char *symbol)
 {
 	struct module *owner;
-	const unsigned long *crc;
 
 	preempt_disable();
-	if (IS_ERR_VALUE(__find_symbol(symbol, &owner, &crc, 1)))
+	if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
 		BUG();
 	module_put(owner);
 	preempt_enable();
@@ -925,13 +929,10 @@ static inline int check_modstruct_versio
 					  struct module *mod)
 {
 	const unsigned long *crc;
-	struct module *owner;
 
-	if (IS_ERR_VALUE(__find_symbol("struct_module",
-						&owner, &crc, 1)))
+	if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
 		BUG();
-	return check_version(sechdrs, versindex, "struct_module", mod,
-			     crc);
+	return check_version(sechdrs, versindex, "struct_module", mod, crc);
 }
 
 /* First part is kernel version, which we ignore. */
@@ -975,8 +976,8 @@ static unsigned long resolve_symbol(Elf_
 	unsigned long ret;
 	const unsigned long *crc;
 
-	ret = __find_symbol(name, &owner, &crc,
-			!(mod->taints & TAINT_PROPRIETARY_MODULE));
+	ret = find_symbol(name, &owner, &crc,
+			  !(mod->taints & TAINT_PROPRIETARY_MODULE), true);
 	if (!IS_ERR_VALUE(ret)) {
 		/* use_module can fail due to OOM,
 		   or module initialization or unloading */
@@ -1377,10 +1378,9 @@ void *__symbol_get(const char *symbol)
 {
 	struct module *owner;
 	unsigned long value;
-	const unsigned long *crc;
 
 	preempt_disable();
-	value = __find_symbol(symbol, &owner, &crc, 1);
+	value = find_symbol(symbol, &owner, NULL, true, true);
 	if (IS_ERR_VALUE(value))
 		value = 0;
 	else if (strong_try_module_get(owner))
@@ -1403,16 +1403,16 @@ static int verify_export_symbols(struct 
 	const unsigned long *crc;
 
 	for (i = 0; i < mod->num_syms; i++)
-		if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name,
-							&owner, &crc, 1))) {
+		if (!IS_ERR_VALUE(find_symbol(mod->syms[i].name,
+					      &owner, &crc, true, false))) {
 			name = mod->syms[i].name;
 			ret = -ENOEXEC;
 			goto dup;
 		}
 
 	for (i = 0; i < mod->num_gpl_syms; i++)
-		if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name,
-							&owner, &crc, 1))) {
+		if (!IS_ERR_VALUE(find_symbol(mod->gpl_syms[i].name,
+					      &owner, &crc, true, false))) {
 			name = mod->gpl_syms[i].name;
 			ret = -ENOEXEC;
 			goto dup;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/2] module: Enhance verify_export_symbols
  2008-03-20  5:25     ` [PATCH 1/2] module: neaten __find_symbol, rename to find_symbol Rusty Russell
@ 2008-03-20  5:27       ` Rusty Russell
  0 siblings, 0 replies; 6+ messages in thread
From: Rusty Russell @ 2008-03-20  5:27 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Make verify_export_symbols check the modules unused, unused_gpl and gpl_future syms

Inspired by Jan Beulich's fix, but table-driven.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 kernel/module.c |   48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff -r 08e60e418777 kernel/module.c
--- a/kernel/module.c	Tue Mar 18 11:30:06 2008 +1100
+++ b/kernel/module.c	Tue Mar 18 14:05:37 2008 +1100
@@ -1397,33 +1397,33 @@ EXPORT_SYMBOL_GPL(__symbol_get);
  */
 static int verify_export_symbols(struct module *mod)
 {
-	const char *name = NULL;
-	unsigned long i, ret = 0;
+	unsigned int i;
 	struct module *owner;
-	const unsigned long *crc;
+	const struct kernel_symbol *s;
+	struct {
+		const struct kernel_symbol *sym;
+		unsigned int num;
+	} arr[] = {
+		{ mod->syms, mod->num_syms },
+		{ mod->gpl_syms, mod->num_gpl_syms },
+		{ mod->gpl_future_syms, mod->num_gpl_future_syms },
+		{ mod->unused_syms, mod->num_unused_syms },
+		{ mod->unused_gpl_syms, mod->num_unused_gpl_syms },
+	};
 
-	for (i = 0; i < mod->num_syms; i++)
-		if (!IS_ERR_VALUE(find_symbol(mod->syms[i].name,
-					      &owner, &crc, true, false))) {
-			name = mod->syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
+	for (i = 0; i < ARRAY_SIZE(arr); i++) {
+		for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
+			if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
+						      NULL, true, false))) {
+				printk(KERN_ERR
+				       "%s: exports duplicate symbol %s"
+				       " (owned by %s)\n",
+				       mod->name, s->name, module_name(owner));
+				return -ENOEXEC;
+			}
 		}
-
-	for (i = 0; i < mod->num_gpl_syms; i++)
-		if (!IS_ERR_VALUE(find_symbol(mod->gpl_syms[i].name,
-					      &owner, &crc, true, false))) {
-			name = mod->gpl_syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
-		}
-
-dup:
-	if (ret)
-		printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
-			mod->name, name, module_name(owner));
-
-	return ret;
+	}
+	return 0;
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] fix verify_export_symbols()
@ 2008-01-10 16:37 Jan Beulich
  0 siblings, 0 replies; 6+ messages in thread
From: Jan Beulich @ 2008-01-10 16:37 UTC (permalink / raw)
  To: linux-kernel

When the newer export flavors were added, it was apparently forgotten
to add respective code here.
In order to not double the (source) size of the function, add some
abstraction to reduce code duplication.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
---

 kernel/module.c |   37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

--- linux-2.6.24-rc7/kernel/module.c	2008-01-10 16:50:54.000000000 +0100
+++ 2.6.24-rc7-verify-export-symbols/kernel/module.c	2008-01-08 16:42:35.000000000 +0100
@@ -1344,31 +1344,32 @@ EXPORT_SYMBOL_GPL(__symbol_get);
  */
 static int verify_export_symbols(struct module *mod)
 {
-	const char *name = NULL;
-	unsigned long i, ret = 0;
+	const char *name;
+	unsigned int i;
 	struct module *owner;
 	const unsigned long *crc;
 
-	for (i = 0; i < mod->num_syms; i++)
-		if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
-			name = mod->syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
-		}
+#define VERIFY(syms) \
+	for (i = 0; i < mod->num_##syms; i++) { \
+		name = mod->syms[i].name; \
+		if (__find_symbol(name, &owner, &crc, 1)) \
+			goto dup; \
+	}
 
-	for (i = 0; i < mod->num_gpl_syms; i++)
-		if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
-			name = mod->gpl_syms[i].name;
-			ret = -ENOEXEC;
-			goto dup;
-		}
+	VERIFY(syms);
+	VERIFY(gpl_syms);
+	VERIFY(gpl_future_syms);
+	VERIFY(unused_syms);
+	VERIFY(unused_gpl_syms);
+#undef VERIFY
+
+	return 0;
 
 dup:
-	if (ret)
-		printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
-			mod->name, name, module_name(owner));
+	printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
+	       mod->name, name, module_name(owner));
 
-	return ret;
+	return -ENOEXEC;
 }
 
 /* Change all symbols so that st_value encodes the pointer directly. */




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-03-20  5:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-13  9:04 [PATCH] fix verify_export_symbols() Jan Beulich
2008-03-17 22:36 ` Rusty Russell
2008-03-18  0:29   ` Rusty Russell
2008-03-20  5:25     ` [PATCH 1/2] module: neaten __find_symbol, rename to find_symbol Rusty Russell
2008-03-20  5:27       ` [PATCH 2/2] module: Enhance verify_export_symbols Rusty Russell
  -- strict thread matches above, loose matches on Subject: below --
2008-01-10 16:37 [PATCH] fix verify_export_symbols() Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).