@@ -387,6 +387,60 @@ static inline void gdb_continue(GDBState *s)
387
387
#endif
388
388
}
389
389
390
+ /*
391
+ * Resume execution, per CPU actions. For user-mode emulation it's
392
+ * equivalent to gdb_continue.
393
+ */
394
+ static int gdb_continue_partial (GDBState * s , char * newstates )
395
+ {
396
+ CPUState * cpu ;
397
+ int res = 0 ;
398
+ #ifdef CONFIG_USER_ONLY
399
+ /*
400
+ * This is not exactly accurate, but it's an improvement compared to the
401
+ * previous situation, where only one CPU would be single-stepped.
402
+ */
403
+ CPU_FOREACH (cpu ) {
404
+ if (newstates [cpu -> cpu_index ] == 's' ) {
405
+ cpu_single_step (cpu , sstep_flags );
406
+ }
407
+ }
408
+ s -> running_state = 1 ;
409
+ #else
410
+ int flag = 0 ;
411
+
412
+ if (!runstate_needs_reset ()) {
413
+ if (vm_prepare_start ()) {
414
+ return 0 ;
415
+ }
416
+
417
+ CPU_FOREACH (cpu ) {
418
+ switch (newstates [cpu -> cpu_index ]) {
419
+ case 0 :
420
+ case 1 :
421
+ break ; /* nothing to do here */
422
+ case 's' :
423
+ cpu_single_step (cpu , sstep_flags );
424
+ cpu_resume (cpu );
425
+ flag = 1 ;
426
+ break ;
427
+ case 'c' :
428
+ cpu_resume (cpu );
429
+ flag = 1 ;
430
+ break ;
431
+ default :
432
+ res = -1 ;
433
+ break ;
434
+ }
435
+ }
436
+ }
437
+ if (flag ) {
438
+ qemu_clock_enable (QEMU_CLOCK_VIRTUAL , true);
439
+ }
440
+ #endif
441
+ return res ;
442
+ }
443
+
390
444
static void put_buffer (GDBState * s , const uint8_t * buf , int len )
391
445
{
392
446
#ifdef CONFIG_USER_ONLY
@@ -785,6 +839,107 @@ static int is_query_packet(const char *p, const char *query, char separator)
785
839
(p [query_len ] == '\0' || p [query_len ] == separator );
786
840
}
787
841
842
+ /**
843
+ * gdb_handle_vcont - Parses and handles a vCont packet.
844
+ * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
845
+ * a format error, 0 on success.
846
+ */
847
+ static int gdb_handle_vcont (GDBState * s , const char * p )
848
+ {
849
+ int res , idx , signal = 0 ;
850
+ char cur_action ;
851
+ char * newstates ;
852
+ unsigned long tmp ;
853
+ CPUState * cpu ;
854
+ #ifdef CONFIG_USER_ONLY
855
+ int max_cpus = 1 ; /* global variable max_cpus exists only in system mode */
856
+
857
+ CPU_FOREACH (cpu ) {
858
+ max_cpus = max_cpus <= cpu -> cpu_index ? cpu -> cpu_index + 1 : max_cpus ;
859
+ }
860
+ #endif
861
+ /* uninitialised CPUs stay 0 */
862
+ newstates = g_new0 (char , max_cpus );
863
+
864
+ /* mark valid CPUs with 1 */
865
+ CPU_FOREACH (cpu ) {
866
+ newstates [cpu -> cpu_index ] = 1 ;
867
+ }
868
+
869
+ /*
870
+ * res keeps track of what error we are returning, with -ENOTSUP meaning
871
+ * that the command is unknown or unsupported, thus returning an empty
872
+ * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
873
+ * or incorrect parameters passed.
874
+ */
875
+ res = 0 ;
876
+ while (* p ) {
877
+ if (* p ++ != ';' ) {
878
+ res = - ENOTSUP ;
879
+ goto out ;
880
+ }
881
+
882
+ cur_action = * p ++ ;
883
+ if (cur_action == 'C' || cur_action == 'S' ) {
884
+ cur_action = tolower (cur_action );
885
+ res = qemu_strtoul (p + 1 , & p , 16 , & tmp );
886
+ if (res ) {
887
+ goto out ;
888
+ }
889
+ signal = gdb_signal_to_target (tmp );
890
+ } else if (cur_action != 'c' && cur_action != 's' ) {
891
+ /* unknown/invalid/unsupported command */
892
+ res = - ENOTSUP ;
893
+ goto out ;
894
+ }
895
+ /* thread specification. special values: (none), -1 = all; 0 = any */
896
+ if ((p [0 ] == ':' && p [1 ] == '-' && p [2 ] == '1' ) || (p [0 ] != ':' )) {
897
+ if (* p == ':' ) {
898
+ p += 3 ;
899
+ }
900
+ for (idx = 0 ; idx < max_cpus ; idx ++ ) {
901
+ if (newstates [idx ] == 1 ) {
902
+ newstates [idx ] = cur_action ;
903
+ }
904
+ }
905
+ } else if (* p == ':' ) {
906
+ p ++ ;
907
+ res = qemu_strtoul (p , & p , 16 , & tmp );
908
+ if (res ) {
909
+ goto out ;
910
+ }
911
+ idx = tmp ;
912
+ /* 0 means any thread, so we pick the first valid CPU */
913
+ if (!idx ) {
914
+ idx = cpu_index (first_cpu );
915
+ }
916
+
917
+ /*
918
+ * If we are in user mode, the thread specified is actually a
919
+ * thread id, and not an index. We need to find the actual
920
+ * CPU first, and only then we can use its index.
921
+ */
922
+ cpu = find_cpu (idx );
923
+ /* invalid CPU/thread specified */
924
+ if (!idx || !cpu ) {
925
+ res = - EINVAL ;
926
+ goto out ;
927
+ }
928
+ /* only use if no previous match occourred */
929
+ if (newstates [cpu -> cpu_index ] == 1 ) {
930
+ newstates [cpu -> cpu_index ] = cur_action ;
931
+ }
932
+ }
933
+ }
934
+ s -> signal = signal ;
935
+ gdb_continue_partial (s , newstates );
936
+
937
+ out :
938
+ g_free (newstates );
939
+
940
+ return res ;
941
+ }
942
+
788
943
static int gdb_handle_packet (GDBState * s , const char * line_buf )
789
944
{
790
945
CPUState * cpu ;
@@ -830,60 +985,20 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
830
985
return RS_IDLE ;
831
986
case 'v' :
832
987
if (strncmp (p , "Cont" , 4 ) == 0 ) {
833
- int res_signal , res_thread ;
834
-
835
988
p += 4 ;
836
989
if (* p == '?' ) {
837
990
put_packet (s , "vCont;c;C;s;S" );
838
991
break ;
839
992
}
840
- res = 0 ;
841
- res_signal = 0 ;
842
- res_thread = 0 ;
843
- while (* p ) {
844
- int action , signal ;
845
-
846
- if (* p ++ != ';' ) {
847
- res = 0 ;
848
- break ;
849
- }
850
- action = * p ++ ;
851
- signal = 0 ;
852
- if (action == 'C' || action == 'S' ) {
853
- signal = gdb_signal_to_target (strtoul (p , (char * * )& p , 16 ));
854
- if (signal == -1 ) {
855
- signal = 0 ;
856
- }
857
- } else if (action != 'c' && action != 's' ) {
858
- res = 0 ;
859
- break ;
860
- }
861
- thread = 0 ;
862
- if (* p == ':' ) {
863
- thread = strtoull (p + 1 , (char * * )& p , 16 );
864
- }
865
- action = tolower (action );
866
- if (res == 0 || (res == 'c' && action == 's' )) {
867
- res = action ;
868
- res_signal = signal ;
869
- res_thread = thread ;
870
- }
871
- }
993
+
994
+ res = gdb_handle_vcont (s , p );
995
+
872
996
if (res ) {
873
- if (res_thread != -1 && res_thread != 0 ) {
874
- cpu = find_cpu (res_thread );
875
- if (cpu == NULL ) {
876
- put_packet (s , "E22" );
877
- break ;
878
- }
879
- s -> c_cpu = cpu ;
880
- }
881
- if (res == 's' ) {
882
- cpu_single_step (s -> c_cpu , sstep_flags );
997
+ if ((res == - EINVAL ) || (res == - ERANGE )) {
998
+ put_packet (s , "E22" );
999
+ break ;
883
1000
}
884
- s -> signal = res_signal ;
885
- gdb_continue (s );
886
- return RS_IDLE ;
1001
+ goto unknown_command ;
887
1002
}
888
1003
break ;
889
1004
} else {
0 commit comments