Skip to content

Commit

Permalink
Add a very hackish /proc/PID/stack.
Browse files Browse the repository at this point in the history
It walks the stack and identifies anything that looks like a kernel symbol.
This could be a lot more sophisticated.
  • Loading branch information
awesomekling committed Oct 26, 2018
1 parent 81627cf commit c928b06
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 13 deletions.
1 change: 1 addition & 0 deletions Kernel/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.floppy-image
Boot/boot.bin
kernel
kernel.map
1 change: 1 addition & 0 deletions Kernel/Console.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <AK/Compiler.h>
#include <VirtualFileSystem/CharacterDevice.h>

class Console final : public CharacterDevice {
Expand Down
9 changes: 6 additions & 3 deletions Kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ ARCH_FLAGS =
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
KERNEL_FLAGS = -ffreestanding -fno-stack-protector -fno-ident
WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings
FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -fmerge-all-constants -fno-unroll-loops -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fno-pie -fno-pic
#FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections
FLAVOR_FLAGS = -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -fmerge-all-constants -fno-unroll-loops -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fno-pie -fno-pic
#FLAVOR_FLAGS = -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
INCLUDE_FLAGS = -I.. -I.

Expand All @@ -71,7 +71,10 @@ LD = ld
LDFLAGS = -T linker.ld --strip-debug -melf_i386 --gc-sections --build-id=none -z norelro -z now


all: $(KERNEL) $(IMAGE)
all: $(KERNEL) $(IMAGE) kernel.map

kernel.map: kernel
@echo "MKMAP $@"; sh mkmap.sh

$(KERNEL): $(OBJS)
@echo "LD $@"; $(LD) $(LDFLAGS) -o $@ -Ttext 0x10000 $(OBJS)
Expand Down
36 changes: 36 additions & 0 deletions Kernel/ProcFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ProcFileSystem.h"
#include "Task.h"
#include <VirtualFileSystem/VirtualFileSystem.h>
#include "system.h"

static ProcFileSystem* s_the;

Expand Down Expand Up @@ -48,6 +49,41 @@ void ProcFileSystem::addProcess(Task& task)
*ptr = '\0';
return ByteBuffer::copy((byte*)buffer, ptr - buffer);
}), dir.index());
addFile(createGeneratedFile("stack", [&task] {
InterruptDisabler disabler;
auto& syms = ksyms();
dword firstKsymAddress = syms.first().address;
dword lastKsymAddress = syms.last().address;
struct RecognizedSymbol {
dword address;
const char* name;
dword offset;
};
Vector<RecognizedSymbol> recognizedSymbols;
size_t bytesNeeded = 0;
for (dword* stackPtr = (dword*)task.stackPtr(); (dword)stackPtr < task.stackTop(); ++stackPtr) {
if (*stackPtr < firstKsymAddress || *stackPtr > lastKsymAddress)
continue;
const char* name = nullptr;
unsigned offset = 0;
for (unsigned i = 0; i < syms.size(); ++i) {
if (*stackPtr < syms[i+1].address) {
name = syms[i].name.characters();
offset = *stackPtr - syms[i].address;
bytesNeeded += syms[i].name.length() + 8 + 16;
break;
}
}
recognizedSymbols.append({ *stackPtr, name, offset });
}
auto buffer = ByteBuffer::createUninitialized(bytesNeeded);
char* ptr = (char*)buffer.pointer();
for (auto& symbol : recognizedSymbols) {
kprintf("%p %s +%u\n", symbol.address, symbol.name, symbol.offset);
}
buffer.trim(ptr - (char*)buffer.pointer());
return buffer;
}), dir.index());
}

void ProcFileSystem::removeProcess(Task& task)
Expand Down
12 changes: 6 additions & 6 deletions Kernel/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,21 +378,21 @@ Task::Task(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel ring)
// FIXME: This memory is leaked.
// But uh, there's also no kernel task termination, so I guess it's not technically leaked...
dword stackBottom = (dword)kmalloc(defaultStackSize);
m_stackTop = (stackBottom + defaultStackSize) & 0xffffff8;
m_tss.esp = m_stackTop;
m_stackTop0 = (stackBottom + defaultStackSize) & 0xffffff8;
m_tss.esp = m_stackTop0;
} else {
auto* region = allocateRegion(defaultStackSize, "stack");
ASSERT(region);
m_stackTop = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
m_stackTop3 = region->linearAddress.offset(defaultStackSize).get() & 0xfffffff8;
m_tss.esp = m_stackTop3;
}
m_tss.esp = m_stackTop;

if (isRing3()) {
// Ring3 tasks need a separate stack for Ring0.
m_kernelStack = kmalloc(defaultStackSize);
DWORD ring0StackTop = ((DWORD)m_kernelStack + defaultStackSize) & 0xffffff8;
m_stackTop0 = ((DWORD)m_kernelStack + defaultStackSize) & 0xffffff8;
m_tss.ss0 = 0x10;
m_tss.esp0 = ring0StackTop;
m_tss.esp0 = m_stackTop0;
}

// HACK: Ring2 SS in the TSS is the current PID.
Expand Down
6 changes: 5 additions & 1 deletion Kernel/Task.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ class Task : public InlineLinkedListNode<Task> {

size_t fileHandleCount() const { return m_fileHandles.size(); }

dword stackPtr() const { return m_tss.esp; }
dword stackTop() const { return m_tss.ss == 0x10 ? m_stackTop0 : m_stackTop3; }

private:
friend class MemoryManager;
friend bool scheduleNewTask();
Expand All @@ -140,7 +143,8 @@ class Task : public InlineLinkedListNode<Task> {
gid_t m_gid { 0 };
DWORD m_ticks { 0 };
DWORD m_ticksLeft { 0 };
DWORD m_stackTop { 0 };
DWORD m_stackTop0 { 0 };
DWORD m_stackTop3 { 0 };
FarPtr m_farPtr;
State m_state { Invalid };
DWORD m_wakeupTime { 0 };
Expand Down
Binary file modified Kernel/_fs_contents
Binary file not shown.
51 changes: 51 additions & 0 deletions Kernel/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "RTC.h"

#define TEST_VFS
#define KERNEL_MAP
//#define STRESS_TEST_SPAWNING
//#define TEST_ELF_LOADER
//#define TEST_CRASHY_USER_PROCESSES
Expand All @@ -49,6 +50,43 @@ void banner()
kprintf("\n");
}

static byte parseHexDigit(char nibble)
{
if (nibble >= '0' && nibble <= '9')
return nibble - '0';
ASSERT(nibble >= 'a' && nibble <= 'f');
return 10 + (nibble - 'a');
}

static Vector<KSym>* s_ksyms;

Vector<KSym>& ksyms()
{
return *s_ksyms;
}

static void loadKernelMap(const ByteBuffer& buffer)
{
s_ksyms = new Vector<KSym>;
auto* bufptr = (const char*)buffer.pointer();
auto* startOfName = bufptr;
dword address = 0;

while (bufptr < buffer.endPointer()) {
for (unsigned i = 0; i < 8; ++i)
address = (address << 4) | parseHexDigit(*(bufptr++));
bufptr += 3;
startOfName = bufptr;
while (*(++bufptr)) {
if (*bufptr == '\n') {
break;
}
}
ksyms().append({ address, String(startOfName, bufptr - startOfName) });
++bufptr;
}
}

#ifdef TEST_CRASHY_USER_PROCESSES
static void user_main() NORETURN;
static void user_main()
Expand Down Expand Up @@ -108,6 +146,19 @@ static void init_stage2()

vfs->mountRoot(e2fs.copyRef());

#ifdef KERNEL_MAP
{
auto handle = vfs->open("/kernel.map");
if (!handle) {
kprintf("Failed to open /kernel.map\n");
} else {
auto buffer = handle->readEntireFile();
ASSERT(buffer);
loadKernelMap(buffer);
}
}
#endif

vfs->mount(ProcFileSystem::the(), "/proc");

#endif
Expand Down
4 changes: 2 additions & 2 deletions Kernel/kmalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ kmalloc( DWORD size )
}
}

kprintf( "kmalloc(): PANIC! Out of memory (no suitable block)" );
kprintf("kmalloc(): PANIC! Out of memory (no suitable block for size %u)\n", size);
HANG;

return 0L;
return nullptr;
}

PUBLIC void
Expand Down
5 changes: 5 additions & 0 deletions Kernel/mkmap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
tmp=$(mktemp)
nm -C kernel > $tmp
perl -lpe '$_=hex' $tmp | paste -d" " - $tmp | sort -n | cut -d" " -f 2- > kernel.map
rm $tmp
1 change: 1 addition & 0 deletions Kernel/sync-sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ cp ../Userland/false mnt/bin/false
cp ../Userland/hostname mnt/bin/hostname
cp ../Userland/cat mnt/bin/cat
cp ../Userland/uname mnt/bin/uname
cp kernel.map mnt/
umount mnt
sync
9 changes: 9 additions & 0 deletions Kernel/system.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
#pragma once

#include "types.h"
#include <AK/Vector.h>
#include <AK/String.h>

struct KSym {
dword address;
String name;
};

Vector<KSym>& ksyms() PURE;

struct system_t
{
Expand Down
2 changes: 1 addition & 1 deletion Userland/cat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int main(int argc, char** argv)
return 1;
}
for (;;) {
char buf[128];
char buf[4096];
ssize_t nread = read(fd, buf, sizeof(buf));
if (nread == 0)
break;
Expand Down
6 changes: 6 additions & 0 deletions VirtualFileSystem/SyntheticFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ auto SyntheticFileSystem::createGeneratedFile(String&& name, Function<ByteBuffer

InodeIdentifier SyntheticFileSystem::addFile(OwnPtr<File>&& file, InodeIndex parent)
{
ASSERT_INTERRUPTS_DISABLED();
ASSERT(file);
auto it = m_inodes.find(parent);
ASSERT(it != m_inodes.end());
Expand All @@ -92,6 +93,7 @@ InodeIdentifier SyntheticFileSystem::addFile(OwnPtr<File>&& file, InodeIndex par

bool SyntheticFileSystem::removeFile(InodeIndex inode)
{
ASSERT_INTERRUPTS_DISABLED();
auto it = m_inodes.find(inode);
if (it == m_inodes.end())
return false;
Expand Down Expand Up @@ -127,6 +129,7 @@ InodeIdentifier SyntheticFileSystem::rootInode() const

bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Function<bool(const DirectoryEntry&)> callback) const
{
InterruptDisabler disabler;
ASSERT(inode.fileSystemID() == id());
#ifdef SYNTHFS_DEBUG
kprintf("[synthfs] enumerateDirectoryInode %u\n", inode.index());
Expand All @@ -150,6 +153,7 @@ bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Functio

InodeMetadata SyntheticFileSystem::inodeMetadata(InodeIdentifier inode) const
{
InterruptDisabler disabler;
ASSERT(inode.fileSystemID() == id());
#ifdef SYNTHFS_DEBUG
kprintf("[synthfs] inodeMetadata(%u)\n", inode.index());
Expand Down Expand Up @@ -186,6 +190,8 @@ bool SyntheticFileSystem::writeInode(InodeIdentifier, const ByteBuffer&)

Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::off_t offset, Unix::size_t count, byte* buffer) const
{
InterruptDisabler disabler;

ASSERT(inode.fileSystemID() == id());
#ifdef SYNTHFS_DEBUG
kprintf("[synthfs] readInode %u\n", inode.index());
Expand Down

0 comments on commit c928b06

Please sign in to comment.