]> Joshua Wise's Git repositories - netwatch.git/blobdiff - net/http/fs.c
Improve correctness of backtrace library.
[netwatch.git] / net / http / fs.c
index 9e6358d627632bbef54410f5047402402164764a..2a63b4d7c777a7b95505571b4f05bf102f95765f 100644 (file)
 #include "fs.h"
 #include "fsdata.h"
 #include "fsdata.c"
+#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 fill_regs(struct fs_file *file)
+void handle_regs(struct fs_file *file)
+{
+  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 unsigned char buf[2048];
+  int i = 10;
+  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>");
+  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(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);
-    
+  bp = state_get_reg(longmode ? STATE_REG_RBP : STATE_REG_EBP);
+  
+
+  outputf("Backtrace:");
+  while ((peip = demap(bp+(longmode?8:4))) != 0x0 && i--)
+  {
+    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))
+    {
+      len += snprintf(buf + len, LEFT, "&lt;unreadable frame&gt;\n");
+      break;
+    }
+    outputf("   *EBP: %08x", *(uint32_t *)pebp);
+
+    if (longmode)
+      next = *(uint64_t *)pebp;
+    else
+      next = *(uint32_t *)pebp;
+
+    if (bp >= next && next)
+    {
+      len += snprintf(buf + len, LEFT, "&lt;recursive frame&gt;\n");
+      break;
+    }
+
+    bp = next;
+  }
+
+  if (i == -1)
+    len += snprintf(buf + len, LEFT, "...\n");
+  else if (bp && !peip)
+    len += snprintf(buf + len, LEFT, "&lt;unreadable fp @ %08x&gt;\n", (uint32_t) bp);
+  else
+    len += snprintf(buf + len, LEFT, "&lt;root&gt;");
+
+  len += snprintf(buf + len, LEFT, "</pre></tt></body></html>");
   
   file->data = buf;
-  file->len = strlen(buf);
+  file->len = len;
+}
+
+void handle_reboot(struct fs_file *file)
+{
+  outb(0xCF9, 0x4);
+  file->data = "So long!";
+  file->len = 8;
 }
 
 
@@ -76,7 +149,17 @@ fs_open(const char *name, struct fs_file *file)
   /* /registers.html is CGI */
   if (!strcmp(name, "/registers.html"))
   {
-    fill_regs(file);
+    handle_regs(file);
+    return 1;
+  }
+  if (!strcmp(name, "/backtrace.html"))
+  {
+    handle_backtrace(file);
+    return 1;
+  }
+  if (!strcmp(name, "/reboot"))
+  {
+    handle_reboot(file);
     return 1;
   }
 
@@ -85,7 +168,7 @@ fs_open(const char *name, struct fs_file *file)
       f = f->next) {
     if (!strcmp(name, (const char*)f->name)) {
       file->data = f->data;
-      file->len = f->len;
+      file->len = f->len-1;
       return 1;
     }
   }
This page took 0.026191 seconds and 4 git commands to generate.