... |
... |
@@ -522,12 +522,19 @@ sigill_handler(HANDLER_ARGS) |
522
|
522
|
|
523
|
523
|
/*
|
524
|
524
|
* Compute the maximum length of the string from the
|
525
|
|
- * offset in the branch instruction. (The signed offset
|
526
|
|
- * is in the low 22 bits of the instruction.) Then try
|
527
|
|
- * to find the last nul character for end of the string.
|
|
525
|
+ * offset in the branch instruction. This code assumes
|
|
526
|
+ * a ba,pt instruction which has a 19-bit word offset in
|
|
527
|
+ * the low part of the instruction. Because branches
|
|
528
|
+ * have a delay slot, the string starts two words past
|
|
529
|
+ * the branch instruction.
|
528
|
530
|
*/
|
529
|
|
- string = (unsigned char *) &pc[2];
|
530
|
|
- length = (pc[1] & 0x3fffff);
|
|
531
|
+ string = (unsigned char *) &pc[3];
|
|
532
|
+ /*
|
|
533
|
+ * The offset is in 32-bit words, so subtract one for
|
|
534
|
+ * the instruction in the branch delay slot and scale up
|
|
535
|
+ * the offet to be in bytes.
|
|
536
|
+ */
|
|
537
|
+ length = 4 * ((pc[1] & 0x7FFFF) - 1);
|
531
|
538
|
|
532
|
539
|
while (string[length - 1] == '\0') {
|
533
|
540
|
--length;
|
... |
... |
@@ -538,14 +545,14 @@ sigill_handler(HANDLER_ARGS) |
538
|
545
|
* don't actually want to abort. We want to continue,
|
539
|
546
|
* but print out a useful message.
|
540
|
547
|
*/
|
541
|
|
- printf("NOT-IMPLEMENTED: %p: \"%.*s\"\n", pc, length, (char*)(pc + 2));
|
|
548
|
+ printf("NOT-IMPLEMENTED: %p: \"%.*s\"\n", pc, length, string);
|
542
|
549
|
|
543
|
550
|
/*
|
544
|
|
- * Skip over the UDF instruction so if we can
|
|
551
|
+ * Skip over the illtrap instruction so if we can
|
545
|
552
|
* continue. This will execute the branch, skipping
|
546
|
553
|
* over the string too.
|
547
|
554
|
*/
|
548
|
|
- SC_PC(context) = (unsigned long) (pc + 1);
|
|
555
|
+ SC_PC(os_context) = (unsigned long) (pc + 1);
|
549
|
556
|
|
550
|
557
|
}
|
551
|
558
|
break;
|