+
+ file->data = http_output_buffer;
+}
+
+#define LEFT (sizeof(http_output_buffer) - len)
+
+void handle_backtrace(struct fs_file *file)
+{
+ int i = 10;
+ int len;
+ unsigned long *pebp, *peip;
+ unsigned long ebp;
+ unsigned long cr3;
+
+ char * buf = http_output_buffer;
+
+ strcpy(buf, "<html><head><title>Backtrace</title></head><body><tt><pre>");
+ len = strlen(buf);
+ ebp = *(unsigned long *)0xAFFE4;
+ cr3 = *(unsigned long *)0xAFFF8;
+
+ len += snprintf(buf + len, LEFT, "0x%08x, from\n", *(unsigned long*)0xAFFF0);
+
+ /* I never thought I'd do this again. */
+ while ((peip = demap(cr3, ebp+4)) != 0x0 && i--)
+ {
+ len += snprintf(buf + len, LEFT, "0x%08x, from\n", *peip);
+
+ pebp = demap(cr3, ebp);
+ if (!pebp)
+ {
+ len += snprintf(buf + len, LEFT, "<unreadable %ebp>\n");
+ break;
+ }
+ if (ebp >= *pebp && *pebp)
+ {
+ len += snprintf(buf + len, LEFT, "<recursive %ebp>\n");
+ break;
+ }
+ ebp = *pebp;
+ }
+
+ if (i == -1)
+ len += snprintf(buf + len, LEFT, "...\n");
+ else
+ len += snprintf(buf + len, LEFT, "<root>");
+
+ len += snprintf(buf + len, LEFT, "</pre></tt></body></html>");