From fba09d4c08df02bf54d969502252eddb930a6d5f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Thu, 15 Mar 2012 05:29:51 +0000 Subject: [PATCH] Fill out fake preload structure to let userland tools like pmc(3) know about kernel module base address and actual size --- sys/conf/Makefile.mips | 2 +- sys/mips/mips/machdep.c | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/sys/conf/Makefile.mips b/sys/conf/Makefile.mips index c50f9c251a8..69eea9eaff8 100644 --- a/sys/conf/Makefile.mips +++ b/sys/conf/Makefile.mips @@ -44,7 +44,7 @@ MKMODULESENV+= MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} # We default to the MIPS32 ISA, if none specified in the # kernel configuration file. ARCH_FLAGS?=-march=mips32 -EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 +EXTRA_FLAGS=-fno-pic -mno-abicalls -G0 -DKERNLOADADDR=${KERNLOADADDR} HACK_EXTRA_FLAGS=-shared diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 8a9fabe3801..21b85c571d9 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -380,6 +380,56 @@ mips_vector_init(void) void mips_postboot_fixup(void) { + static char fake_preload[256]; + caddr_t preload_ptr = (caddr_t)&fake_preload[0]; + size_t size = 0; + + /* + * Provide kernel module file information + */ + *(uint32_t*)(preload_ptr + size) = MODINFO_NAME; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = strlen("kernel") + 1; + size += sizeof(uint32_t); + strcpy((char*)(preload_ptr + size), "kernel"); + size += strlen("kernel") + 1; + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_TYPE; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = strlen("elf kernel") + 1; + size += sizeof(uint32_t); + strcpy((char*)(preload_ptr + size), "elf kernel"); + size += strlen("elf kernel") + 1; + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_ADDR; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = sizeof(vm_offset_t); + size += sizeof(uint32_t); + *(vm_offset_t*)(preload_ptr + size) = KERNLOADADDR; + size += sizeof(vm_offset_t); + size = roundup(size, sizeof(u_long)); + + *(uint32_t*)(preload_ptr + size) = MODINFO_SIZE; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = sizeof(size_t); + size += sizeof(uint32_t); + *(vm_offset_t*)(preload_ptr + size) = (size_t)&end - KERNLOADADDR; + size = roundup(size, sizeof(u_long)); + size += sizeof(size_t); + + /* End marker */ + *(uint32_t*)(preload_ptr + size) = 0; + size += sizeof(uint32_t); + *(uint32_t*)(preload_ptr + size) = 0; + size += sizeof(uint32_t); + + KASSERT((size < sizeof(fake_preload)), + ("fake preload size is more thenallocated")); + + preload_metadata = (void *)fake_preload; + #ifdef DDB Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end; Elf_Size symtabsize = 0;