@@ -72,14 +72,67 @@ const char* tail_last_lines(const char *s, size_t n) {
7272 return s ;
7373}
7474
75+ /* Tiny decoder for exceptions that carry an error code */
76+ static inline const char * print_error_code_detail (uint64_t vec , uint64_t ec ) {
77+ static char message [MAX_STRINGLEN ];
78+ switch (vec ) {
79+ case 10 : /* #TS */
80+ case 11 : /* #NP */
81+ case 12 : /* #SS */
82+ case 13 : { /* #GP */
83+ const unsigned ext = (ec >> 0 ) & 1 ; /* set if originated externally */
84+ const unsigned idt = (ec >> 1 ) & 1 ; /* 1 => refers to IDT gate */
85+ const unsigned ti = (ec >> 2 ) & 1 ; /* 0=GDT, 1=LDT (ignored if idt=1) */
86+ const unsigned idx = (unsigned )((ec >> 3 ) & 0x1FFF ); /* selector index */
7587
76- void error_handler (uint8_t int_no , uint64_t errorcode , uint64_t irq_no , void * opaque ) {
88+ const char * table = idt ? "IDT" : (ti ? "LDT" : "GDT" );
89+ snprintf (message , MAX_STRINGLEN , "idx=%u, table=%s%s" , idx , table , ext ? ", ext" : "" );
90+ break ;
91+ }
92+ case 14 : { /* #PF: Page Fault */
93+ const int p = (ec >> 0 ) & 1 ; /* 0=not-present, 1=protection */
94+ const int wr = (ec >> 1 ) & 1 ; /* 1=write, 0=read */
95+ const int us = (ec >> 2 ) & 1 ; /* 1=user, 0=kernel */
96+ const int rsv = (ec >> 3 ) & 1 ; /* reserved bit violation */
97+ const int ift = (ec >> 4 ) & 1 ; /* instruction fetch */
98+ const int pkey = (ec >> 5 ) & 1 ; /* protection key (if enabled) */
99+ const int sstk = (ec >> 6 ) & 1 ; /* CET shadow stack (if enabled) */
100+ /* bit 7 (HLAT) exists on some parts; ignore silently if 0 */
101+
102+ snprintf (message , MAX_STRINGLEN , "%s, %s, %s%s%s%s%s" ,
103+ p ? "protection" : "not-present" ,
104+ wr ? "write" : "read" ,
105+ us ? "user" : "kernel" ,
106+ rsv ? ", rsvd-bit" : "" ,
107+ ift ? ", ifetch" : "" ,
108+ pkey ? ", pkey" : "" ,
109+ sstk ? ", sstk" : "" );
110+ break ;
111+ }
112+ default :
113+ snprintf (message , MAX_STRINGLEN , "no error detail" );
114+ break ;
115+ }
116+ return message ;
117+ }
118+
119+ void error_handler (uint8_t int_no , uint64_t errorcode , uint64_t rip , void * opaque ) {
77120 interrupts_off ();
78121 setforeground (COLOUR_LIGHTRED );
79122 setbackground (COLOUR_BLACK );
80123 const char * log = tail_last_lines (dprintf_buffer_snapshot (), 15 );
81- kprintf ("\nFatal exception %02X (Error code %016lx): %s\n" , int_no , errorcode , error_table [int_no ]);
82- dprintf ("\nFatal exception %02X (Error code %016lx): %s\n" , int_no , errorcode , error_table [int_no ]);
124+ aprintf ("\nFatal exception %02X (Error code %016lx): %s (%s)\n" , int_no , errorcode , error_table [int_no ], print_error_code_detail (int_no , errorcode ));
125+ if (rip ) {
126+ uint64_t offset = 0 ;
127+ const char * mname = NULL , * sname = NULL ;
128+ if (module_addr_to_symbol (rip , & mname , & sname , & offset )) {
129+ /* print "mname:sname+off" (or mname:[???]) */
130+ aprintf ("\tfault @ %s:%s()+0%08lx [0x%lx]\n" , mname , sname , offset , (uint64_t ) rip );
131+ } else {
132+ const char * name = findsymbol (rip , & offset );
133+ aprintf ("\tfault @ %s()+0%08lx [0x%lx]\n" , name ? name : "[???]" , offset , (uint64_t ) rip );
134+ }
135+ }
83136 setforeground (COLOUR_WHITE );
84137 kprintf ("------------------------------------[ DEBUG LOG ]-----------------------------------\n" );
85138 setforeground (COLOUR_GREY );
0 commit comments