Warning, cross-references for /kernel/kdb/i386-stub.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 #include "types.h"
0130 #include "kernel.h"
0131 #include "util/printf.h"
0132 #include "arch/i386.h"
0133
0134
0135
0136
0137
0138
0139 extern void putDebugChar(int);
0140 extern int getDebugChar();
0141
0142 #define exceptionHandler(n,h) set_idt_descriptor_by_addr (n, h, 0x3);
0143
0144
0145
0146
0147 #define BUFMAX 400
0148
0149 static char initialized;
0150
0151 int remote_debug;
0152
0153
0154 static const char hexchars[]="0123456789abcdef";
0155
0156
0157 #define NUMREGS 16
0158
0159
0160 #define NUMREGBYTES (NUMREGS * 4)
0161
0162 enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
0163 PC ,
0164 PS ,
0165 CS, SS, DS, ES, FS, GS};
0166
0167
0168
0169
0170 int _registers[NUMREGS];
0171
0172 #define STACKSIZE 10000
0173 int remcomStack[STACKSIZE/sizeof(int)];
0174 static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
0175
0176
0177
0178
0179 extern void
0180 return_to_prog ();
0181
0182
0183
0184
0185 asm(".text");
0186 asm(".globl return_to_prog");
0187 asm("return_to_prog:");
0188 asm(" movw _registers+44, %ss");
0189 asm(" movl _registers+16, %esp");
0190 asm(" movl _registers+4, %ecx");
0191 asm(" movl _registers+8, %edx");
0192 asm(" movl _registers+12, %ebx");
0193 asm(" movl _registers+20, %ebp");
0194 asm(" movl _registers+24, %esi");
0195 asm(" movl _registers+28, %edi");
0196 asm(" movw _registers+48, %ds");
0197 asm(" movw _registers+52, %es");
0198 asm(" movw _registers+56, %fs");
0199 asm(" movw _registers+60, %gs");
0200 asm(" movl _registers+36, %eax");
0201 asm(" pushl %eax");
0202 asm(" movl _registers+40, %eax");
0203 asm(" pushl %eax");
0204 asm(" movl _registers+32, %eax");
0205 asm(" pushl %eax");
0206 asm(" movl _registers, %eax");
0207
0208
0209 asm(" iret");
0210
0211
0212 int gdb_i386errcode;
0213
0214
0215 int gdb_i386vector = -1;
0216
0217
0218
0219 #define SAVE_REGISTERS1() \
0220 asm ("movl %eax, _registers"); \
0221 asm ("movl %ecx, _registers+4"); \
0222 asm ("movl %edx, _registers+8"); \
0223 asm ("movl %ebx, _registers+12"); \
0224 asm ("movl %ebp, _registers+20"); \
0225 asm ("movl %esi, _registers+24"); \
0226 asm ("movl %edi, _registers+28"); \
0227 asm ("movw $0, %ax"); \
0228 asm ("movw %ds, _registers+48"); \
0229 asm ("movw %ax, _registers+50"); \
0230 asm ("movw %es, _registers+52"); \
0231 asm ("movw %ax, _registers+54"); \
0232 asm ("movw %fs, _registers+56"); \
0233 asm ("movw %ax, _registers+58"); \
0234 asm ("movw %gs, _registers+60"); \
0235 asm ("movw %ax, _registers+62");
0236 #define SAVE_ERRCODE() \
0237 asm ("popl %ebx"); \
0238 asm ("movl %ebx, gdb_i386errcode");
0239 #define SAVE_REGISTERS2() \
0240 asm ("popl %ebx"); \
0241 asm ("movl %ebx, _registers+32"); \
0242 asm ("popl %ebx"); \
0243 asm ("movl %ebx, _registers+40"); \
0244 asm ("movw %ax, _registers+42"); \
0245 asm ("popl %ebx"); \
0246 asm ("movl %ebx, _registers+36"); \
0247 \
0248 asm ("movw %ss, _registers+44"); \
0249 asm ("movw %ax, _registers+46"); \
0250 asm ("movl %esp, _registers+16");
0251
0252
0253 #define CHECK_FAULT() \
0254 asm ("cmpl $0, _mem_fault_routine"); \
0255 asm ("jne mem_fault");
0256
0257 asm (".text");
0258 asm ("mem_fault:");
0259
0260
0261 asm (" popl %eax");
0262 asm (" movl %eax, gdb_i386errcode");
0263
0264 asm (" popl %eax");
0265
0266
0267 asm (" movl _mem_fault_routine, %eax");
0268 asm (" popl %ecx");
0269 asm (" popl %edx");
0270
0271
0272
0273
0274 asm (" leave");
0275
0276
0277 asm (" pushl %edx");
0278 asm (" pushl %ecx");
0279 asm (" pushl %eax");
0280
0281
0282 asm (" movl $0, %eax");
0283 asm (" movl %eax, _mem_fault_routine");
0284
0285 asm ("iret");
0286
0287 #define CALL_HOOK() asm("call _remcomHandler");
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 extern void __catchException3();
0300 asm(".text");
0301 asm(".globl __catchException3");
0302 asm("__catchException3:");
0303 SAVE_REGISTERS1();
0304 SAVE_REGISTERS2();
0305 asm ("pushl $3");
0306 CALL_HOOK();
0307
0308
0309 extern void __catchException1();
0310 asm(".text");
0311 asm(".globl __catchException1");
0312 asm("__catchException1:");
0313 SAVE_REGISTERS1();
0314 SAVE_REGISTERS2();
0315 asm ("pushl $1");
0316 CALL_HOOK();
0317
0318
0319 extern void __catchException0();
0320 asm(".text");
0321 asm(".globl __catchException0");
0322 asm("__catchException0:");
0323 SAVE_REGISTERS1();
0324 SAVE_REGISTERS2();
0325 asm ("pushl $0");
0326 CALL_HOOK();
0327
0328
0329 extern void __catchException4();
0330 asm(".text");
0331 asm(".globl __catchException4");
0332 asm("__catchException4:");
0333 SAVE_REGISTERS1();
0334 SAVE_REGISTERS2();
0335 asm ("pushl $4");
0336 CALL_HOOK();
0337
0338
0339 extern void __catchException5();
0340 asm(".text");
0341 asm(".globl __catchException5");
0342 asm("__catchException5:");
0343 SAVE_REGISTERS1();
0344 SAVE_REGISTERS2();
0345 asm ("pushl $5");
0346 CALL_HOOK();
0347
0348
0349 extern void __catchException6();
0350 asm(".text");
0351 asm(".globl __catchException6");
0352 asm("__catchException6:");
0353 SAVE_REGISTERS1();
0354 SAVE_REGISTERS2();
0355 asm ("pushl $6");
0356 CALL_HOOK();
0357
0358
0359 extern void __catchException7();
0360 asm(".text");
0361 asm(".globl __catchException7");
0362 asm("__catchException7:");
0363 SAVE_REGISTERS1();
0364 SAVE_REGISTERS2();
0365 asm ("pushl $7");
0366 CALL_HOOK();
0367
0368
0369 extern void __catchException8();
0370 asm(".text");
0371 asm(".globl __catchException8");
0372 asm("__catchException8:");
0373 SAVE_REGISTERS1();
0374 SAVE_ERRCODE();
0375 SAVE_REGISTERS2();
0376 asm ("pushl $8");
0377 CALL_HOOK();
0378
0379
0380 extern void __catchException9();
0381 asm(".text");
0382 asm(".globl __catchException9");
0383 asm("__catchException9:");
0384 SAVE_REGISTERS1();
0385 SAVE_REGISTERS2();
0386 asm ("pushl $9");
0387 CALL_HOOK();
0388
0389
0390 extern void __catchException10();
0391 asm(".text");
0392 asm(".globl __catchException10");
0393 asm("__catchException10:");
0394 SAVE_REGISTERS1();
0395 SAVE_ERRCODE();
0396 SAVE_REGISTERS2();
0397 asm ("pushl $10");
0398 CALL_HOOK();
0399
0400
0401 extern void __catchException12();
0402 asm(".text");
0403 asm(".globl __catchException12");
0404 asm("__catchException12:");
0405 SAVE_REGISTERS1();
0406 SAVE_ERRCODE();
0407 SAVE_REGISTERS2();
0408 asm ("pushl $12");
0409 CALL_HOOK();
0410
0411
0412 extern void __catchException16();
0413 asm(".text");
0414 asm(".globl __catchException16");
0415 asm("__catchException16:");
0416 SAVE_REGISTERS1();
0417 SAVE_REGISTERS2();
0418 asm ("pushl $16");
0419 CALL_HOOK();
0420
0421
0422
0423
0424 extern void __catchException13 ();
0425 asm (".text");
0426 asm (".globl __catchException13");
0427 asm ("__catchException13:");
0428 CHECK_FAULT();
0429 SAVE_REGISTERS1();
0430 SAVE_ERRCODE();
0431 SAVE_REGISTERS2();
0432 asm ("pushl $13");
0433 CALL_HOOK();
0434
0435
0436 extern void __catchException11 ();
0437 asm (".text");
0438 asm (".globl __catchException11");
0439 asm ("__catchException11:");
0440 CHECK_FAULT();
0441 SAVE_REGISTERS1();
0442 SAVE_ERRCODE();
0443 SAVE_REGISTERS2();
0444 asm ("pushl $11");
0445 CALL_HOOK();
0446
0447
0448 extern void __catchException14 ();
0449 asm (".text");
0450 asm (".globl __catchException14");
0451 asm ("__catchException14:");
0452 CHECK_FAULT();
0453 SAVE_REGISTERS1();
0454 SAVE_ERRCODE();
0455 SAVE_REGISTERS2();
0456 asm ("pushl $14");
0457 CALL_HOOK();
0458
0459
0460
0461
0462
0463 asm("_remcomHandler:");
0464 asm(" popl %eax");
0465 asm(" popl %eax");
0466 asm(" movl stackPtr, %esp");
0467 asm(" pushl %eax");
0468 asm(" call handle_exception");
0469
0470 void
0471 _returnFromException ()
0472 {
0473 return_to_prog ();
0474 }
0475
0476 int
0477 hex (ch)
0478 char ch;
0479 {
0480 if ((ch >= 'a') && (ch <= 'f'))
0481 return (ch - 'a' + 10);
0482 if ((ch >= '0') && (ch <= '9'))
0483 return (ch - '0');
0484 if ((ch >= 'A') && (ch <= 'F'))
0485 return (ch - 'A' + 10);
0486 return (-1);
0487 }
0488
0489 static char remcomInBuffer[BUFMAX];
0490 static char remcomOutBuffer[BUFMAX];
0491
0492
0493
0494 char *
0495 getpacket (void)
0496 {
0497 char *buffer = &remcomInBuffer[0];
0498 unsigned char checksum;
0499 unsigned char xmitcsum;
0500 int count;
0501 char ch;
0502
0503 while (1)
0504 {
0505
0506 while ((ch = getDebugChar ()) != '$')
0507 ;
0508
0509 retry:
0510 checksum = 0;
0511 xmitcsum = -1;
0512 count = 0;
0513
0514
0515 while (count < BUFMAX - 1)
0516 {
0517 ch = getDebugChar ();
0518 if (ch == '$')
0519 goto retry;
0520 if (ch == '#')
0521 break;
0522 checksum = checksum + ch;
0523 buffer[count] = ch;
0524 count = count + 1;
0525 }
0526 buffer[count] = 0;
0527
0528 if (ch == '#')
0529 {
0530 ch = getDebugChar ();
0531 xmitcsum = hex (ch) << 4;
0532 ch = getDebugChar ();
0533 xmitcsum += hex (ch);
0534
0535 if (checksum != xmitcsum)
0536 {
0537 if (remote_debug)
0538 {
0539 #if 0
0540 fprintf (stderr, "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
0541 checksum, xmitcsum, buffer);
0542 #endif
0543 }
0544 putDebugChar ('-');
0545 }
0546 else
0547 {
0548 putDebugChar ('+');
0549
0550
0551 if (buffer[2] == ':')
0552 {
0553 putDebugChar (buffer[0]);
0554 putDebugChar (buffer[1]);
0555
0556 return &buffer[3];
0557 }
0558
0559 return &buffer[0];
0560 }
0561 }
0562 }
0563 }
0564
0565
0566
0567 void
0568 putpacket (char *buffer)
0569 {
0570 unsigned char checksum;
0571 int count;
0572 char ch;
0573
0574
0575 do
0576 {
0577 putDebugChar ('$');
0578 checksum = 0;
0579 count = 0;
0580
0581 while ((ch = buffer[count]))
0582 {
0583 putDebugChar (ch);
0584 checksum += ch;
0585 count += 1;
0586 }
0587
0588 putDebugChar ('#');
0589 putDebugChar (hexchars[checksum >> 4]);
0590 putDebugChar (hexchars[checksum % 16]);
0591
0592 }
0593 while (getDebugChar () != '+');
0594 }
0595
0596 void
0597 debug_error (format, parm)
0598 char *format;
0599 char *parm;
0600 {
0601 #if 0
0602 if (remote_debug)
0603 fprintf (stderr, format, parm);
0604 #endif
0605 }
0606
0607
0608 static void (*volatile _mem_fault_routine) () = NULL;
0609
0610
0611
0612 static volatile int mem_err = 0;
0613
0614 void
0615 set_mem_err (void)
0616 {
0617 mem_err = 1;
0618 }
0619
0620
0621
0622
0623
0624 int
0625 get_char (char *addr)
0626 {
0627 return *addr;
0628 }
0629
0630 void
0631 set_char (char *addr, int val)
0632 {
0633 *addr = val;
0634 }
0635
0636
0637
0638
0639
0640 char *
0641 mem2hex (mem, buf, count, may_fault)
0642 char *mem;
0643 char *buf;
0644 int count;
0645 int may_fault;
0646 {
0647 int i;
0648 unsigned char ch;
0649 extern char *_start;
0650
0651 if (mem == (char *)&_start) {
0652
0653
0654
0655 *buf++ = 'C';
0656 *buf++ = 'C';
0657 *buf = 0;
0658 return buf;
0659 }
0660
0661 if (may_fault)
0662 _mem_fault_routine = set_mem_err;
0663 for (i = 0; i < count; i++)
0664 {
0665 ch = get_char (mem++);
0666 if (may_fault && mem_err)
0667 return (buf);
0668 *buf++ = hexchars[ch >> 4];
0669 *buf++ = hexchars[ch % 16];
0670 }
0671 *buf = 0;
0672 if (may_fault)
0673 _mem_fault_routine = NULL;
0674 return (buf);
0675 }
0676
0677
0678
0679 char *
0680 hex2mem (buf, mem, count, may_fault)
0681 char *buf;
0682 char *mem;
0683 int count;
0684 int may_fault;
0685 {
0686 int i;
0687 unsigned char ch;
0688 extern char *_start;
0689
0690 if (mem == (char *)&_start) return mem + 1;
0691
0692 if (may_fault)
0693 _mem_fault_routine = set_mem_err;
0694 for (i = 0; i < count; i++)
0695 {
0696 ch = hex (*buf++) << 4;
0697 ch = ch + hex (*buf++);
0698 set_char (mem++, ch);
0699 if (may_fault && mem_err)
0700 return (mem);
0701 }
0702 if (may_fault)
0703 _mem_fault_routine = NULL;
0704 return (mem);
0705 }
0706
0707
0708
0709 int
0710 computeSignal (int exceptionVector)
0711 {
0712 int sigval;
0713 switch (exceptionVector)
0714 {
0715 case 0:
0716 sigval = 8;
0717 break;
0718 case 1:
0719 sigval = 5;
0720 break;
0721 case 3:
0722 sigval = 5;
0723 break;
0724 case 4:
0725 sigval = 16;
0726 break;
0727 case 5:
0728 sigval = 16;
0729 break;
0730 case 6:
0731 sigval = 4;
0732 break;
0733 case 7:
0734 sigval = 8;
0735 break;
0736 case 8:
0737 sigval = 7;
0738 break;
0739 case 9:
0740 sigval = 11;
0741 break;
0742 case 10:
0743 sigval = 11;
0744 break;
0745 case 11:
0746 sigval = 11;
0747 break;
0748 case 12:
0749 sigval = 11;
0750 break;
0751 case 13:
0752 sigval = 11;
0753 break;
0754 case 14:
0755 sigval = 11;
0756 break;
0757 case 16:
0758 sigval = 7;
0759 break;
0760 default:
0761 sigval = 7;
0762 }
0763 return (sigval);
0764 }
0765
0766
0767
0768
0769
0770 int
0771 hexToInt (char **ptr, int *intValue)
0772 {
0773 int numChars = 0;
0774 int hexValue;
0775
0776 *intValue = 0;
0777
0778 while (**ptr)
0779 {
0780 hexValue = hex (**ptr);
0781 if (hexValue >= 0)
0782 {
0783 *intValue = (*intValue << 4) | hexValue;
0784 numChars++;
0785 }
0786 else
0787 break;
0788
0789 (*ptr)++;
0790 }
0791
0792 return (numChars);
0793 }
0794
0795
0796
0797
0798 void
0799 handle_exception (int exceptionVector)
0800 {
0801 int sigval, stepping;
0802 int addr, length;
0803 char *ptr;
0804 int newPC;
0805
0806 gdb_i386vector = exceptionVector;
0807
0808 if (remote_debug)
0809 {
0810 printf ("vector=%d, sr=0x%x, pc=0x%x\n",
0811 exceptionVector, _registers[PS], _registers[PC]);
0812 }
0813
0814
0815 sigval = computeSignal (exceptionVector);
0816
0817 ptr = remcomOutBuffer;
0818
0819 *ptr++ = 'T';
0820 *ptr++ = hexchars[sigval >> 4];
0821 *ptr++ = hexchars[sigval & 0xf];
0822
0823 *ptr++ = hexchars[ESP];
0824 *ptr++ = ':';
0825 ptr = mem2hex((char *)&_registers[ESP], ptr, 4, 0);
0826 *ptr++ = ';';
0827
0828 *ptr++ = hexchars[EBP];
0829 *ptr++ = ':';
0830 ptr = mem2hex((char *)&_registers[EBP], ptr, 4, 0);
0831 *ptr++ = ';';
0832
0833 *ptr++ = hexchars[PC];
0834 *ptr++ = ':';
0835 ptr = mem2hex((char *)&_registers[PC], ptr, 4, 0);
0836 *ptr++ = ';';
0837
0838 *ptr = '\0';
0839
0840 putpacket (remcomOutBuffer);
0841
0842 stepping = 0;
0843
0844 while (1 == 1)
0845 {
0846 remcomOutBuffer[0] = 0;
0847 ptr = getpacket ();
0848
0849 switch (*ptr++)
0850 {
0851 case '?':
0852 remcomOutBuffer[0] = 'S';
0853 remcomOutBuffer[1] = hexchars[sigval >> 4];
0854 remcomOutBuffer[2] = hexchars[sigval % 16];
0855 remcomOutBuffer[3] = 0;
0856 break;
0857 case 'd':
0858 remote_debug = !(remote_debug);
0859 break;
0860 case 'g':
0861 mem2hex ((char *) _registers, remcomOutBuffer, NUMREGBYTES, 0);
0862 break;
0863 case 'G':
0864 hex2mem (ptr, (char *) _registers, NUMREGBYTES, 0);
0865 strcpy (remcomOutBuffer, "OK");
0866 break;
0867 case 'P':
0868 {
0869 int regno;
0870
0871 if (hexToInt (&ptr, ®no) && *ptr++ == '=') {
0872 if (regno >= 0 && regno < NUMREGS) {
0873 hex2mem (ptr, (char *) &_registers[regno], 4, 0);
0874 strcpy (remcomOutBuffer, "OK");
0875 break;
0876 } else if (regno == 0x29) {
0877
0878 strcpy (remcomOutBuffer, "OK");
0879 break;
0880 }
0881 }
0882 strcpy (remcomOutBuffer, "E01");
0883 break;
0884 }
0885
0886
0887 case 'm':
0888
0889 if (hexToInt (&ptr, &addr))
0890 if (*(ptr++) == ',')
0891 if (hexToInt (&ptr, &length))
0892 {
0893 ptr = 0;
0894 mem_err = 0;
0895 mem2hex ((char *) addr, remcomOutBuffer, length, 1);
0896 if (mem_err)
0897 {
0898 strcpy (remcomOutBuffer, "E03");
0899 debug_error ("memory fault");
0900 }
0901 }
0902
0903 if (ptr)
0904 {
0905 strcpy (remcomOutBuffer, "E01");
0906 }
0907 break;
0908
0909
0910 case 'M':
0911
0912 if (hexToInt (&ptr, &addr))
0913 if (*(ptr++) == ',')
0914 if (hexToInt (&ptr, &length))
0915 if (*(ptr++) == ':')
0916 {
0917 mem_err = 0;
0918 hex2mem (ptr, (char *) addr, length, 1);
0919
0920 if (mem_err)
0921 {
0922 strcpy (remcomOutBuffer, "E03");
0923 debug_error ("memory fault");
0924 }
0925 else
0926 {
0927 strcpy (remcomOutBuffer, "OK");
0928 }
0929
0930 ptr = 0;
0931 }
0932 if (ptr)
0933 {
0934 strcpy (remcomOutBuffer, "E02");
0935 }
0936 break;
0937
0938
0939
0940 case 's':
0941 stepping = 1;
0942 case 'c':
0943
0944 if (hexToInt (&ptr, &addr))
0945 _registers[PC] = addr;
0946
0947 newPC = _registers[PC];
0948
0949
0950 _registers[PS] &= 0xfffffeff;
0951
0952
0953 if (stepping)
0954 _registers[PS] |= 0x100;
0955
0956 _returnFromException ();
0957 break;
0958
0959
0960 case 'k':
0961 #if 0
0962
0963
0964 BREAKPOINT ();
0965 #endif
0966 break;
0967 }
0968
0969
0970 putpacket (remcomOutBuffer);
0971 }
0972 }
0973
0974
0975
0976 void
0977 set_debug_traps (void)
0978 {
0979 char *ptr;
0980 stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
0981
0982 exceptionHandler (1, __catchException1);
0983 exceptionHandler (3, __catchException3);
0984 exceptionHandler (0, __catchException0);
0985 exceptionHandler (4, __catchException4);
0986 exceptionHandler (5, __catchException5);
0987 exceptionHandler (6, __catchException6);
0988 exceptionHandler (7, __catchException7);
0989 exceptionHandler (8, __catchException8);
0990 exceptionHandler (9, __catchException9);
0991 exceptionHandler (10, __catchException10);
0992 exceptionHandler (11, __catchException11);
0993 exceptionHandler (12, __catchException12);
0994 exceptionHandler (13, __catchException13);
0995 exceptionHandler (14, __catchException14);
0996 exceptionHandler (16, __catchException16);
0997
0998 ptr = getpacket ();
0999 printf ("RX GDB packet: %s\n", ptr);
1000 remcomOutBuffer[0] = 0;
1001 putpacket (remcomOutBuffer);
1002
1003 initialized = 1;
1004 }
1005
1006
1007
1008
1009
1010
1011 void
1012 breakpoint (void)
1013 {
1014 if (initialized)
1015 BREAKPOINT ();
1016 }