Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Force the kernel to dynamically reallocate the prel...



details:   https://anonhg.NetBSD.org/src/rev/67f9902e6852
branches:  trunk
changeset: 816484:67f9902e6852
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Jul 08 08:55:48 2016 +0000

description:
Force the kernel to dynamically reallocate the preloaded modules.

diffstat:

 sys/kern/subr_kobj.c |  87 +++++++++++++++++++++------------------------------
 1 files changed, 36 insertions(+), 51 deletions(-)

diffs (173 lines):

diff -r e2c8893922fb -r 67f9902e6852 sys/kern/subr_kobj.c
--- a/sys/kern/subr_kobj.c      Fri Jul 08 08:27:07 2016 +0000
+++ b/sys/kern/subr_kobj.c      Fri Jul 08 08:55:48 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_kobj.c,v 1.53 2016/07/07 06:55:43 msaitoh Exp $   */
+/*     $NetBSD: subr_kobj.c,v 1.54 2016/07/08 08:55:48 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.53 2016/07/07 06:55:43 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.54 2016/07/08 08:55:48 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_modular.h"
@@ -392,14 +392,11 @@
         * Size up code/data(progbits) and bss(nobits).
         */
        alignmask = 0;
-       mapbase = 0;
        mapsize = 0;
        for (i = 0; i < hdr->e_shnum; i++) {
                switch (shdr[i].sh_type) {
                case SHT_PROGBITS:
                case SHT_NOBITS:
-                       if (mapbase == 0)
-                               mapbase = shdr[i].sh_offset;
                        alignmask = shdr[i].sh_addralign - 1;
                        mapsize += alignmask;
                        mapsize &= ~alignmask;
@@ -416,19 +413,17 @@
        if (mapsize == 0) {
                kobj_error(ko, "no text/data/bss");
                error = ENOEXEC;
+               goto out;
+       }
+
+       mapbase = uvm_km_alloc(module_map, round_page(mapsize),
+           0, UVM_KMF_WIRED | UVM_KMF_EXEC);
+       if (mapbase == 0) {
+               kobj_error(ko, "out of memory");
+               error = ENOMEM;
                goto out;
        }
-       if (ko->ko_type == KT_MEMORY) {
-               mapbase += (vaddr_t)ko->ko_source;
-       } else {
-               mapbase = uvm_km_alloc(module_map, round_page(mapsize),
-                   0, UVM_KMF_WIRED | UVM_KMF_EXEC);
-               if (mapbase == 0) {
-                       kobj_error(ko, "out of memory");
-                       error = ENOMEM;
-                       goto out;
-               }
-       }
+
        ko->ko_address = mapbase;
        ko->ko_size = mapsize;
 
@@ -445,21 +440,11 @@
                case SHT_PROGBITS:
                case SHT_NOBITS:
                        alignmask = shdr[i].sh_addralign - 1;
-                       if (ko->ko_type == KT_MEMORY) {
-                               addr = (void *)(shdr[i].sh_offset +
-                                   (vaddr_t)ko->ko_source);
-                               if (((vaddr_t)addr & alignmask) != 0) {
-                                       kobj_error(ko,
-                                           "section %d not aligned", i);
-                                       error = ENOEXEC;
-                                       goto out;
-                               }
-                       } else {
-                               mapbase += alignmask;
-                               mapbase &= ~alignmask;
-                               addr = (void *)mapbase;
-                               mapbase += shdr[i].sh_size;
-                       }
+                       mapbase += alignmask;
+                       mapbase &= ~alignmask;
+                       addr = (void *)mapbase;
+                       mapbase += shdr[i].sh_size;
+
                        ko->ko_progtab[pb].addr = addr;
                        if (shdr[i].sh_type == SHT_PROGBITS) {
                                ko->ko_progtab[pb].name = "<<PROGBITS>>";
@@ -469,16 +454,11 @@
                                        kobj_error(ko, "read failed %d", error);
                                        goto out;
                                }
-                       } else if (ko->ko_type == KT_MEMORY &&
-                           shdr[i].sh_size != 0) {
-                               kobj_error(ko, "non-loadable BSS "
-                                   "section in pre-loaded module");
-                               error = ENOEXEC;
-                               goto out;
-                       } else {
+                       } else { /* SHT_NOBITS */
                                ko->ko_progtab[pb].name = "<<NOBITS>>";
                                memset(addr, 0, shdr[i].sh_size);
                        }
+
                        ko->ko_progtab[pb].size = shdr[i].sh_size;
                        ko->ko_progtab[pb].sec = i;
                        if (ko->ko_shstrtab != NULL && shdr[i].sh_name != 0) {
@@ -555,7 +535,7 @@
                panic("%s:%d: %s: lost rela", __func__, __LINE__,
                   ko->ko_name);
        }
-       if (ko->ko_type != KT_MEMORY && mapbase != ko->ko_address + mapsize) {
+       if (mapbase != ko->ko_address + mapsize) {
                panic("%s:%d: %s: "
                    "mapbase 0x%lx != address %lx + mapsize %ld (0x%lx)\n",
                    __func__, __LINE__, ko->ko_name,
@@ -606,7 +586,7 @@
                        kobj_error(ko, "machine dependent deinit failed %d",
                            error);
        }
-       if (ko->ko_address != 0 && ko->ko_type != KT_MEMORY) {
+       if (ko->ko_address != 0) {
                uvm_km_free(module_map, ko->ko_address, round_page(ko->ko_size),
                    UVM_KMF_WIRED);
        }
@@ -1023,21 +1003,27 @@
        void *base = *basep;
        int error;
 
+       KASSERT(ko->ko_source != NULL);
+
        if (ko->ko_memsize != -1 && off + size > ko->ko_memsize) {
                kobj_error(ko, "preloaded object short");
                error = EINVAL;
                base = NULL;
        } else if (allocate) {
-               base = (uint8_t *)ko->ko_source + off;
+               base = kmem_alloc(size, KM_SLEEP);
+               error = 0;
+       } else {
                error = 0;
-       } else if ((uint8_t *)base != (uint8_t *)ko->ko_source + off) {
-               kobj_error(ko, "object not aligned");
-               kobj_error(ko, "source=%p base=%p off=%d "
-                   "size=%zu", ko->ko_source, base, (int)off, size);
-               error = EINVAL;
-       } else {
-               /* Nothing to do.  Loading in-situ. */
-               error = 0;
+       }
+
+       if (error == 0) {
+               /* Copy the section */
+               memcpy(base, (uint8_t *)ko->ko_source + off, size);
+       }
+
+       if (allocate && error != 0) {
+               kmem_free(base, size);
+               base = NULL;
        }
 
        if (allocate)
@@ -1055,8 +1041,7 @@
 kobj_free(kobj_t ko, void *base, size_t size)
 {
 
-       if (ko->ko_type != KT_MEMORY)
-               kmem_free(base, size);
+       kmem_free(base, size);
 }
 
 extern char module_base[];



Home | Main Index | Thread Index | Old Index