Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/i386/stand/lib Add kernel symbols for multiboot1



details:   https://anonhg.NetBSD.org/src/rev/50deb2267e24
branches:  trunk
changeset: 460343:50deb2267e24
user:      manu <manu%NetBSD.org@localhost>
date:      Fri Oct 18 01:09:46 2019 +0000

description:
Add kernel symbols for multiboot1

diffstat:

 sys/arch/i386/stand/lib/exec_multiboot1.c |  108 +++++++++++++++++++++++++++++-
 sys/arch/i386/stand/lib/libi386.h         |    6 +-
 2 files changed, 112 insertions(+), 2 deletions(-)

diffs (147 lines):

diff -r 27fdc7b15610 -r 50deb2267e24 sys/arch/i386/stand/lib/exec_multiboot1.c
--- a/sys/arch/i386/stand/lib/exec_multiboot1.c Fri Oct 18 01:04:24 2019 +0000
+++ b/sys/arch/i386/stand/lib/exec_multiboot1.c Fri Oct 18 01:09:46 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_multiboot1.c,v 1.2 2019/10/18 01:04:24 manu Exp $ */
+/* $NetBSD: exec_multiboot1.c,v 1.3 2019/10/18 01:09:46 manu Exp $ */
 
 /*
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -42,6 +42,80 @@
 
 extern struct btinfo_modulelist *btinfo_modulelist;
 
+void
+ksyms_addr_set(void *ehdr, void *shdr, void *symbase)
+{
+       int class;
+       Elf32_Ehdr *ehdr32 = NULL;
+       Elf64_Ehdr *ehdr64 = NULL;
+       uint64_t shnum;
+       int i;
+
+       class = ((Elf_Ehdr *)ehdr)->e_ident[EI_CLASS];
+
+        switch (class) {
+        case ELFCLASS32:     
+                ehdr32 = (Elf32_Ehdr *)ehdr;
+                shnum = ehdr32->e_shnum;
+                break;
+        case ELFCLASS64:
+                ehdr64 = (Elf64_Ehdr *)ehdr;
+                shnum = ehdr64->e_shnum;
+                break;
+        default:        
+               panic("Unexpected ELF class");
+               break;
+        }
+
+       for (i = 0; i < shnum; i++) {
+               Elf64_Shdr *shdrp64 = NULL;
+               Elf32_Shdr *shdrp32 = NULL;
+               uint64_t shtype, shaddr, shsize, shoffset;
+
+               switch(class) {
+               case ELFCLASS64:
+                       shdrp64 = &((Elf64_Shdr *)shdr)[i];     
+                       shtype = shdrp64->sh_type;
+                       shaddr = shdrp64->sh_addr;
+                       shsize = shdrp64->sh_size;
+                       shoffset = shdrp64->sh_offset;
+                       break;
+               case ELFCLASS32:
+                       shdrp32 = &((Elf32_Shdr *)shdr)[i];     
+                       shtype = shdrp32->sh_type;
+                       shaddr = shdrp32->sh_addr;
+                       shsize = shdrp32->sh_size;
+                       shoffset = shdrp32->sh_offset;
+                       break;
+               default:
+                       panic("Unexpected ELF class");
+                       break;
+               }
+
+               if (shtype != SHT_SYMTAB && shtype != SHT_STRTAB)
+                       continue;
+
+               if (shaddr != 0 || shsize == 0)
+                       continue;
+
+               shaddr = (uint64_t)(uintptr_t)(symbase + shoffset);
+
+               switch(class) {
+               case ELFCLASS64:
+                       shdrp64->sh_addr = shaddr;
+                       break;
+               case ELFCLASS32:
+                       shdrp32->sh_addr = shaddr;
+                       break;
+               default:
+                       panic("Unexpected ELF class");
+                       break;
+               }
+       }
+
+       return;
+}
+
 static int
 exec_multiboot1(struct multiboot_package *mbp)
 {
@@ -85,6 +159,38 @@
                mbi->mi_mods_addr = vtophys(mbm);
        }
 
+       if (mbp->mbp_marks[MARK_SYM] != 0) {
+               Elf32_Ehdr ehdr;
+               void *shbuf;
+               size_t shlen;
+               u_long shaddr;
+
+               pvbcopy((void *)mbp->mbp_marks[MARK_SYM], &ehdr, sizeof(ehdr));
+
+               if (memcmp(&ehdr.e_ident, ELFMAG, SELFMAG) != 0)
+                       goto skip_ksyms;
+
+               shaddr = mbp->mbp_marks[MARK_SYM] + ehdr.e_shoff;
+
+               shlen = ehdr.e_shnum * ehdr.e_shentsize;
+               shbuf = alloc(shlen);
+
+               pvbcopy((void *)shaddr, shbuf, shlen);
+               ksyms_addr_set(&ehdr, shbuf,
+                   (void *)(KERNBASE + mbp->mbp_marks[MARK_SYM]));
+               vpbcopy(shbuf, (void *)shaddr, shlen);
+
+               dealloc(shbuf, shlen);
+
+               mbi->mi_elfshdr_num = ehdr.e_shnum;
+               mbi->mi_elfshdr_size = ehdr.e_shentsize;
+               mbi->mi_elfshdr_addr = shaddr;
+               mbi->mi_elfshdr_shndx = ehdr.e_shstrndx;
+
+               mbi->mi_flags |= MULTIBOOT_INFO_HAS_ELF_SYMS;
+       }
+skip_ksyms:
+
 #ifdef DEBUG
        printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n",
            mbp->mbp_marks[MARK_ENTRY],
diff -r 27fdc7b15610 -r 50deb2267e24 sys/arch/i386/stand/lib/libi386.h
--- a/sys/arch/i386/stand/lib/libi386.h Fri Oct 18 01:04:24 2019 +0000
+++ b/sys/arch/i386/stand/lib/libi386.h Fri Oct 18 01:09:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libi386.h,v 1.45 2019/09/13 02:19:46 manu Exp $        */
+/*     $NetBSD: libi386.h,v 1.46 2019/10/18 01:09:46 manu Exp $        */
 
 /*
  * Copyright (c) 1996
@@ -171,4 +171,8 @@
 struct btinfo_framebuffer;
 void framebuffer_configure(struct btinfo_framebuffer *);
 
+void ksyms_addr_set(void *, void *, void *);
+
+void ksyms_addr_set(void *, void *, void *);
+
 #endif /* __I386_STAND_LIBI386_H__ */



Home | Main Index | Thread Index | Old Index