Source-Changes-HG archive

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

[src/trunk]: src/sys/lib/libsa Group the sections into segments, and align to...



details:   https://anonhg.NetBSD.org/src/rev/31a1c8920776
branches:  trunk
changeset: 827177:31a1c8920776
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed Oct 18 16:29:56 2017 +0000

description:
Group the sections into segments, and align to KERNALIGN only between
segments. Prerequisite for other changes. Unfortunately the code is not
very compact, but whatever.

diffstat:

 sys/lib/libsa/loadfile_elf32.c |  104 ++++++++++++++++++++++++++++++++++++++--
 1 files changed, 97 insertions(+), 7 deletions(-)

diffs (141 lines):

diff -r 4c7fbe915101 -r 31a1c8920776 sys/lib/libsa/loadfile_elf32.c
--- a/sys/lib/libsa/loadfile_elf32.c    Wed Oct 18 16:01:58 2017 +0000
+++ b/sys/lib/libsa/loadfile_elf32.c    Wed Oct 18 16:29:56 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: loadfile_elf32.c,v 1.47 2017/10/13 10:39:26 maxv Exp $ */
+/* $NetBSD: loadfile_elf32.c,v 1.48 2017/10/18 16:29:56 maxv Exp $ */
 
 /*
  * Copyright (c) 1997, 2008, 2017 The NetBSD Foundation, Inc.
@@ -341,7 +341,7 @@
 {
        const u_long offset = 0;
        Elf_Shdr *shdr;
-       Elf_Addr shpp, addr;
+       Elf_Addr shpp, addr, align;
        int i, j, loaded;
        size_t size, shdrsz;
        Elf_Addr maxp, elfp = 0;
@@ -383,11 +383,22 @@
        maxp += roundup(shdrsz, ELFROUND);
 
        /*
-        * Load the KERNEL SECTIONS.
+        * Load the KERNEL SECTIONS, and group them into segments. First text,
+        * then rodata, then data. Between sections, we align to the requested
+        * section alignment. Between segments, we align to KERNALIGN.
         */
+
+       /* text */
        maxp = roundup(maxp, KERNALIGN);
        for (i = 0; i < elf->e_shnum; i++) {
-               addr = maxp;
+               if (!(shdr[i].sh_flags & SHF_EXECINSTR)) {
+                       continue;
+               }
+               align = shdr[i].sh_addralign;
+               if (align == 0) {
+                       align = ELFROUND;
+               }
+               addr = roundup(maxp, align);
                size = (size_t)shdr[i].sh_size;
 
                loaded = 0;
@@ -411,15 +422,94 @@
                }
 
                if (loaded) {
-                       shdr[i].sh_offset = maxp - elfp;
-                       maxp = roundup(maxp + size, KERNALIGN);
+                       shdr[i].sh_offset = addr - elfp;
+                       maxp = addr + size;
+               }
+       }
+
+       /* rodata */
+       maxp = roundup(maxp, KERNALIGN);
+       for (i = 0; i < elf->e_shnum; i++) {
+               if ((shdr[i].sh_flags & (SHF_EXECINSTR|SHF_WRITE))) {
+                       continue;
+               }
+               align = shdr[i].sh_addralign;
+               if (align == 0) {
+                       align = ELFROUND;
+               }
+               addr = roundup(maxp, align);
+               size = (size_t)shdr[i].sh_size;
+
+               loaded = 0;
+               switch (shdr[i].sh_type) {
+               case SHT_NOBITS:
+                       /* Zero out bss. */
+                       BZERO(addr, size);
+                       loaded = 1;
+                       break;
+               case SHT_PROGBITS:
+                       ret = ELFNAMEEND(readfile_global)(fd, offset,
+                           shdr[i].sh_offset, addr, size);
+                       if (ret == -1) {
+                               goto out;
+                       }
+                       loaded = 1;
+                       break;
+               default:
+                       loaded = 0;
+                       break;
+               }
+
+               if (loaded) {
+                       shdr[i].sh_offset = addr - elfp;
+                       maxp = addr + size;
+               }
+       }
+
+       /* data */
+       maxp = roundup(maxp, KERNALIGN);
+       for (i = 0; i < elf->e_shnum; i++) {
+               if (!(shdr[i].sh_flags & SHF_WRITE) ||
+                   (shdr[i].sh_flags & SHF_EXECINSTR)) {
+                       continue;
+               }
+               align = shdr[i].sh_addralign;
+               if (align == 0) {
+                       align = ELFROUND;
+               }
+               addr = roundup(maxp, align);
+               size = (size_t)shdr[i].sh_size;
+
+               loaded = 0;
+               switch (shdr[i].sh_type) {
+               case SHT_NOBITS:
+                       /* Zero out bss. */
+                       BZERO(addr, size);
+                       loaded = 1;
+                       break;
+               case SHT_PROGBITS:
+                       ret = ELFNAMEEND(readfile_global)(fd, offset,
+                           shdr[i].sh_offset, addr, size);
+                       if (ret == -1) {
+                               goto out;
+                       }
+                       loaded = 1;
+                       break;
+               default:
+                       loaded = 0;
+                       break;
+               }
+
+               if (loaded) {
+                       shdr[i].sh_offset = addr - elfp;
+                       maxp = addr + size;
                }
        }
 
        /*
         * Load the SYM+REL SECTIONS.
         */
-       maxp = roundup(maxp, ELFROUND);
+       maxp = roundup(maxp, KERNALIGN);
        for (i = 0; i < elf->e_shnum; i++) {
                addr = maxp;
                size = (size_t)shdr[i].sh_size;



Home | Main Index | Thread Index | Old Index