-
Notifications
You must be signed in to change notification settings - Fork 546
/
remote.c
16598 lines (13626 loc) · 477 KB
/
remote.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Remote target communications for serial-line targets in custom GDB protocol
Copyright (C) 1988-2024 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* See the GDB User Guide for details of the GDB remote protocol. */
#include <ctype.h>
#include <fcntl.h>
#include "exceptions.h"
#include "inferior.h"
#include "infrun.h"
#include "bfd.h"
#include "symfile.h"
#include "target.h"
#include "process-stratum-target.h"
#include "cli/cli-cmds.h"
#include "objfiles.h"
#include "gdbthread.h"
#include "remote.h"
#include "remote-notif.h"
#include "regcache.h"
#include "value.h"
#include "observable.h"
#include "solib.h"
#include "cli/cli-decode.h"
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/rsp-low.h"
#include "disasm.h"
#include "location.h"
#include "gdbsupport/gdb_sys_time.h"
#include "gdbsupport/event-loop.h"
#include "event-top.h"
#include "inf-loop.h"
#include <signal.h>
#include "serial.h"
#include "gdbcore.h"
#include "remote-fileio.h"
#include "gdbsupport/fileio.h"
#include <sys/stat.h>
#include "xml-support.h"
#include "memory-map.h"
#include "tracepoint.h"
#include "ax.h"
#include "ax-gdb.h"
#include "gdbsupport/agent.h"
#include "btrace.h"
#include "record-btrace.h"
#include "gdbsupport/scoped_restore.h"
#include "gdbsupport/environ.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/search.h"
#include <algorithm>
#include <iterator>
#include <unordered_map>
#include "async-event.h"
#include "gdbsupport/selftest.h"
#include "cli/cli-style.h"
/* The remote target. */
static const char remote_doc[] = N_("\
Use a remote computer via a serial line, using a gdb-specific protocol.\n\
Specify the serial device it is connected to\n\
(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
/* See remote.h */
bool remote_debug = false;
#define OPAQUETHREADBYTES 8
/* a 64 bit opaque identifier */
typedef unsigned char threadref[OPAQUETHREADBYTES];
struct gdb_ext_thread_info;
struct threads_listing_context;
typedef int (*rmt_thread_action) (threadref *ref, void *context);
struct protocol_feature;
struct packet_reg;
struct stop_reply;
typedef std::unique_ptr<stop_reply> stop_reply_up;
/* Generic configuration support for packets the stub optionally
supports. Allows the user to specify the use of the packet as well
as allowing GDB to auto-detect support in the remote stub. */
enum packet_support
{
PACKET_SUPPORT_UNKNOWN = 0,
PACKET_ENABLE,
PACKET_DISABLE
};
/* Convert the packet support auto_boolean to a name used for gdb printing. */
static const char *
get_packet_support_name (auto_boolean support)
{
switch (support)
{
case AUTO_BOOLEAN_TRUE:
return "on";
case AUTO_BOOLEAN_FALSE:
return "off";
case AUTO_BOOLEAN_AUTO:
return "auto";
default:
gdb_assert_not_reached ("invalid var_auto_boolean");
}
}
/* Convert the target type (future remote target or currently connected target)
to a name used for gdb printing. */
static const char *
get_target_type_name (bool target_connected)
{
if (target_connected)
return _("on the current remote target");
else
return _("on future remote targets");
}
/* Analyze a packet's return value and update the packet config
accordingly. */
enum packet_status
{
PACKET_ERROR,
PACKET_OK,
PACKET_UNKNOWN
};
/* Keeps packet's return value. If packet's return value is PACKET_ERROR,
err_msg contains an error message string from E.string or the number
stored as a string from E.num. */
class packet_result
{
private:
/* Private ctors for internal use. Clients should use the public
factory static methods instead. */
/* Construct a PACKET_ERROR packet_result. */
packet_result (const char *err_msg, bool textual_err_msg)
: m_status (PACKET_ERROR),
m_err_msg (err_msg),
m_textual_err_msg (textual_err_msg)
{}
/* Construct an PACKET_OK/PACKET_UNKNOWN packet_result. */
explicit packet_result (enum packet_status status)
: m_status (status)
{
gdb_assert (status != PACKET_ERROR);
}
public:
enum packet_status status () const
{
return this->m_status;
}
const char *err_msg () const
{
gdb_assert (this->m_status == PACKET_ERROR);
return this->m_err_msg.c_str ();
}
bool textual_err_msg () const
{
gdb_assert (this->m_status == PACKET_ERROR);
return this->m_textual_err_msg;
}
static packet_result make_numeric_error (const char *err_msg)
{
return packet_result (err_msg, false);
}
static packet_result make_textual_error (const char *err_msg)
{
return packet_result (err_msg, true);
}
static packet_result make_ok ()
{
return packet_result (PACKET_OK);
}
static packet_result make_unknown ()
{
return packet_result (PACKET_UNKNOWN);
}
private:
enum packet_status m_status;
std::string m_err_msg;
/* True if we have a textual error message, from an "E.MESSAGE"
response. */
bool m_textual_err_msg = false;
};
/* Enumeration of packets for a remote target. */
enum {
PACKET_vCont = 0,
PACKET_X,
PACKET_qSymbol,
PACKET_P,
PACKET_p,
PACKET_Z0,
PACKET_Z1,
PACKET_Z2,
PACKET_Z3,
PACKET_Z4,
PACKET_vFile_setfs,
PACKET_vFile_open,
PACKET_vFile_pread,
PACKET_vFile_pwrite,
PACKET_vFile_close,
PACKET_vFile_unlink,
PACKET_vFile_readlink,
PACKET_vFile_fstat,
PACKET_vFile_stat,
PACKET_qXfer_auxv,
PACKET_qXfer_features,
PACKET_qXfer_exec_file,
PACKET_qXfer_libraries,
PACKET_qXfer_libraries_svr4,
PACKET_qXfer_memory_map,
PACKET_qXfer_osdata,
PACKET_qXfer_threads,
PACKET_qXfer_statictrace_read,
PACKET_qXfer_traceframe_info,
PACKET_qXfer_uib,
PACKET_qGetTIBAddr,
PACKET_qGetTLSAddr,
PACKET_qSupported,
PACKET_qTStatus,
PACKET_QPassSignals,
PACKET_QCatchSyscalls,
PACKET_QProgramSignals,
PACKET_QSetWorkingDir,
PACKET_QStartupWithShell,
PACKET_QEnvironmentHexEncoded,
PACKET_QEnvironmentReset,
PACKET_QEnvironmentUnset,
PACKET_qCRC,
PACKET_qSearch_memory,
PACKET_vAttach,
PACKET_vRun,
PACKET_QStartNoAckMode,
PACKET_vKill,
PACKET_qXfer_siginfo_read,
PACKET_qXfer_siginfo_write,
PACKET_qAttached,
/* Support for conditional tracepoints. */
PACKET_ConditionalTracepoints,
/* Support for target-side breakpoint conditions. */
PACKET_ConditionalBreakpoints,
/* Support for target-side breakpoint commands. */
PACKET_BreakpointCommands,
/* Support for fast tracepoints. */
PACKET_FastTracepoints,
/* Support for static tracepoints. */
PACKET_StaticTracepoints,
/* Support for installing tracepoints while a trace experiment is
running. */
PACKET_InstallInTrace,
PACKET_bc,
PACKET_bs,
PACKET_TracepointSource,
PACKET_QAllow,
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
PACKET_QTBuffer_size,
PACKET_Qbtrace_off,
PACKET_Qbtrace_bts,
PACKET_Qbtrace_pt,
PACKET_qXfer_btrace,
/* Support for the QNonStop packet. */
PACKET_QNonStop,
/* Support for the QThreadEvents packet. */
PACKET_QThreadEvents,
/* Support for the QThreadOptions packet. */
PACKET_QThreadOptions,
/* Support for multi-process extensions. */
PACKET_multiprocess_feature,
/* Support for enabling and disabling tracepoints while a trace
experiment is running. */
PACKET_EnableDisableTracepoints_feature,
/* Support for collecting strings using the tracenz bytecode. */
PACKET_tracenz_feature,
/* Support for continuing to run a trace experiment while GDB is
disconnected. */
PACKET_DisconnectedTracing_feature,
/* Support for qXfer:libraries-svr4:read with a non-empty annex. */
PACKET_augmented_libraries_svr4_read_feature,
/* Support for the qXfer:btrace-conf:read packet. */
PACKET_qXfer_btrace_conf,
/* Support for the Qbtrace-conf:bts:size packet. */
PACKET_Qbtrace_conf_bts_size,
/* Support for swbreak+ feature. */
PACKET_swbreak_feature,
/* Support for hwbreak+ feature. */
PACKET_hwbreak_feature,
/* Support for fork events. */
PACKET_fork_event_feature,
/* Support for vfork events. */
PACKET_vfork_event_feature,
/* Support for the Qbtrace-conf:pt:size packet. */
PACKET_Qbtrace_conf_pt_size,
/* Support for the Qbtrace-conf:pt:ptwrite packet. */
PACKET_Qbtrace_conf_pt_ptwrite,
/* Support for the Qbtrace-conf:pt:event-tracing packet. */
PACKET_Qbtrace_conf_pt_event_tracing,
/* Support for exec events. */
PACKET_exec_event_feature,
/* Support for query supported vCont actions. */
PACKET_vContSupported,
/* Support remote CTRL-C. */
PACKET_vCtrlC,
/* Support TARGET_WAITKIND_NO_RESUMED. */
PACKET_no_resumed,
/* Support for memory tagging, allocation tag fetch/store
packets and the tag violation stop replies. */
PACKET_memory_tagging_feature,
/* Support for the qIsAddressTagged packet. */
PACKET_qIsAddressTagged,
/* Support for accepting error message in a E.errtext format.
This allows every remote packet to return E.errtext.
This feature only exists to fix a backwards compatibility issue
with the qRcmd and m packets. Historically, these two packets didn't
support E.errtext style errors, but when this feature is on
these two packets can receive E.errtext style errors.
All new packets should be written to always accept E.errtext style
errors, and so they should not need to check for this feature. */
PACKET_accept_error_message,
PACKET_MAX
};
struct threads_listing_context;
/* Stub vCont actions support.
Each field is a boolean flag indicating whether the stub reports
support for the corresponding action. */
struct vCont_action_support
{
/* vCont;t */
bool t = false;
/* vCont;r */
bool r = false;
/* vCont;s */
bool s = false;
/* vCont;S */
bool S = false;
};
/* About this many threadids fit in a packet. */
#define MAXTHREADLISTRESULTS 32
/* Data for the vFile:pread readahead cache. */
struct readahead_cache
{
/* Invalidate the readahead cache. */
void invalidate ();
/* Invalidate the readahead cache if it is holding data for FD. */
void invalidate_fd (int fd);
/* Serve pread from the readahead cache. Returns number of bytes
read, or 0 if the request can't be served from the cache. */
int pread (int fd, gdb_byte *read_buf, size_t len, ULONGEST offset);
/* The file descriptor for the file that is being cached. -1 if the
cache is invalid. */
int fd = -1;
/* The offset into the file that the cache buffer corresponds
to. */
ULONGEST offset = 0;
/* The buffer holding the cache contents. */
gdb::byte_vector buf;
/* Cache hit and miss counters. */
ULONGEST hit_count = 0;
ULONGEST miss_count = 0;
};
/* Description of the remote protocol for a given architecture. */
struct packet_reg
{
long offset; /* Offset into G packet. */
long regnum; /* GDB's internal register number. */
LONGEST pnum; /* Remote protocol register number. */
int in_g_packet; /* Always part of G packet. */
/* long size in bytes; == register_size (arch, regnum);
at present. */
/* char *name; == gdbarch_register_name (arch, regnum);
at present. */
};
struct remote_arch_state
{
explicit remote_arch_state (struct gdbarch *gdbarch);
/* Description of the remote protocol registers. */
long sizeof_g_packet;
/* Description of the remote protocol registers indexed by REGNUM
(making an array gdbarch_num_regs in size). */
std::unique_ptr<packet_reg[]> regs;
/* This is the size (in chars) of the first response to the ``g''
packet. It is used as a heuristic when determining the maximum
size of memory-read and memory-write packets. A target will
typically only reserve a buffer large enough to hold the ``g''
packet. The size does not include packet overhead (headers and
trailers). */
long actual_register_packet_size;
/* This is the maximum size (in chars) of a non read/write packet.
It is also used as a cap on the size of read/write packets. */
long remote_packet_size;
};
/* Description of the remote protocol state for the currently
connected target. This is per-target state, and independent of the
selected architecture. */
class remote_state
{
public:
remote_state ();
~remote_state ();
/* Get the remote arch state for GDBARCH. */
struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
void create_async_event_handler ()
{
gdb_assert (m_async_event_handler_token == nullptr);
m_async_event_handler_token
= ::create_async_event_handler ([] (gdb_client_data data)
{
inferior_event_handler (INF_REG_EVENT);
},
nullptr, "remote");
}
void mark_async_event_handler ()
{
gdb_assert (this->is_async_p ());
::mark_async_event_handler (m_async_event_handler_token);
}
void clear_async_event_handler ()
{ ::clear_async_event_handler (m_async_event_handler_token); }
bool async_event_handler_marked () const
{ return ::async_event_handler_marked (m_async_event_handler_token); }
void delete_async_event_handler ()
{
if (m_async_event_handler_token != nullptr)
::delete_async_event_handler (&m_async_event_handler_token);
}
bool is_async_p () const
{
/* We're async whenever the serial device is. */
gdb_assert (this->remote_desc != nullptr);
return serial_is_async_p (this->remote_desc);
}
bool can_async_p () const
{
/* We can async whenever the serial device can. */
gdb_assert (this->remote_desc != nullptr);
return serial_can_async_p (this->remote_desc);
}
public: /* data */
/* A buffer to use for incoming packets, and its current size. The
buffer is grown dynamically for larger incoming packets.
Outgoing packets may also be constructed in this buffer.
The size of the buffer is always at least REMOTE_PACKET_SIZE;
REMOTE_PACKET_SIZE should be used to limit the length of outgoing
packets. */
gdb::char_vector buf;
/* True if we're going through initial connection setup (finding out
about the remote side's threads, relocating symbols, etc.). */
bool starting_up = false;
/* If we negotiated packet size explicitly (and thus can bypass
heuristics for the largest packet size that will not overflow
a buffer in the stub), this will be set to that packet size.
Otherwise zero, meaning to use the guessed size. */
long explicit_packet_size = 0;
/* True, if in no ack mode. That is, neither GDB nor the stub will
expect acks from each other. The connection is assumed to be
reliable. */
bool noack_mode = false;
/* True if we're connected in extended remote mode. */
bool extended = false;
/* True if we resumed the target and we're waiting for the target to
stop. In the mean time, we can't start another command/query.
The remote server wouldn't be ready to process it, so we'd
timeout waiting for a reply that would never come and eventually
we'd close the connection. This can happen in asynchronous mode
because we allow GDB commands while the target is running. */
bool waiting_for_stop_reply = false;
/* The status of the stub support for the various vCont actions. */
vCont_action_support supports_vCont;
/* True if the user has pressed Ctrl-C, but the target hasn't
responded to that. */
bool ctrlc_pending_p = false;
/* True if we saw a Ctrl-C while reading or writing from/to the
remote descriptor. At that point it is not safe to send a remote
interrupt packet, so we instead remember we saw the Ctrl-C and
process it once we're done with sending/receiving the current
packet, which should be shortly. If however that takes too long,
and the user presses Ctrl-C again, we offer to disconnect. */
bool got_ctrlc_during_io = false;
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
remote_open knows that we don't have a file open when the program
starts. */
struct serial *remote_desc = nullptr;
/* These are the threads which we last sent to the remote system. The
TID member will be -1 for all or -2 for not sent yet. */
ptid_t general_thread = null_ptid;
ptid_t continue_thread = null_ptid;
/* This is the traceframe which we last selected on the remote system.
It will be -1 if no traceframe is selected. */
int remote_traceframe_number = -1;
char *last_pass_packet = nullptr;
/* The last QProgramSignals packet sent to the target. We bypass
sending a new program signals list down to the target if the new
packet is exactly the same as the last we sent. IOW, we only let
the target know about program signals list changes. */
char *last_program_signals_packet = nullptr;
/* Similarly, the last QThreadEvents state we sent to the
target. */
bool last_thread_events = false;
gdb_signal last_sent_signal = GDB_SIGNAL_0;
bool last_sent_step = false;
/* The execution direction of the last resume we got. */
exec_direction_kind last_resume_exec_dir = EXEC_FORWARD;
char *finished_object = nullptr;
char *finished_annex = nullptr;
ULONGEST finished_offset = 0;
/* Should we try the 'ThreadInfo' query packet?
This variable (NOT available to the user: auto-detect only!)
determines whether GDB will use the new, simpler "ThreadInfo"
query or the older, more complex syntax for thread queries.
This is an auto-detect variable (set to true at each connect,
and set to false when the target fails to recognize it). */
bool use_threadinfo_query = false;
bool use_threadextra_query = false;
threadref echo_nextthread {};
threadref nextthread {};
threadref resultthreadlist[MAXTHREADLISTRESULTS] {};
/* The state of remote notification. */
struct remote_notif_state *notif_state = nullptr;
/* The branch trace configuration. */
struct btrace_config btrace_config {};
/* The argument to the last "vFile:setfs:" packet we sent, used
to avoid sending repeated unnecessary "vFile:setfs:" packets.
Initialized to -1 to indicate that no "vFile:setfs:" packet
has yet been sent. */
int fs_pid = -1;
/* A readahead cache for vFile:pread. Often, reading a binary
involves a sequence of small reads. E.g., when parsing an ELF
file. A readahead cache helps mostly the case of remote
debugging on a connection with higher latency, due to the
request/reply nature of the RSP. We only cache data for a single
file descriptor at a time. */
struct readahead_cache readahead_cache;
/* The list of already fetched and acknowledged stop events. This
queue is used for notification Stop, and other notifications
don't need queue for their events, because the notification
events of Stop can't be consumed immediately, so that events
should be queued first, and be consumed by remote_wait_{ns,as}
one per time. Other notifications can consume their events
immediately, so queue is not needed for them. */
std::vector<stop_reply_up> stop_reply_queue;
/* FIXME: cagney/1999-09-23: Even though getpkt was called with
``forever'' still use the normal timeout mechanism. This is
currently used by the ASYNC code to guarantee that target reads
during the initial connect always time-out. Once getpkt has been
modified to return a timeout indication and, in turn
remote_wait()/wait_for_inferior() have gained a timeout parameter
this can go away. */
bool wait_forever_enabled_p = true;
/* The set of thread options the target reported it supports, via
qSupported. */
gdb_thread_options supported_thread_options = 0;
/* Contains the regnums of the expedited registers in the last stop
reply packet. */
std::set<int> last_seen_expedited_registers;
private:
/* Asynchronous signal handle registered as event loop source for
when we have pending events ready to be passed to the core. */
async_event_handler *m_async_event_handler_token = nullptr;
/* Mapping of remote protocol data for each gdbarch. Usually there
is only one entry here, though we may see more with stubs that
support multi-process. */
std::unordered_map<struct gdbarch *, remote_arch_state>
m_arch_states;
};
static const target_info remote_target_info = {
"remote",
N_("Remote target using gdb-specific protocol"),
remote_doc
};
/* Description of a remote packet. */
struct packet_description
{
/* Name of the packet used for gdb output. */
const char *name;
/* Title of the packet, used by the set/show remote name-packet
commands to identify the individual packages and gdb output. */
const char *title;
};
/* Configuration of a remote packet. */
struct packet_config
{
/* If auto, GDB auto-detects support for this packet or feature,
either through qSupported, or by trying the packet and looking
at the response. If true, GDB assumes the target supports this
packet. If false, the packet is disabled. Configs that don't
have an associated command always have this set to auto. */
enum auto_boolean detect;
/* Does the target support this packet? */
enum packet_support support;
};
/* User configurable variables for the number of characters in a
memory read/write packet. MIN (rsa->remote_packet_size,
rsa->sizeof_g_packet) is the default. Some targets need smaller
values (fifo overruns, et.al.) and some users need larger values
(speed up transfers). The variables ``preferred_*'' (the user
request), ``current_*'' (what was actually set) and ``forced_*''
(Positive - a soft limit, negative - a hard limit). */
struct memory_packet_config
{
const char *name;
long size;
int fixed_p;
};
/* These global variables contain the default configuration for every new
remote_feature object. */
static memory_packet_config memory_read_packet_config =
{
"memory-read-packet-size",
};
static memory_packet_config memory_write_packet_config =
{
"memory-write-packet-size",
};
/* This global array contains packet descriptions (name and title). */
static packet_description packets_descriptions[PACKET_MAX];
/* This global array contains the default configuration for every new
per-remote target array. */
static packet_config remote_protocol_packets[PACKET_MAX];
/* Description of a remote target's features. It stores the configuration
and provides functions to determine supported features of the target. */
struct remote_features
{
remote_features ()
{
m_memory_read_packet_config = memory_read_packet_config;
m_memory_write_packet_config = memory_write_packet_config;
std::copy (std::begin (remote_protocol_packets),
std::end (remote_protocol_packets),
std::begin (m_protocol_packets));
}
~remote_features () = default;
DISABLE_COPY_AND_ASSIGN (remote_features);
/* Returns whether a given packet defined by its enum value is supported. */
enum packet_support packet_support (int) const;
/* Returns the packet's corresponding "set remote foo-packet" command
state. See struct packet_config for more details. */
enum auto_boolean packet_set_cmd_state (int packet) const
{ return m_protocol_packets[packet].detect; }
/* Returns true if the multi-process extensions are in effect. */
int remote_multi_process_p () const
{ return packet_support (PACKET_multiprocess_feature) == PACKET_ENABLE; }
/* Returns true if fork events are supported. */
int remote_fork_event_p () const
{ return packet_support (PACKET_fork_event_feature) == PACKET_ENABLE; }
/* Returns true if vfork events are supported. */
int remote_vfork_event_p () const
{ return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE; }
/* Returns true if exec events are supported. */
int remote_exec_event_p () const
{ return packet_support (PACKET_exec_event_feature) == PACKET_ENABLE; }
/* Returns true if memory tagging is supported, false otherwise. */
bool remote_memory_tagging_p () const
{ return packet_support (PACKET_memory_tagging_feature) == PACKET_ENABLE; }
/* Reset all packets back to "unknown support". Called when opening a
new connection to a remote target. */
void reset_all_packet_configs_support ();
/* Check result value in BUF for packet WHICH_PACKET and update the packet's
support configuration accordingly. */
packet_result packet_ok (const char *buf, const int which_packet);
packet_result packet_ok (const gdb::char_vector &buf, const int which_packet);
/* Configuration of a remote target's memory read packet. */
memory_packet_config m_memory_read_packet_config;
/* Configuration of a remote target's memory write packet. */
memory_packet_config m_memory_write_packet_config;
/* The per-remote target array which stores a remote's packet
configurations. */
packet_config m_protocol_packets[PACKET_MAX];
};
class remote_target : public process_stratum_target
{
public:
remote_target () = default;
~remote_target () override;
const target_info &info () const override
{ return remote_target_info; }
const char *connection_string () override;
thread_control_capabilities get_thread_control_capabilities () override
{ return tc_schedlock; }
/* Open a remote connection. */
static void open (const char *, int);
void close () override;
void detach (inferior *, int) override;
void disconnect (const char *, int) override;
void commit_requested_thread_options ();
void commit_resumed () override;
void resume (ptid_t, int, enum gdb_signal) override;
ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
bool has_pending_events () override;
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
void prepare_to_store (struct regcache *) override;
int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override;
int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
enum remove_bp_reason) override;
bool stopped_by_sw_breakpoint () override;
bool supports_stopped_by_sw_breakpoint () override;
bool stopped_by_hw_breakpoint () override;
bool supports_stopped_by_hw_breakpoint () override;
bool stopped_by_watchpoint () override;
bool stopped_data_address (CORE_ADDR *) override;
bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
int can_use_hw_breakpoint (enum bptype, int, int) override;
int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
struct expression *) override;
void kill () override;
void load (const char *, int) override;
void mourn_inferior () override;
void pass_signals (gdb::array_view<const unsigned char>) override;
int set_syscall_catchpoint (int, bool, int,
gdb::array_view<const int>) override;
void program_signals (gdb::array_view<const unsigned char>) override;
bool thread_alive (ptid_t ptid) override;
const char *thread_name (struct thread_info *) override;
void update_thread_list () override;
std::string pid_to_str (ptid_t) override;
const char *extra_thread_info (struct thread_info *) override;
ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
int handle_len,
inferior *inf) override;
gdb::array_view<const gdb_byte> thread_info_to_thread_handle (struct thread_info *tp)
override;
void stop (ptid_t) override;
void interrupt () override;
void pass_ctrlc () override;
enum target_xfer_status xfer_partial (enum target_object object,
const char *annex,
gdb_byte *readbuf,
const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len) override;
ULONGEST get_memory_xfer_limit () override;
void rcmd (const char *command, struct ui_file *output) override;
const char *pid_to_exec_file (int pid) override;
void log_command (const char *cmd) override
{
serial_log_command (this, cmd);
}
CORE_ADDR get_thread_local_address (ptid_t ptid,
CORE_ADDR load_module_addr,
CORE_ADDR offset) override;
bool can_execute_reverse () override;
std::vector<mem_region> memory_map () override;
void flash_erase (ULONGEST address, LONGEST length) override;
void flash_done () override;
const struct target_desc *read_description () override;
int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
const gdb_byte *pattern, ULONGEST pattern_len,
CORE_ADDR *found_addrp) override;
bool can_async_p () override;
bool is_async_p () override;
void async (bool) override;
int async_wait_fd () override;
void thread_events (bool) override;
bool supports_set_thread_options (gdb_thread_options) override;
int can_do_single_step () override;
void terminal_inferior () override;