1919 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020
2121#include " kernel/system/interrupts/exceptions.hpp"
22+
23+ #include < shared/utils/string.hpp>
24+
2225#include " kernel/memory/memory.hpp"
2326#include " kernel/memory/page_reference_tracker.hpp"
2427#include " kernel/memory/paging.hpp"
2831#include " kernel/tasking/tasking.hpp"
2932#include " kernel/tasking/tasking_memory.hpp"
3033#include " shared/logger/logger.hpp"
31- #include " shared/panic.hpp"
32-
33- #define DEBUG_PRINT_STACK_TRACE 1
3434
3535/* *
3636 * Names of the exceptions
@@ -99,6 +99,98 @@ bool exceptionsHandleDivideError(g_task* task)
9999 return true ;
100100}
101101
102+ g_elf_object* exceptionsFindResponsibleObject (g_task* task, g_address rip)
103+ {
104+ g_elf_object* object = nullptr ;
105+
106+ auto iter = hashmapIteratorStart (task->process ->object ->loadedObjects );
107+ while (hashmapIteratorHasNext (&iter))
108+ {
109+ auto nextObject = hashmapIteratorNext (&iter)->value ;
110+ if (rip >= nextObject->startAddress && rip < nextObject->endAddress )
111+ {
112+ object = nextObject;
113+ break ;
114+ }
115+ }
116+ hashmapIteratorEnd (&iter);
117+
118+ return object;
119+ }
120+
121+ Elf64_Sym* exceptionsFindFunctionSymbol (g_elf_object* object, g_address rip)
122+ {
123+ if (object->root )
124+ {
125+ // TODO: Symbol lookup only works well for shared libs so far, for some reason
126+ return nullptr ;
127+ }
128+
129+ Elf64_Sym* bestMatch = nullptr ;
130+ g_address localRip = rip - object->baseAddress ;
131+
132+ for (uint64_t symbolIndex = 0 ; symbolIndex < object->dynamicSymbolTableSize ; symbolIndex++)
133+ {
134+ auto & symbol = object->dynamicSymbolTable [symbolIndex];
135+
136+ if (ELF64_ST_TYPE (symbol.st_info ) == STT_FUNC)
137+ {
138+ if (localRip >= symbol.st_value &&
139+ localRip < symbol.st_value + symbol.st_size )
140+ {
141+ return &symbol;
142+ }
143+
144+ if (localRip >= symbol.st_value &&
145+ (!bestMatch || symbol.st_value > bestMatch->st_value ))
146+ {
147+ bestMatch = &symbol;
148+ }
149+ }
150+ }
151+
152+ return bestMatch;
153+ }
154+
155+ void exceptionsPrintCallAtRip (g_task* task, g_address rip)
156+ {
157+ auto object = exceptionsFindResponsibleObject (task, rip);
158+ auto function = object ? exceptionsFindFunctionSymbol (object, rip) : nullptr ;
159+
160+ if (object && function)
161+ {
162+ auto functionName = function->st_name ? &object->dynamicStringTable [function->st_name ] : " ?" ;
163+ logInfo (" %# %h (%s <%s> %h)" , rip, object->name , functionName, rip - object->baseAddress );
164+ }
165+ else if (object)
166+ {
167+ logInfo (" %# %h (%s %h)" , rip, object->name , rip - object->baseAddress );
168+ }
169+ else
170+ {
171+ logInfo (" %# %h" , rip);
172+ }
173+ }
174+
175+ void exceptionsPrintStackTrace (g_task* task, volatile g_processor_state* state)
176+ {
177+ logInfo (" %# stack trace:" );
178+ exceptionsPrintCallAtRip (task, state->rip );
179+
180+ auto rbp = reinterpret_cast <g_address*>(state->rbp );
181+ for (int frame = 0 ; frame < 25 ; ++frame)
182+ {
183+ g_address rip = rbp[1 ];
184+ if (rip < 0x1000 )
185+ {
186+ break ;
187+ }
188+ rbp = reinterpret_cast <g_address*>(rbp[0 ]);
189+
190+ exceptionsPrintCallAtRip (task, rip);
191+ }
192+ }
193+
102194/* *
103195 * Dumps the current CPU state to the log file
104196 */
@@ -113,54 +205,28 @@ void exceptionsDumpState(g_task* task, volatile g_processor_state* state)
113205 // Page fault
114206 logInfo (" %# accessed address: %h" , exceptionsGetCR2 ());
115207 }
208+ logInfo (" %# INTR: %h ERROR: %h" , state->intr , state->error );
116209 logInfo (" %# RIP: %h RFLAGS: %h" , state->rip , state->rflags );
117- logInfo (" %# RAX: %h RBX: %h" , state->rax , state->rbx );
118- logInfo (" %# RCX: %h RDX: %h" , state->rcx , state->rdx );
119- logInfo (" %# RSP: %h RBP: %h" , state->rsp , state->rbp );
120210 logInfo (" %# CS: %h SS: %h" , state->cs , state->ss );
121- logInfo (" %# INTR: %h ERROR: %h" , state->intr , state->error );
211+ logInfo (" %# RSP: %h RBP: %h" , state->rbp , state->rbp );
212+ logInfo (" %# RAX: %h RBX: %h %RCX: %h RDX: %h" , state->rax , state->rbx , state->rcx , state->rdx );
122213 if (task)
123214 {
124215 logInfo (" %# task stack: %h - %h" , task->stack .start , task->stack .end );
125216 logInfo (" %# intr stack: %h - %h" , task->interruptStack .start , task->interruptStack .end );
126217
218+ logInfo (" %# loaded objects:" );
127219 auto iter = hashmapIteratorStart (task->process ->object ->loadedObjects );
128220 while (hashmapIteratorHasNext (&iter))
129221 {
130222 auto object = hashmapIteratorNext (&iter)->value ;
131223
132- logInfo (" %# obj %x-%x: %s" , object->startAddress , object->endAddress , object->name );
133-
134- if (state->rip >= object->startAddress && state->rip < object->endAddress )
135- {
136- if (object == task->process ->object )
137- {
138- logInfo (" %# caused in executable object" );
139- }
140- else
141- {
142- logInfo (" %# caused in object '%s' at offset %x" , object->name , state->rip - object->baseAddress );
143- }
144- break ;
145- }
224+ logInfo (" %# %x-%x: %s" , object->startAddress , object->endAddress , object->name );
146225 }
147226 hashmapIteratorEnd (&iter);
148227 }
149228
150- #if DEBUG_PRINT_STACK_TRACE
151- g_address* rbp = reinterpret_cast <g_address*>(state->rbp );
152- logInfo (" %# stack trace:" );
153- for (int frame = 0 ; frame < 8 ; ++frame)
154- {
155- g_address rip = rbp[1 ];
156- if (rip < 0x1000 )
157- {
158- break ;
159- }
160- rbp = reinterpret_cast <g_address*>(rbp[0 ]);
161- logInfo (" %# %h" , rip);
162- }
163- #endif
229+ exceptionsPrintStackTrace (task, state);
164230}
165231
166232bool exceptionsHandlePageFault (g_task* task, volatile g_processor_state* state)
0 commit comments