Module Name:    src
Committed By:   maxv
Date:           Mon Aug  1 15:41:05 UTC 2016

Modified Files:
        src/sys/kern: subr_kobj.c

Log Message:
Don't fail if a module does not have a data or rodata section. Small
modules don't have data.


To generate a diff of this commit:
cvs rdiff -u -r1.57 -r1.58 src/sys/kern/subr_kobj.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_kobj.c
diff -u src/sys/kern/subr_kobj.c:1.57 src/sys/kern/subr_kobj.c:1.58
--- src/sys/kern/subr_kobj.c:1.57	Wed Jul 20 13:36:19 2016
+++ src/sys/kern/subr_kobj.c	Mon Aug  1 15:41:05 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_kobj.c,v 1.57 2016/07/20 13:36:19 maxv Exp $	*/
+/*	$NetBSD: subr_kobj.c,v 1.58 2016/08/01 15:41:05 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.57 2016/07/20 13:36:19 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.58 2016/08/01 15:41:05 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_modular.h"
@@ -424,16 +424,38 @@ kobj_load(kobj_t ko)
 		error = ENOEXEC;
  		goto out;
  	}
-	if (map_data_size == 0) {
-		kobj_error(ko, "no data/bss");
-		error = ENOEXEC;
- 		goto out;
- 	}
-	if (map_rodata_size == 0) {
-		kobj_error(ko, "no rodata");
-		error = ENOEXEC;
- 		goto out;
- 	}
+
+	if (map_data_size != 0) {
+		map_data_base = uvm_km_alloc(module_map, round_page(map_data_size),
+			0, UVM_KMF_WIRED);
+		if (map_data_base == 0) {
+			kobj_error(ko, "out of memory");
+			error = ENOMEM;
+			goto out;
+		}
+		ko->ko_data_address = map_data_base;
+		ko->ko_data_size = map_data_size;
+ 	} else {
+		map_data_base = 0;
+		ko->ko_data_address = 0;
+		ko->ko_data_size = 0;
+	}
+
+	if (map_rodata_size != 0) {
+		map_rodata_base = uvm_km_alloc(module_map, round_page(map_rodata_size),
+			0, UVM_KMF_WIRED);
+		if (map_rodata_base == 0) {
+			kobj_error(ko, "out of memory");
+			error = ENOMEM;
+			goto out;
+		}
+		ko->ko_rodata_address = map_rodata_base;
+		ko->ko_rodata_size = map_rodata_size;
+ 	} else {
+		map_rodata_base = 0;
+		ko->ko_rodata_address = 0;
+		ko->ko_rodata_size = 0;
+	}
 
 	map_text_base = uvm_km_alloc(module_map, round_page(map_text_size),
 	    0, UVM_KMF_WIRED | UVM_KMF_EXEC);
@@ -445,26 +467,6 @@ kobj_load(kobj_t ko)
 	ko->ko_text_address = map_text_base;
 	ko->ko_text_size = map_text_size;
 
-	map_data_base = uvm_km_alloc(module_map, round_page(map_data_size),
-	    0, UVM_KMF_WIRED);
-	if (map_data_base == 0) {
-		kobj_error(ko, "out of memory");
-		error = ENOMEM;
-		goto out;
-	}
-	ko->ko_data_address = map_data_base;
-	ko->ko_data_size = map_data_size;
-
-	map_rodata_base = uvm_km_alloc(module_map, round_page(map_rodata_size),
-	    0, UVM_KMF_WIRED);
-	if (map_rodata_base == 0) {
-		kobj_error(ko, "out of memory");
-		error = ENOMEM;
-		goto out;
-	}
-	ko->ko_rodata_address = map_rodata_base;
-	ko->ko_rodata_size = map_rodata_size;
-
 	/*
 	 * Now load code/data(progbits), zero bss(nobits), allocate space
 	 * for and load relocs
@@ -649,16 +651,22 @@ kobj_unload(kobj_t ko)
 		if (error != 0)
 			kobj_error(ko, "machine dependent deinit failed (text) %d",
 			    error);
-		error = kobj_machdep(ko, (void *)ko->ko_data_address,
-		    ko->ko_data_size, false);
- 		if (error != 0)
-			kobj_error(ko, "machine dependent deinit failed (data) %d",
- 			    error);
-		error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
-		    ko->ko_rodata_size, false);
- 		if (error != 0)
-			kobj_error(ko, "machine dependent deinit failed (rodata) %d",
- 			    error);
+
+		if (ko->ko_data_address != 0) {
+			error = kobj_machdep(ko, (void *)ko->ko_data_address,
+			    ko->ko_data_size, false);
+	 		if (error != 0)
+				kobj_error(ko, "machine dependent deinit failed"
+				    "(data) %d", error);
+		}
+
+		if (ko->ko_rodata_address != 0) {
+			error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
+			    ko->ko_rodata_size, false);
+	 		if (error != 0)
+				kobj_error(ko, "machine dependent deinit failed"
+				    "(rodata) %d", error);
+		}
 	}
 	if (ko->ko_text_address != 0) {
 		uvm_km_free(module_map, ko->ko_text_address,
@@ -752,8 +760,11 @@ kobj_affix(kobj_t ko, const char *name)
 	/* Change the memory protections, when needed. */
 	uvm_km_protect(module_map, ko->ko_text_address, ko->ko_text_size,
 	    VM_PROT_READ|VM_PROT_EXECUTE);
-	uvm_km_protect(module_map, ko->ko_rodata_address, ko->ko_rodata_size,
-	    VM_PROT_READ);
+	if (ko->ko_rodata_address != 0) {
+		uvm_km_protect(module_map, ko->ko_rodata_address,
+		    ko->ko_rodata_size, VM_PROT_READ);
+	}
+
 
 	/*
 	 * Notify MD code that a module has been loaded.
@@ -766,16 +777,23 @@ kobj_affix(kobj_t ko, const char *name)
 		if (error != 0)
 			kobj_error(ko, "machine dependent init failed (text) %d",
 			    error);
-		error = kobj_machdep(ko, (void *)ko->ko_data_address,
-		    ko->ko_data_size, true);
-		if (error != 0)
-			kobj_error(ko, "machine dependent init failed (data) %d",
-			    error);
-		error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
-		    ko->ko_rodata_size, true);
-		if (error != 0)
-			kobj_error(ko, "machine dependent init failed (rodata) %d",
-			    error);
+
+		if (ko->ko_data_address != 0) {
+			error = kobj_machdep(ko, (void *)ko->ko_data_address,
+			    ko->ko_data_size, true);
+			if (error != 0)
+				kobj_error(ko, "machine dependent init failed"
+				    "(data) %d", error);
+		}
+
+		if (ko->ko_rodata_address != 0) {
+			error = kobj_machdep(ko, (void *)ko->ko_rodata_address,
+			    ko->ko_rodata_size, true);
+			if (error != 0)
+				kobj_error(ko, "machine dependent init failed"
+				    "(rodata) %d", error);
+		}
+
 		ko->ko_loaded = true;
 	}
 

Reply via email to