diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/KSyms.cpp | 136 | ||||
-rw-r--r-- | Kernel/KSyms.h | 16 | ||||
-rw-r--r-- | Kernel/Makefile | 3 | ||||
-rw-r--r-- | Kernel/ProcFileSystem.cpp | 6 | ||||
-rw-r--r-- | Kernel/Process.cpp | 4 | ||||
-rw-r--r-- | Kernel/init.cpp | 147 | ||||
-rw-r--r-- | Kernel/system.h | 8 |
7 files changed, 163 insertions, 157 deletions
diff --git a/Kernel/KSyms.cpp b/Kernel/KSyms.cpp new file mode 100644 index 0000000000..405b8abf8a --- /dev/null +++ b/Kernel/KSyms.cpp @@ -0,0 +1,136 @@ +#include "KSyms.h" +#include "Process.h" +#include "Scheduler.h" + +static KSym* s_ksyms; +dword ksym_lowest_address; +dword ksym_highest_address; +dword ksym_count; +bool ksyms_ready; + +static byte parse_hex_digit(char nibble) +{ + if (nibble >= '0' && nibble <= '9') + return nibble - '0'; + ASSERT(nibble >= 'a' && nibble <= 'f'); + return 10 + (nibble - 'a'); +} + +const KSym* ksymbolicate(dword address) +{ + if (address < ksym_lowest_address || address > ksym_highest_address) + return nullptr; + for (unsigned i = 0; i < ksym_count; ++i) { + if (address < s_ksyms[i + 1].address) + return &s_ksyms[i]; + } + return nullptr; +} + +static void load_ksyms_from_data(const ByteBuffer& buffer) +{ + // FIXME: It's gross that this vector grows dynamically rather than being sized-to-fit. + // We're wasting that eternal kmalloc memory. + auto* bufptr = (const char*)buffer.pointer(); + auto* start_of_name = bufptr; + dword address = 0; + + for (unsigned i = 0; i < 8; ++i) + ksym_count = (ksym_count << 4) | parse_hex_digit(*(bufptr++)); + s_ksyms = static_cast<KSym*>(kmalloc_eternal(sizeof(KSym) * ksym_count)); + ++bufptr; // skip newline + + kprintf("Loading ksyms: \033[s"); + + unsigned current_ksym_index = 0; + + while (bufptr < buffer.end_pointer()) { + for (unsigned i = 0; i < 8; ++i) + address = (address << 4) | parse_hex_digit(*(bufptr++)); + bufptr += 3; + start_of_name = bufptr; + while (*(++bufptr)) { + if (*bufptr == '\n') { + break; + } + } + auto& ksym = s_ksyms[current_ksym_index]; + ksym.address = address; + char* name = static_cast<char*>(kmalloc_eternal((bufptr - start_of_name) + 1)); + memcpy(name, start_of_name, bufptr - start_of_name); + name[bufptr - start_of_name] = '\0'; + ksym.name = name; + + if (ksym.address < ksym_lowest_address) + ksym_lowest_address = ksym.address; + if (ksym.address > ksym_highest_address) + ksym_highest_address = ksym.address; + + if ((current_ksym_index % 10) == 0 || ksym_count == current_ksym_index) + kprintf("\033[u\033[s%u/%u", current_ksym_index, ksym_count); + ++bufptr; + ++current_ksym_index; + } + kprintf("\n"); + ksyms_ready = true; +} + +void dump_backtrace(bool use_ksyms) +{ + if (!current) { + HANG; + return; + } + if (use_ksyms && !ksyms_ready) { + HANG; + return; + } + struct RecognizedSymbol { + dword address; + const KSym* ksym; + }; + Vector<RecognizedSymbol> recognized_symbols; + if (use_ksyms) { + for (dword* stackPtr = (dword*)&use_ksyms; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) { + dword retaddr = stackPtr[1]; + if (auto* ksym = ksymbolicate(retaddr)) + recognized_symbols.append({ retaddr, ksym }); + } + } else{ + for (dword* stackPtr = (dword*)&use_ksyms; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) { + dword retaddr = stackPtr[1]; + kprintf("%x (next: %x)\n", retaddr, stackPtr ? (dword*)*stackPtr : 0); + } + return; + } + size_t bytesNeeded = 0; + for (auto& symbol : recognized_symbols) { + bytesNeeded += strlen(symbol.ksym->name) + 8 + 16; + } + for (auto& symbol : recognized_symbols) { + unsigned offset = symbol.address - symbol.ksym->address; + dbgprintf("%p %s +%u\n", symbol.address, symbol.ksym->name, offset); + } +} + +void init_ksyms() +{ + ksyms_ready = false; + ksym_lowest_address = 0xffffffff; + ksym_highest_address = 0; + ksym_count = 0; +} + +void load_ksyms() +{ + int error; + auto descriptor = VFS::the().open("/kernel.map", error); + if (!descriptor) { + kprintf("Failed to open /kernel.map\n"); + } else { + auto buffer = descriptor->read_entire_file(); + ASSERT(buffer); + load_ksyms_from_data(buffer); + } +} + diff --git a/Kernel/KSyms.h b/Kernel/KSyms.h new file mode 100644 index 0000000000..45558de201 --- /dev/null +++ b/Kernel/KSyms.h @@ -0,0 +1,16 @@ +#pragma once + +#include <AK/AKString.h> +#include <AK/Vector.h> + +struct KSym { + dword address; + const char* name; +}; + +const KSym* ksymbolicate(dword address) PURE; +void load_ksyms(); + +extern bool ksyms_ready; +extern dword ksym_lowest_address; +extern dword ksym_highest_address; diff --git a/Kernel/Makefile b/Kernel/Makefile index 64d619a716..0b50600ec7 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -23,7 +23,8 @@ KERNEL_OBJS = \ Scheduler.o \ DoubleBuffer.o \ ELFImage.o \ - ELFLoader.o + ELFLoader.o \ + KSyms.o VFS_OBJS = \ ../VirtualFileSystem/DiskDevice.o \ diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index aa691af8c5..b636a68bed 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -5,6 +5,7 @@ #include "MemoryManager.h" #include "StdLib.h" #include "i386.h" +#include "KSyms.h" static ProcFS* s_the; @@ -116,15 +117,14 @@ ByteBuffer procfs$pid_stack(Process& process) } size_t bytesNeeded = 0; for (auto& symbol : recognizedSymbols) { - bytesNeeded += symbol.ksym->name.length() + 8 + 16; + bytesNeeded += strlen(symbol.ksym->name) + 8 + 16; } auto buffer = ByteBuffer::create_uninitialized(bytesNeeded); char* bufptr = (char*)buffer.pointer(); for (auto& symbol : recognizedSymbols) { - // FIXME: This doesn't actually create a file! unsigned offset = symbol.address - symbol.ksym->address; - bufptr += ksprintf(bufptr, "%p %s +%u\n", symbol.address, symbol.ksym->name.characters(), offset); + bufptr += ksprintf(bufptr, "%p %s +%u\n", symbol.address, symbol.ksym->name, offset); } buffer.trim(bufptr - (char*)buffer.pointer()); return buffer; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 5470127a24..0635a5aa13 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -17,6 +17,7 @@ #include "Syscall.h" #include "Scheduler.h" #include "FIFO.h" +#include "KSyms.h" //#define DEBUG_IO //#define TASK_DEBUG @@ -1559,7 +1560,8 @@ bool Process::isValidAddressForKernel(LinearAddress laddr) const // This code allows access outside of the known used address ranges to get caught. InterruptDisabler disabler; - if (laddr.get() >= ksyms().first().address && laddr.get() <= ksyms().last().address) + // FIXME: What if we're indexing into the ksym with the highest address though? + if (laddr.get() >= ksym_lowest_address && laddr.get() <= ksym_highest_address) return true; if (is_kmalloc_address(laddr.asPtr())) return true; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 5890580c2c..007e44349d 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -6,26 +6,22 @@ #include "Process.h" #include "system.h" #include "PIC.h" -#include "StdLib.h" -#include "Syscall.h" #include "CMOS.h" #include "IDEDiskDevice.h" +#include "KSyms.h" #include <VirtualFileSystem/NullDevice.h> #include <VirtualFileSystem/ZeroDevice.h> #include <VirtualFileSystem/FullDevice.h> #include <VirtualFileSystem/RandomDevice.h> #include <VirtualFileSystem/Ext2FileSystem.h> #include <VirtualFileSystem/VirtualFileSystem.h> -#include <VirtualFileSystem/FileDescriptor.h> -#include <AK/OwnPtr.h> #include "MemoryManager.h" -#include "Console.h" + #include "ProcFileSystem.h" #include "RTC.h" #include "VirtualConsole.h" #include "Scheduler.h" -#define KSYMS #define SPAWN_MULTIPLE_SHELLS //#define STRESS_TEST_SPAWNING @@ -37,116 +33,6 @@ VirtualConsole* tty2; VirtualConsole* tty3; Keyboard* keyboard; -static byte parseHexDigit(char nibble) -{ - if (nibble >= '0' && nibble <= '9') - return nibble - '0'; - ASSERT(nibble >= 'a' && nibble <= 'f'); - return 10 + (nibble - 'a'); -} - -#ifdef KSYMS -static Vector<KSym, KmallocEternalAllocator>* s_ksyms; -static bool s_ksyms_ready; - -Vector<KSym, KmallocEternalAllocator>& ksyms() -{ - return *s_ksyms; -} - -bool ksyms_ready() -{ - return s_ksyms_ready; -} - -const KSym* ksymbolicate(dword address) -{ - if (address < ksyms().first().address || address > ksyms().last().address) - return nullptr; - for (unsigned i = 0; i < ksyms().size(); ++i) { - if (address < ksyms()[i + 1].address) - return &ksyms()[i]; - } - return nullptr; -} - -static void loadKsyms(const ByteBuffer& buffer) -{ - // FIXME: It's gross that this vector grows dynamically rather than being sized-to-fit. - // We're wasting that eternal kmalloc memory. - s_ksyms = new Vector<KSym, KmallocEternalAllocator>; - auto* bufptr = (const char*)buffer.pointer(); - auto* startOfName = bufptr; - dword address = 0; - dword ksym_count = 0; - - for (unsigned i = 0; i < 8; ++i) - ksym_count = (ksym_count << 4) | parseHexDigit(*(bufptr++)); - s_ksyms->ensureCapacity(ksym_count); - ++bufptr; // skip newline - - kprintf("Loading ksyms: \033[s"); - - while (bufptr < buffer.end_pointer()) { - for (unsigned i = 0; i < 8; ++i) - address = (address << 4) | parseHexDigit(*(bufptr++)); - bufptr += 3; - startOfName = bufptr; - while (*(++bufptr)) { - if (*bufptr == '\n') { - break; - } - } - // FIXME: The Strings here should be eternally allocated too. - ksyms().append({ address, String(startOfName, bufptr - startOfName) }); - - if ((ksyms().size() % 10) == 0 || ksym_count == ksyms().size()) - kprintf("\033[u\033[s%u/%u", ksyms().size(), ksym_count); - ++bufptr; - } - kprintf("\n"); - s_ksyms_ready = true; -} - -void dump_backtrace(bool use_ksyms) -{ - if (!current) { - HANG; - return; - } - if (use_ksyms && !ksyms_ready()) { - HANG; - return; - } - struct RecognizedSymbol { - dword address; - const KSym* ksym; - }; - Vector<RecognizedSymbol> recognizedSymbols; - if (use_ksyms) { - for (dword* stackPtr = (dword*)&use_ksyms; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) { - dword retaddr = stackPtr[1]; - if (auto* ksym = ksymbolicate(retaddr)) - recognizedSymbols.append({ retaddr, ksym }); - } - } else{ - for (dword* stackPtr = (dword*)&use_ksyms; current->isValidAddressForKernel(LinearAddress((dword)stackPtr)); stackPtr = (dword*)*stackPtr) { - dword retaddr = stackPtr[1]; - kprintf("%x (next: %x)\n", retaddr, stackPtr ? (dword*)*stackPtr : 0); - } - return; - } - size_t bytesNeeded = 0; - for (auto& symbol : recognizedSymbols) { - bytesNeeded += symbol.ksym->name.length() + 8 + 16; - } - for (auto& symbol : recognizedSymbols) { - unsigned offset = symbol.address - symbol.ksym->address; - dbgprintf("%p %s +%u\n", symbol.address, symbol.ksym->name.characters(), offset); - } -} -#endif - #ifdef STRESS_TEST_SPAWNING static void spawn_stress() NORETURN; static void spawn_stress() @@ -208,19 +94,7 @@ static void init_stage2() vfs->mount_root(e2fs.copyRef()); -#ifdef KSYMS - { - int error; - auto descriptor = vfs->open("/kernel.map", error); - if (!descriptor) { - kprintf("Failed to open /kernel.map\n"); - } else { - auto buffer = descriptor->read_entire_file(); - ASSERT(buffer); - loadKsyms(buffer); - } - } -#endif + load_ksyms(); vfs->mount(ProcFS::the(), "/proc"); @@ -305,18 +179,3 @@ void init() asm("hlt"); } } - -void log_try_lock(const char* where) -{ - kprintf("[%u] >>> locking... (%s)\n", current->pid(), where); -} - -void log_locked(const char* where) -{ - kprintf("[%u] >>> locked() in %s\n", current->pid(), where); -} - -void log_unlocked(const char* where) -{ - kprintf("[%u] <<< unlocked()\n", current->pid(), where); -} diff --git a/Kernel/system.h b/Kernel/system.h index 262d1d6d59..689de3749c 100644 --- a/Kernel/system.h +++ b/Kernel/system.h @@ -4,14 +4,6 @@ #include <AK/Vector.h> #include <AK/AKString.h> -struct KSym { - dword address; - String name; -}; - -Vector<KSym, KmallocEternalAllocator>& ksyms() PURE; -const KSym* ksymbolicate(dword address) PURE; - struct system_t { time_t uptime; |