... |
... |
@@ -153,7 +153,8 @@ arch_skip_instruction(os_context_t * context) |
153
|
153
|
/* Get and skip the lisp error code. */
|
154
|
154
|
char* pc = (char *) SC_PC(context);
|
155
|
155
|
|
156
|
|
- pc += 2; /* skip 0x0f and 0x0b */
|
|
156
|
+ /* Skip over the UD2 inst (0x0f, 0x0b) */
|
|
157
|
+ pc += 2;
|
157
|
158
|
|
158
|
159
|
code = *pc++;
|
159
|
160
|
SC_PC(context) = (unsigned long) pc;
|
... |
... |
@@ -173,6 +174,8 @@ arch_skip_instruction(os_context_t * context) |
173
|
174
|
break;
|
174
|
175
|
|
175
|
176
|
case trap_Breakpoint:
|
|
177
|
+ lose("Unexpected breakpoint trap in arch_skip_instruction\n");
|
|
178
|
+ break;
|
176
|
179
|
case trap_FunctionEndBreakpoint:
|
177
|
180
|
break;
|
178
|
181
|
|
... |
... |
@@ -231,6 +234,11 @@ arch_remove_breakpoint(void *pc, unsigned long orig_inst) |
231
|
234
|
(stderr, "arch_remove_breakpoint: %p orig %lx\n",
|
232
|
235
|
pc, orig_inst));
|
233
|
236
|
unsigned char *ptr = (unsigned char *) pc;
|
|
237
|
+ /*
|
|
238
|
+ * Just restore all the bytes from orig_inst. Should we just
|
|
239
|
+ * re-install just the one byte that was taken by the int3
|
|
240
|
+ * instruction?
|
|
241
|
+ */
|
234
|
242
|
ptr[0] = orig_inst & 0xff;
|
235
|
243
|
ptr[1] = (orig_inst >> 8) & 0xff;
|
236
|
244
|
ptr[2] = (orig_inst >> 16) & 0xff;
|
... |
... |
@@ -267,8 +275,12 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst) |
267
|
275
|
|
268
|
276
|
*((char *) pc) = orig_inst & 0xff;
|
269
|
277
|
|
|
278
|
+ /*
|
|
279
|
+ * If we have the SC_EFLAGS macro, we can enable single-stepping
|
|
280
|
+ * by setting the bit. Otherwise, we need a more complicated way
|
|
281
|
+ * of enabling single-stepping.
|
|
282
|
+ */
|
270
|
283
|
#ifdef SC_EFLAGS
|
271
|
|
- /* Enable single-stepping */
|
272
|
284
|
SC_EFLAGS(context) |= 0x100;
|
273
|
285
|
#else
|
274
|
286
|
|
... |
... |
@@ -305,6 +317,11 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst) |
305
|
317
|
}
|
306
|
318
|
|
307
|
319
|
|
|
320
|
+/*
|
|
321
|
+ * Handles the break instruction from lisp, which is now UD2 followed
|
|
322
|
+ * by the trap code. In particular, this does not handle the
|
|
323
|
+ * breakpoint traps.
|
|
324
|
+ */
|
308
|
325
|
void
|
309
|
326
|
sigill_handler(HANDLER_ARGS)
|
310
|
327
|
{
|
... |
... |
@@ -322,9 +339,6 @@ sigill_handler(HANDLER_ARGS) |
322
|
339
|
*((unsigned char*)SC_PC(context) + 3),
|
323
|
340
|
*((unsigned char*)SC_PC(context) + 4)));
|
324
|
341
|
|
325
|
|
- if (single_stepping) {
|
326
|
|
- lose("sigill handler with single-stepping enabled?\n");
|
327
|
|
- }
|
328
|
342
|
|
329
|
343
|
/* This is just for info in case monitor wants to print an approx */
|
330
|
344
|
current_control_stack_pointer = (unsigned long *) SC_SP(os_context);
|
... |
... |
@@ -346,6 +360,14 @@ sigill_handler(HANDLER_ARGS) |
346
|
360
|
DPRINTF(debug_handlers,
|
347
|
361
|
(stderr, "pc %x\n", *(unsigned short *)SC_PC(context)));
|
348
|
362
|
|
|
363
|
+ /*
|
|
364
|
+ * Make sure the trapping instruction is UD2. Abort if not.
|
|
365
|
+ *
|
|
366
|
+ * TODO: aborting is probably not the best idea. Could get here
|
|
367
|
+ * from other illegal instructions in, say, C code? Maybe we
|
|
368
|
+ * should call interrupt_handle_now, as we do below for an unknown
|
|
369
|
+ * trap code?
|
|
370
|
+ */
|
349
|
371
|
if (*(unsigned short *) SC_PC(context) == 0x0b0f) {
|
350
|
372
|
trap = *(((char *)SC_PC(context)) + 2);
|
351
|
373
|
} else {
|
... |
... |
@@ -413,6 +435,9 @@ sigill_handler(HANDLER_ARGS) |
413
|
435
|
}
|
414
|
436
|
}
|
415
|
437
|
|
|
438
|
+/*
|
|
439
|
+ * Handles the breakpoint trap (int3) and also single-stepping
|
|
440
|
+ */
|
416
|
441
|
void
|
417
|
442
|
sigtrap_handler(HANDLER_ARGS)
|
418
|
443
|
{
|
... |
... |
@@ -464,6 +489,13 @@ sigtrap_handler(HANDLER_ARGS) |
464
|
489
|
|
465
|
490
|
DPRINTF(debug_handlers, (stderr, "*C break\n"));
|
466
|
491
|
|
|
492
|
+ /*
|
|
493
|
+ * The int3 instruction causes a trap that leaves us just after
|
|
494
|
+ * the instruction. Backup one so we're at the beginning. This
|
|
495
|
+ * is really important so that when we handle the breakpoint, the
|
|
496
|
+ * offset of the instruction matches where Lisp thinks the
|
|
497
|
+ * breakpoint was placed.
|
|
498
|
+ */
|
467
|
499
|
SC_PC(os_context) -= 1;
|
468
|
500
|
|
469
|
501
|
handle_breakpoint(signal, CODE(code), os_context);
|