Rizin
unix-like reverse engineering framework and cli tools
common.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2019 Srimanta Barua <srimanta.barua1@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* Common functions for both client and server. Not part of the libgdbr interface */
5 
6 #include "libgdbr.h"
7 #include "gdbr_common.h"
8 #include "packet.h"
9 #include "utils.h"
10 #include "rz_util/rz_str.h"
11 
13  char *tok = NULL;
14  // Catch no data received
15  if (!*g->data) {
16  return -1;
17  }
18  // TODO handle the message correct and set all infos like packetsize, thread stuff and features
19  tok = strtok(g->data, ";");
20  while (tok) {
21  if (rz_str_startswith(tok, "PacketSize=")) {
22  // Largest packet size we support is 2048
23  g->stub_features.pkt_sz = RZ_MIN(strtoul(tok + strlen("PacketSize="), NULL, 16), 2048);
24  // Shouldn't be smaller than 64 (Erroneous 0 etc.)
25  g->stub_features.pkt_sz = RZ_MAX(g->stub_features.pkt_sz, 64);
26  } else if (rz_str_startswith(tok, "qXfer:")) {
27  if (!tok[6]) {
28  tok = strtok(NULL, ";");
29  continue;
30  }
31  char *p = tok + 6;
32  if (rz_str_startswith(p, "btrace:read")) {
33  g->stub_features.qXfer_btrace_read = (p[strlen("btrace:read")] == '+');
34  } else if (rz_str_startswith(p, "btrace-conf:read")) {
35  g->stub_features.qXfer_btrace_conf_read = (p[strlen("btrace-conf:read")] == '+');
36  } else if (rz_str_startswith(p, "spu:read")) {
37  g->stub_features.qXfer_spu_read = (p[strlen("spu:read")] == '+');
38  } else if (rz_str_startswith(p, "spu:write")) {
39  g->stub_features.qXfer_spu_write = (p[strlen("spu:write")] == '+');
40  } else if (rz_str_startswith(p, "libraries:read")) {
41  g->stub_features.qXfer_libraries_read = (p[strlen("libraries:read")] == '+');
42  } else if (rz_str_startswith(p, "libraries-svr4:read")) {
43  g->stub_features.qXfer_libraries_svr4_read = (p[strlen("libraries-svr4:read")] == '+');
44  } else if (rz_str_startswith(p, "memory-map:read")) {
45  g->stub_features.qXfer_memory_map_read = (p[strlen("memory-map:read")] == '+');
46  } else if (rz_str_startswith(p, "auxv:read")) {
47  g->stub_features.qXfer_auxv_read = (p[strlen("auxv:read")] == '+');
48  } else if (rz_str_startswith(p, "exec-file:read")) {
49  g->stub_features.qXfer_exec_file_read = (p[strlen("exec-file:read")] == '+');
50  } else if (rz_str_startswith(p, "features:read")) {
51  g->stub_features.qXfer_features_read = (p[strlen("features:read")] == '+');
52  } else if (rz_str_startswith(p, "sdata:read")) {
53  g->stub_features.qXfer_sdata_read = (p[strlen("sdata:read")] == '+');
54  } else if (rz_str_startswith(p, "siginfo:read")) {
55  g->stub_features.qXfer_siginfo_read = (p[strlen("siginfo:read")] == '+');
56  } else if (rz_str_startswith(p, "siginfo:write")) {
57  g->stub_features.qXfer_siginfo_write = (p[strlen("siginfo:write")] == '+');
58  } else if (rz_str_startswith(p, "threads:read")) {
59  g->stub_features.qXfer_threads_read = (p[strlen("threads:read")] == '+');
60  } else if (rz_str_startswith(p, "traceframe-info:read")) {
61  g->stub_features.qXfer_traceframe_info_read = (p[strlen("traceframe-info:read")] == '+');
62  } else if (rz_str_startswith(p, "uib:read")) {
63  g->stub_features.qXfer_uib_read = (p[strlen("uib:read")] == '+');
64  } else if (rz_str_startswith(p, "fdpic:read")) {
65  g->stub_features.qXfer_fdpic_read = (p[strlen("fdpic:read")] == '+');
66  } else if (rz_str_startswith(p, "osdata:read")) {
67  g->stub_features.qXfer_osdata_read = (p[strlen("osdata:read")] == '+');
68  }
69  } else if (tok[0] == 'Q') {
70  if (rz_str_startswith(tok, "Qbtrace")) {
71  if (!tok[strlen("Qbtrace")]) {
72  tok = strtok(NULL, ";");
73  continue;
74  }
75  char *p = tok + 7;
76  if (rz_str_startswith(p, ":off")) {
77  g->stub_features.Qbtrace_off = (p[4] == '+');
78  } else if (rz_str_startswith(p, ":bts")) {
79  g->stub_features.Qbtrace_bts = (p[4] == '+');
80  } else if (rz_str_startswith(p, ":pt")) {
81  g->stub_features.Qbtrace_pt = (p[3] == '+');
82  } else if (rz_str_startswith(p, "-conf:bts:size")) {
83  g->stub_features.Qbtrace_conf_bts_size = (p[strlen("-conf:bts:size")] == '+');
84  } else if (rz_str_startswith(p, ":-conf:pt:size")) {
85  g->stub_features.Qbtrace_conf_pt_size = (p[strlen("-conf:pt:size")] == '+');
86  }
87  } else if (rz_str_startswith(tok, "QNonStop")) {
88  g->stub_features.QNonStop = (tok[strlen("QNonStop")] == '+');
89  } else if (rz_str_startswith(tok, "QCatchSyscalls")) {
90  g->stub_features.QCatchSyscalls = (tok[strlen("QCatchSyscalls")] == '+');
91  } else if (rz_str_startswith(tok, "QPassSignals")) {
92  g->stub_features.QPassSignals = (tok[strlen("QPassSignals")] == '+');
93  } else if (rz_str_startswith(tok, "QStartNoAckMode")) {
94  g->stub_features.QStartNoAckMode = (tok[strlen("QStartNoAckMode")] == '+');
95  } else if (rz_str_startswith(tok, "QAgent")) {
96  g->stub_features.QAgent = (tok[strlen("QAgent")] == '+');
97  } else if (rz_str_startswith(tok, "QAllow")) {
98  g->stub_features.QAllow = (tok[strlen("QAllow")] == '+');
99  } else if (rz_str_startswith(tok, "QDisableRandomization")) {
100  g->stub_features.QDisableRandomization = (tok[strlen("QDisableRandomization")] == '+');
101  } else if (rz_str_startswith(tok, "QTBuffer:size")) {
102  g->stub_features.QTBuffer_size = (tok[strlen("QTBuffer:size")] == '+');
103  } else if (rz_str_startswith(tok, "QThreadEvents")) {
104  g->stub_features.QThreadEvents = (tok[strlen("QThreadEvents")] == '+');
105  } else if (rz_str_startswith(tok, "QThreadSuffixSupported")) {
106  g->remote_type = GDB_REMOTE_TYPE_LLDB;
107  g->stub_features.lldb.QThreadSuffixSupported = (tok[strlen("QThreadSuffixSupported")] == '+');
108  } else if (rz_str_startswith(tok, "QListThreadsInStopReply")) {
109  g->remote_type = GDB_REMOTE_TYPE_LLDB;
110  g->stub_features.lldb.QListThreadsInStopReply = (tok[strlen("QListThreadsInStopReply")] == '+');
111  }
112  } else if (rz_str_startswith(tok, "multiprocess")) {
113  g->stub_features.multiprocess = (tok[strlen("multiprocess")] == '+');
114  } else if (rz_str_startswith(tok, "qEcho")) {
115  g->remote_type = GDB_REMOTE_TYPE_LLDB;
116  g->stub_features.lldb.qEcho = (tok[strlen("qEcho")] == '+');
117  } else if (rz_str_startswith(tok, "ReverseStep")) {
118  g->stub_features.ReverseStep = (tok[strlen("ReverseStep")] == '+');
119  } else if (rz_str_startswith(tok, "ReverseContinue")) {
120  g->stub_features.ReverseContinue = (tok[strlen("ReverseContinue")] == '+');
121  }
122  // TODO
123  tok = strtok(NULL, ";");
124  }
125  return send_ack(g);
126 }
127 
128 // SENDING MESSAGES/ACK
129 
131  if (g) {
132  if (g->no_ack) {
133  return 0;
134  }
135  if (rz_socket_write(g->sock, "+", 1) < 0) {
136  return -1;
137  }
138  if (g->server_debug) {
139  eprintf("[sent ack]\n");
140  }
141  return 0;
142  }
143  return -1;
144 }
145 
146 int send_msg(libgdbr_t *g, const char *msg) {
147  int ret;
148  if (!g || !msg) {
149  return -1;
150  }
151  ret = pack(g, msg);
152  if (ret < 0) {
153  return -1;
154  }
155  ret = send_packet(g);
156  g->send_len = ret;
157  return ret;
158 }
#define NULL
Definition: cris-opc.c:27
struct @667 g
void * p
Definition: libc.cpp:67
#define GDB_REMOTE_TYPE_LLDB
Definition: libgdbr.h:20
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
int send_packet(libgdbr_t *g)
sends a packet sends a packet to the established connection
Definition: packet.c:193
int pack(libgdbr_t *g, const char *msg)
Definition: packet.c:206
int send_msg(libgdbr_t *g, const char *msg)
Function sends a message to the remote gdb instance.
Definition: common.c:146
int handle_qSupported(libgdbr_t *g)
Definition: common.c:12
int send_ack(libgdbr_t *g)
Functions sends a single ack ('+')
Definition: common.c:130
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119