Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Split the data+bss+rodata segment in two data+bss and ro...
details: https://anonhg.NetBSD.org/src/rev/0d35ac0d4bb4
branches: trunk
changeset: 346583:0d35ac0d4bb4
user: maxv <maxv%NetBSD.org@localhost>
date: Wed Jul 20 13:36:19 2016 +0000
description:
Split the data+bss+rodata segment in two data+bss and rodata segments. The
latter is made read-only.
diffstat:
sys/kern/subr_kobj.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
sys/kern/subr_kobj_vfs.c | 8 +++++-
sys/sys/kobj_impl.h | 6 +++-
3 files changed, 62 insertions(+), 6 deletions(-)
diffs (203 lines):
diff -r ca539694eca0 -r 0d35ac0d4bb4 sys/kern/subr_kobj.c
--- a/sys/kern/subr_kobj.c Wed Jul 20 13:11:58 2016 +0000
+++ b/sys/kern/subr_kobj.c Wed Jul 20 13:36:19 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_kobj.c,v 1.56 2016/07/20 13:11:58 maxv Exp $ */
+/* $NetBSD: subr_kobj.c,v 1.57 2016/07/20 13:36:19 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.56 2016/07/20 13:11:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.57 2016/07/20 13:36:19 maxv Exp $");
#ifdef _KERNEL_OPT
#include "opt_modular.h"
@@ -162,8 +162,10 @@
Elf_Sym *es;
vaddr_t map_text_base;
vaddr_t map_data_base;
+ vaddr_t map_rodata_base;
size_t map_text_size;
size_t map_data_size;
+ size_t map_rodata_size;
int error;
int symtabindex;
int symstrindex;
@@ -396,6 +398,7 @@
alignmask = 0;
map_text_size = 0;
map_data_size = 0;
+ map_rodata_size = 0;
for (i = 0; i < hdr->e_shnum; i++) {
if (shdr[i].sh_type != SHT_PROGBITS &&
shdr[i].sh_type != SHT_NOBITS)
@@ -405,6 +408,10 @@
map_text_size += alignmask;
map_text_size &= ~alignmask;
map_text_size += shdr[i].sh_size;
+ } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
+ map_rodata_size += alignmask;
+ map_rodata_size &= ~alignmask;
+ map_rodata_size += shdr[i].sh_size;
} else {
map_data_size += alignmask;
map_data_size &= ~alignmask;
@@ -422,6 +429,11 @@
error = ENOEXEC;
goto out;
}
+ if (map_rodata_size == 0) {
+ kobj_error(ko, "no rodata");
+ error = ENOEXEC;
+ goto out;
+ }
map_text_base = uvm_km_alloc(module_map, round_page(map_text_size),
0, UVM_KMF_WIRED | UVM_KMF_EXEC);
@@ -443,6 +455,16 @@
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
@@ -461,6 +483,11 @@
map_text_base &= ~alignmask;
addr = (void *)map_text_base;
map_text_base += shdr[i].sh_size;
+ } else if (!(shdr[i].sh_flags & SHF_WRITE)) {
+ map_rodata_base += alignmask;
+ map_rodata_base &= ~alignmask;
+ addr = (void *)map_rodata_base;
+ map_rodata_base += shdr[i].sh_size;
} else {
map_data_base += alignmask;
map_data_base &= ~alignmask;
@@ -572,6 +599,13 @@
(long)ko->ko_data_address, (long)map_data_size,
(long)ko->ko_data_address + map_data_size);
}
+ if (map_rodata_base != ko->ko_rodata_address + map_rodata_size) {
+ panic("%s:%d: %s: map_rodata_base 0x%lx != address %lx "
+ "+ map_rodata_size %ld (0x%lx)\n",
+ __func__, __LINE__, ko->ko_name, (long)map_rodata_base,
+ (long)ko->ko_rodata_address, (long)map_rodata_size,
+ (long)ko->ko_rodata_address + map_rodata_size);
+ }
/*
* Perform local relocations only. Relocations relating to global
@@ -620,6 +654,11 @@
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_text_address != 0) {
uvm_km_free(module_map, ko->ko_text_address,
@@ -629,6 +668,10 @@
uvm_km_free(module_map, ko->ko_data_address,
round_page(ko->ko_data_size), UVM_KMF_WIRED);
}
+ if (ko->ko_rodata_address != 0) {
+ uvm_km_free(module_map, ko->ko_rodata_address,
+ round_page(ko->ko_rodata_size), UVM_KMF_WIRED);
+ }
if (ko->ko_ksyms == true) {
ksyms_modunload(ko->ko_name);
}
@@ -709,6 +752,8 @@
/* 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);
/*
* Notify MD code that a module has been loaded.
@@ -726,6 +771,11 @@
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);
ko->ko_loaded = true;
}
diff -r ca539694eca0 -r 0d35ac0d4bb4 sys/kern/subr_kobj_vfs.c
--- a/sys/kern/subr_kobj_vfs.c Wed Jul 20 13:11:58 2016 +0000
+++ b/sys/kern/subr_kobj_vfs.c Wed Jul 20 13:36:19 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_kobj_vfs.c,v 1.9 2016/07/09 07:25:00 maxv Exp $ */
+/* $NetBSD: subr_kobj_vfs.c,v 1.10 2016/07/20 13:36:19 maxv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
#include <sys/vnode.h>
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kobj_vfs.c,v 1.9 2016/07/09 07:25:00 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj_vfs.c,v 1.10 2016/07/20 13:36:19 maxv Exp $");
static void
kobj_close_vfs(kobj_t ko)
@@ -114,6 +114,10 @@
(uintptr_t)base + size <=
(uintptr_t)ko->ko_data_address + ko->ko_data_size)
ok = true;
+ if ((uintptr_t)base >= (uintptr_t)ko->ko_rodata_address &&
+ (uintptr_t)base + size <=
+ (uintptr_t)ko->ko_rodata_address + ko->ko_rodata_size)
+ ok = true;
if (!ok)
panic("kobj_read_vfs: not in a dedicated segment");
#endif
diff -r ca539694eca0 -r 0d35ac0d4bb4 sys/sys/kobj_impl.h
--- a/sys/sys/kobj_impl.h Wed Jul 20 13:11:58 2016 +0000
+++ b/sys/sys/kobj_impl.h Wed Jul 20 13:36:19 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kobj_impl.h,v 1.4 2016/07/09 07:25:00 maxv Exp $ */
+/* $NetBSD: kobj_impl.h,v 1.5 2016/07/20 13:36:19 maxv Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -109,6 +109,7 @@
ssize_t ko_memsize;
vaddr_t ko_text_address; /* Address of text segment */
vaddr_t ko_data_address; /* Address of data segment */
+ vaddr_t ko_rodata_address; /* Address of rodata segment */
Elf_Shdr *ko_shdr;
progent_t *ko_progtab;
relaent_t *ko_relatab;
@@ -117,7 +118,8 @@
char *ko_strtab; /* String table */
char *ko_shstrtab; /* Section name string table */
size_t ko_text_size; /* Size of text segment */
- size_t ko_data_size; /* Size of data/bss/rodata segment */
+ size_t ko_data_size; /* Size of data/bss segment */
+ size_t ko_rodata_size; /* Size of rodata segment */
size_t ko_symcnt; /* Number of symbols */
size_t ko_strtabsz; /* Number of bytes in string table */
size_t ko_shstrtabsz; /* Number of bytes in scn str table */
Home |
Main Index |
Thread Index |
Old Index