Changeset 2f89140 in rtems
- Timestamp:
- Mar 8, 2002, 4:32:07 PM (19 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 34f5067
- Parents:
- ffdc659
- Location:
- c/src/lib/libbsp
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/mips/shared/gdbstub/ChangeLog
rffdc659 r2f89140 1 2001-03-05 Greg Menke <gregory.menke@gsfc.nasa.gov> 2 3 * mips-stub.c: Debugged & tweaked the gdb command processing, 4 zbreak stuff, breakpoint and step code. Implemented 'T' command 5 support and debugged remote gdb support w/ the Mongoose bsp. 6 Added the memory segment support. 7 * memlimits.h: Disabled all contents in favor of memory sement 8 support. This file could probably go away. 9 * rtems-stub-glue.c (rtems_gdb_index_to_stub_id()): New routine. 10 rtems_gdb_stub_get_register_from_context(): Implemented MIPS version. 11 rtems_gdb_stub_get_offsets(): Implemented MIPS version. 12 * README: Updated. 13 1 14 2001-03-01 Joel Sherrill <joel@OARcorp.com> 2 15 -
c/src/lib/libbsp/mips/shared/gdbstub/README
rffdc659 r2f89140 2 2 # $Id$ 3 3 # 4 5 /*****************************************************/ 6 7 Debugged this stub against the MongooseV bsp. Relies on putting break 8 instructions on breakpoints and step targets- normal stuff, and does not 9 employ hardware breakpoint support at this time. As written, a single 10 breakpoint in a loop will not be reasserted unless the user steps or has 11 a 2nd one, since breakpoints are only reset when the gdb stub is 12 re-entered. A useful enhancement would be to fix the break instruction 13 management so the stub could invisibly put a 2nd break after the 1st 14 "official" one so it can silently reset breakpoints. Shouldn't be too 15 hard, mostly a matter of working it out. 16 17 This was tested only against an R3000 MIPS. It should work OK on a 18 R4000. Needs to be tested at some point. 19 20 This stub supports threads as implemented by gdb 5 and doesn't have any 21 bugs I'm aware of. 22 23 Greg Menke 24 3/5/2002 25 26 /*****************************************************/ 4 27 5 28 -
c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h
rffdc659 r2f89140 50 50 int hstr2nibble(const char *buf, int *nibble); 51 51 52 Thread_Control *rtems_gdb_index_to_stub_id(int); 52 53 int rtems_gdb_stub_thread_support_ok(void); 53 54 int rtems_gdb_stub_get_current_thread(void); … … 160 161 #define NUM_REGS 72 161 162 163 164 165 166 167 168 void mips_gdb_stub_install(int enableThreads) ; 169 170 171 #define MEMOPT_READABLE 1 172 #define MEMOPT_WRITEABLE 2 173 174 #define NUM_MEMSEGS 10 175 176 int gdbstub_add_memsegment(unsigned,unsigned,int); 177 178 179 162 180 #endif /* _GDB_IF_H */ -
c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h
rffdc659 r2f89140 13 13 */ 14 14 15 #ifndef _ LIMITS_H_16 #define _ LIMITS_H_15 #ifndef _MEMLIMITS_H_ 16 #define _MEMLIMITS_H_ 17 17 18 18 /* … … 46 46 */ 47 47 48 /* 48 49 #define K0_LIMIT_FOR_READ (K0BASE+0x18000000) 49 50 #define K1_LIMIT_FOR_READ (K1BASE+K1SIZE) … … 68 69 || ((K1BASE <= (int)ptr) && ((int)ptr < K1_LIMIT_FOR_STEP)))) 69 70 70 #endif /* _LIMITS_H_ */ 71 struct memseg 72 { 73 unsigned begin, end, opts; 74 }; 75 76 #define MEMOPT_READABLE 1 77 #define MEMOPT_WRITEABLE 2 78 79 #define NUM_MEMSEGS 10 80 81 82 int add_memsegment(unsigned,unsigned,int); 83 int is_readable(unsigned,unsigned); 84 int is_writeable(unsigned,unsigned); 85 int is_steppable(unsigned); 86 */ 87 88 #endif /* _MEMLIMITS_H_ */ -
c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c
rffdc659 r2f89140 125 125 #include <signal.h> 126 126 #include "mips_opcode.h" 127 #include "memlimits.h" 127 /* #include "memlimits.h" */ 128 128 #include <rtems.h> 129 129 #include "gdb_if.h" … … 210 210 */ 211 211 extern char getDebugChar (void); 212 213 212 extern void putDebugChar (char); 213 214 215 216 /* 217 * The following definitions are used for the gdb stub memory map 218 */ 219 struct memseg 220 { 221 unsigned begin, end, opts; 222 }; 223 224 static int is_readable(unsigned,unsigned); 225 static int is_writeable(unsigned,unsigned); 226 static int is_steppable(unsigned); 227 228 229 230 214 231 215 232 … … 226 243 /* Structure to keep info on a z-breaks */ 227 244 #define BREAKNUM 32 245 228 246 struct z0break 229 247 { … … 233 251 234 252 /* Location, preserved data */ 235 unsigned char*address;236 char buf[2];253 unsigned *address; 254 unsigned instr; 237 255 }; 238 256 … … 630 648 631 649 650 651 652 653 654 632 655 /* 633 656 * Saved instruction data for single step support … … 669 692 doSStep (void) 670 693 { 671 InstFmt inst; 672 673 instrBuffer.targetAddr = (unsigned *)(registers[PC]+4); /* set default */ 674 675 inst.word = *(unsigned *)registers[PC]; /* read the next instruction */ 676 677 switch (inst.RType.op) { /* override default if branch */ 678 case OP_SPECIAL: 679 switch (inst.RType.func) { 680 case OP_JR: 681 case OP_JALR: 682 instrBuffer.targetAddr = 683 (unsigned *)registers[inst.RType.rs]; 684 break; 685 }; 686 break; 687 688 case OP_REGIMM: 689 switch (inst.IType.rt) { 690 case OP_BLTZ: 691 case OP_BLTZL: 692 case OP_BLTZAL: 693 case OP_BLTZALL: 694 if (registers[inst.IType.rs] < 0 ) 694 struct z0break *z0; 695 InstFmt inst; 696 697 instrBuffer.targetAddr = (unsigned *)(registers[PC]+4); /* set default */ 698 699 inst.word = *(unsigned *)registers[PC]; /* read the next instruction */ 700 701 switch (inst.RType.op) { /* override default if branch */ 702 case OP_SPECIAL: 703 switch (inst.RType.func) { 704 case OP_JR: 705 case OP_JALR: 706 instrBuffer.targetAddr = 707 (unsigned *)registers[inst.RType.rs]; 708 break; 709 }; 710 break; 711 712 case OP_REGIMM: 713 switch (inst.IType.rt) { 714 case OP_BLTZ: 715 case OP_BLTZL: 716 case OP_BLTZAL: 717 case OP_BLTZALL: 718 if (registers[inst.IType.rs] < 0 ) 719 instrBuffer.targetAddr = 720 (unsigned *)(((signed short)inst.IType.imm<<2) 721 + (registers[PC]+4)); 722 else 723 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 724 break; 725 case OP_BGEZ: 726 case OP_BGEZL: 727 case OP_BGEZAL: 728 case OP_BGEZALL: 729 if (registers[inst.IType.rs] >= 0 ) 730 instrBuffer.targetAddr = 731 (unsigned *)(((signed short)inst.IType.imm<<2) 732 + (registers[PC]+4)); 733 else 734 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 735 break; 736 }; 737 break; 738 739 case OP_J: 740 case OP_JAL: 741 instrBuffer.targetAddr = 742 (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000)); 743 break; 744 745 case OP_BEQ: 746 case OP_BEQL: 747 if (registers[inst.IType.rs] == registers[inst.IType.rt]) 695 748 instrBuffer.targetAddr = 696 (unsigned *)(((signed short)inst.IType.imm<<2) 697 + (registers[PC]+4)); 698 else 749 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 750 else 699 751 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 700 break; 701 case OP_BGEZ: 702 case OP_BGEZL: 703 case OP_BGEZAL: 704 case OP_BGEZALL: 705 if (registers[inst.IType.rs] >= 0 ) 752 break; 753 case OP_BNE: 754 case OP_BNEL: 755 if (registers[inst.IType.rs] != registers[inst.IType.rt]) 706 756 instrBuffer.targetAddr = 707 (unsigned *)(((signed short)inst.IType.imm<<2) 708 + (registers[PC]+4)); 709 else 757 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 758 else 710 759 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 711 break; 712 }; 713 break; 714 715 case OP_J: 716 case OP_JAL: 717 instrBuffer.targetAddr = 718 (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000)); 719 break; 720 721 case OP_BEQ: 722 case OP_BEQL: 723 if (registers[inst.IType.rs] == registers[inst.IType.rt]) 724 instrBuffer.targetAddr = 725 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 726 else 727 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 728 break; 729 case OP_BNE: 730 case OP_BNEL: 731 if (registers[inst.IType.rs] != registers[inst.IType.rt]) 732 instrBuffer.targetAddr = 733 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 734 else 735 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 736 break; 737 case OP_BLEZ: 738 case OP_BLEZL: 739 if (registers[inst.IType.rs] <= 0) 740 instrBuffer.targetAddr = 741 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 742 else 743 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 744 break; 745 case OP_BGTZ: 746 case OP_BGTZL: 747 if (registers[inst.IType.rs] > 0) 748 instrBuffer.targetAddr = 749 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 750 else 751 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 752 break; 753 754 case OP_COP1: 755 if (inst.RType.rs == OP_BC) 756 switch (inst.RType.rt) { 757 case COPz_BCF: 758 case COPz_BCFL: 759 if (registers[FCSR] & CSR_C) 760 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 761 else 762 instrBuffer.targetAddr = 763 (unsigned *)(((signed short)inst.IType.imm<<2) 764 + (registers[PC]+4)); 765 break; 766 case COPz_BCT: 767 case COPz_BCTL: 768 if (registers[FCSR] & CSR_C) 769 instrBuffer.targetAddr = 770 (unsigned *)(((signed short)inst.IType.imm<<2) 771 + (registers[PC]+4)); 772 else 773 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 774 break; 775 }; 776 break; 777 } 778 779 if is_steppable (instrBuffer.targetAddr) 780 { 760 break; 761 case OP_BLEZ: 762 case OP_BLEZL: 763 if (registers[inst.IType.rs] <= 0) 764 instrBuffer.targetAddr = 765 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 766 else 767 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 768 break; 769 case OP_BGTZ: 770 case OP_BGTZL: 771 if (registers[inst.IType.rs] > 0) 772 instrBuffer.targetAddr = 773 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4)); 774 else 775 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 776 break; 777 778 case OP_COP1: 779 if (inst.RType.rs == OP_BC) 780 switch (inst.RType.rt) { 781 case COPz_BCF: 782 case COPz_BCFL: 783 if (registers[FCSR] & CSR_C) 784 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 785 else 786 instrBuffer.targetAddr = 787 (unsigned *)(((signed short)inst.IType.imm<<2) 788 + (registers[PC]+4)); 789 break; 790 case COPz_BCT: 791 case COPz_BCTL: 792 if (registers[FCSR] & CSR_C) 793 instrBuffer.targetAddr = 794 (unsigned *)(((signed short)inst.IType.imm<<2) 795 + (registers[PC]+4)); 796 else 797 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8); 798 break; 799 }; 800 break; 801 } 802 803 804 if( is_steppable((unsigned)instrBuffer.targetAddr) && *(instrBuffer.targetAddr) != BREAK_INSTR ) 805 { 781 806 instrBuffer.savedInstr = *instrBuffer.targetAddr; 782 807 *instrBuffer.targetAddr = BREAK_INSTR; 783 784 else785 808 } 809 else 810 { 786 811 instrBuffer.targetAddr = NULL; 787 812 instrBuffer.savedInstr = NOP_INSTR; 788 } 789 return; 790 } 813 } 814 return; 815 } 816 817 818 819 791 820 792 821 … … 862 891 ) 863 892 { 864 char *optr; 865 int sigval; 866 867 optr = outBuffer; 868 *optr++ = 'T'; 869 sigval = computeSignal (); 870 *optr++ = highhex (sigval); 871 *optr++ = lowhex (sigval); 872 873 *optr++ = gdb_hexchars[SP]; 874 *optr++ = ':'; 875 optr = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ ); 876 *optr++ = ';'; 893 char *optr; 894 int sigval; 895 896 optr = outBuffer; 897 *optr++ = 'T'; 898 sigval = computeSignal (); 899 *optr++ = highhex (sigval); 900 *optr++ = lowhex (sigval); 901 902 *optr++ = highhex(SP); /*gdb_hexchars[SP]; */ 903 *optr++ = lowhex(SP); 904 *optr++ = ':'; 905 optr = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ ); 906 *optr++ = ';'; 877 907 878 *optr++ = gdb_hexchars[PC]; 879 *optr++ = ':'; 880 optr = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ ); 881 *optr++ = ';'; 908 *optr++ = highhex(PC); /*gdb_hexchars[PC]; */ 909 *optr++ = lowhex(PC); 910 *optr++ = ':'; 911 optr = mem2hstr(optr, (unsigned char *)&frame->epc, R_SZ ); 912 *optr++ = ';'; 882 913 883 914 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 884 if (do_threads) { 885 *optr++ = 't'; 886 *optr++ = 'h'; 887 *optr++ = 'r'; 888 *optr++ = 'e'; 889 *optr++ = 'a'; 890 *optr++ = 'd'; 891 *optr++ = ':'; 892 optr = thread2vhstr(optr, thread); 893 *optr++ = ';'; 894 } 915 if (do_threads) 916 { 917 *optr++ = 't'; 918 *optr++ = 'h'; 919 *optr++ = 'r'; 920 *optr++ = 'e'; 921 *optr++ = 'a'; 922 *optr++ = 'd'; 923 *optr++ = ':'; 924 optr = thread2vhstr(optr, thread); 925 *optr++ = ';'; 926 } 895 927 #endif 896 putpacket (outBuffer); 897 898 *optr++ = '\0'; 899 } 900 928 *optr++ = '\0'; 929 } 930 931 932 933 934 935 /* 936 * Scratch frame used to retrieve contexts for different threads, so as 937 * not to disrupt our current context on the stack 938 */ 939 CPU_Interrupt_frame current_thread_registers; 901 940 902 941 … … 908 947 */ 909 948 910 CPU_Interrupt_frame current_thread_registers;911 949 912 950 void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame) 913 951 { 914 int host_has_detached = 0; 915 int regno, addr, length; 916 long long regval; 917 char *ptr; 918 int current_thread; /* current generic thread */ 919 int thread; /* stopped thread: context exception happened in */ 920 void *regptr; 921 int binary; 922 923 registers = (mips_register_t *)frame; 924 925 thread = 0; 952 int host_has_detached = 0; 953 int regno, addr, length; 954 char *ptr; 955 int current_thread; /* current generic thread */ 956 int thread; /* stopped thread: context exception happened in */ 957 958 long long regval; 959 void *regptr; 960 int binary; 961 962 963 registers = (mips_register_t *)frame; 964 965 thread = 0; 926 966 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 927 if (do_threads) {928 thread = rtems_gdb_stub_get_current_thread();929 }967 if (do_threads) { 968 thread = rtems_gdb_stub_get_current_thread(); 969 } 930 970 #endif 931 current_thread = thread; 932 933 /* reply to host that an exception has occurred with some basic info */ 934 gdb_stub_report_exception_info(vector, frame, thread); 935 936 937 /* 938 * Restore the saved instruction at 939 * the single-step target address. 940 */ 941 undoSStep (); 942 943 while (!(host_has_detached)) { 971 current_thread = thread; 972 973 974 { 975 /* reapply all breakpoints regardless of how we came in */ 976 struct z0break *z0, *zother; 977 978 for (zother=z0break_list; zother!=NULL; zother=zother->next) 979 { 980 if( zother->instr == 0xffffffff ) 981 { 982 /* grab the instruction */ 983 zother->instr = *(zother->address); 984 /* and insert the breakpoint */ 985 *(zother->address) = BREAK_INSTR; 986 } 987 } 988 989 990 991 /* see if we're coming from a breakpoint */ 992 if( *((unsigned *)frame->epc) == BREAK_INSTR ) 993 { 994 /* see if its one of our zbreaks */ 995 for (z0=z0break_list; z0!=NULL; z0=z0->next) 996 { 997 if( (unsigned)z0->address == frame->epc) 998 break; 999 } 1000 if( z0 ) 1001 { 1002 /* restore the original instruction */ 1003 *(z0->address) = z0->instr; 1004 /* flag the breakpoint */ 1005 z0->instr = 0xffffffff; 1006 1007 /* 1008 now when we return, we'll execute the original code in 1009 the original state. This leaves our breakpoint inactive 1010 since the break instruction isn't there, but we'll reapply 1011 it the next time we come in via step or breakpoint 1012 */ 1013 } 1014 else 1015 { 1016 /* not a zbreak, see if its our trusty stepping code */ 1017 1018 /* 1019 * Restore the saved instruction at 1020 * the single-step target address. 1021 */ 1022 undoSStep(); 1023 } 1024 } 1025 } 1026 1027 1028 1029 1030 1031 /* reply to host that an exception has occurred with some basic info */ 1032 gdb_stub_report_exception_info(vector, frame, thread); 1033 putpacket (outBuffer); 1034 1035 1036 1037 while (!(host_has_detached)) { 944 1038 outBuffer[0] = '\0'; 945 1039 getpacket (inBuffer); … … 947 1041 948 1042 switch (inBuffer[0]) { 949 case '?':950 gdb_stub_report_exception_info(vector, frame, thread);951 break;952 953 case 'd': /* toggle debug flag */954 /* can print ill-formed commands in valid packets & checksum errors */955 break;956 957 case 'D':958 /* remote system is detaching - return OK and exit from debugger */959 strcpy (outBuffer, "OK");960 host_has_detached = 1;961 break;962 963 case 'g': /* return the values of the CPU registers */964 regptr = registers;1043 case '?': 1044 gdb_stub_report_exception_info(vector, frame, thread); 1045 break; 1046 1047 case 'd': /* toggle debug flag */ 1048 /* can print ill-formed commands in valid packets & checksum errors */ 1049 break; 1050 1051 case 'D': 1052 /* remote system is detaching - return OK and exit from debugger */ 1053 strcpy (outBuffer, "OK"); 1054 host_has_detached = 1; 1055 break; 1056 1057 case 'g': /* return the values of the CPU registers */ 1058 regptr = registers; 965 1059 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 966 if (do_threads && current_thread != thread )967 regptr = ¤t_thread_registers;1060 if (do_threads && current_thread != thread ) 1061 regptr = ¤t_thread_registers; 968 1062 #endif 969 mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);970 971 break; 972 973 case 'G': /* set the values of the CPU registers - return OK */974 regptr = registers;1063 mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer); 1064 break; 1065 1066 1067 case 'G': /* set the values of the CPU registers - return OK */ 1068 regptr = registers; 975 1069 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 976 if (do_threads && current_thread != thread )977 regptr = ¤t_thread_registers;1070 if (do_threads && current_thread != thread ) 1071 regptr = ¤t_thread_registers; 978 1072 #endif 979 if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers))) 980 strcpy (outBuffer, "OK"); 981 else 982 strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */ 983 break; 984 985 case 'P': 986 /* Pn...=r... Write register n... with value r... - return OK */ 987 ptr = &inBuffer[1]; 988 if (hexToInt(&ptr, ®no) && 989 *ptr++ == '=' && 990 hexToLongLong(&ptr, ®val)) 1073 if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers))) 1074 strcpy (outBuffer, "OK"); 1075 else 1076 strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */ 1077 break; 1078 1079 1080 case 'P': 1081 /* Pn...=r... Write register n... with value r... - return OK */ 1082 ptr = &inBuffer[1]; 1083 if (hexToInt(&ptr, ®no) && 1084 *ptr++ == '=' && 1085 hexToLongLong(&ptr, ®val)) 991 1086 { 992 registers[regno] = regval; 993 strcpy (outBuffer, "OK"); 994 } 995 else 996 strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */ 997 break; 998 999 case 'm': 1000 /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 1001 ptr = &inBuffer[1]; 1002 if (hexToInt (&ptr, &addr) 1003 && *ptr++ == ',' 1004 && hexToInt (&ptr, &length) 1005 && is_readable (addr, length) 1006 && (length < (BUFMAX - 4)/2)) 1007 mem2hex ((void *)addr, length, outBuffer); 1008 else 1009 strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */ 1010 break; 1011 1012 case 'X': /* XAA..AA,LLLL:<binary data>#cs */ 1013 binary = 1; 1014 case 'M': 1015 /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA - return OK */ 1016 ptr = &inBuffer[1]; 1017 if (hexToInt (&ptr, &addr) 1018 && *ptr++ == ',' 1019 && hexToInt (&ptr, &length) 1020 && *ptr++ == ':' 1021 && is_writeable (addr, length) ) { 1022 if ( binary ) 1023 hex2mem (ptr, (void *)addr, length); 1024 else 1025 bin2mem (ptr, (void *)addr, length); 1026 strcpy (outBuffer, "OK"); 1027 } 1028 else 1029 strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */ 1030 break; 1031 1032 case 'c': 1033 /* cAA..AA Continue at address AA..AA(optional) */ 1034 case 's': 1035 /* sAA..AA Step one instruction from AA..AA(optional) */ 1036 { 1087 registers[regno] = regval; 1088 strcpy (outBuffer, "OK"); 1089 } 1090 else 1091 strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */ 1092 break; 1093 1094 1095 case 'm': 1096 /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 1097 ptr = &inBuffer[1]; 1098 if (hexToInt (&ptr, &addr) 1099 && *ptr++ == ',' 1100 && hexToInt (&ptr, &length) 1101 && is_readable (addr, length) 1102 && (length < (BUFMAX - 4)/2)) 1103 mem2hex ((void *)addr, length, outBuffer); 1104 else 1105 strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */ 1106 break; 1107 1108 1109 case 'X': /* XAA..AA,LLLL:<binary data>#cs */ 1110 binary = 1; 1111 case 'M': 1112 /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA - return OK */ 1113 ptr = &inBuffer[1]; 1114 if (hexToInt (&ptr, &addr) 1115 && *ptr++ == ',' 1116 && hexToInt (&ptr, &length) 1117 && *ptr++ == ':' 1118 && is_writeable (addr, length) ) { 1119 if ( binary ) 1120 hex2mem (ptr, (void *)addr, length); 1121 else 1122 bin2mem (ptr, (void *)addr, length); 1123 strcpy (outBuffer, "OK"); 1124 } 1125 else 1126 strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */ 1127 break; 1128 1129 1130 1131 case 'c': 1132 /* cAA..AA Continue at address AA..AA(optional) */ 1133 case 's': 1134 /* sAA..AA Step one instruction from AA..AA(optional) */ 1135 { 1037 1136 /* try to read optional parameter, pc unchanged if no parm */ 1038 1137 ptr = &inBuffer[1]; 1039 1138 if (hexToInt (&ptr, &addr)) 1040 registers[PC] = addr;1139 registers[PC] = addr; 1041 1140 1042 1141 if (inBuffer[0] == 's') 1043 doSStep (); 1044 } 1045 return; 1046 1047 case 'k': /* remove all zbreaks if any */ 1048 { 1049 int ret; 1050 struct z0break *z0, *z0last; 1051 1052 ret = 1; 1053 z0last = NULL; 1054 1055 for (z0=z0break_list; z0!=NULL; z0=z0->next) { 1056 if (!hstr2mem(z0->address, z0->buf, 1)) { 1057 ret = 0; 1058 } 1059 1060 z0last = z0; 1061 } 1062 1063 /* Free entries if any */ 1064 if (z0last != NULL) { 1065 z0last->next = z0break_avail; 1066 z0break_avail = z0break_list; 1067 z0break_list = NULL; 1068 } 1069 } 1070 1071 break; 1072 1073 case 'q': /* queries */ 1142 doSStep (); 1143 } 1144 goto stubexit; 1145 1146 1147 1148 1149 1150 case 'k': /* remove all zbreaks if any */ 1151 dumpzbreaks: 1152 { 1153 { 1154 /* Unlink the entire list */ 1155 struct z0break *z0, *znxt; 1156 1157 while( (z0= z0break_list) ) 1158 { 1159 1160 /* put back the instruction */ 1161 if( z0->instr != 0xffffffff ) 1162 *(z0->address) = z0->instr; 1163 1164 /* pop off the top entry */ 1165 znxt = z0->next; 1166 if( znxt ) znxt->prev = NULL; 1167 z0break_list = znxt; 1168 1169 /* and put it on the free list */ 1170 z0->prev = NULL; 1171 z0->next = z0break_avail; 1172 z0break_avail = z0; 1173 } 1174 } 1175 1176 strcpy(outBuffer, "OK"); 1177 } 1178 break; 1179 1180 1181 1182 1183 1184 case 'q': /* queries */ 1074 1185 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 1075 rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );1186 rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread ); 1076 1187 #endif 1077 break; 1188 break; 1189 1190 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 1191 case 'T': 1192 { 1193 int testThread; 1194 1195 if( vhstr2thread(&inBuffer[1], &testThread) == NULL ) 1196 { 1197 strcpy(outBuffer, "E01"); 1198 break; 1199 } 1200 1201 if( rtems_gdb_index_to_stub_id(testThread) == NULL ) 1202 { 1203 strcpy(outBuffer, "E02"); 1204 } 1205 else 1206 { 1207 strcpy(outBuffer, "OK"); 1208 } 1209 } 1210 break; 1211 #endif 1078 1212 1079 case 'H': /* set new thread */1213 case 'H': /* set new thread */ 1080 1214 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 1081 1082 1083 1215 if (inBuffer[1] != 'g') { 1216 break; 1217 } 1084 1218 1085 1086 1087 1219 if (!do_threads) { 1220 break; 1221 } 1088 1222 1089 1090 1223 { 1224 int tmp, ret; 1091 1225 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 if (tmp == current_thread) {1104 /* No changes */1105 1106 1107 1108 1109 /* Save current thread registers if necessary */1110 if (current_thread != thread) {1111 ret = rtems_gdb_stub_set_thread_regs(1112 current_thread, (unsigned int *) ¤t_thread_registers);1113 1114 1115 1116 1117 1118 1119 tmp, (unsigned int *) ¤t_thread_registers);1120 1121 1122 1123 1124 1125 1126 1226 /* Set new generic thread */ 1227 if (vhstr2thread(&inBuffer[2], &tmp) == NULL) { 1228 strcpy(outBuffer, "E01"); 1229 break; 1230 } 1231 1232 /* 0 means `thread' */ 1233 if (tmp == 0) { 1234 tmp = thread; 1235 } 1236 1237 if (tmp == current_thread) { 1238 /* No changes */ 1239 strcpy(outBuffer, "OK"); 1240 break; 1241 } 1242 1243 /* Save current thread registers if necessary */ 1244 if (current_thread != thread) { 1245 ret = rtems_gdb_stub_set_thread_regs( 1246 current_thread, (unsigned int *) ¤t_thread_registers); 1247 ASSERT(ret); 1248 } 1249 1250 /* Read new registers if necessary */ 1251 if (tmp != thread) { 1252 ret = rtems_gdb_stub_get_thread_regs( 1253 tmp, (unsigned int *) ¤t_thread_registers); 1254 1255 if (!ret) { 1256 /* Thread does not exist */ 1257 strcpy(outBuffer, "E02"); 1258 break; 1259 } 1260 } 1127 1261 1128 current_thread = tmp; 1129 strcpy(outBuffer, "OK"); 1130 } 1131 1262 current_thread = tmp; 1263 strcpy(outBuffer, "OK"); 1264 } 1132 1265 #endif 1133 break; 1134 1135 case 'Z': /* Add breakpoint */ 1136 { 1266 break; 1267 1268 1269 1270 1271 case 'Z': /* Add breakpoint */ 1272 { 1137 1273 int ret, type, len; 1138 unsigned char*address;1274 unsigned *address; 1139 1275 struct z0break *z0; 1140 1276 1141 1277 ret = parse_zbreak(inBuffer, &type, &address, &len); 1142 1278 if (!ret) { 1143 strcpy(outBuffer, "E01");1144 break;1279 strcpy(outBuffer, "E01"); 1280 break; 1145 1281 } 1146 1282 1147 1283 if (type != 0) { 1148 /* We support only software break points so far */ 1149 break; 1150 } 1151 1152 if (len != 1) { 1284 /* We support only software break points so far */ 1153 1285 strcpy(outBuffer, "E02"); 1154 1286 break; 1155 1287 } 1156 1288 1289 if (len != R_SZ) { /* was 1 */ 1290 strcpy(outBuffer, "E03"); 1291 break; 1292 } 1293 1157 1294 /* Let us check whether this break point already set */ 1158 1295 for (z0=z0break_list; z0!=NULL; z0=z0->next) { 1159 1296 if (z0->address == address) { 1160 1297 break; 1161 1298 } 1162 1299 } 1163 1300 1164 1301 if (z0 != NULL) { 1165 /* Repeated packet*/1166 strcpy(outBuffer, "OK");1167 break;1302 /* we already have a breakpoint for this address */ 1303 strcpy(outBuffer, "E04"); 1304 break; 1168 1305 } 1169 1306 1170 1307 /* Let us allocate new break point */ 1171 1308 if (z0break_avail == NULL) { 1172 strcpy(outBuffer, "E03"); 1173 break; 1174 } 1309 strcpy(outBuffer, "E05"); 1310 break; 1311 } 1312 1175 1313 1176 1314 /* Get entry */ … … 1179 1317 1180 1318 /* Let us copy memory from address add stuff the break point in */ 1181 if (mem2hstr(z0->buf, address, 1) == NULL || 1182 !hstr2mem(address, "cc" , 1)) { 1183 /* Memory error */ 1184 z0->next = z0break_avail; 1185 z0break_avail = z0; 1186 strcpy(outBuffer, "E03"); 1187 break; 1188 } 1319 /* 1320 *if (mem2hstr(z0->buf, address, 1) == NULL || 1321 !hstr2mem(address, "cc" , 1)) { 1322 1323 * Memory error * 1324 z0->next = z0break_avail; 1325 z0break_avail = z0; 1326 strcpy(outBuffer, "E05"); 1327 break; 1328 }*/ 1189 1329 1190 1330 /* Fill it */ 1191 1331 z0->address = address; 1192 1332 1333 if( z0->address == frame->epc ) 1334 { 1335 /* re-asserting the breakpoint that put us in here, so 1336 we'll add the breakpoint but leave the code in place 1337 since we'll be returning to it when the user continues */ 1338 z0->instr = 0xffffffff; 1339 } 1340 else 1341 { 1342 /* grab the instruction */ 1343 z0->instr = *(z0->address); 1344 /* and insert the break */ 1345 *(z0->address) = BREAK_INSTR; 1346 } 1347 1193 1348 /* Add to the list */ 1194 z0->next = z0break_list; 1195 z0->prev = NULL; 1196 1197 if (z0break_list != NULL) { 1198 z0break_list->prev = z0; 1199 } 1200 1201 z0break_list = z0; 1349 { 1350 struct z0break *znxt = z0break_list; 1351 1352 z0->prev = NULL; 1353 z0->next = znxt; 1354 1355 if( znxt ) znxt->prev = z0; 1356 z0break_list = z0; 1357 } 1202 1358 1203 1359 strcpy(outBuffer, "OK"); 1204 } 1205 1206 case 'z': /* remove breakpoint */ 1207 { 1208 int ret, type, len; 1209 unsigned char *address; 1210 struct z0break *z0, *z0last; 1211 1212 if (inBuffer[1] == 'z') { 1213 /* zz packet - remove all breaks */ 1214 ret = 1; 1360 } 1361 break; 1362 1363 1364 case 'z': /* remove breakpoint */ 1365 if (inBuffer[1] == 'z') 1366 { 1367 goto dumpzbreaks; 1368 1369 1370 /* 1371 * zz packet - remove all breaks * 1215 1372 z0last = NULL; 1216 for (z0=z0break_list; z0!=NULL; z0=z0->next) { 1217 if(!hstr2mem(z0->address, z0->buf, 1)) { 1218 ret = 0; 1219 } 1220 1221 z0last = z0; 1222 } 1223 1224 /* Free entries if any */ 1373 1374 for (z0=z0break_list; z0!=NULL; z0=z0->next) 1375 { 1376 if(!hstr2mem(z0->address, z0->buf, R_SZ)) 1377 { 1378 ret = 0; 1379 } 1380 z0last = z0; 1381 } 1382 1383 * Free entries if any * 1225 1384 if (z0last != NULL) { 1226 z0last->next = z0break_avail; 1227 z0break_avail = z0break_list; 1228 z0break_list = NULL; 1385 z0last->next = z0break_avail; 1386 z0break_avail = z0break_list; 1387 z0break_list = NULL; 1388 } 1389 1390 if (ret) { 1391 strcpy(outBuffer, "OK"); 1392 } else { 1393 strcpy(outBuffer, "E04"); 1394 } 1395 break; 1396 */ 1397 } 1398 else 1399 { 1400 int ret, type, len; 1401 unsigned *address; 1402 struct z0break *z0; 1403 1404 ret = parse_zbreak(inBuffer, &type, &address, &len); 1405 if (!ret) { 1406 strcpy(outBuffer, "E01"); 1407 break; 1408 } 1409 1410 if (type != 0) { 1411 /* We support only software break points so far */ 1412 break; 1413 } 1414 1415 if (len != R_SZ) { 1416 strcpy(outBuffer, "E02"); 1417 break; 1418 } 1419 1420 /* Let us check whether this break point set */ 1421 for (z0=z0break_list; z0!=NULL; z0=z0->next) { 1422 if (z0->address == address) { 1423 break; 1229 1424 } 1230 1231 if (ret) { 1232 strcpy(outBuffer, "OK"); 1233 } else { 1234 strcpy(outBuffer, "E04"); 1235 } 1236 1237 break; 1238 } 1425 } 1239 1426 1240 ret = parse_zbreak(inBuffer, &type, &address, &len); 1241 if (!ret) { 1242 strcpy(outBuffer, "E01");1243 1244 1427 if (z0 == NULL) { 1428 /* Unknown breakpoint */ 1429 strcpy(outBuffer, "E03"); 1430 break; 1431 } 1245 1432 1246 if (type != 0) { 1247 /* We support only software break points so far */ 1248 break; 1249 } 1250 1251 if (len != 1) { 1252 strcpy(outBuffer, "E02"); 1253 break; 1254 } 1255 1256 /* Let us check whether this break point set */ 1257 for (z0=z0break_list; z0!=NULL; z0=z0->next) { 1258 if (z0->address == address) { 1259 break; 1260 } 1261 } 1262 1263 if (z0 == NULL) { 1264 /* Unknown breakpoint */ 1265 strcpy(outBuffer, "E03"); 1266 break; 1267 } 1268 1269 if (!hstr2mem(z0->address, z0->buf, 1)) { 1270 strcpy(outBuffer, "E04"); 1271 break; 1272 } 1433 /* 1434 if (!hstr2mem(z0->address, z0->buf, R_SZ)) { 1435 strcpy(outBuffer, "E04"); 1436 break; 1437 }*/ 1438 1439 if( z0->instr != 0xffffffff ) 1440 { 1441 /* put the old instruction back */ 1442 *(z0->address) = z0->instr; 1443 } 1273 1444 1274 /* Unlink entry */ 1275 if (z0->prev == NULL) { 1276 z0break_list = z0->next; 1277 if (z0break_list != NULL) { 1278 z0break_list->prev = NULL; 1279 } 1280 } else if (z0->next == NULL) { 1281 z0->prev->next = NULL; 1282 } else { 1283 z0->prev->next = z0->next; 1284 z0->next->prev = z0->prev; 1285 } 1286 1287 z0->next = z0break_avail; 1288 z0break_avail = z0; 1289 1290 strcpy(outBuffer, "OK"); 1291 } 1292 1293 break; 1294 default: /* do nothing */ 1295 break; 1445 /* Unlink entry */ 1446 { 1447 struct z0break *zprv = z0->prev, *znxt = z0->next; 1448 1449 if( zprv ) zprv->next = znxt; 1450 if( znxt ) znxt->prev = zprv; 1451 1452 if( !zprv ) z0break_list = znxt; 1453 1454 znxt = z0break_avail; 1455 1456 z0break_avail = z0; 1457 z0->prev = NULL; 1458 z0->next = znxt; 1459 } 1460 1461 strcpy(outBuffer, "OK"); 1462 } 1463 break; 1464 1465 1466 default: /* do nothing */ 1467 break; 1296 1468 } 1297 1469 1298 1470 /* reply to the request */ 1299 1471 putpacket (outBuffer); 1300 } 1472 } 1473 1474 stubexit: 1301 1475 1302 1476 /* … … 1307 1481 * and write back each dirty line in the D-cache. This needs to be done 1308 1482 * before the target program is resumed in order to ensure that software 1309 * breakpoints and downloaded code will actually take effect. 1483 * breakpoints and downloaded code will actually take effect. This 1484 * is because modifications to code in ram will affect the D-cache, 1485 * but not necessarily the I-cache. 1310 1486 */ 1311 1487 1312 return; 1313 } 1314 1315 static char initialized; /* 0 means we are not initialized */ 1316 1317 void mips_gdb_stub_install(void) 1488 { 1489 extern void clear_cache(); 1490 clear_cache(); 1491 } 1492 1493 return; 1494 } 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 static int numsegs; 1506 static struct memseg memsegments[NUM_MEMSEGS]; 1507 1508 int gdbstub_add_memsegment( unsigned base, unsigned end, int opts ) 1509 { 1510 if( numsegs == NUM_MEMSEGS ) return -1; 1511 1512 memsegments[numsegs].begin = base; 1513 memsegments[numsegs].end = end; 1514 memsegments[numsegs].opts = opts; 1515 1516 ++numsegs; 1517 return RTEMS_SUCCESSFUL; 1518 } 1519 1520 1521 1522 1523 static int is_readable(unsigned ptr, unsigned len) 1524 { 1525 struct memseg *ms; 1526 int i; 1527 1528 if( (ptr & 0x3) ) return -1; 1529 1530 for(i=0; i<numsegs; i++) 1531 { 1532 ms= &memsegments[i]; 1533 1534 if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) ) 1535 return -1; 1536 } 1537 return 0; 1538 } 1539 1540 1541 static int is_writeable(unsigned ptr, unsigned len) 1542 { 1543 struct memseg *ms; 1544 int i; 1545 1546 if( (ptr & 0x3) ) return -1; 1547 1548 for(i=0; i<numsegs; i++) 1549 { 1550 ms= &memsegments[i]; 1551 1552 if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) ) 1553 return -1; 1554 } 1555 return 0; 1556 } 1557 1558 1559 static int is_steppable(unsigned ptr) 1560 { 1561 struct memseg *ms; 1562 int i; 1563 1564 if( (ptr & 0x3) ) return -1; 1565 1566 for(i=0; i<numsegs; i++) 1567 { 1568 ms= &memsegments[i]; 1569 1570 if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) ) 1571 return -1; 1572 } 1573 return 0; 1574 } 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 static char initialized = 0; /* 0 means we are not initialized */ 1590 1591 void mips_gdb_stub_install(int enableThreads) 1318 1592 { 1319 1593 /* … … 1342 1616 rtems_isr_entry old; 1343 1617 1344 if (initialized) { 1618 if (initialized) 1619 { 1345 1620 ASSERT(0); 1346 1621 return; 1347 1622 } 1348 1623 1349 /* z0breaks */ 1350 for (i=0; i<(sizeof(z0break_arr)/sizeof(z0break_arr[0]))-1; i++) { 1351 z0break_arr[i].next = &z0break_arr[i+1]; 1352 } 1353 1354 z0break_arr[i].next = NULL; 1355 z0break_avail = &z0break_arr[0]; 1356 z0break_list = NULL; 1357 1624 memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS ); 1625 numsegs = 0; 1626 1627 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT) 1628 if( enableThreads ) 1629 do_threads = 1; 1630 else 1631 do_threads = 0; 1632 #endif 1633 1634 { 1635 struct z0break *z0; 1636 1637 z0break_avail = NULL; 1638 z0break_list = NULL; 1639 1640 /* z0breaks list init, now we'll do it so it makes sense... */ 1641 for (i=0; i<BREAKNUM; i++) 1642 { 1643 memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break)); 1644 1645 z0->next = z0break_avail; 1646 z0break_avail = z0; 1647 } 1648 } 1358 1649 1359 1650 for(i=0; exceptionVector[i] > -1; i++) … … 1363 1654 1364 1655 initialized = 1; 1656 1365 1657 /* get the attention of gdb */ 1366 mips_break(1);1367 } 1368 1369 1370 1658 /* mips_break(1); disabled so user code can choose to invoke it or not */ 1659 } 1660 1661 1662 -
c/src/lib/libbsp/mips/shared/gdbstub/rtems-stub-glue.c
rffdc659 r2f89140 30 30 31 31 #include <rtems.h> 32 33 32 #include <string.h> 34 33 … … 40 39 41 40 extern const char gdb_hexchars[]; 41 42 42 43 43 /* … … 51 51 ); 52 52 53 54 55 56 57 58 53 59 /* Check whether it is OK to enable thread support */ 54 60 int rtems_gdb_stub_thread_support_ok(void) … … 59 65 return 0; 60 66 } 67 68 69 70 61 71 62 72 /* … … 102 112 } 103 113 114 115 116 /* Return the RTEMS thread id from a gdb thread id */ 117 Thread_Control *rtems_gdb_index_to_stub_id( 118 int thread 119 ) 120 { 121 Objects_Id thread_obj_id; 122 Objects_Id min_id, max_id; 123 int first_posix_id, first_rtems_id; 124 Objects_Information *obj_info; 125 Thread_Control *th; 126 127 ASSERT(registers != NULL); 128 129 if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { 130 /* Should not happen */ 131 return NULL; 132 } 133 134 if (thread == 1) { 135 th = _Thread_Idle; 136 goto found; 137 } 138 139 /* Let us get object associtated with current thread */ 140 first_rtems_id = 2; 141 142 thread_obj_id = _Thread_Executing->Object.id; 143 144 /* Let us figure out thread_id for gdb */ 145 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 146 147 min_id = obj_info->minimum_id; 148 max_id = obj_info->maximum_id; 149 150 if (thread <= (first_rtems_id + (max_id - min_id))) { 151 th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); 152 153 if (th != NULL) { 154 goto found; 155 } 156 157 /* Thread does not exist */ 158 return NULL; 159 } 160 161 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 162 163 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 164 165 min_id = obj_info->minimum_id; 166 max_id = obj_info->maximum_id; 167 168 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 169 if (th == NULL) { 170 /* Thread does not exist */ 171 return NULL; 172 } 173 174 found: 175 return th; 176 } 177 178 179 180 181 182 104 183 /* Get id of the thread stopped by exception */ 105 184 int rtems_gdb_stub_get_current_thread(void) … … 107 186 return rtems_gdb_stub_id_to_index( _Thread_Executing->Object.id ); 108 187 } 188 189 190 109 191 110 192 /* Get id of the next thread after athread, if argument <= 0 find the … … 175 257 return 0; 176 258 } 259 260 261 262 177 263 178 264 … … 184 270 ) 185 271 { 186 Objects_Id thread_obj_id; 187 Objects_Id min_id, max_id; 188 int first_posix_id, first_rtems_id; 189 Objects_Information *obj_info; 190 Thread_Control *th; 191 192 ASSERT(registers != NULL); 193 194 if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { 195 /* Should not happen */ 196 return 0; 197 } 198 199 if (thread == 1) { 200 th = _Thread_Idle; 201 goto found; 202 } 203 204 /* Let us get object associtated with current thread */ 205 first_rtems_id = 2; 206 207 thread_obj_id = _Thread_Executing->Object.id; 208 209 /* Let us figure out thread_id for gdb */ 210 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 211 212 min_id = obj_info->minimum_id; 213 max_id = obj_info->maximum_id; 214 215 if (thread <= (first_rtems_id + (max_id - min_id))) { 216 th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); 217 218 if (th != NULL) { 219 goto found; 220 } 221 222 /* Thread does not exist */ 223 return 0; 224 } 225 226 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 227 228 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 229 230 min_id = obj_info->minimum_id; 231 max_id = obj_info->maximum_id; 232 233 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 234 if (th == NULL) { 235 /* Thread does not exist */ 236 return 0; 237 } 238 239 found: 240 241 rtems_gdb_stub_get_registers_from_context( registers, th ); 242 243 return 1; 244 } 272 Thread_Control *th; 273 274 th= rtems_gdb_index_to_stub_id(thread); 275 276 if( th ) 277 { 278 rtems_gdb_stub_get_registers_from_context( registers, th ); 279 return 1; 280 } 281 return 0; 282 } 283 284 285 286 245 287 246 288 … … 248 290 exist or register values will screw up the threads, 249 291 and 1 otherwise */ 292 250 293 int rtems_gdb_stub_set_thread_regs( 251 294 int thread, … … 259 302 return 1; 260 303 } 304 305 306 307 261 308 262 309 … … 268 315 ) 269 316 { 270 Objects_Id thread_obj_id;271 Objects_Id min_id, max_id;272 int first_posix_id, first_rtems_id;273 Objects_Information *obj_info;274 Thread_Control *th;275 unsigned32 name;276 char tmp_buf[20];277 278 ASSERT(info != NULL);279 280 if (thread <= 0) {281 return 0;282 }283 284 if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {285 /* We have one thread let us use value317 Objects_Id thread_obj_id; 318 Objects_Id min_id, max_id; 319 int first_posix_id, first_rtems_id; 320 Objects_Information *obj_info; 321 Thread_Control *th; 322 unsigned32 name; 323 char tmp_buf[20]; 324 325 ASSERT(info != NULL); 326 327 if (thread <= 0) { 328 return 0; 329 } 330 331 if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) { 332 /* We have one thread let us use value 286 333 which will never happen for real thread */ 287 strcpy(info->display, "idle thread");288 strcpy(info->name, "IDLE");289 info->more_display[0] = 0; /* Nothing */290 291 return 1;292 }293 294 /* Let us get object associtated with current thread */295 thread_obj_id = _Thread_Executing->Object.id;296 297 /* Let us figure out thread_id for gdb */298 first_rtems_id = 2;334 strcpy(info->display, "idle thread"); 335 strcpy(info->name, "IDLE"); 336 info->more_display[0] = 0; /* Nothing */ 337 338 return 1; 339 } 340 341 /* Let us get object associtated with current thread */ 342 thread_obj_id = _Thread_Executing->Object.id; 343 344 /* Let us figure out thread_id for gdb */ 345 first_rtems_id = 2; 299 346 300 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];301 302 min_id = obj_info->minimum_id;303 max_id = obj_info->maximum_id;304 305 if (thread <= (first_rtems_id + (max_id - min_id))) {347 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 348 349 min_id = obj_info->minimum_id; 350 max_id = obj_info->maximum_id; 351 352 if (thread <= (first_rtems_id + (max_id - min_id))) { 306 353 th = (Thread_Control *)(obj_info->local_table[thread - 307 354 first_rtems_id + 1]); 308 355 309 if (th == NULL) {310 /* Thread does not exist */311 return 0;312 }313 314 strcpy(info->display, "rtems task: control at 0x");315 316 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];317 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];318 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];319 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];320 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];321 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];322 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];323 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];324 tmp_buf[8] = 0;325 326 strcat(info->display, tmp_buf);356 if (th == NULL) { 357 /* Thread does not exist */ 358 return 0; 359 } 360 361 strcpy(info->display, "rtems task: control at 0x"); 362 363 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; 364 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; 365 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; 366 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; 367 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; 368 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; 369 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; 370 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; 371 tmp_buf[8] = 0; 372 373 strcat(info->display, tmp_buf); 327 374 328 name = *(unsigned32 *)(obj_info->local_table[thread]->name);375 name = *(unsigned32 *)(obj_info->local_table[thread]->name); 329 376 330 info->name[0] = (name >> 24) & 0xff;331 info->name[1] = (name >> 16) & 0xff;332 info->name[2] = (name >> 8) & 0xff;333 info->name[3] = name & 0xff;334 info->name[4] = 0;335 336 info->more_display[0] = 0; /* Nothing */337 338 return 1;339 }340 341 first_posix_id = first_rtems_id + (max_id - min_id) + 1;342 343 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];344 345 min_id = obj_info->minimum_id;346 max_id = obj_info->maximum_id;347 348 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);349 if (th == NULL)350 377 info->name[0] = (name >> 24) & 0xff; 378 info->name[1] = (name >> 16) & 0xff; 379 info->name[2] = (name >> 8) & 0xff; 380 info->name[3] = name & 0xff; 381 info->name[4] = 0; 382 383 info->more_display[0] = 0; /* Nothing */ 384 385 return 1; 386 } 387 388 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 389 390 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 391 392 min_id = obj_info->minimum_id; 393 max_id = obj_info->maximum_id; 394 395 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 396 if (th == NULL) 397 { 351 398 /* Thread does not exist */ 352 399 return 0; 353 354 355 strcpy(info->display, "posix thread: control at 0x");356 357 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];358 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];359 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];360 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];361 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];362 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];363 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];364 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];365 tmp_buf[8] = 0;366 367 strcat(info->display, tmp_buf);368 369 name = *(unsigned32 *)(obj_info->local_table[thread -370 first_posix_id + 1]->name);371 372 info->name[0] = (name >> 24) & 0xff;373 info->name[1] = (name >> 16) & 0xff;374 info->name[2] = (name >> 8) & 0xff;375 info->name[3] = name & 0xff;376 info->name[4] = 0;377 378 info->more_display[0] = 0; /* Nothing */400 } 401 402 strcpy(info->display, "posix thread: control at 0x"); 403 404 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; 405 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; 406 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; 407 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; 408 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; 409 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; 410 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; 411 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; 412 tmp_buf[8] = 0; 413 414 strcat(info->display, tmp_buf); 415 416 name = *(unsigned32 *)(obj_info->local_table[thread - 417 first_posix_id + 1]->name); 418 419 info->name[0] = (name >> 24) & 0xff; 420 info->name[1] = (name >> 16) & 0xff; 421 info->name[2] = (name >> 8) & 0xff; 422 info->name[3] = name & 0xff; 423 info->name[4] = 0; 424 425 info->more_display[0] = 0; /* Nothing */ 379 426 380 return 1;427 return 1; 381 428 } 382 429 383 430 /*******************************************************/ 431 432 433 434 384 435 385 436 … … 598 649 pack_qm_header(char *out, int count, int done, int athread) 599 650 { 600 ASSERT(out != 0); 601 ASSERT(count >= 0 && count < 256); 602 603 *out++ = 'q'; 604 *out++ = 'M'; 605 606 *out++ = gdb_hexchars[(count >> 4) & 0x0f]; 607 *out++ = gdb_hexchars[count & 0x0f]; 608 609 if (done) { 610 *out++ = '1'; 611 } else { 612 *out++ = '0'; 613 } 614 615 thread2fhstr(out, athread); 616 617 return; 618 } 651 ASSERT(out != 0); 652 ASSERT(count >= 0 && count < 256); 653 654 *out++ = 'q'; 655 *out++ = 'M'; 656 657 *out++ = gdb_hexchars[(count >> 4) & 0x0f]; 658 *out++ = gdb_hexchars[count & 0x0f]; 659 660 if (done) { 661 *out++ = '1'; 662 } else { 663 *out++ = '0'; 664 } 665 666 thread2fhstr(out, athread); 667 return; 668 } 669 670 671 672 673 674 675 676 677 678 619 679 620 680 … … 643 703 break; 644 704 705 706 707 645 708 case 'P': 646 709 /* Thread info query */ … … 670 733 pack_qq(outbuffer, mask, rthread, &info); 671 734 } 672 673 735 break; 736 737 738 739 740 674 741 case 'L': 675 /* Thread infoquery */742 /* Thread list query */ 676 743 if (!do_threads) { 677 744 break; … … 725 792 /* Fill header */ 726 793 pack_qm_header(outbuffer, i, done, athread); 727 728 794 } 729 795 break; 796 797 798 799 800 801 730 802 default: 731 803 if (memcmp(inbuffer, "qOffsets", 8) == 0) { … … 773 845 break; 774 846 } 775 776 } 847 } 848 849 850 851 852 777 853 778 854 /* Present thread in the variable length string format */ … … 1197 1273 to mem_fault, they won't get restored, so there better not be any 1198 1274 saved). */ 1275 1199 1276 unsigned char 1200 1277 get_byte (const unsigned char *addr) … … 1208 1285 *addr = val; 1209 1286 } 1287 1288 1289 1290 1291 1292 1210 1293 1211 1294 … … 1274 1357 } 1275 1358 1359 1360 1361 1362 1276 1363 #elif defined(__mips__) 1364 1365 1277 1366 void rtems_gdb_stub_get_registers_from_context( 1278 1367 int *registers, … … 1280 1369 ) 1281 1370 { 1282 } 1371 registers[S0] = (unsigned)th->Registers.s0; 1372 registers[S1] = (unsigned)th->Registers.s1; 1373 registers[S2] = (unsigned)th->Registers.s2; 1374 registers[S3] = (unsigned)th->Registers.s3; 1375 registers[S4] = (unsigned)th->Registers.s4; 1376 registers[S5] = (unsigned)th->Registers.s5; 1377 registers[S6] = (unsigned)th->Registers.s6; 1378 registers[S7] = (unsigned)th->Registers.s7; 1379 1380 registers[SP] = (unsigned)th->Registers.sp; 1381 registers[RA] = (unsigned)th->Registers.ra; 1382 1383 registers[SR] = (unsigned)th->Registers.c0_sr; 1384 registers[PC] = (unsigned)th->Registers.c0_epc; 1385 } 1386 1283 1387 1284 1388 int rtems_gdb_stub_get_offsets( … … 1287 1391 unsigned char **bss_addr 1288 1392 ) 1289 { 1393 { 1394 /* 1395 extern unsigned32 _ftext; 1396 extern unsigned32 _fdata; 1397 extern unsigned32 _bss_start; 1398 1399 *text_addr = &_ftext; 1400 *data_addr = &_fdata; 1401 *bss_addr = &_bss_start; 1402 */ 1290 1403 *text_addr = 0; 1291 1404 *data_addr = 0; 1292 1405 *bss_addr = 0; 1293 1294 1406 return 1; 1295 1407 } -
c/src/lib/libbsp/shared/gdbstub/rtems-stub-glue.c
rffdc659 r2f89140 30 30 31 31 #include <rtems.h> 32 33 32 #include <string.h> 34 33 … … 40 39 41 40 extern const char gdb_hexchars[]; 41 42 42 43 43 /* … … 51 51 ); 52 52 53 54 55 56 57 58 53 59 /* Check whether it is OK to enable thread support */ 54 60 int rtems_gdb_stub_thread_support_ok(void) … … 59 65 return 0; 60 66 } 67 68 69 70 61 71 62 72 /* … … 102 112 } 103 113 114 115 116 /* Return the RTEMS thread id from a gdb thread id */ 117 Thread_Control *rtems_gdb_index_to_stub_id( 118 int thread 119 ) 120 { 121 Objects_Id thread_obj_id; 122 Objects_Id min_id, max_id; 123 int first_posix_id, first_rtems_id; 124 Objects_Information *obj_info; 125 Thread_Control *th; 126 127 ASSERT(registers != NULL); 128 129 if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { 130 /* Should not happen */ 131 return NULL; 132 } 133 134 if (thread == 1) { 135 th = _Thread_Idle; 136 goto found; 137 } 138 139 /* Let us get object associtated with current thread */ 140 first_rtems_id = 2; 141 142 thread_obj_id = _Thread_Executing->Object.id; 143 144 /* Let us figure out thread_id for gdb */ 145 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 146 147 min_id = obj_info->minimum_id; 148 max_id = obj_info->maximum_id; 149 150 if (thread <= (first_rtems_id + (max_id - min_id))) { 151 th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); 152 153 if (th != NULL) { 154 goto found; 155 } 156 157 /* Thread does not exist */ 158 return NULL; 159 } 160 161 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 162 163 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 164 165 min_id = obj_info->minimum_id; 166 max_id = obj_info->maximum_id; 167 168 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 169 if (th == NULL) { 170 /* Thread does not exist */ 171 return NULL; 172 } 173 174 found: 175 return th; 176 } 177 178 179 180 181 182 104 183 /* Get id of the thread stopped by exception */ 105 184 int rtems_gdb_stub_get_current_thread(void) … … 107 186 return rtems_gdb_stub_id_to_index( _Thread_Executing->Object.id ); 108 187 } 188 189 190 109 191 110 192 /* Get id of the next thread after athread, if argument <= 0 find the … … 175 257 return 0; 176 258 } 259 260 261 262 177 263 178 264 … … 184 270 ) 185 271 { 186 Objects_Id thread_obj_id; 187 Objects_Id min_id, max_id; 188 int first_posix_id, first_rtems_id; 189 Objects_Information *obj_info; 190 Thread_Control *th; 191 192 ASSERT(registers != NULL); 193 194 if (_System_state_Get() != SYSTEM_STATE_UP || thread <= 0) { 195 /* Should not happen */ 196 return 0; 197 } 198 199 if (thread == 1) { 200 th = _Thread_Idle; 201 goto found; 202 } 203 204 /* Let us get object associtated with current thread */ 205 first_rtems_id = 2; 206 207 thread_obj_id = _Thread_Executing->Object.id; 208 209 /* Let us figure out thread_id for gdb */ 210 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 211 212 min_id = obj_info->minimum_id; 213 max_id = obj_info->maximum_id; 214 215 if (thread <= (first_rtems_id + (max_id - min_id))) { 216 th = (Thread_Control *)(obj_info->local_table[thread - first_rtems_id + 1]); 217 218 if (th != NULL) { 219 goto found; 220 } 221 222 /* Thread does not exist */ 223 return 0; 224 } 225 226 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 227 228 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 229 230 min_id = obj_info->minimum_id; 231 max_id = obj_info->maximum_id; 232 233 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 234 if (th == NULL) { 235 /* Thread does not exist */ 236 return 0; 237 } 238 239 found: 240 241 rtems_gdb_stub_get_registers_from_context( registers, th ); 242 243 return 1; 244 } 272 Thread_Control *th; 273 274 th= rtems_gdb_index_to_stub_id(thread); 275 276 if( th ) 277 { 278 rtems_gdb_stub_get_registers_from_context( registers, th ); 279 return 1; 280 } 281 return 0; 282 } 283 284 285 286 245 287 246 288 … … 248 290 exist or register values will screw up the threads, 249 291 and 1 otherwise */ 292 250 293 int rtems_gdb_stub_set_thread_regs( 251 294 int thread, … … 259 302 return 1; 260 303 } 304 305 306 307 261 308 262 309 … … 268 315 ) 269 316 { 270 Objects_Id thread_obj_id;271 Objects_Id min_id, max_id;272 int first_posix_id, first_rtems_id;273 Objects_Information *obj_info;274 Thread_Control *th;275 unsigned32 name;276 char tmp_buf[20];277 278 ASSERT(info != NULL);279 280 if (thread <= 0) {281 return 0;282 }283 284 if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) {285 /* We have one thread let us use value317 Objects_Id thread_obj_id; 318 Objects_Id min_id, max_id; 319 int first_posix_id, first_rtems_id; 320 Objects_Information *obj_info; 321 Thread_Control *th; 322 unsigned32 name; 323 char tmp_buf[20]; 324 325 ASSERT(info != NULL); 326 327 if (thread <= 0) { 328 return 0; 329 } 330 331 if (_System_state_Get() != SYSTEM_STATE_UP || thread == 1) { 332 /* We have one thread let us use value 286 333 which will never happen for real thread */ 287 strcpy(info->display, "idle thread");288 strcpy(info->name, "IDLE");289 info->more_display[0] = 0; /* Nothing */290 291 return 1;292 }293 294 /* Let us get object associtated with current thread */295 thread_obj_id = _Thread_Executing->Object.id;296 297 /* Let us figure out thread_id for gdb */298 first_rtems_id = 2;334 strcpy(info->display, "idle thread"); 335 strcpy(info->name, "IDLE"); 336 info->more_display[0] = 0; /* Nothing */ 337 338 return 1; 339 } 340 341 /* Let us get object associtated with current thread */ 342 thread_obj_id = _Thread_Executing->Object.id; 343 344 /* Let us figure out thread_id for gdb */ 345 first_rtems_id = 2; 299 346 300 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS];301 302 min_id = obj_info->minimum_id;303 max_id = obj_info->maximum_id;304 305 if (thread <= (first_rtems_id + (max_id - min_id))) {347 obj_info = _Objects_Information_table[OBJECTS_RTEMS_TASKS]; 348 349 min_id = obj_info->minimum_id; 350 max_id = obj_info->maximum_id; 351 352 if (thread <= (first_rtems_id + (max_id - min_id))) { 306 353 th = (Thread_Control *)(obj_info->local_table[thread - 307 354 first_rtems_id + 1]); 308 355 309 if (th == NULL) {310 /* Thread does not exist */311 return 0;312 }313 314 strcpy(info->display, "rtems task: control at 0x");315 316 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];317 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];318 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];319 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];320 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];321 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];322 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];323 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];324 tmp_buf[8] = 0;325 326 strcat(info->display, tmp_buf);356 if (th == NULL) { 357 /* Thread does not exist */ 358 return 0; 359 } 360 361 strcpy(info->display, "rtems task: control at 0x"); 362 363 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; 364 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; 365 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; 366 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; 367 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; 368 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; 369 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; 370 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; 371 tmp_buf[8] = 0; 372 373 strcat(info->display, tmp_buf); 327 374 328 name = *(unsigned32 *)(obj_info->local_table[thread]->name);375 name = *(unsigned32 *)(obj_info->local_table[thread]->name); 329 376 330 info->name[0] = (name >> 24) & 0xff;331 info->name[1] = (name >> 16) & 0xff;332 info->name[2] = (name >> 8) & 0xff;333 info->name[3] = name & 0xff;334 info->name[4] = 0;335 336 info->more_display[0] = 0; /* Nothing */337 338 return 1;339 }340 341 first_posix_id = first_rtems_id + (max_id - min_id) + 1;342 343 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS];344 345 min_id = obj_info->minimum_id;346 max_id = obj_info->maximum_id;347 348 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]);349 if (th == NULL)350 377 info->name[0] = (name >> 24) & 0xff; 378 info->name[1] = (name >> 16) & 0xff; 379 info->name[2] = (name >> 8) & 0xff; 380 info->name[3] = name & 0xff; 381 info->name[4] = 0; 382 383 info->more_display[0] = 0; /* Nothing */ 384 385 return 1; 386 } 387 388 first_posix_id = first_rtems_id + (max_id - min_id) + 1; 389 390 obj_info = _Objects_Information_table[OBJECTS_POSIX_THREADS]; 391 392 min_id = obj_info->minimum_id; 393 max_id = obj_info->maximum_id; 394 395 th = (Thread_Control *)(obj_info->local_table[thread - first_posix_id + 1]); 396 if (th == NULL) 397 { 351 398 /* Thread does not exist */ 352 399 return 0; 353 354 355 strcpy(info->display, "posix thread: control at 0x");356 357 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf];358 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf];359 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf];360 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf];361 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf];362 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf];363 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf];364 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf];365 tmp_buf[8] = 0;366 367 strcat(info->display, tmp_buf);368 369 name = *(unsigned32 *)(obj_info->local_table[thread -370 first_posix_id + 1]->name);371 372 info->name[0] = (name >> 24) & 0xff;373 info->name[1] = (name >> 16) & 0xff;374 info->name[2] = (name >> 8) & 0xff;375 info->name[3] = name & 0xff;376 info->name[4] = 0;377 378 info->more_display[0] = 0; /* Nothing */400 } 401 402 strcpy(info->display, "posix thread: control at 0x"); 403 404 tmp_buf[0] = gdb_hexchars[(((int)th) >> 28) & 0xf]; 405 tmp_buf[1] = gdb_hexchars[(((int)th) >> 24) & 0xf]; 406 tmp_buf[2] = gdb_hexchars[(((int)th) >> 20) & 0xf]; 407 tmp_buf[3] = gdb_hexchars[(((int)th) >> 16) & 0xf]; 408 tmp_buf[4] = gdb_hexchars[(((int)th) >> 12) & 0xf]; 409 tmp_buf[5] = gdb_hexchars[(((int)th) >> 8) & 0xf]; 410 tmp_buf[6] = gdb_hexchars[(((int)th) >> 4) & 0xf]; 411 tmp_buf[7] = gdb_hexchars[((int)th) & 0xf]; 412 tmp_buf[8] = 0; 413 414 strcat(info->display, tmp_buf); 415 416 name = *(unsigned32 *)(obj_info->local_table[thread - 417 first_posix_id + 1]->name); 418 419 info->name[0] = (name >> 24) & 0xff; 420 info->name[1] = (name >> 16) & 0xff; 421 info->name[2] = (name >> 8) & 0xff; 422 info->name[3] = name & 0xff; 423 info->name[4] = 0; 424 425 info->more_display[0] = 0; /* Nothing */ 379 426 380 return 1;427 return 1; 381 428 } 382 429 383 430 /*******************************************************/ 431 432 433 434 384 435 385 436 … … 598 649 pack_qm_header(char *out, int count, int done, int athread) 599 650 { 600 ASSERT(out != 0); 601 ASSERT(count >= 0 && count < 256); 602 603 *out++ = 'q'; 604 *out++ = 'M'; 605 606 *out++ = gdb_hexchars[(count >> 4) & 0x0f]; 607 *out++ = gdb_hexchars[count & 0x0f]; 608 609 if (done) { 610 *out++ = '1'; 611 } else { 612 *out++ = '0'; 613 } 614 615 thread2fhstr(out, athread); 616 617 return; 618 } 651 ASSERT(out != 0); 652 ASSERT(count >= 0 && count < 256); 653 654 *out++ = 'q'; 655 *out++ = 'M'; 656 657 *out++ = gdb_hexchars[(count >> 4) & 0x0f]; 658 *out++ = gdb_hexchars[count & 0x0f]; 659 660 if (done) { 661 *out++ = '1'; 662 } else { 663 *out++ = '0'; 664 } 665 666 thread2fhstr(out, athread); 667 return; 668 } 669 670 671 672 673 674 675 676 677 678 619 679 620 680 … … 643 703 break; 644 704 705 706 707 645 708 case 'P': 646 709 /* Thread info query */ … … 670 733 pack_qq(outbuffer, mask, rthread, &info); 671 734 } 672 673 735 break; 736 737 738 739 740 674 741 case 'L': 675 /* Thread infoquery */742 /* Thread list query */ 676 743 if (!do_threads) { 677 744 break; … … 725 792 /* Fill header */ 726 793 pack_qm_header(outbuffer, i, done, athread); 727 728 794 } 729 795 break; 796 797 798 799 800 801 730 802 default: 731 803 if (memcmp(inbuffer, "qOffsets", 8) == 0) { … … 773 845 break; 774 846 } 775 776 } 847 } 848 849 850 851 852 777 853 778 854 /* Present thread in the variable length string format */ … … 1197 1273 to mem_fault, they won't get restored, so there better not be any 1198 1274 saved). */ 1275 1199 1276 unsigned char 1200 1277 get_byte (const unsigned char *addr) … … 1208 1285 *addr = val; 1209 1286 } 1287 1288 1289 1290 1291 1292 1210 1293 1211 1294 … … 1274 1357 } 1275 1358 1359 1360 1361 1362 1276 1363 #elif defined(__mips__) 1364 1365 1277 1366 void rtems_gdb_stub_get_registers_from_context( 1278 1367 int *registers, … … 1280 1369 ) 1281 1370 { 1282 } 1371 registers[S0] = (unsigned)th->Registers.s0; 1372 registers[S1] = (unsigned)th->Registers.s1; 1373 registers[S2] = (unsigned)th->Registers.s2; 1374 registers[S3] = (unsigned)th->Registers.s3; 1375 registers[S4] = (unsigned)th->Registers.s4; 1376 registers[S5] = (unsigned)th->Registers.s5; 1377 registers[S6] = (unsigned)th->Registers.s6; 1378 registers[S7] = (unsigned)th->Registers.s7; 1379 1380 registers[SP] = (unsigned)th->Registers.sp; 1381 registers[RA] = (unsigned)th->Registers.ra; 1382 1383 registers[SR] = (unsigned)th->Registers.c0_sr; 1384 registers[PC] = (unsigned)th->Registers.c0_epc; 1385 } 1386 1283 1387 1284 1388 int rtems_gdb_stub_get_offsets( … … 1287 1391 unsigned char **bss_addr 1288 1392 ) 1289 { 1393 { 1394 /* 1395 extern unsigned32 _ftext; 1396 extern unsigned32 _fdata; 1397 extern unsigned32 _bss_start; 1398 1399 *text_addr = &_ftext; 1400 *data_addr = &_fdata; 1401 *bss_addr = &_bss_start; 1402 */ 1290 1403 *text_addr = 0; 1291 1404 *data_addr = 0; 1292 1405 *bss_addr = 0; 1293 1294 1406 return 1; 1295 1407 }
Note: See TracChangeset
for help on using the changeset viewer.