diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/kernel/service/serviceSyscalls.c b/src/kernel/service/serviceSyscalls.c index 1e4c4c6..ee32b74 100644 --- a/src/kernel/service/serviceSyscalls.c +++ b/src/kernel/service/serviceSyscalls.c @@ -1,3 +1,4 @@ +#include "elf.h" #include #include #include @@ -72,3 +73,18 @@ service->nameHash); call->avoidReschedule = true; } + +void handleLookupSymbolSyscall(Syscall *call) { + Service *service = listGet(services, call->parameters[0]); + uint32_t location = call->parameters[1]; + for (uint32_t i = 0; i < service->symbolTableSize / sizeof(SymbolEntry); + i++) { + SymbolEntry *entry = &service->symbolTable[i]; + if (location >= entry->value && + location <= entry->value + entry->size) { + char *name = service->stringTable + entry->name; + call->returnValue = insertString(name); + return; + } + } +} diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/kernel/service/serviceSyscalls.c b/src/kernel/service/serviceSyscalls.c index 1e4c4c6..ee32b74 100644 --- a/src/kernel/service/serviceSyscalls.c +++ b/src/kernel/service/serviceSyscalls.c @@ -1,3 +1,4 @@ +#include "elf.h" #include #include #include @@ -72,3 +73,18 @@ service->nameHash); call->avoidReschedule = true; } + +void handleLookupSymbolSyscall(Syscall *call) { + Service *service = listGet(services, call->parameters[0]); + uint32_t location = call->parameters[1]; + for (uint32_t i = 0; i < service->symbolTableSize / sizeof(SymbolEntry); + i++) { + SymbolEntry *entry = &service->symbolTable[i]; + if (location >= entry->value && + location <= entry->value + entry->size) { + char *name = service->stringTable + entry->name; + call->returnValue = insertString(name); + return; + } + } +} diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index e93c99c..ca5779e 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -68,6 +68,7 @@ extern uintptr_t handleInsertStringSyscall, handleReadStringLengthSyscall, handleReadStringSyscall, handleDiscardStringSyscall; extern uintptr_t handleRequestMemorySyscall; +extern uintptr_t handleLookupSymbolSyscall; void (*syscallHandlers[])(Syscall *) = { 0, @@ -89,6 +90,7 @@ (void *)&handleReadStringSyscall, (void *)&handleDiscardStringSyscall, (void *)&handleRequestMemorySyscall, + (void *)&handleLookupSymbolSyscall, }; void processSyscall(Syscall *call) { diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/kernel/service/serviceSyscalls.c b/src/kernel/service/serviceSyscalls.c index 1e4c4c6..ee32b74 100644 --- a/src/kernel/service/serviceSyscalls.c +++ b/src/kernel/service/serviceSyscalls.c @@ -1,3 +1,4 @@ +#include "elf.h" #include #include #include @@ -72,3 +73,18 @@ service->nameHash); call->avoidReschedule = true; } + +void handleLookupSymbolSyscall(Syscall *call) { + Service *service = listGet(services, call->parameters[0]); + uint32_t location = call->parameters[1]; + for (uint32_t i = 0; i < service->symbolTableSize / sizeof(SymbolEntry); + i++) { + SymbolEntry *entry = &service->symbolTable[i]; + if (location >= entry->value && + location <= entry->value + entry->size) { + char *name = service->stringTable + entry->name; + call->returnValue = insertString(name); + return; + } + } +} diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index e93c99c..ca5779e 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -68,6 +68,7 @@ extern uintptr_t handleInsertStringSyscall, handleReadStringLengthSyscall, handleReadStringSyscall, handleDiscardStringSyscall; extern uintptr_t handleRequestMemorySyscall; +extern uintptr_t handleLookupSymbolSyscall; void (*syscallHandlers[])(Syscall *) = { 0, @@ -89,6 +90,7 @@ (void *)&handleReadStringSyscall, (void *)&handleDiscardStringSyscall, (void *)&handleRequestMemorySyscall, + (void *)&handleLookupSymbolSyscall, }; void processSyscall(Syscall *call) { diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index bdcb8be..3410b46 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -24,6 +24,7 @@ SYS_READ_STRING = 16, SYS_DISCARD_STRING = 17, SYS_REQUEST_MEMORY = 18, + SYS_LOOKUP_SYMBOL = 19, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/kernel/service/serviceSyscalls.c b/src/kernel/service/serviceSyscalls.c index 1e4c4c6..ee32b74 100644 --- a/src/kernel/service/serviceSyscalls.c +++ b/src/kernel/service/serviceSyscalls.c @@ -1,3 +1,4 @@ +#include "elf.h" #include #include #include @@ -72,3 +73,18 @@ service->nameHash); call->avoidReschedule = true; } + +void handleLookupSymbolSyscall(Syscall *call) { + Service *service = listGet(services, call->parameters[0]); + uint32_t location = call->parameters[1]; + for (uint32_t i = 0; i < service->symbolTableSize / sizeof(SymbolEntry); + i++) { + SymbolEntry *entry = &service->symbolTable[i]; + if (location >= entry->value && + location <= entry->value + entry->size) { + char *name = service->stringTable + entry->name; + call->returnValue = insertString(name); + return; + } + } +} diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index e93c99c..ca5779e 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -68,6 +68,7 @@ extern uintptr_t handleInsertStringSyscall, handleReadStringLengthSyscall, handleReadStringSyscall, handleDiscardStringSyscall; extern uintptr_t handleRequestMemorySyscall; +extern uintptr_t handleLookupSymbolSyscall; void (*syscallHandlers[])(Syscall *) = { 0, @@ -89,6 +90,7 @@ (void *)&handleReadStringSyscall, (void *)&handleDiscardStringSyscall, (void *)&handleRequestMemorySyscall, + (void *)&handleLookupSymbolSyscall, }; void processSyscall(Syscall *call) { diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index bdcb8be..3410b46 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -24,6 +24,7 @@ SYS_READ_STRING = 16, SYS_DISCARD_STRING = 17, SYS_REQUEST_MEMORY = 18, + SYS_LOOKUP_SYMBOL = 19, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/userland/hlib/service/service.c b/src/userland/hlib/service/service.c index 7707fe1..b26ba11 100644 --- a/src/userland/hlib/service/service.c +++ b/src/userland/hlib/service/service.c @@ -23,3 +23,7 @@ } uint32_t getServiceId() { return syscall(SYS_GET_SERVICE_ID, 0, 0, 0, 0); } + +uint32_t lookupSymbol(uint32_t serviceId, uint32_t address) { + return syscall(SYS_LOOKUP_SYMBOL, serviceId, address, 0, 0); +} diff --git a/src/include/hlib.h b/src/include/hlib.h index b6f9631..9b11389 100644 --- a/src/include/hlib.h +++ b/src/include/hlib.h @@ -43,6 +43,7 @@ extern uintptr_t hashString(char *string); extern void *requestMemory(uint32_t pageCount, void *targetAddress, void *physicalAddress); +extern uint32_t lookupSymbol(uint32_t serviceId, uint32_t address); #define MAX(x, y) (x > y ? (x) : (y)) diff --git a/src/kernel/include/service.h b/src/kernel/include/service.h index 46da745..ede83b1 100644 --- a/src/kernel/include/service.h +++ b/src/kernel/include/service.h @@ -1,6 +1,7 @@ #ifndef SERVICE_H #define SERVICE_H +#include "../service/elf.h" #include #include #include @@ -11,6 +12,9 @@ uintptr_t nameHash; ListElement *functions; ListElement *events; + SymbolEntry *symbolTable; + char *stringTable; + uint32_t symbolTableSize; } Service; // the name is subject to change diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c index 19513ba..30f3197 100644 --- a/src/kernel/interrupts/interrupts.c +++ b/src/kernel/interrupts/interrupts.c @@ -29,15 +29,28 @@ ; } +uint32_t getServiceId(Service *searchService) { + uint32_t i = 0; + foreach (services, Service *, service, { + if (service == searchService) { + return i; + } + i++; + }) + ; + return i; +} + void onException(void *ebp, void *cr3, uint32_t d, uint32_t c, uint32_t b, uint32_t a, uint32_t intNo, uint32_t errorCode, uint32_t eip) { foreach (interruptSubscriptions[0], ServiceFunction *, provider, { + Service *service = (Service *)currentSyscall->service; scheduleFunction( provider, NULL, intNo, errorCode, eip, U32(getPhysicalAddress( ((Service *)currentSyscall->service)->pagingInfo.pageDirectory, ebp)), - ((Service *)currentSyscall->service)->nameHash); + service->nameHash, getServiceId(service)); }) } diff --git a/src/kernel/service/elf.h b/src/kernel/service/elf.h index af9e01c..1fbfbd2 100644 --- a/src/kernel/service/elf.h +++ b/src/kernel/service/elf.h @@ -49,4 +49,13 @@ uint32_t entrySize; } SectionHeader; +typedef struct { + uint32_t name; + uint32_t value; + uint32_t size; + uint8_t info; + uint8_t other; + uint16_t sectionHeaderIndex; +} SymbolEntry; + #endif diff --git a/src/kernel/service/service.c b/src/kernel/service/service.c index 6903d7a..f227df2 100644 --- a/src/kernel/service/service.c +++ b/src/kernel/service/service.c @@ -64,6 +64,18 @@ end: programHeader = (void *)programHeader + header->programHeaderEntrySize; } + for (uint32_t i = 0; i < header->sectionHeaderEntryCount; i++) { + SectionHeader *sectionHeader = elfStart + + header->sectionHeaderTablePosition + + i * header->sectionHeaderEntrySize; + if (sectionHeader->type == 2 && !service->symbolTable) { + service->symbolTable = elfStart + sectionHeader->offset; + service->symbolTableSize = sectionHeader->size; + } + if (sectionHeader->type == 3 && !service->stringTable) { + service->stringTable = elfStart + sectionHeader->offset; + } + } ServiceFunction *main = malloc(sizeof(ServiceFunction)); main->name = "main"; main->service = service; diff --git a/src/kernel/service/serviceSyscalls.c b/src/kernel/service/serviceSyscalls.c index 1e4c4c6..ee32b74 100644 --- a/src/kernel/service/serviceSyscalls.c +++ b/src/kernel/service/serviceSyscalls.c @@ -1,3 +1,4 @@ +#include "elf.h" #include #include #include @@ -72,3 +73,18 @@ service->nameHash); call->avoidReschedule = true; } + +void handleLookupSymbolSyscall(Syscall *call) { + Service *service = listGet(services, call->parameters[0]); + uint32_t location = call->parameters[1]; + for (uint32_t i = 0; i < service->symbolTableSize / sizeof(SymbolEntry); + i++) { + SymbolEntry *entry = &service->symbolTable[i]; + if (location >= entry->value && + location <= entry->value + entry->size) { + char *name = service->stringTable + entry->name; + call->returnValue = insertString(name); + return; + } + } +} diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c index e93c99c..ca5779e 100644 --- a/src/kernel/syscalls/syscall.c +++ b/src/kernel/syscalls/syscall.c @@ -68,6 +68,7 @@ extern uintptr_t handleInsertStringSyscall, handleReadStringLengthSyscall, handleReadStringSyscall, handleDiscardStringSyscall; extern uintptr_t handleRequestMemorySyscall; +extern uintptr_t handleLookupSymbolSyscall; void (*syscallHandlers[])(Syscall *) = { 0, @@ -89,6 +90,7 @@ (void *)&handleReadStringSyscall, (void *)&handleDiscardStringSyscall, (void *)&handleRequestMemorySyscall, + (void *)&handleLookupSymbolSyscall, }; void processSyscall(Syscall *call) { diff --git a/src/userland/hlib/include/syscalls.h b/src/userland/hlib/include/syscalls.h index bdcb8be..3410b46 100644 --- a/src/userland/hlib/include/syscalls.h +++ b/src/userland/hlib/include/syscalls.h @@ -24,6 +24,7 @@ SYS_READ_STRING = 16, SYS_DISCARD_STRING = 17, SYS_REQUEST_MEMORY = 18, + SYS_LOOKUP_SYMBOL = 19, } SyscallIds; extern uint32_t getFunction(uint32_t module, char *name); diff --git a/src/userland/hlib/service/service.c b/src/userland/hlib/service/service.c index 7707fe1..b26ba11 100644 --- a/src/userland/hlib/service/service.c +++ b/src/userland/hlib/service/service.c @@ -23,3 +23,7 @@ } uint32_t getServiceId() { return syscall(SYS_GET_SERVICE_ID, 0, 0, 0, 0); } + +uint32_t lookupSymbol(uint32_t serviceId, uint32_t address) { + return syscall(SYS_LOOKUP_SYMBOL, serviceId, address, 0, 0); +} diff --git a/src/userland/log/main.c b/src/userland/log/main.c index a8bf9eb..dff007e 100644 --- a/src/userland/log/main.c +++ b/src/userland/log/main.c @@ -71,7 +71,11 @@ void *eip; } StackFrame; -void trace(void *address, uint32_t serviceId) { printf("0x%x", address); } +void trace(void *address, uint32_t serviceId) { + uint32_t name = lookupSymbol(serviceId, U32(address)); + readString(name, buffer); + printf("0x%x / %s", address, buffer); +} void onException(uint32_t intNo, uint32_t errorCode, void *crashAddress, void *start, uint32_t serviceName, uint32_t serviceId) {