From d3a9db3aff54ea485f409eaaef3d8f56ad77f0dc Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 5 Oct 2020 11:00:05 -0700 Subject: 6958 --- html/039debug.cc.html | 194 ++++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 84 deletions(-) (limited to 'html/039debug.cc.html') diff --git a/html/039debug.cc.html b/html/039debug.cc.html index 7f792b4f..0f71c0f2 100644 --- a/html/039debug.cc.html +++ b/html/039debug.cc.html @@ -15,10 +15,10 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .LineNr { } +.SpecialChar { color: #d70000; } .Constant { color: #008787; } .Comment { color: #005faf; } .Delimiter { color: #c000c0; } -.Special { color: #d70000; } .Identifier { color: #af5f00; } .Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; } .Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; } @@ -65,8 +65,8 @@ if ('onhashchange' in window) { 5 //: (It'll only affect the trace.) 6 7 :(before "End Globals") - 8 map</*address*/uint32_t, string> Symbol_name; // used only by 'bootstrap run' - 9 map</*address*/uint32_t, string> Source_line; // used only by 'bootstrap run' + 8 map</*address*/uint32_t, string> Symbol_name; // used only by 'bootstrap run' + 9 map</*address*/uint32_t, string> Source_line; // used only by 'bootstrap run' 10 :(before "End --trace Settings") 11 load_labels(); 12 load_source_lines(); @@ -75,12 +75,12 @@ if ('onhashchange' in window) { 15 ifstream fin("labels"); 16 if (fin.fail()) return; 17 fin >> std::hex; - 18 while (has_data(fin)) { + 18 while (has_data(fin)) { 19 uint32_t addr = 0; 20 fin >> addr; 21 string name; 22 fin >> name; - 23 put(Symbol_name, addr, name); + 23 put(Symbol_name, addr, name); 24 } 25 } 26 @@ -88,38 +88,38 @@ if ('onhashchange' in window) { 28 ifstream fin("source_lines"); 29 if (fin.fail()) return; 30 fin >> std::hex; - 31 while (has_data(fin)) { + 31 while (has_data(fin)) { 32 uint32_t addr = 0; 33 fin >> addr; 34 string line; 35 getline(fin, line); - 36 put(Source_line, addr, hacky_squeeze_out_whitespace(line)); + 36 put(Source_line, addr, hacky_squeeze_out_whitespace(line)); 37 } 38 } 39 40 :(after "Run One Instruction") - 41 if (contains_key(Symbol_name, EIP)) - 42 trace(Callstack_depth, "run") << "== label " << get(Symbol_name, EIP) << end(); - 43 if (contains_key(Source_line, EIP)) - 44 trace(Callstack_depth, "run") << "inst: " << get(Source_line, EIP) << end(); + 41 if (contains_key(Symbol_name, EIP)) + 42 trace(Callstack_depth, "run") << "== label " << get(Symbol_name, EIP) << end(); + 43 if (contains_key(Source_line, EIP)) + 44 trace(Callstack_depth, "run") << "inst: " << get(Source_line, EIP) << end(); 45 else 46 // no source line info; do what you can - 47 trace(Callstack_depth, "run") << "inst: " << debug_info(EIP) << end(); + 47 trace(Callstack_depth, "run") << "inst: " << debug_info(EIP) << end(); 48 49 :(code) 50 string debug_info(uint32_t inst_address) { - 51 uint8_t op = read_mem_u8(inst_address); + 51 uint8_t op = read_mem_u8(inst_address); 52 if (op != 0xe8) { 53 ostringstream out; - 54 out << HEXBYTE << NUM(op); + 54 out << HEXBYTE << NUM(op); 55 return out.str(); 56 } - 57 int32_t offset = read_mem_i32(inst_address+/*skip op*/1); + 57 int32_t offset = read_mem_i32(inst_address+/*skip op*/1); 58 uint32_t next_eip = inst_address+/*inst length*/5+offset; - 59 if (contains_key(Symbol_name, next_eip)) - 60 return "e8/call "+get(Symbol_name, next_eip); + 59 if (contains_key(Symbol_name, next_eip)) + 60 return "e8/call "+get(Symbol_name, next_eip); 61 ostringstream out; - 62 out << "e8/call 0x" << HEXWORD << next_eip; + 62 out << "e8/call 0x" << HEXWORD << next_eip; 63 return out.str(); 64 } 65 @@ -130,83 +130,109 @@ if ('onhashchange' in window) { 70 :(after "Run One Instruction") 71 dump_watch_points(); 72 :(before "End Globals") - 73 map<string, uint32_t> Watch_points; + 73 map<string, uint32_t> Watch_points; 74 :(before "End Reset") - 75 Watch_points.clear(); + 75 Watch_points.clear(); 76 :(code) 77 void dump_watch_points() { - 78 if (Watch_points.empty()) return; - 79 trace(Callstack_depth, "dbg") << "watch points:" << end(); - 80 for (map<string, uint32_t>::iterator p = Watch_points.begin(); p != Watch_points.end(); ++p) - 81 trace(Callstack_depth, "dbg") << " " << p->first << ": " << HEXWORD << p->second << " -> " << HEXWORD << read_mem_u32(p->second) << end(); + 78 if (Watch_points.empty()) return; + 79 trace(Callstack_depth, "dbg") << "watch points:" << end(); + 80 for (map<string, uint32_t>::iterator p = Watch_points.begin(); p != Watch_points.end(); ++p) + 81 trace(Callstack_depth, "dbg") << " " << p->first << ": " << HEXWORD << p->second << " -> " << HEXWORD << read_mem_u32(p->second) << end(); 82 } 83 84 :(before "End Globals") - 85 string Watch_this_effective_address; + 85 string Watch_this_effective_address; 86 :(after "Run One Instruction") - 87 Watch_this_effective_address = ""; - 88 if (contains_key(Symbol_name, EIP) && starts_with(get(Symbol_name, EIP), "$watch-")) - 89 Watch_this_effective_address = get(Symbol_name, EIP); + 87 Watch_this_effective_address = ""; + 88 if (contains_key(Symbol_name, EIP) && starts_with(get(Symbol_name, EIP), "$watch-")) + 89 Watch_this_effective_address = get(Symbol_name, EIP); 90 :(after "Found effective_address(addr)") - 91 if (!Watch_this_effective_address.empty()) { - 92 dbg << "now watching " << HEXWORD << addr << " for " << Watch_this_effective_address << end(); - 93 put(Watch_points, Watch_this_effective_address, addr); + 91 if (!Watch_this_effective_address.empty()) { + 92 dbg << "now watching " << HEXWORD << addr << " for " << Watch_this_effective_address << end(); + 93 put(Watch_points, Watch_this_effective_address, addr); 94 } 95 - 96 //: Special label that dumps regions of memory. - 97 //: Not a general mechanism; by the time you get here you're willing to hack - 98 //: on the emulator. + 96 //: If a label starts with '$dump-stack', dump out to the trace n bytes on + 97 //: either side of ESP. + 98 99 :(after "Run One Instruction") -100 if (contains_key(Symbol_name, EIP) && get(Symbol_name, EIP) == "$dump-stream-at-EAX") -101 dump_stream_at(Reg[EAX].u); -102 :(code) -103 void dump_stream_at(uint32_t stream_start) { -104 int32_t stream_length = read_mem_i32(stream_start + 8); -105 dbg << "stream length: " << std::dec << stream_length << end(); -106 for (int i = 0; i < stream_length + 12; ++i) -107 dbg << "0x" << HEXWORD << (stream_start+i) << ": " << HEXBYTE << NUM(read_mem_u8(stream_start+i)) << end(); -108 } -109 -110 //: helpers -111 -112 :(code) -113 string hacky_squeeze_out_whitespace(const string& s) { -114 // strip whitespace at start -115 string::const_iterator first = s.begin(); -116 while (first != s.end() && isspace(*first)) -117 ++first; -118 if (first == s.end()) return ""; -119 -120 // strip whitespace at end -121 string::const_iterator last = --s.end(); -122 while (last != s.begin() && isspace(*last)) -123 --last; -124 ++last; -125 -126 // replace runs of spaces/dots with single space until comment or string -127 // TODO: -128 // leave alone dots not surrounded by whitespace -129 // leave alone '#' within word -130 // leave alone '"' within word -131 // squeeze spaces after end of string -132 ostringstream out; -133 bool previous_was_space = false; -134 bool in_comment_or_string = false; -135 for (string::const_iterator curr = first; curr != last; ++curr) { -136 if (in_comment_or_string) -137 out << *curr; -138 else if (isspace(*curr) || *curr == '.') -139 previous_was_space = true; -140 else { -141 if (previous_was_space) -142 out << ' '; -143 out << *curr; -144 previous_was_space = false; -145 if (*curr == '#' || *curr == '"') in_comment_or_string = true; -146 } -147 } -148 return out.str(); -149 } +100 if (contains_key(Symbol_name, EIP) && starts_with(get(Symbol_name, EIP), "$dump-stack")) { +101 dump_stack(64); +102 } +103 :(code) +104 void dump_stack(int n) { +105 uint32_t stack_pointer = Reg[ESP].u; +106 uint32_t start = ((stack_pointer-n)&0xfffffff0); +107 dbg << "stack:" << end(); +108 for (uint32_t addr = start; addr < start+n*2; addr+=16) { +109 if (addr >= AFTER_STACK) break; +110 ostringstream out; +111 out << HEXWORD << addr << ":"; +112 for (int i = 0; i < 16; i+=4) { +113 out << ' '; +114 out << ((addr+i == stack_pointer) ? '[' : ' '); +115 out << HEXWORD << read_mem_u32(addr+i); +116 out << ((addr+i == stack_pointer) ? ']' : ' '); +117 } +118 dbg << out.str() << end(); +119 } +120 } +121 +122 //: Special label that dumps regions of memory. +123 //: Not a general mechanism; by the time you get here you're willing to hack +124 //: on the emulator. +125 :(after "Run One Instruction") +126 if (contains_key(Symbol_name, EIP) && get(Symbol_name, EIP) == "$dump-stream-at-EAX") +127 dump_stream_at(Reg[EAX].u); +128 :(code) +129 void dump_stream_at(uint32_t stream_start) { +130 int32_t stream_length = read_mem_i32(stream_start + 8); +131 dbg << "stream length: " << std::dec << stream_length << end(); +132 for (int i = 0; i < stream_length + 12; ++i) +133 dbg << "0x" << HEXWORD << (stream_start+i) << ": " << HEXBYTE << NUM(read_mem_u8(stream_start+i)) << end(); +134 } +135 +136 //: helpers +137 +138 :(code) +139 string hacky_squeeze_out_whitespace(const string& s) { +140 // strip whitespace at start +141 string::const_iterator first = s.begin(); +142 while (first != s.end() && isspace(*first)) +143 ++first; +144 if (first == s.end()) return ""; +145 +146 // strip whitespace at end +147 string::const_iterator last = --s.end(); +148 while (last != s.begin() && isspace(*last)) +149 --last; +150 ++last; +151 +152 // replace runs of spaces/dots with single space until comment or string +153 // TODO: +154 // leave alone dots not surrounded by whitespace +155 // leave alone '#' within word +156 // leave alone '"' within word +157 // squeeze spaces after end of string +158 ostringstream out; +159 bool previous_was_space = false; +160 bool in_comment_or_string = false; +161 for (string::const_iterator curr = first; curr != last; ++curr) { +162 if (in_comment_or_string) +163 out << *curr; +164 else if (isspace(*curr) || *curr == '.') +165 previous_was_space = true; +166 else { +167 if (previous_was_space) +168 out << ' '; +169 out << *curr; +170 previous_was_space = false; +171 if (*curr == '#' || *curr == '"') in_comment_or_string = true; +172 } +173 } +174 return out.str(); +175 } -- cgit 1.4.1-2-gfad0