Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/amd64/stand/prekern Change the mapping logic: don't...
details: https://anonhg.NetBSD.org/src/rev/5380203d6abd
branches: trunk
changeset: 357522:5380203d6abd
user: maxv <maxv%NetBSD.org@localhost>
date: Mon Nov 13 21:14:03 2017 +0000
description:
Change the mapping logic: don't group sections of the same type into
segments, and rather map each section independently at a random VA.
In particular, .data and .bss are not merged anymore and reside at
different addresses.
diffstat:
sys/arch/amd64/stand/prekern/elf.c | 193 ++++----------------------------
sys/arch/amd64/stand/prekern/mm.c | 73 ++---------
sys/arch/amd64/stand/prekern/prekern.h | 10 +-
3 files changed, 44 insertions(+), 232 deletions(-)
diffs (truncated from 357 to 300 lines):
diff -r 75355ac647cc -r 5380203d6abd sys/arch/amd64/stand/prekern/elf.c
--- a/sys/arch/amd64/stand/prekern/elf.c Mon Nov 13 20:38:31 2017 +0000
+++ b/sys/arch/amd64/stand/prekern/elf.c Mon Nov 13 21:14:03 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: elf.c,v 1.9 2017/11/09 15:56:56 maxv Exp $ */
+/* $NetBSD: elf.c,v 1.10 2017/11/13 21:14:04 maxv Exp $ */
/*
* Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -258,184 +258,41 @@
}
}
-static bool
-elf_section_is_text(Elf_Shdr *shdr)
-{
- if (shdr->sh_type != SHT_NOBITS &&
- shdr->sh_type != SHT_PROGBITS) {
- return false;
- }
- if (!(shdr->sh_flags & SHF_EXECINSTR)) {
- return false;
- }
- return true;
-}
-
-static bool
-elf_section_is_rodata(Elf_Shdr *shdr)
-{
- if (shdr->sh_type != SHT_NOBITS &&
- shdr->sh_type != SHT_PROGBITS) {
- return false;
- }
- if (shdr->sh_flags & (SHF_EXECINSTR|SHF_WRITE)) {
- return false;
- }
- return true;
-}
-
-static bool
-elf_section_is_data(Elf_Shdr *shdr)
-{
- if (shdr->sh_type != SHT_NOBITS &&
- shdr->sh_type != SHT_PROGBITS) {
- return false;
- }
- if (!(shdr->sh_flags & SHF_WRITE) ||
- (shdr->sh_flags & SHF_EXECINSTR)) {
- return false;
- }
- return true;
-}
-
void
-elf_get_text(paddr_t *pa, size_t *sz)
-{
- const paddr_t basepa = kernpa_start;
- paddr_t minpa, maxpa, secpa;
- size_t i, secsz;
-
- minpa = 0xFFFFFFFFFFFFFFFF, maxpa = 0;
- for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_text(&eif.shdr[i])) {
- continue;
- }
- secpa = basepa + eif.shdr[i].sh_offset;
- secsz = eif.shdr[i].sh_size;
- if (secpa < minpa) {
- minpa = secpa;
- }
- if (secpa + secsz > maxpa) {
- maxpa = secpa + secsz;
- }
- }
- ASSERT(minpa % PAGE_SIZE == 0);
-
- *pa = minpa;
- *sz = maxpa - minpa;
-}
-
-void
-elf_build_text(vaddr_t textva, paddr_t textpa)
+elf_map_sections()
{
const paddr_t basepa = kernpa_start;
const vaddr_t headva = (vaddr_t)eif.ehdr;
- size_t i, offtext;
+ Elf_Shdr *shdr;
+ int segtype;
+ vaddr_t secva;
+ paddr_t secpa;
+ size_t i, secsz;
for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_text(&eif.shdr[i])) {
+ shdr = &eif.shdr[i];
+
+ if (shdr->sh_type != SHT_NOBITS &&
+ shdr->sh_type != SHT_PROGBITS) {
continue;
}
- /* Offset of the section within the text segment. */
- offtext = basepa + eif.shdr[i].sh_offset - textpa;
+ if (shdr->sh_flags & SHF_EXECINSTR) {
+ segtype = BTSEG_TEXT;
+ } else if (shdr->sh_flags & SHF_WRITE) {
+ segtype = BTSEG_DATA;
+ } else {
+ segtype = BTSEG_RODATA;
+ }
+ secpa = basepa + shdr->sh_offset;
+ secsz = shdr->sh_size;
+ ASSERT(shdr->sh_offset != 0);
+ ASSERT(secpa % PAGE_SIZE == 0);
+
+ secva = mm_map_segment(segtype, secpa, secsz);
/* We want (headva + sh_offset) to be the VA of the section. */
- eif.shdr[i].sh_offset = (textva + offtext - headva);
- }
-}
-
-void
-elf_get_rodata(paddr_t *pa, size_t *sz)
-{
- const paddr_t basepa = kernpa_start;
- paddr_t minpa, maxpa, secpa;
- size_t i, secsz;
-
- minpa = 0xFFFFFFFFFFFFFFFF, maxpa = 0;
- for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_rodata(&eif.shdr[i])) {
- continue;
- }
- secpa = basepa + eif.shdr[i].sh_offset;
- secsz = eif.shdr[i].sh_size;
- if (secpa < minpa) {
- minpa = secpa;
- }
- if (secpa + secsz > maxpa) {
- maxpa = secpa + secsz;
- }
- }
- ASSERT(minpa % PAGE_SIZE == 0);
-
- *pa = minpa;
- *sz = maxpa - minpa;
-}
-
-void
-elf_build_rodata(vaddr_t rodatava, paddr_t rodatapa)
-{
- const paddr_t basepa = kernpa_start;
- const vaddr_t headva = (vaddr_t)eif.ehdr;
- size_t i, offrodata;
-
- for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_rodata(&eif.shdr[i])) {
- continue;
- }
-
- /* Offset of the section within the rodata segment. */
- offrodata = basepa + eif.shdr[i].sh_offset - rodatapa;
-
- /* We want (headva + sh_offset) to be the VA of the section. */
- eif.shdr[i].sh_offset = (rodatava + offrodata - headva);
- }
-}
-
-void
-elf_get_data(paddr_t *pa, size_t *sz)
-{
- const paddr_t basepa = kernpa_start;
- paddr_t minpa, maxpa, secpa;
- size_t i, secsz;
-
- minpa = 0xFFFFFFFFFFFFFFFF, maxpa = 0;
- for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_data(&eif.shdr[i])) {
- continue;
- }
- secpa = basepa + eif.shdr[i].sh_offset;
- secsz = eif.shdr[i].sh_size;
- if (secpa < minpa) {
- minpa = secpa;
- }
- if (secpa + secsz > maxpa) {
- maxpa = secpa + secsz;
- }
- }
- ASSERT(minpa % PAGE_SIZE == 0);
-
- *pa = minpa;
- *sz = maxpa - minpa;
-}
-
-void
-elf_build_data(vaddr_t datava, paddr_t datapa)
-{
- const paddr_t basepa = kernpa_start;
- const vaddr_t headva = (vaddr_t)eif.ehdr;
- size_t i, offdata;
-
- for (i = 0; i < eif.ehdr->e_shnum; i++) {
- if (!elf_section_is_data(&eif.shdr[i])) {
- continue;
- }
-
- /* Offset of the section within the data segment. */
- offdata = basepa + eif.shdr[i].sh_offset - datapa;
-
- /* We want (headva + sh_offset) to be the VA of the section. */
- eif.shdr[i].sh_offset = (datava + offdata - headva);
+ shdr->sh_offset = secva - headva;
}
}
diff -r 75355ac647cc -r 5380203d6abd sys/arch/amd64/stand/prekern/mm.c
--- a/sys/arch/amd64/stand/prekern/mm.c Mon Nov 13 20:38:31 2017 +0000
+++ b/sys/arch/amd64/stand/prekern/mm.c Mon Nov 13 21:14:03 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mm.c,v 1.11 2017/11/11 13:50:57 maxv Exp $ */
+/* $NetBSD: mm.c,v 1.12 2017/11/13 21:14:04 maxv Exp $ */
/*
* Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -313,75 +313,34 @@
fatal("bootspace_addseg: segments full");
}
-static void
-mm_map_segments()
+vaddr_t
+mm_map_segment(int segtype, paddr_t pa, size_t elfsz)
{
- size_t i, npages, size, elfsz;
+ size_t i, npages, size;
vaddr_t randva;
- paddr_t pa;
+ char pad;
- /*
- * Kernel text segment.
- */
- elf_get_text(&pa, &elfsz);
size = roundup(elfsz, PAGE_SIZE);
randva = mm_randva_kregion(size);
npages = size / PAGE_SIZE;
- /* Enter the area and build the ELF info */
for (i = 0; i < npages; i++) {
mm_enter_pa(pa + i * PAGE_SIZE,
randva + i * PAGE_SIZE, MM_PROT_READ|MM_PROT_WRITE);
}
- elf_build_text(randva, pa);
-
- /* Fill in the padding */
- memset((void *)(randva + elfsz), PAD_TEXT, size - elfsz);
-
- /* Register the values in bootspace */
- bootspace_addseg(BTSEG_TEXT, randva, pa, size);
-
- /*
- * Kernel rodata segment.
- */
- elf_get_rodata(&pa, &elfsz);
- size = roundup(elfsz, PAGE_SIZE);
- randva = mm_randva_kregion(size);
- npages = size / PAGE_SIZE;
-
- /* Enter the area and build the ELF info */
- for (i = 0; i < npages; i++) {
- mm_enter_pa(pa + i * PAGE_SIZE,
- randva + i * PAGE_SIZE, MM_PROT_READ|MM_PROT_WRITE);
- }
- elf_build_rodata(randva, pa);
- /* Fill in the padding */
- memset((void *)(randva + elfsz), PAD_RODATA, size - elfsz);
-
- /* Register the values in bootspace */
- bootspace_addseg(BTSEG_RODATA, randva, pa, size);
+ if (segtype == BTSEG_TEXT) {
+ pad = PAD_TEXT;
+ } else if (segtype == BTSEG_RODATA) {
+ pad = PAD_RODATA;
+ } else {
+ pad = PAD_DATA;
+ }
+ memset((void *)(randva + elfsz), pad, size - elfsz);
- /*
- * Kernel data segment.
- */
- elf_get_data(&pa, &elfsz);
- size = roundup(elfsz, PAGE_SIZE);
- randva = mm_randva_kregion(size);
- npages = size / PAGE_SIZE;
+ bootspace_addseg(segtype, randva, pa, size);
Home |
Main Index |
Thread Index |
Old Index