00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "src/common/shared.hpp"
00019 #include "src/common/string.hpp"
00020 #include "src/common/io.hpp"
00021 #include "src/tty/teletype.hpp"
00022 #include "src/memory/memset.hpp"
00023 #include "src/module/coresyms.hpp"
00024 #include "src/module/mangle.hpp"
00025 #include "src/module/elf.hpp"
00026 #include "src/common/error.hpp"
00027 #include "src/collection/avlmap.hpp"
00028
00033 uint32 sysfail_dbg=0;
00034
00036
00037 const uint32 CALL_TRACE_COUNT = 0xa;
00038
00048 using namespace Collection;
00049 struct AvlMap<uint32,uint32,generic_cmp<uint32> > *dbg_val_map;
00050 bool dbg_map_availlable = false;
00051
00052 void init_dbg_val_map() {
00053 dbg_val_map = new struct AvlMap<uint32,uint32,generic_cmp<uint32> >();
00054 dbg_map_availlable = true;
00055 }
00056
00060 uint32 get_dbg_val(uint32 key) {
00061 if (dbg_map_availlable == false)
00062 return 0;
00063 struct Option<Tuple2<uint32,uint32> > opt= dbg_val_map->find(key);
00064 if (opt.isNone())
00065 return 0;
00066 else
00067 return opt.get()._2;
00068 }
00069
00070 bool set_dbg_val(uint32 key, uint32 val) {
00071 if (!dbg_map_availlable) {
00072 println(key, " -> ", val);
00073 complain("dbg_map not initialised");
00074 return false;
00075 }
00076 return dbg_val_map->update(key,val);
00077 }
00078
00079
00080
00081
00082 void panic()
00083 {
00085 for(;;) Teletype::vidmem[1].ch++;
00086
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 void debug_dump_call_trace(uint32 eip, uint32 addr)
00102 {
00103 uint32 *trace;
00104 char *ch;
00105 string demangled;
00106 string num;
00107 int i;
00108 uint32 cnt=0;
00109
00110 trace= (uint32*) addr;
00111 memset(&demangled, 0, sizeof(demangled));
00112 memset(&num, 0, sizeof(num));
00113
00114
00115 alert("\nCALL TRACE: \n");
00116
00117 ch= Syms::sym_name (eip, STT_FUNC);
00118 if (ch!=NULL)
00119 {
00120 i= Syms::Mangle::demangle(ch, &demangled, trace+2);
00121 if ((i == ESUCCESS) && (demangled.v() != NULL))
00122 { alert("(#1) "); alert(demangled.v()); alert("\n"); }
00123 }
00124
00125
00126 while (ESUCCESS)
00127 {
00128 cnt++;
00129
00130 if (*(trace) < 0x100000)
00131 break;
00132 if (cnt+1>CALL_TRACE_COUNT)
00133 break;
00134
00135 ch= Syms::sym_name( *(trace+1), STT_FUNC);
00136 if (ch==NULL)
00137 break;
00138
00139 i= Syms::Mangle::demangle(ch, &demangled, trace+2);
00140 if ((i != ESUCCESS)||(demangled.v() == NULL))
00141 break;
00142
00143 num.decim(cnt+1);
00144
00145 alert("(#");
00146 alert(num.v());
00147 alert(") ");
00148 alert(demangled.v());
00149 alert("\n");
00150
00151 trace= (uint32*)*(trace);
00152 }
00153
00154
00155 alert("===end traceback\n");
00156 }
00157
00158
00159 void debug_dump_call_trace()
00160 {
00161 uint32 eip, esp;
00162 asm volatile ("mov (%%ebp), %%eax\nmov 4(%%ebp), %%ebx" : "=a" (esp), "=b" (eip));
00163 debug_dump_call_trace(eip,esp);
00164 alert("\n");
00165 }
00166
00167
00168 void put_bochs(char ch)
00169 {
00170 IOPorts::outb(PORT_E9, ch);
00171 }
00172
00173
00174 void write_bochs(const char *text)
00175 {
00176 uint32 fl;
00177 asm volatile("pushf\npopl %0\ncli":"=g" (fl));
00178 while ( *text != '\0')
00179 IOPorts::outb(PORT_E9, *(text++));
00180 asm volatile("pushl %0\npopf"::"g"(fl));
00181 }
00182
00183
00184 void write_bochs_num(uint32 n, uint32 radix, uint32 n_pos, char first_letter)
00185 {
00186 uint32 cipher;
00187 uint32 fl;
00188 asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00189 while (n_pos)
00190 {
00191 cipher = n / n_pos;
00192 if (cipher <= 9) { if (cipher || (radix!=10)) put_bochs(cipher + (char) '0'); }
00193 else put_bochs(cipher + first_letter - 0xA);
00194
00195 n -= cipher * n_pos;
00196 n_pos = n_pos / radix;
00197 }
00198 asm volatile("pushl %0\npopf"::"g"(fl));
00199 }
00200
00201
00202 void write_bochs(int i)
00203 {
00204 write_bochs_num(i, 16, 0x10000000, 'A');
00205 }
00206
00207
00208
00209
00210
00211
00212