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/31fa91d284ef
branches:  trunk
changeset: 827823:31fa91d284ef
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 05baabcca8b5 -r 31fa91d284ef 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 05baabcca8b5 -r 31fa91d284ef 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