#include <io.h>
#include <minilib.h>
#include <paging.h>
+#include <demap.h>
#include <output.h>
+#include <state.h>
+
+static char http_output_buffer[1280];
/*-----------------------------------------------------------------------------------*/
void handle_regs(struct fs_file *file)
{
- static char buf[2048];
-
- sprintf(buf,
- "<html><head><title>Registers</title></head><body>"
- "<p>At the time you requested this page, the system's registers were:</p>"
- "<tt><pre>"
- "%%eax: 0x%08x %%ebx: 0x%08x %%ecx: 0x%08x %%edx: 0x%08x\n"
- "%%ebp: 0x%08x %%esi: 0x%08x %%edi: 0x%08x %%esp: 0x%08x\n"
- "%%cr0: 0x%08x %%cr3: 0x%08x %%eip: 0x%08x %%eflags: 0x%08x\n"
- "</pre></tt></body></html>",
- *(unsigned long*)0xAFFD0,
- *(unsigned long*)0xAFFDC,
- *(unsigned long*)0xAFFD4,
- *(unsigned long*)0xAFFD8,
- *(unsigned long*)0xAFFE4,
- *(unsigned long*)0xAFFE8,
- *(unsigned long*)0xAFFEC,
- *(unsigned long*)0xAFFE0,
- *(unsigned long*)0xAFFFC,
- *(unsigned long*)0xAFFF8,
- *(unsigned long*)0xAFFF0,
- *(unsigned long*)0xAFFF4);
-
-
- file->data = buf;
- file->len = strlen(buf)-1;
+ int i;
+ int len;
+
+ len = snprintf(http_output_buffer, sizeof(http_output_buffer), "<html><pre>");
+
+ for (i = 0; i < state_num_regs(); i++) {
+ len += state_dump_reg(http_output_buffer + len, sizeof(http_output_buffer) - len, i);
+ }
+
+ file->len = len;
+ file->data = http_output_buffer;
}
+#define LEFT (sizeof(http_output_buffer) - len)
+
void handle_backtrace(struct fs_file *file)
{
- static char buf[2048];
- static char buf2[64];
int i = 10;
- unsigned long *pebp, *peip;
- unsigned long ebp;
- unsigned long cr3;
+ int len;
+ void *pebp, *peip;
+ uint64_t bp, next;
+
+ int longmode = (get_operating_mode() == LONG_64BIT);
+
+ char * buf = http_output_buffer;
strcpy(buf, "<html><head><title>Backtrace</title></head><body><tt><pre>");
- ebp = *(unsigned long *)0xAFFE4;
- cr3 = *(unsigned long *)0xAFFF8;
+ len = strlen(buf);
+
+ bp = state_get_reg(longmode ? STATE_REG_RIP : STATE_REG_EIP);
+
+ if (longmode)
+ len += snprintf(buf + len, LEFT, "0x%08x%08x, from\n", (uint32_t)(bp >> 32), (uint32_t)bp);
+ else
+ len += snprintf(buf + len, LEFT, "0x%08x, from\n", (uint32_t)bp);
- sprintf(buf2, "0x%08x, from\n", *(unsigned long*)0xAFFF0);
- strcat(buf, buf2);
+ bp = state_get_reg(longmode ? STATE_REG_RBP : STATE_REG_EBP);
- /* I never thought I'd do this again. */
- while ((peip = demap(cr3, ebp+4)) != 0x0 && i--)
+
+ outputf("Backtrace:");
+ while ((peip = demap(bp+(longmode?8:4))) != 0x0 && i--)
{
- sprintf(buf2, "0x%08x, from\n", *peip);
- strcat(buf, buf2);
- pebp = demap(cr3, ebp);
- if (!pebp)
+ if (longmode) {
+ uint64_t rip;
+ rip = *(uint64_t *)peip;
+ len += snprintf(buf + len, LEFT, "0x%08x%08x, from\n", (uint32_t)(rip >> 32), (uint32_t)rip);
+ } else {
+ len += snprintf(buf + len, LEFT, "0x%08x, from\n", *(uint32_t *)peip);
+ }
+ outputf(" EIP: %08x", *(uint32_t *)peip);
+
+ pebp = demap(bp);
+ if (!pebp || (bp & 3))
{
- strcat(buf, "<unreadable %ebp>\n");
+ len += snprintf(buf + len, LEFT, "<unreadable frame>\n");
break;
}
- if (ebp >= *pebp && *pebp)
+ outputf(" *EBP: %08x", *(uint32_t *)pebp);
+
+ if (longmode)
+ next = *(uint64_t *)pebp;
+ else
+ next = *(uint32_t *)pebp;
+
+ if (bp >= next && next)
{
- strcat(buf, "<recursive %ebp>\n");
+ len += snprintf(buf + len, LEFT, "<recursive frame>\n");
break;
}
- ebp = *pebp;
+
+ bp = next;
}
+
if (i == -1)
- strcat(buf, "...\n");
+ len += snprintf(buf + len, LEFT, "...\n");
+ else if (bp && !peip)
+ len += snprintf(buf + len, LEFT, "<unreadable fp @ %08x>\n", (uint32_t) bp);
else
- strcat(buf, "<root>");
- strcat(buf, "</pre></tt></body></html>");
+ len += snprintf(buf + len, LEFT, "<root>");
+
+ len += snprintf(buf + len, LEFT, "</pre></tt></body></html>");
file->data = buf;
- file->len = strlen(buf)-1;
+ file->len = len;
}
void handle_reboot(struct fs_file *file)