OLD | NEW |
1 /* Copyright (C) 1992-1994, 1997-2000, 2003-2005, 2007-2012 Free | 1 /* Copyright (C) 1992-1994, 1997-2000, 2003-2005, 2007-2012 Free |
2 Software Foundation, Inc. | 2 Software Foundation, Inc. |
3 | 3 |
4 This file is part of GDB. | 4 This file is part of GDB. |
5 | 5 |
6 This program is free software; you can redistribute it and/or modify | 6 This program is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation; either version 3 of the License, or | 8 the Free Software Foundation; either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 - ADA_TASKS_ARRAY: The known_tasks is an array; | 208 - ADA_TASKS_ARRAY: The known_tasks is an array; |
209 - ADA_TASKS_LIST: The known_tasks is a list. */ | 209 - ADA_TASKS_LIST: The known_tasks is a list. */ |
210 enum ada_known_tasks_kind known_tasks_kind; | 210 enum ada_known_tasks_kind known_tasks_kind; |
211 | 211 |
212 /* The address of the known_tasks structure. This is where | 212 /* The address of the known_tasks structure. This is where |
213 the runtime stores the information for all Ada tasks. | 213 the runtime stores the information for all Ada tasks. |
214 The interpretation of this field depends on KNOWN_TASKS_KIND | 214 The interpretation of this field depends on KNOWN_TASKS_KIND |
215 above. */ | 215 above. */ |
216 CORE_ADDR known_tasks_addr; | 216 CORE_ADDR known_tasks_addr; |
217 | 217 |
| 218 /* Type of elements of the known task. Usually a pointer. */ |
| 219 struct type *known_tasks_element; |
| 220 |
| 221 /* Number of elements in the known tasks array. */ |
| 222 unsigned int known_tasks_length; |
| 223 |
218 /* When nonzero, this flag indicates that the task_list field | 224 /* When nonzero, this flag indicates that the task_list field |
219 below is up to date. When set to zero, the list has either | 225 below is up to date. When set to zero, the list has either |
220 not been initialized, or has potentially become stale. */ | 226 not been initialized, or has potentially become stale. */ |
221 int task_list_valid_p; | 227 int task_list_valid_p; |
222 | 228 |
223 /* The list of Ada tasks. | 229 /* The list of Ada tasks. |
224 | 230 |
225 Note: To each task we associate a number that the user can use to | 231 Note: To each task we associate a number that the user can use to |
226 reference it - this number is printed beside each task in the tasks | 232 reference it - this number is printed beside each task in the tasks |
227 info listing displayed by "info tasks". This number is equal to | 233 info listing displayed by "info tasks". This number is equal to |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf); | 773 struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf); |
768 | 774 |
769 read_atcb (task_id, &task_info); | 775 read_atcb (task_id, &task_info); |
770 VEC_safe_push (ada_task_info_s, data->task_list, &task_info); | 776 VEC_safe_push (ada_task_info_s, data->task_list, &task_info); |
771 } | 777 } |
772 | 778 |
773 /* Read the Known_Tasks array from the inferior memory, and store | 779 /* Read the Known_Tasks array from the inferior memory, and store |
774 it in the current inferior's TASK_LIST. Return non-zero upon success. */ | 780 it in the current inferior's TASK_LIST. Return non-zero upon success. */ |
775 | 781 |
776 static int | 782 static int |
777 read_known_tasks_array (CORE_ADDR known_tasks_addr) | 783 read_known_tasks_array (struct ada_tasks_inferior_data *data) |
778 { | 784 { |
779 const int target_ptr_byte = | 785 const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element); |
780 gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT; | 786 const int known_tasks_size = target_ptr_byte * data->known_tasks_length; |
781 const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS; | |
782 gdb_byte *known_tasks = alloca (known_tasks_size); | 787 gdb_byte *known_tasks = alloca (known_tasks_size); |
783 int i; | 788 int i; |
784 | 789 |
785 /* Build a new list by reading the ATCBs from the Known_Tasks array | 790 /* Build a new list by reading the ATCBs from the Known_Tasks array |
786 in the Ada runtime. */ | 791 in the Ada runtime. */ |
787 read_memory (known_tasks_addr, known_tasks, known_tasks_size); | 792 read_memory (data->known_tasks_addr, known_tasks, known_tasks_size); |
788 for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++) | 793 for (i = 0; i < data->known_tasks_length; i++) |
789 { | 794 { |
790 struct type *data_ptr_type = | |
791 builtin_type (target_gdbarch)->builtin_data_ptr; | |
792 CORE_ADDR task_id = | 795 CORE_ADDR task_id = |
793 extract_typed_address (known_tasks + i * target_ptr_byte, | 796 extract_typed_address (known_tasks + i * target_ptr_byte, |
794 » » » data_ptr_type); | 797 » » » data->known_tasks_element); |
795 | 798 |
796 if (task_id != 0) | 799 if (task_id != 0) |
797 add_ada_task (task_id, current_inferior ()); | 800 add_ada_task (task_id, current_inferior ()); |
798 } | 801 } |
799 | 802 |
800 return 1; | 803 return 1; |
801 } | 804 } |
802 | 805 |
803 /* Read the known tasks from the inferior memory, and store it in | 806 /* Read the known tasks from the inferior memory, and store it in |
804 the current inferior's TASK_LIST. Return non-zero upon success. */ | 807 the current inferior's TASK_LIST. Return non-zero upon success. */ |
805 | 808 |
806 static int | 809 static int |
807 read_known_tasks_list (CORE_ADDR known_tasks_addr) | 810 read_known_tasks_list (struct ada_tasks_inferior_data *data) |
808 { | 811 { |
809 const int target_ptr_byte = | 812 const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element); |
810 gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT; | |
811 gdb_byte *known_tasks = alloca (target_ptr_byte); | 813 gdb_byte *known_tasks = alloca (target_ptr_byte); |
812 struct type *data_ptr_type = | |
813 builtin_type (target_gdbarch)->builtin_data_ptr; | |
814 CORE_ADDR task_id; | 814 CORE_ADDR task_id; |
815 const struct ada_tasks_pspace_data *pspace_data | 815 const struct ada_tasks_pspace_data *pspace_data |
816 = get_ada_tasks_pspace_data (current_program_space); | 816 = get_ada_tasks_pspace_data (current_program_space); |
817 | 817 |
818 /* Sanity check. */ | 818 /* Sanity check. */ |
819 if (pspace_data->atcb_fieldno.activation_link < 0) | 819 if (pspace_data->atcb_fieldno.activation_link < 0) |
820 return 0; | 820 return 0; |
821 | 821 |
822 /* Build a new list by reading the ATCBs. Read head of the list. */ | 822 /* Build a new list by reading the ATCBs. Read head of the list. */ |
823 read_memory (known_tasks_addr, known_tasks, target_ptr_byte); | 823 read_memory (data->known_tasks_addr, known_tasks, target_ptr_byte); |
824 task_id = extract_typed_address (known_tasks, data_ptr_type); | 824 task_id = extract_typed_address (known_tasks, data->known_tasks_element); |
825 while (task_id != 0) | 825 while (task_id != 0) |
826 { | 826 { |
827 struct value *tcb_value; | 827 struct value *tcb_value; |
828 struct value *common_value; | 828 struct value *common_value; |
829 | 829 |
830 add_ada_task (task_id, current_inferior ()); | 830 add_ada_task (task_id, current_inferior ()); |
831 | 831 |
832 /* Read the chain. */ | 832 /* Read the chain. */ |
833 tcb_value = value_from_contents_and_address (pspace_data->atcb_type, | 833 tcb_value = value_from_contents_and_address (pspace_data->atcb_type, |
834 NULL, task_id); | 834 NULL, task_id); |
835 common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common); | 835 common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common); |
836 task_id = value_as_address | 836 task_id = value_as_address |
837 (value_field (common_value, | 837 (value_field (common_value, |
838 pspace_data->atcb_fieldno.activation_link)); | 838 pspace_data->atcb_fieldno.activation_link)); |
839 } | 839 } |
840 | 840 |
841 return 1; | 841 return 1; |
842 } | 842 } |
843 | 843 |
844 /* Return the address of the variable NAME that contains all the known | 844 /* Set all fields of the current inferior ada-tasks data pointed by DATA. |
845 tasks maintained in the Ada Runtime. Return NULL if the variable | 845 Do nothing if those fields are already set and still up to date. */ |
846 could not be found, meaning that the inferior program probably does | |
847 not use tasking. */ | |
848 | 846 |
849 static CORE_ADDR | 847 static void |
850 get_known_tasks_addr (const char *name) | 848 ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data) |
851 { | 849 { |
852 struct minimal_symbol *msym; | 850 struct minimal_symbol *msym; |
| 851 struct symbol *sym; |
853 | 852 |
854 msym = lookup_minimal_symbol (name, NULL, NULL); | 853 /* Return now if already set. */ |
855 if (msym == NULL) | |
856 return 0; | |
857 | |
858 return SYMBOL_VALUE_ADDRESS (msym); | |
859 } | |
860 | |
861 /* Assuming DATA is the ada-tasks' data for the current inferior, | |
862 set the known_tasks_kind and known_tasks_addr fields. Do nothing | |
863 if those fields are already set and still up to date. */ | |
864 | |
865 static void | |
866 ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data) | |
867 { | |
868 CORE_ADDR known_tasks_addr; | |
869 | |
870 if (data->known_tasks_kind != ADA_TASKS_UNKNOWN) | 854 if (data->known_tasks_kind != ADA_TASKS_UNKNOWN) |
871 return; | 855 return; |
872 | 856 |
873 known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME); | 857 /* Try array. */ |
874 if (known_tasks_addr != 0) | 858 |
| 859 msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL); |
| 860 if (msym != NULL) |
875 { | 861 { |
876 data->known_tasks_kind = ADA_TASKS_ARRAY; | 862 data->known_tasks_kind = ADA_TASKS_ARRAY; |
877 data->known_tasks_addr = known_tasks_addr; | 863 data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym); |
| 864 |
| 865 /* Try to get pointer type and array length from the symtab. */ |
| 866 sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN, |
| 867 » » » » language_c, NULL); |
| 868 if (sym != NULL) |
| 869 » { |
| 870 » /* Validate. */ |
| 871 » struct type *type = check_typedef (SYMBOL_TYPE (sym)); |
| 872 » struct type *eltype = NULL; |
| 873 » struct type *idxtype = NULL; |
| 874 |
| 875 » if (TYPE_CODE (type) == TYPE_CODE_ARRAY) |
| 876 » eltype = check_typedef (TYPE_TARGET_TYPE (type)); |
| 877 » if (eltype != NULL |
| 878 » && TYPE_CODE (eltype) == TYPE_CODE_PTR) |
| 879 » idxtype = check_typedef (TYPE_INDEX_TYPE (type)); |
| 880 » if (idxtype != NULL |
| 881 » && !TYPE_LOW_BOUND_UNDEFINED (idxtype) |
| 882 » && !TYPE_HIGH_BOUND_UNDEFINED (idxtype)) |
| 883 » { |
| 884 » data->known_tasks_element = eltype; |
| 885 » data->known_tasks_length = |
| 886 » » TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1; |
| 887 » return; |
| 888 » } |
| 889 » } |
| 890 |
| 891 /* Fallback to default values. The runtime may have been stripped (as |
| 892 » in some distributions), but it is likely that the executable still |
| 893 » contains debug information on the task type (due to implicit with of |
| 894 » Ada.Tasking). */ |
| 895 data->known_tasks_element = |
| 896 » builtin_type (target_gdbarch)->builtin_data_ptr; |
| 897 data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS; |
878 return; | 898 return; |
879 } | 899 } |
880 | 900 |
881 known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST); | 901 |
882 if (known_tasks_addr != 0) | 902 /* Try list. */ |
| 903 |
| 904 msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL); |
| 905 if (msym != NULL) |
883 { | 906 { |
884 data->known_tasks_kind = ADA_TASKS_LIST; | 907 data->known_tasks_kind = ADA_TASKS_LIST; |
885 data->known_tasks_addr = known_tasks_addr; | 908 data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym); |
| 909 data->known_tasks_length = 1; |
| 910 |
| 911 sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN, |
| 912 » » » » language_c, NULL); |
| 913 if (sym != NULL && SYMBOL_VALUE_ADDRESS (sym) != 0) |
| 914 » { |
| 915 » /* Validate. */ |
| 916 » struct type *type = check_typedef (SYMBOL_TYPE (sym)); |
| 917 |
| 918 » if (TYPE_CODE (type) == TYPE_CODE_PTR) |
| 919 » { |
| 920 » data->known_tasks_element = type; |
| 921 » return; |
| 922 » } |
| 923 » } |
| 924 |
| 925 /* Fallback to default values. */ |
| 926 data->known_tasks_element = |
| 927 » builtin_type (target_gdbarch)->builtin_data_ptr; |
| 928 data->known_tasks_length = 1; |
886 return; | 929 return; |
887 } | 930 } |
888 | 931 |
| 932 /* Can't find tasks. */ |
| 933 |
889 data->known_tasks_kind = ADA_TASKS_NOT_FOUND; | 934 data->known_tasks_kind = ADA_TASKS_NOT_FOUND; |
890 data->known_tasks_addr = 0; | 935 data->known_tasks_addr = 0; |
891 } | 936 } |
892 | 937 |
893 /* Read the known tasks from the current inferior's memory, and store it | 938 /* Read the known tasks from the current inferior's memory, and store it |
894 in the current inferior's data TASK_LIST. | 939 in the current inferior's data TASK_LIST. |
895 Return non-zero upon success. */ | 940 Return non-zero upon success. */ |
896 | 941 |
897 static int | 942 static int |
898 read_known_tasks (void) | 943 read_known_tasks (void) |
899 { | 944 { |
900 struct ada_tasks_inferior_data *data = | 945 struct ada_tasks_inferior_data *data = |
901 get_ada_tasks_inferior_data (current_inferior ()); | 946 get_ada_tasks_inferior_data (current_inferior ()); |
902 | 947 |
903 /* Step 1: Clear the current list, if necessary. */ | 948 /* Step 1: Clear the current list, if necessary. */ |
904 VEC_truncate (ada_task_info_s, data->task_list, 0); | 949 VEC_truncate (ada_task_info_s, data->task_list, 0); |
905 | 950 |
906 /* Step 2: do the real work. | 951 /* Step 2: do the real work. |
907 If the application does not use task, then no more needs to be done. | 952 If the application does not use task, then no more needs to be done. |
908 It is important to have the task list cleared (see above) before we | 953 It is important to have the task list cleared (see above) before we |
909 return, as we don't want a stale task list to be used... This can | 954 return, as we don't want a stale task list to be used... This can |
910 happen for instance when debugging a non-multitasking program after | 955 happen for instance when debugging a non-multitasking program after |
911 having debugged a multitasking one. */ | 956 having debugged a multitasking one. */ |
912 ada_set_current_inferior_known_tasks_addr (data); | 957 ada_tasks_inferior_data_sniffer (data); |
913 gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN); | 958 gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN); |
914 | 959 |
915 switch (data->known_tasks_kind) | 960 switch (data->known_tasks_kind) |
916 { | 961 { |
917 case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */ | 962 case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior. */ |
918 return 0; | 963 return 0; |
919 case ADA_TASKS_ARRAY: | 964 case ADA_TASKS_ARRAY: |
920 return read_known_tasks_array (data->known_tasks_addr); | 965 return read_known_tasks_array (data); |
921 case ADA_TASKS_LIST: | 966 case ADA_TASKS_LIST: |
922 return read_known_tasks_list (data->known_tasks_addr); | 967 return read_known_tasks_list (data); |
923 } | 968 } |
924 | 969 |
925 /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks | 970 /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks |
926 array unless needed. Then report a success. */ | 971 array unless needed. Then report a success. */ |
927 data->task_list_valid_p = 1; | 972 data->task_list_valid_p = 1; |
928 | 973 |
929 return 1; | 974 return 1; |
930 } | 975 } |
931 | 976 |
932 /* Build the task_list by reading the Known_Tasks array from | 977 /* Build the task_list by reading the Known_Tasks array from |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 | 1443 |
1399 /* Some new commands provided by this module. */ | 1444 /* Some new commands provided by this module. */ |
1400 add_info ("tasks", info_tasks_command, | 1445 add_info ("tasks", info_tasks_command, |
1401 _("Provide information about all known Ada tasks")); | 1446 _("Provide information about all known Ada tasks")); |
1402 add_cmd ("task", class_run, task_command, | 1447 add_cmd ("task", class_run, task_command, |
1403 _("Use this command to switch between Ada tasks.\n\ | 1448 _("Use this command to switch between Ada tasks.\n\ |
1404 Without argument, this command simply prints the current task ID"), | 1449 Without argument, this command simply prints the current task ID"), |
1405 &cmdlist); | 1450 &cmdlist); |
1406 } | 1451 } |
1407 | 1452 |
OLD | NEW |