| @@ -33,7 +33,6 @@ · 32 unmodified lines |
| 33 | #include <linux/kallsyms.h> | 33 | #include <linux/kallsyms.h> |
| 34 | #include <linux/kgdb.h> | 34 | #include <linux/kgdb.h> |
| 35 | #include <linux/kdb.h> | 35 | #include <linux/kdb.h> |
| 36 | #include <linux/list.h> | | |
| 37 | #include <linux/notifier.h> | 36 | #include <linux/notifier.h> |
| 38 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
| 39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
| @@ -654,16 +653,17 @@ static void kdb_cmderror(int diag) · 614 unmodified lines |
| 654 | * Returns: | 653 | * Returns: |
| 655 | * zero for success, a kdb diagnostic if error | 654 | * zero for success, a kdb diagnostic if error |
| 656 | */ | 655 | */ |
| 657 | struct defcmd_set { | 656 | struct kdb_macro { |
| 658 | int count; | 657 | kdbtab_t cmd; /* Macro command */ |
| 659 | bool usable; | 658 | struct list_head statements; /* Associated statement list */ |
| 660 | char *name; | | |
| 661 | char *usage; | | |
| 662 | char *help; | | |
| 663 | char **command; | | |
| 664 | }; | 659 | }; |
| 665 | static struct defcmd_set *defcmd_set; | 660 | |
| 666 | static int defcmd_set_count; | 661 | struct kdb_macro_statement { |
| | 662 | char *statement; /* Statement text */ |
| | 663 | struct list_head list_node; /* Statement list node */ |
| | 664 | }; |
| | 665 | |
| | 666 | static struct kdb_macro *kdb_macro; |
| 667 | static bool defcmd_in_progress; | 667 | static bool defcmd_in_progress; |
| 668 | | 668 | |
| 669 | /* Forward references */ | 669 | /* Forward references */ |
| @@ -671,53 +671,55 @@ static int kdb_exec_defcmd(int argc, const char **argv); · 1 unmodified line |
| 671 | | 671 | |
| 672 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) | 672 | static int kdb_defcmd2(const char *cmdstr, const char *argv0) |
| 673 | { | 673 | { |
| 674 | struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; | 674 | struct kdb_macro_statement *kms; |
| 675 | char **save_command = s->command; | 675 | |
| | 676 | if (!kdb_macro) |
| | 677 | return KDB_NOTIMP; |
| | 678 | |
| 676 | if (strcmp(argv0, "endefcmd") == 0) { | 679 | if (strcmp(argv0, "endefcmd") == 0) { |
| 677 | defcmd_in_progress = false; | 680 | defcmd_in_progress = false; |
| 678 | if (!s->count) | 681 | if (!list_empty(&kdb_macro->statements)) |
| 679 | s->usable = false; | 682 | kdb_register(&kdb_macro->cmd); |
| 680 | if (s->usable) | | |
| 681 | /* macros are always safe because when executed each | | |
| 682 | * internal command re-enters kdb_parse() and is | | |
| 683 | * safety checked individually. | | |
| 684 | */ | | |
| 685 | kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, | | |
| 686 | s->help, 0, | | |
| 687 | KDB_ENABLE_ALWAYS_SAFE); | | |
| 688 | return 0; | 683 | return 0; |
| 689 | } | 684 | } |
| 690 | if (!s->usable) | 685 | |
| 691 | return KDB_NOTIMP; | 686 | kms = kmalloc(sizeof(*kms), GFP_KDB); |
| 692 | s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); | 687 | if (!kms) { |
| 693 | if (!s->command) { | 688 | kdb_printf("Could not allocate new kdb macro command: %s\n", |
| 694 | kdb_printf("Could not allocate new kdb_defcmd table for %s\n", | | |
| 695 | cmdstr); | 689 | cmdstr); |
| 696 | s->usable = false; | | |
| 697 | return KDB_NOTIMP; | 690 | return KDB_NOTIMP; |
| 698 | } | 691 | } |
| 699 | memcpy(s->command, save_command, s->count * sizeof(*(s->command))); | 692 | |
| 700 | s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); | 693 | kms->statement = kdb_strdup(cmdstr, GFP_KDB); |
| 701 | kfree(save_command); | 694 | list_add_tail(&kms->list_node, &kdb_macro->statements); |
| | 695 | |
| 702 | return 0; | 696 | return 0; |
| 703 | } | 697 | } |
| 704 | | 698 | |
| 705 | static int kdb_defcmd(int argc, const char **argv) | 699 | static int kdb_defcmd(int argc, const char **argv) |
| 706 | { | 700 | { |
| 707 | struct defcmd_set *save_defcmd_set = defcmd_set, *s; | 701 | kdbtab_t *mp; |
| | 702 | |
| 708 | if (defcmd_in_progress) { | 703 | if (defcmd_in_progress) { |
| 709 | kdb_printf("kdb: nested defcmd detected, assuming missing " | 704 | kdb_printf("kdb: nested defcmd detected, assuming missing " |
| 710 | "endefcmd\n"); | 705 | "endefcmd\n"); |
| 711 | kdb_defcmd2("endefcmd", "endefcmd"); | 706 | kdb_defcmd2("endefcmd", "endefcmd"); |
| 712 | } | 707 | } |
| 713 | if (argc == 0) { | 708 | if (argc == 0) { |
| 714 | int i; | 709 | kdbtab_t *kp; |
| 715 | for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { | 710 | struct kdb_macro *kmp; |
| 716 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, | 711 | struct kdb_macro_statement *kms; |
| 717 | s->usage, s->help); | 712 | |
| 718 | for (i = 0; i < s->count; ++i) | 713 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| 719 | kdb_printf("%s", s->command[i]); | 714 | if (kp->func == kdb_exec_defcmd) { |
| 720 | kdb_printf("endefcmd\n"); | 715 | kdb_printf("defcmd %s \"%s\" \"%s\"\n", |
| | 716 | kp->name, kp->usage, kp->help); |
| | 717 | kmp = container_of(kp, struct kdb_macro, cmd); |
| | 718 | list_for_each_entry(kms, &kmp->statements, |
| | 719 | list_node) |
| | 720 | kdb_printf("%s", kms->statement); |
| | 721 | kdb_printf("endefcmd\n"); |
| | 722 | } |
| 721 | } | 723 | } |
| 722 | return 0; | 724 | return 0; |
| 723 | } | 725 | } |
| @@ -727,45 +729,43 @@ static int kdb_defcmd(int argc, const char **argv) · 3 unmodified lines |
| 727 | kdb_printf("Command only available during kdb_init()\n"); | 729 | kdb_printf("Command only available during kdb_init()\n"); |
| 728 | return KDB_NOTIMP; | 730 | return KDB_NOTIMP; |
| 729 | } | 731 | } |
| 730 | defcmd_set = kmalloc_array(defcmd_set_count + 1, sizeof(*defcmd_set), | 732 | kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); |
| 731 | GFP_KDB); | 733 | if (!kdb_macro) |
| 732 | if (!defcmd_set) | | |
| 733 | goto fail_defcmd; | 734 | goto fail_defcmd; |
| 734 | memcpy(defcmd_set, save_defcmd_set, | 735 | |
| 735 | defcmd_set_count * sizeof(*defcmd_set)); | 736 | mp = &kdb_macro->cmd; |
| 736 | s = defcmd_set + defcmd_set_count; | 737 | mp->func = kdb_exec_defcmd; |
| 737 | memset(s, 0, sizeof(*s)); | 738 | mp->minlen = 0; |
| 738 | s->usable = true; | 739 | mp->flags = KDB_ENABLE_ALWAYS_SAFE; |
| 739 | s->name = kdb_strdup(argv[1], GFP_KDB); | 740 | mp->name = kdb_strdup(argv[1], GFP_KDB); |
| 740 | if (!s->name) | 741 | if (!mp->name) |
| 741 | goto fail_name; | 742 | goto fail_name; |
| 742 | s->usage = kdb_strdup(argv[2], GFP_KDB); | 743 | mp->usage = kdb_strdup(argv[2], GFP_KDB); |
| 743 | if (!s->usage) | 744 | if (!mp->usage) |
| 744 | goto fail_usage; | 745 | goto fail_usage; |
| 745 | s->help = kdb_strdup(argv[3], GFP_KDB); | 746 | mp->help = kdb_strdup(argv[3], GFP_KDB); |
| 746 | if (!s->help) | 747 | if (!mp->help) |
| 747 | goto fail_help; | 748 | goto fail_help; |
| 748 | if (s->usage[0] == '"') { | 749 | if (mp->usage[0] == '"') { |
| 749 | strcpy(s->usage, argv[2]+1); | 750 | strcpy(mp->usage, argv[2]+1); |
| 750 | s->usage[strlen(s->usage)-1] = '\0'; | 751 | mp->usage[strlen(mp->usage)-1] = '\0'; |
| 751 | } | 752 | } |
| 752 | if (s->help[0] == '"') { | 753 | if (mp->help[0] == '"') { |
| 753 | strcpy(s->help, argv[3]+1); | 754 | strcpy(mp->help, argv[3]+1); |
| 754 | s->help[strlen(s->help)-1] = '\0'; | 755 | mp->help[strlen(mp->help)-1] = '\0'; |
| 755 | } | 756 | } |
| 756 | ++defcmd_set_count; | 757 | |
| | 758 | INIT_LIST_HEAD(&kdb_macro->statements); |
| 757 | defcmd_in_progress = true; | 759 | defcmd_in_progress = true; |
| 758 | kfree(save_defcmd_set); | | |
| 759 | return 0; | 760 | return 0; |
| 760 | fail_help: | 761 | fail_help: |
| 761 | kfree(s->usage); | 762 | kfree(mp->usage); |
| 762 | fail_usage: | 763 | fail_usage: |
| 763 | kfree(s->name); | 764 | kfree(mp->name); |
| 764 | fail_name: | 765 | fail_name: |
| 765 | kfree(defcmd_set); | 766 | kfree(kdb_macro); |
| 766 | fail_defcmd: | 767 | fail_defcmd: |
| 767 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); | 768 | kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); |
| 768 | defcmd_set = save_defcmd_set; | | |
| 769 | return KDB_NOTIMP; | 769 | return KDB_NOTIMP; |
| 770 | } | 770 | } |
| 771 | | 771 | |
| @@ -780,25 +780,31 @@ fail_defcmd: · 8 unmodified lines |
| 780 | */ | 780 | */ |
| 781 | static int kdb_exec_defcmd(int argc, const char **argv) | 781 | static int kdb_exec_defcmd(int argc, const char **argv) |
| 782 | { | 782 | { |
| 783 | int i, ret; | 783 | int ret; |
| 784 | struct defcmd_set *s; | 784 | kdbtab_t *kp; |
| | 785 | struct kdb_macro *kmp; |
| | 786 | struct kdb_macro_statement *kms; |
| | 787 | |
| 785 | if (argc != 0) | 788 | if (argc != 0) |
| 786 | return KDB_ARGCOUNT; | 789 | return KDB_ARGCOUNT; |
| 787 | for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { | 790 | |
| 788 | if (strcmp(s->name, argv[0]) == 0) | 791 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| | 792 | if (strcmp(kp->name, argv[0]) == 0) |
| 789 | break; | 793 | break; |
| 790 | } | 794 | } |
| 791 | if (i == defcmd_set_count) { | 795 | if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { |
| 792 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", | 796 | kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", |
| 793 | argv[0]); | 797 | argv[0]); |
| 794 | return KDB_NOTIMP; | 798 | return KDB_NOTIMP; |
| 795 | } | 799 | } |
| 796 | for (i = 0; i < s->count; ++i) { | 800 | kmp = container_of(kp, struct kdb_macro, cmd); |
| 797 | /* Recursive use of kdb_parse, do not use argv after | 801 | list_for_each_entry(kms, &kmp->statements, list_node) { |
| 798 | * this point */ | 802 | /* |
| | 803 | * Recursive use of kdb_parse, do not use argv after this point. |
| | 804 | */ |
| 799 | argv = NULL; | 805 | argv = NULL; |
| 800 | kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); | 806 | kdb_printf("[%s]kdb> %s\n", kmp->cmd.name, kms->statement); |
| 801 | ret = kdb_parse(s->command[i]); | 807 | ret = kdb_parse(kms->statement); |
| 802 | if (ret) | 808 | if (ret) |
| 803 | return ret; | 809 | return ret; |
| 804 | } | 810 | } |
| @@ -1009,11 +1015,11 @@ int kdb_parse(const char *cmdstr) · 204 unmodified lines |
| 1009 | * If this command is allowed to be abbreviated, | 1015 | * If this command is allowed to be abbreviated, |
| 1010 | * check to see if this is it. | 1016 | * check to see if this is it. |
| 1011 | */ | 1017 | */ |
| 1012 | if (tp->cmd_minlen && (strlen(argv[0]) <= tp->cmd_minlen) && | 1018 | if (tp->minlen && (strlen(argv[0]) <= tp->minlen) && |
| 1013 | (strncmp(argv[0], tp->cmd_name, tp->cmd_minlen) == 0)) | 1019 | (strncmp(argv[0], tp->name, tp->minlen) == 0)) |
| 1014 | break; | 1020 | break; |
| 1015 | | 1021 | |
| 1016 | if (strcmp(argv[0], tp->cmd_name) == 0) | 1022 | if (strcmp(argv[0], tp->name) == 0) |
| 1017 | break; | 1023 | break; |
| 1018 | } | 1024 | } |
| 1019 | | 1025 | |
| @@ -1024,8 +1030,7 @@ int kdb_parse(const char *cmdstr) · 4 unmodified lines |
| 1024 | */ | 1030 | */ |
| 1025 | if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) { | 1031 | if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) { |
| 1026 | list_for_each_entry(tp, &kdb_cmds_head, list_node) { | 1032 | list_for_each_entry(tp, &kdb_cmds_head, list_node) { |
| 1027 | if (strncmp(argv[0], tp->cmd_name, | 1033 | if (strncmp(argv[0], tp->name, strlen(tp->name)) == 0) |
| 1028 | strlen(tp->cmd_name)) == 0) | | |
| 1029 | break; | 1034 | break; |
| 1030 | } | 1035 | } |
| 1031 | } | 1036 | } |
| @@ -1033,19 +1038,19 @@ int kdb_parse(const char *cmdstr) · 1 unmodified line |
| 1033 | if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) { | 1038 | if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) { |
| 1034 | int result; | 1039 | int result; |
| 1035 | | 1040 | |
| 1036 | if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) | 1041 | if (!kdb_check_flags(tp->flags, kdb_cmd_enabled, argc <= 1)) |
| 1037 | return KDB_NOPERM; | 1042 | return KDB_NOPERM; |
| 1038 | | 1043 | |
| 1039 | KDB_STATE_SET(CMD); | 1044 | KDB_STATE_SET(CMD); |
| 1040 | result = (*tp->cmd_func)(argc-1, (const char **)argv); | 1045 | result = (*tp->func)(argc-1, (const char **)argv); |
| 1041 | if (result && ignore_errors && result > KDB_CMD_GO) | 1046 | if (result && ignore_errors && result > KDB_CMD_GO) |
| 1042 | result = 0; | 1047 | result = 0; |
| 1043 | KDB_STATE_CLEAR(CMD); | 1048 | KDB_STATE_CLEAR(CMD); |
| 1044 | | 1049 | |
| 1045 | if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) | 1050 | if (tp->flags & KDB_REPEAT_WITH_ARGS) |
| 1046 | return result; | 1051 | return result; |
| 1047 | | 1052 | |
| 1048 | argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; | 1053 | argc = tp->flags & KDB_REPEAT_NO_ARGS ? 1 : 0; |
| 1049 | if (argv[argc]) | 1054 | if (argv[argc]) |
| 1050 | *(argv[argc]) = '\0'; | 1055 | *(argv[argc]) = '\0'; |
| 1051 | return result; | 1056 | return result; |
| @@ -2412,12 +2417,12 @@ static int kdb_help(int argc, const char **argv) · 1360 unmodified lines |
| 2412 | char *space = ""; | 2417 | char *space = ""; |
| 2413 | if (KDB_FLAG(CMD_INTERRUPT)) | 2418 | if (KDB_FLAG(CMD_INTERRUPT)) |
| 2414 | return 0; | 2419 | return 0; |
| 2415 | if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) | 2420 | if (!kdb_check_flags(kt->flags, kdb_cmd_enabled, true)) |
| 2416 | continue; | 2421 | continue; |
| 2417 | if (strlen(kt->cmd_usage) > 20) | 2422 | if (strlen(kt->usage) > 20) |
| 2418 | space = "\n "; | 2423 | space = "\n "; |
| 2419 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, | 2424 | kdb_printf("%-15.15s %-20s%s%s\n", kt->name, |
| 2420 | kt->cmd_usage, space, kt->cmd_help); | 2425 | kt->usage, space, kt->help); |
| 2421 | } | 2426 | } |
| 2422 | return 0; | 2427 | return 0; |
| 2423 | } | 2428 | } |
| @@ -2613,56 +2618,32 @@ static int kdb_grep_help(int argc, const char **argv) · 189 unmodified lines |
| 2613 | return 0; | 2618 | return 0; |
| 2614 | } | 2619 | } |
| 2615 | | 2620 | |
| 2616 | /* | 2621 | /** |
| 2617 | * kdb_register_flags - This function is used to register a kernel | 2622 | * kdb_register() - This function is used to register a kernel debugger |
| 2618 | * debugger command. | 2623 | * command. |
| 2619 | * Inputs: | 2624 | * @cmd: pointer to kdb command |
| 2620 | * cmd Command name | 2625 | * |
| 2621 | * func Function to execute the command | 2626 | * Note that it's the job of the caller to keep the memory for the cmd |
| 2622 | * usage A simple usage string showing arguments | 2627 | * allocated until unregister is called. |
| 2623 | * help A simple help string describing command | | |
| 2624 | * repeat Does the command auto repeat on enter? | | |
| 2625 | * Returns: | | |
| 2626 | * zero for success, one if a duplicate command. | | |
| 2627 | */ | 2628 | */ |
| 2628 | int kdb_register_flags(char *cmd, | 2629 | int kdb_register(kdbtab_t *cmd) |
| 2629 | kdb_func_t func, | | |
| 2630 | char *usage, | | |
| 2631 | char *help, | | |
| 2632 | short minlen, | | |
| 2633 | kdb_cmdflags_t flags) | | |
| 2634 | { | 2630 | { |
| 2635 | kdbtab_t *kp; | 2631 | kdbtab_t *kp; |
| 2636 | | 2632 | |
| 2637 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { | 2633 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { |
| 2638 | if (strcmp(kp->cmd_name, cmd) == 0) { | 2634 | if (strcmp(kp->name, cmd->name) == 0) { |
| 2639 | kdb_printf("Duplicate kdb command registered: " | 2635 | kdb_printf("Duplicate kdb cmd: %s, func %p help %s\n", |
| 2640 | "%s, func %px help %s\n", cmd, func, help); | 2636 | cmd->name, cmd->func, cmd->help); |
| 2641 | return 1; | 2637 | return 1; |
| 2642 | } | 2638 | } |
| 2643 | } | 2639 | } |
| 2644 | | 2640 | |
| 2645 | kp = kmalloc(sizeof(*kp), GFP_KDB); | 2641 | list_add_tail(&cmd->list_node, &kdb_cmds_head); |
| 2646 | if (!kp) { | | |
| 2647 | kdb_printf("Could not allocate new kdb_command table\n"); | | |
| 2648 | return 1; | | |
| 2649 | } | | |
| 2650 | | | |
| 2651 | kp->cmd_name = cmd; | | |
| 2652 | kp->cmd_func = func; | | |
| 2653 | kp->cmd_usage = usage; | | |
| 2654 | kp->cmd_help = help; | | |
| 2655 | kp->cmd_minlen = minlen; | | |
| 2656 | kp->cmd_flags = flags; | | |
| 2657 | kp->is_dynamic = true; | | |
| 2658 | | | |
| 2659 | list_add_tail(&kp->list_node, &kdb_cmds_head); | | |
| 2660 | | | |
| 2661 | return 0; | 2642 | return 0; |
| 2662 | } | 2643 | } |
| 2663 | EXPORT_SYMBOL_GPL(kdb_register_flags); | 2644 | EXPORT_SYMBOL_GPL(kdb_register); |
| 2664 | | 2645 | |
| 2665 | /* | 2646 | /** |
| 2666 | * kdb_register_table() - This function is used to register a kdb command | 2647 | * kdb_register_table() - This function is used to register a kdb command |
| 2667 | * table. | 2648 | * table. |
| 2668 | * @kp: pointer to kdb command table | 2649 | * @kp: pointer to kdb command table |
| @@ -2676,266 +2657,231 @@ void kdb_register_table(kdbtab_t *kp, size_t len) · 7 unmodified lines |
| 2676 | } | 2657 | } |
| 2677 | } | 2658 | } |
| 2678 | | 2659 | |
| 2679 | /* | 2660 | /** |
| 2680 | * kdb_register - Compatibility register function for commands that do | 2661 | * kdb_unregister() - This function is used to unregister a kernel debugger |
| 2681 | * not need to specify a repeat state. Equivalent to | 2662 | * command. It is generally called when a module which |
| 2682 | * kdb_register_flags with flags set to 0. | 2663 | * implements kdb command is unloaded. |
| 2683 | * Inputs: | 2664 | * @cmd: pointer to kdb command |
| 2684 | * cmd Command name | | |
| 2685 | * func Function to execute the command | | |
| 2686 | * usage A simple usage string showing arguments | | |
| 2687 | * help A simple help string describing command | | |
| 2688 | * Returns: | | |
| 2689 | * zero for success, one if a duplicate command. | | |
| 2690 | */ | 2665 | */ |
| 2691 | int kdb_register(char *cmd, | 2666 | void kdb_unregister(kdbtab_t *cmd) |
| 2692 | kdb_func_t func, | | |
| 2693 | char *usage, | | |
| 2694 | char *help, | | |
| 2695 | short minlen) | | |
| 2696 | { | 2667 | { |
| 2697 | return kdb_register_flags(cmd, func, usage, help, minlen, 0); | 2668 | list_del(&cmd->list_node); |
| 2698 | } | | |
| 2699 | EXPORT_SYMBOL_GPL(kdb_register); | | |
| 2700 | | | |
| 2701 | /* | | |
| 2702 | * kdb_unregister - This function is used to unregister a kernel | | |
| 2703 | * debugger command. It is generally called when a module which | | |
| 2704 | * implements kdb commands is unloaded. | | |
| 2705 | * Inputs: | | |
| 2706 | * cmd Command name | | |
| 2707 | * Returns: | | |
| 2708 | * zero for success, one command not registered. | | |
| 2709 | */ | | |
| 2710 | int kdb_unregister(char *cmd) | | |
| 2711 | { | | |
| 2712 | kdbtab_t *kp; | | |
| 2713 | | | |
| 2714 | /* | | |
| 2715 | * find the command. | | |
| 2716 | */ | | |
| 2717 | list_for_each_entry(kp, &kdb_cmds_head, list_node) { | | |
| 2718 | if (strcmp(kp->cmd_name, cmd) == 0) { | | |
| 2719 | list_del(&kp->list_node); | | |
| 2720 | if (kp->is_dynamic) | | |
| 2721 | kfree(kp); | | |
| 2722 | return 0; | | |
| 2723 | } | | |
| 2724 | } | | |
| 2725 | | | |
| 2726 | /* Couldn't find it. */ | | |
| 2727 | return 1; | | |
| 2728 | } | 2669 | } |
| 2729 | EXPORT_SYMBOL_GPL(kdb_unregister); | 2670 | EXPORT_SYMBOL_GPL(kdb_unregister); |
| 2730 | | 2671 | |
| 2731 | static kdbtab_t maintab[] = { | 2672 | static kdbtab_t maintab[] = { |
| 2732 | { .cmd_name = "md", | 2673 | { .name = "md", |
| 2733 | .cmd_func = kdb_md, | 2674 | .func = kdb_md, |
| 2734 | .cmd_usage = "<vaddr>", | 2675 | .usage = "<vaddr>", |
| 2735 | .cmd_help = "Display Memory Contents, also mdWcN, e.g. md8c1", | 2676 | .help = "Display Memory Contents, also mdWcN, e.g. md8c1", |
| 2736 | .cmd_minlen = 1, | 2677 | .minlen = 1, |
| 2737 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2678 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2738 | }, | 2679 | }, |
| 2739 | { .cmd_name = "mdr", | 2680 | { .name = "mdr", |
| 2740 | .cmd_func = kdb_md, | 2681 | .func = kdb_md, |
| 2741 | .cmd_usage = "<vaddr> <bytes>", | 2682 | .usage = "<vaddr> <bytes>", |
| 2742 | .cmd_help = "Display Raw Memory", | 2683 | .help = "Display Raw Memory", |
| 2743 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2684 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2744 | }, | 2685 | }, |
| 2745 | { .cmd_name = "mdp", | 2686 | { .name = "mdp", |
| 2746 | .cmd_func = kdb_md, | 2687 | .func = kdb_md, |
| 2747 | .cmd_usage = "<paddr> <bytes>", | 2688 | .usage = "<paddr> <bytes>", |
| 2748 | .cmd_help = "Display Physical Memory", | 2689 | .help = "Display Physical Memory", |
| 2749 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2690 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2750 | }, | 2691 | }, |
| 2751 | { .cmd_name = "mds", | 2692 | { .name = "mds", |
| 2752 | .cmd_func = kdb_md, | 2693 | .func = kdb_md, |
| 2753 | .cmd_usage = "<vaddr>", | 2694 | .usage = "<vaddr>", |
| 2754 | .cmd_help = "Display Memory Symbolically", | 2695 | .help = "Display Memory Symbolically", |
| 2755 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, | 2696 | .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, |
| 2756 | }, | 2697 | }, |
| 2757 | { .cmd_name = "mm", | 2698 | { .name = "mm", |
| 2758 | .cmd_func = kdb_mm, | 2699 | .func = kdb_mm, |
| 2759 | .cmd_usage = "<vaddr> <contents>", | 2700 | .usage = "<vaddr> <contents>", |
| 2760 | .cmd_help = "Modify Memory Contents", | 2701 | .help = "Modify Memory Contents", |
| 2761 | .cmd_flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, | 2702 | .flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, |
| 2762 | }, | 2703 | }, |
| 2763 | { .cmd_name = "go", | 2704 | { .name = "go", |
| 2764 | .cmd_func = kdb_go, | 2705 | .func = kdb_go, |
| 2765 | .cmd_usage = "[<vaddr>]", | 2706 | .usage = "[<vaddr>]", |
| 2766 | .cmd_help = "Continue Execution", | 2707 | .help = "Continue Execution", |
| 2767 | .cmd_minlen = 1, | 2708 | .minlen = 1, |
| 2768 | .cmd_flags = KDB_ENABLE_REG_WRITE | | 2709 | .flags = KDB_ENABLE_REG_WRITE | |
| 2769 | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, | 2710 | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, |
| 2770 | }, | 2711 | }, |
| 2771 | { .cmd_name = "rd", | 2712 | { .name = "rd", |
| 2772 | .cmd_func = kdb_rd, | 2713 | .func = kdb_rd, |
| 2773 | .cmd_usage = "", | 2714 | .usage = "", |
| 2774 | .cmd_help = "Display Registers", | 2715 | .help = "Display Registers", |
| 2775 | .cmd_flags = KDB_ENABLE_REG_READ, | 2716 | .flags = KDB_ENABLE_REG_READ, |
| 2776 | }, | 2717 | }, |
| 2777 | { .cmd_name = "rm", | 2718 | { .name = "rm", |
| 2778 | .cmd_func = kdb_rm, | 2719 | .func = kdb_rm, |
| 2779 | .cmd_usage = "<reg> <contents>", | 2720 | .usage = "<reg> <contents>", |
| 2780 | .cmd_help = "Modify Registers", | 2721 | .help = "Modify Registers", |
| 2781 | .cmd_flags = KDB_ENABLE_REG_WRITE, | 2722 | .flags = KDB_ENABLE_REG_WRITE, |
| 2782 | }, | 2723 | }, |
| 2783 | { .cmd_name = "ef", | 2724 | { .name = "ef", |
| 2784 | .cmd_func = kdb_ef, | 2725 | .func = kdb_ef, |
| 2785 | .cmd_usage = "<vaddr>", | 2726 | .usage = "<vaddr>", |
| 2786 | .cmd_help = "Display exception frame", | 2727 | .help = "Display exception frame", |
| 2787 | .cmd_flags = KDB_ENABLE_MEM_READ, | 2728 | .flags = KDB_ENABLE_MEM_READ, |
| 2788 | }, | 2729 | }, |
| 2789 | { .cmd_name = "bt", | 2730 | { .name = "bt", |
| 2790 | .cmd_func = kdb_bt, | 2731 | .func = kdb_bt, |
| 2791 | .cmd_usage = "[<vaddr>]", | 2732 | .usage = "[<vaddr>]", |
| 2792 | .cmd_help = "Stack traceback", | 2733 | .help = "Stack traceback", |
| 2793 | .cmd_minlen = 1, | 2734 | .minlen = 1, |
| 2794 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, | 2735 | .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, |
| 2795 | }, | 2736 | }, |
| 2796 | { .cmd_name = "btp", | 2737 | { .name = "btp", |
| 2797 | .cmd_func = kdb_bt, | 2738 | .func = kdb_bt, |
| 2798 | .cmd_usage = "<pid>", | 2739 | .usage = "<pid>", |
| 2799 | .cmd_help = "Display stack for process <pid>", | 2740 | .help = "Display stack for process <pid>", |
| 2800 | .cmd_flags = KDB_ENABLE_INSPECT, | 2741 | .flags = KDB_ENABLE_INSPECT, |
| 2801 | }, | 2742 | }, |
| 2802 | { .cmd_name = "bta", | 2743 | { .name = "bta", |
| 2803 | .cmd_func = kdb_bt, | 2744 | .func = kdb_bt, |
| 2804 | .cmd_usage = "[D|R|S|T|C|Z|E|U|I|M|A]", | 2745 | .usage = "[D|R|S|T|C|Z|E|U|I|M|A]", |
| 2805 | .cmd_help = "Backtrace all processes matching state flag", | 2746 | .help = "Backtrace all processes matching state flag", |
| 2806 | .cmd_flags = KDB_ENABLE_INSPECT, | 2747 | .flags = KDB_ENABLE_INSPECT, |
| 2807 | }, | 2748 | }, |
| 2808 | { .cmd_name = "btc", | 2749 | { .name = "btc", |
| 2809 | .cmd_func = kdb_bt, | 2750 | .func = kdb_bt, |
| 2810 | .cmd_usage = "", | 2751 | .usage = "", |
| 2811 | .cmd_help = "Backtrace current process on each cpu", | 2752 | .help = "Backtrace current process on each cpu", |
| 2812 | .cmd_flags = KDB_ENABLE_INSPECT, | 2753 | .flags = KDB_ENABLE_INSPECT, |
| 2813 | }, | 2754 | }, |
| 2814 | { .cmd_name = "btt", | 2755 | { .name = "btt", |
| 2815 | .cmd_func = kdb_bt, | 2756 | .func = kdb_bt, |
| 2816 | .cmd_usage = "<vaddr>", | 2757 | .usage = "<vaddr>", |
| 2817 | .cmd_help = "Backtrace process given its struct task address", | 2758 | .help = "Backtrace process given its struct task address", |
| 2818 | .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, | 2759 | .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, |
| 2819 | }, | 2760 | }, |
| 2820 | { .cmd_name = "env", | 2761 | { .name = "env", |
| 2821 | .cmd_func = kdb_env, | 2762 | .func = kdb_env, |
| 2822 | .cmd_usage = "", | 2763 | .usage = "", |
| 2823 | .cmd_help = "Show environment variables", | 2764 | .help = "Show environment variables", |
| 2824 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2765 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2825 | }, | 2766 | }, |
| 2826 | { .cmd_name = "set", | 2767 | { .name = "set", |
| 2827 | .cmd_func = kdb_set, | 2768 | .func = kdb_set, |
| 2828 | .cmd_usage = "", | 2769 | .usage = "", |
| 2829 | .cmd_help = "Set environment variables", | 2770 | .help = "Set environment variables", |
| 2830 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2771 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2831 | }, | 2772 | }, |
| 2832 | { .cmd_name = "help", | 2773 | { .name = "help", |
| 2833 | .cmd_func = kdb_help, | 2774 | .func = kdb_help, |
| 2834 | .cmd_usage = "", | 2775 | .usage = "", |
| 2835 | .cmd_help = "Display Help Message", | 2776 | .help = "Display Help Message", |
| 2836 | .cmd_minlen = 1, | 2777 | .minlen = 1, |
| 2837 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2778 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2838 | }, | 2779 | }, |
| 2839 | { .cmd_name = "?", | 2780 | { .name = "?", |
| 2840 | .cmd_func = kdb_help, | 2781 | .func = kdb_help, |
| 2841 | .cmd_usage = "", | 2782 | .usage = "", |
| 2842 | .cmd_help = "Display Help Message", | 2783 | .help = "Display Help Message", |
| 2843 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2784 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2844 | }, | 2785 | }, |
| 2845 | { .cmd_name = "cpu", | 2786 | { .name = "cpu", |
| 2846 | .cmd_func = kdb_cpu, | 2787 | .func = kdb_cpu, |
| 2847 | .cmd_usage = "<cpunum>", | 2788 | .usage = "<cpunum>", |
| 2848 | .cmd_help = "Switch to new cpu", | 2789 | .help = "Switch to new cpu", |
| 2849 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, | 2790 | .flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, |
| 2850 | }, | 2791 | }, |
| 2851 | { .cmd_name = "kgdb", | 2792 | { .name = "kgdb", |
| 2852 | .cmd_func = kdb_kgdb, | 2793 | .func = kdb_kgdb, |
| 2853 | .cmd_usage = "", | 2794 | .usage = "", |
| 2854 | .cmd_help = "Enter kgdb mode", | 2795 | .help = "Enter kgdb mode", |
| 2855 | .cmd_flags = 0, | 2796 | .flags = 0, |
| 2856 | }, | 2797 | }, |
| 2857 | { .cmd_name = "ps", | 2798 | { .name = "ps", |
| 2858 | .cmd_func = kdb_ps, | 2799 | .func = kdb_ps, |
| 2859 | .cmd_usage = "[<flags>|A]", | 2800 | .usage = "[<flags>|A]", |
| 2860 | .cmd_help = "Display active task list", | 2801 | .help = "Display active task list", |
| 2861 | .cmd_flags = KDB_ENABLE_INSPECT, | 2802 | .flags = KDB_ENABLE_INSPECT, |
| 2862 | }, | 2803 | }, |
| 2863 | { .cmd_name = "pid", | 2804 | { .name = "pid", |
| 2864 | .cmd_func = kdb_pid, | 2805 | .func = kdb_pid, |
| 2865 | .cmd_usage = "<pidnum>", | 2806 | .usage = "<pidnum>", |
| 2866 | .cmd_help = "Switch to another task", | 2807 | .help = "Switch to another task", |
| 2867 | .cmd_flags = KDB_ENABLE_INSPECT, | 2808 | .flags = KDB_ENABLE_INSPECT, |
| 2868 | }, | 2809 | }, |
| 2869 | { .cmd_name = "reboot", | 2810 | { .name = "reboot", |
| 2870 | .cmd_func = kdb_reboot, | 2811 | .func = kdb_reboot, |
| 2871 | .cmd_usage = "", | 2812 | .usage = "", |
| 2872 | .cmd_help = "Reboot the machine immediately", | 2813 | .help = "Reboot the machine immediately", |
| 2873 | .cmd_flags = KDB_ENABLE_REBOOT, | 2814 | .flags = KDB_ENABLE_REBOOT, |
| 2874 | }, | 2815 | }, |
| 2875 | #if defined(CONFIG_MODULES) | 2816 | #if defined(CONFIG_MODULES) |
| 2876 | { .cmd_name = "lsmod", | 2817 | { .name = "lsmod", |
| 2877 | .cmd_func = kdb_lsmod, | 2818 | .func = kdb_lsmod, |
| 2878 | .cmd_usage = "", | 2819 | .usage = "", |
| 2879 | .cmd_help = "List loaded kernel modules", | 2820 | .help = "List loaded kernel modules", |
| 2880 | .cmd_flags = KDB_ENABLE_INSPECT, | 2821 | .flags = KDB_ENABLE_INSPECT, |
| 2881 | }, | 2822 | }, |
| 2882 | #endif | 2823 | #endif |
| 2883 | #if defined(CONFIG_MAGIC_SYSRQ) | 2824 | #if defined(CONFIG_MAGIC_SYSRQ) |
| 2884 | { .cmd_name = "sr", | 2825 | { .name = "sr", |
| 2885 | .cmd_func = kdb_sr, | 2826 | .func = kdb_sr, |
| 2886 | .cmd_usage = "<key>", | 2827 | .usage = "<key>", |
| 2887 | .cmd_help = "Magic SysRq key", | 2828 | .help = "Magic SysRq key", |
| 2888 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2829 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2889 | }, | 2830 | }, |
| 2890 | #endif | 2831 | #endif |
| 2891 | #if defined(CONFIG_PRINTK) | 2832 | #if defined(CONFIG_PRINTK) |
| 2892 | { .cmd_name = "dmesg", | 2833 | { .name = "dmesg", |
| 2893 | .cmd_func = kdb_dmesg, | 2834 | .func = kdb_dmesg, |
| 2894 | .cmd_usage = "[lines]", | 2835 | .usage = "[lines]", |
| 2895 | .cmd_help = "Display syslog buffer", | 2836 | .help = "Display syslog buffer", |
| 2896 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2837 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2897 | }, | 2838 | }, |
| 2898 | #endif | 2839 | #endif |
| 2899 | { .cmd_name = "defcmd", | 2840 | { .name = "defcmd", |
| 2900 | .cmd_func = kdb_defcmd, | 2841 | .func = kdb_defcmd, |
| 2901 | .cmd_usage = "name \"usage\" \"help\"", | 2842 | .usage = "name \"usage\" \"help\"", |
| 2902 | .cmd_help = "Define a set of commands, down to endefcmd", | 2843 | .help = "Define a set of commands, down to endefcmd", |
| 2903 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2844 | /* |
| | 2845 | * Macros are always safe because when executed each |
| | 2846 | * internal command re-enters kdb_parse() and is safety |
| | 2847 | * checked individually. |
| | 2848 | */ |
| | 2849 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2904 | }, | 2850 | }, |
| 2905 | { .cmd_name = "kill", | 2851 | { .name = "kill", |
| 2906 | .cmd_func = kdb_kill, | 2852 | .func = kdb_kill, |
| 2907 | .cmd_usage = "<-signal> <pid>", | 2853 | .usage = "<-signal> <pid>", |
| 2908 | .cmd_help = "Send a signal to a process", | 2854 | .help = "Send a signal to a process", |
| 2909 | .cmd_flags = KDB_ENABLE_SIGNAL, | 2855 | .flags = KDB_ENABLE_SIGNAL, |
| 2910 | }, | 2856 | }, |
| 2911 | { .cmd_name = "summary", | 2857 | { .name = "summary", |
| 2912 | .cmd_func = kdb_summary, | 2858 | .func = kdb_summary, |
| 2913 | .cmd_usage = "", | 2859 | .usage = "", |
| 2914 | .cmd_help = "Summarize the system", | 2860 | .help = "Summarize the system", |
| 2915 | .cmd_minlen = 4, | 2861 | .minlen = 4, |
| 2916 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2862 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2917 | }, | 2863 | }, |
| 2918 | { .cmd_name = "per_cpu", | 2864 | { .name = "per_cpu", |
| 2919 | .cmd_func = kdb_per_cpu, | 2865 | .func = kdb_per_cpu, |
| 2920 | .cmd_usage = "<sym> [<bytes>] [<cpu>]", | 2866 | .usage = "<sym> [<bytes>] [<cpu>]", |
| 2921 | .cmd_help = "Display per_cpu variables", | 2867 | .help = "Display per_cpu variables", |
| 2922 | .cmd_minlen = 3, | 2868 | .minlen = 3, |
| 2923 | .cmd_flags = KDB_ENABLE_MEM_READ, | 2869 | .flags = KDB_ENABLE_MEM_READ, |
| 2924 | }, | 2870 | }, |
| 2925 | { .cmd_name = "grephelp", | 2871 | { .name = "grephelp", |
| 2926 | .cmd_func = kdb_grep_help, | 2872 | .func = kdb_grep_help, |
| 2927 | .cmd_usage = "", | 2873 | .usage = "", |
| 2928 | .cmd_help = "Display help on | grep", | 2874 | .help = "Display help on | grep", |
| 2929 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2875 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2930 | }, | 2876 | }, |
| 2931 | }; | 2877 | }; |
| 2932 | | 2878 | |
| 2933 | static kdbtab_t nmicmd = { | 2879 | static kdbtab_t nmicmd = { |
| 2934 | .cmd_name = "disable_nmi", | 2880 | .name = "disable_nmi", |
| 2935 | .cmd_func = kdb_disable_nmi, | 2881 | .func = kdb_disable_nmi, |
| 2936 | .cmd_usage = "", | 2882 | .usage = "", |
| 2937 | .cmd_help = "Disable NMI entry to KDB", | 2883 | .help = "Disable NMI entry to KDB", |
| 2938 | .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, | 2884 | .flags = KDB_ENABLE_ALWAYS_SAFE, |
| 2939 | }; | 2885 | }; |
| 2940 | | 2886 | |
| 2941 | /* Initialize the kdb command table. */ | 2887 | /* Initialize the kdb command table. */ |