1 /* 2 * QEMU monitor, target-dependent part 3 * 4 * Copyright (c) 2003-2004 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "monitor-internal.h" 27 #include "monitor/qdev.h" 28 #include "net/slirp.h" 29 #include "sysemu/device_tree.h" 30 #include "monitor/hmp-target.h" 31 #include "monitor/hmp.h" 32 #include "block/block-hmp-cmds.h" 33 #include "qapi/qapi-commands-control.h" 34 #include "qapi/qapi-commands-misc.h" 35 #include "qapi/qapi-commands-machine.h" 36 #include "qapi/error.h" 37 #include "qemu/cutils.h" 38 39 #if defined(TARGET_S390X) 40 #include "hw/s390x/storage-keys.h" 41 #include "hw/s390x/storage-attributes.h" 42 #endif 43 44 /* Make devices configuration available for use in hmp-commands*.hx templates */ 45 #include CONFIG_DEVICES 46 47 static HMPCommand hmp_info_cmds[]; 48 49 /** 50 * Is @name in the '|' separated list of names @list? 51 */ 52 int hmp_compare_cmd(const char *name, const char *list) 53 { 54 const char *p, *pstart; 55 int len; 56 len = strlen(name); 57 p = list; 58 for (;;) { 59 pstart = p; 60 p = qemu_strchrnul(p, '|'); 61 if ((p - pstart) == len && !memcmp(pstart, name, len)) { 62 return 1; 63 } 64 if (*p == '\0') { 65 break; 66 } 67 p++; 68 } 69 return 0; 70 } 71 72 /* Please update hmp-commands.hx when adding or changing commands */ 73 static HMPCommand hmp_info_cmds[] = { 74 #include "hmp-commands-info.h" 75 { NULL, NULL, }, 76 }; 77 78 /* hmp_cmds and hmp_info_cmds would be sorted at runtime */ 79 HMPCommand hmp_cmds[] = { 80 #include "hmp-commands.h" 81 { NULL, NULL, }, 82 }; 83 84 /* 85 * Set @pval to the value in the register identified by @name. 86 * return 0 if OK, -1 if not found 87 */ 88 int get_monitor_def(Monitor *mon, int64_t *pval, const char *name) 89 { 90 const MonitorDef *md = target_monitor_defs(); 91 CPUState *cs = mon_get_cpu(mon); 92 void *ptr; 93 uint64_t tmp = 0; 94 int ret; 95 96 if (cs == NULL || md == NULL) { 97 return -1; 98 } 99 100 for(; md->name != NULL; md++) { 101 if (hmp_compare_cmd(name, md->name)) { 102 if (md->get_value) { 103 *pval = md->get_value(mon, md, md->offset); 104 } else { 105 CPUArchState *env = mon_get_cpu_env(mon); 106 ptr = (uint8_t *)env + md->offset; 107 switch(md->type) { 108 case MD_I32: 109 *pval = *(int32_t *)ptr; 110 break; 111 case MD_TLONG: 112 *pval = *(target_long *)ptr; 113 break; 114 default: 115 *pval = 0; 116 break; 117 } 118 } 119 return 0; 120 } 121 } 122 123 ret = target_get_monitor_def(cs, name, &tmp); 124 if (!ret) { 125 *pval = (target_long) tmp; 126 } 127 128 return ret; 129 } 130 131 static int 132 compare_mon_cmd(const void *a, const void *b) 133 { 134 return strcmp(((const HMPCommand *)a)->name, 135 ((const HMPCommand *)b)->name); 136 } 137 138 static void __attribute__((__constructor__)) sortcmdlist(void) 139 { 140 qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1, 141 sizeof(*hmp_cmds), 142 compare_mon_cmd); 143 qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1, 144 sizeof(*hmp_info_cmds), 145 compare_mon_cmd); 146 } 147 148 void monitor_register_hmp(const char *name, bool info, 149 void (*cmd)(Monitor *mon, const QDict *qdict)) 150 { 151 HMPCommand *table = info ? hmp_info_cmds : hmp_cmds; 152 153 while (table->name != NULL) { 154 if (strcmp(table->name, name) == 0) { 155 g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); 156 table->cmd = cmd; 157 return; 158 } 159 table++; 160 } 161 g_assert_not_reached(); 162 } 163 164 void monitor_register_hmp_info_hrt(const char *name, 165 HumanReadableText *(*handler)(Error **errp)) 166 { 167 HMPCommand *table = hmp_info_cmds; 168 169 while (table->name != NULL) { 170 if (strcmp(table->name, name) == 0) { 171 g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); 172 table->cmd_info_hrt = handler; 173 return; 174 } 175 table++; 176 } 177 g_assert_not_reached(); 178 } 179