6 static int test_sstep();
7 static int test_break(char *errbuf, size_t bufsize);
8 static int test_other(char *errbuf, size_t bufsize);
9 static int test_log_only();
13 #define write_debug_register(num, val) \
14 asm volatile("mov %0, %%db" #num : : "r" ((Mword)val))
16 #define read_debug_register(num) \
17 ({Mword val; asm volatile("mov %%db" #num ",%0" : "=r"(val)); val;})
19 IMPLEMENTATION[ia32,amd64]:
25 PUBLIC inline NEEDS["kmem.h"]
27 Breakpoint::set(Address _addr, Mword _len, Mode _mode, Log _log)
31 user = Kmem::is_kmem_page_fault(_addr, 0) ? ADDR_KERNEL : ADDR_USER;
38 Jdb_bp::get_dr(Mword i)
42 case 0: return read_debug_register(0);
43 case 1: return read_debug_register(1);
44 case 2: return read_debug_register(2);
45 case 3: return read_debug_register(3);
46 case 6: return read_debug_register(6);
54 Jdb_bp::global_breakpoints()
61 Jdb_bp::set_debug_address_register(int num, Mword addr, Mword len,
62 Breakpoint::Mode mode, Space *)
65 set_dr7(num, len, mode, dr7);
68 case 0: write_debug_register(0, addr); break;
69 case 1: write_debug_register(1, addr); break;
70 case 2: write_debug_register(2, addr); break;
71 case 3: write_debug_register(3, addr); break;
79 Jdb_bp::clr_debug_address_register(int num)
86 Jdb_bp::at_jdb_enter()
88 dr7 = read_debug_register(7);
89 // disable breakpoints while we are in kernel debugger
90 write_debug_register(7, dr7 & Val_enter);
95 Jdb_bp::at_jdb_leave()
97 write_debug_register(6, Val_leave);
98 write_debug_register(7, dr7);
101 /** @return 1 if single step occured */
106 Mword dr6 = read_debug_register(6);
107 if (!(dr6 & Val_test_sstep))
110 // single step has highest priority, don't consider other conditions
111 write_debug_register(6, Val_leave);
115 /** @return 1 if breakpoint occured */
118 Jdb_bp::test_break(char *errbuf, size_t bufsize)
120 Mword dr6 = read_debug_register(6);
121 if (!(dr6 & Val_test))
124 int ret = test_break(dr6, errbuf, bufsize);
125 write_debug_register(6, dr6 & ~Val_test);
129 /** @return 1 if other debug exception occured */
132 Jdb_bp::test_other(char *errbuf, size_t bufsize)
134 Mword dr6 = read_debug_register(6);
135 if (!(dr6 & Val_test_other))
138 snprintf(errbuf, bufsize, "unknown trap 1 (dr6="L4_PTR_FMT")", dr6);
139 write_debug_register(6, Val_leave);
143 /** @return 0 if only breakpoints were logged and jdb should not be entered */
146 Jdb_bp::test_log_only()
148 Mword dr6 = read_debug_register(6);
152 dr7 = read_debug_register(7);
153 // disable breakpoints -- we might trigger a r/w breakpoint again
154 write_debug_register(7, dr7 & Val_enter);
156 write_debug_register(6, dr6);
157 write_debug_register(7, dr7);
158 if (!(dr6 & Val_test_other))
159 // don't enter jdb, breakpoints only logged
170 Jdb::bp_test_log_only = test_log_only;
171 Jdb::bp_test_break = test_break;
172 Jdb::bp_test_sstep = test_sstep;
173 Jdb::bp_test_other = test_other;