Skip to content

Commit 23926ed

Browse files
committed
gdb_packet: allow for external packet buffer
Allow supplying a packet buffer from an external source. This allows the GDB packet functions to be thread-safe, assuming the packet buffer comes from some form of thread-local storage. Guard this function with a macro to allow keeping the previous behavior. Signed-off-by: Sean Cross <[email protected]>
1 parent 4956ed6 commit 23926ed

File tree

1 file changed

+47
-33
lines changed

1 file changed

+47
-33
lines changed

src/gdb_packet.c

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,23 @@ typedef enum packet_state {
4141

4242
static bool noackmode = false;
4343

44+
#ifdef EXTERNAL_PACKET_BUFFER
45+
extern gdb_packet_s *gdb_full_packet_buffer(void);
46+
#else
4447
/* This has to be aligned so the remote protocol can re-use it without causing Problems */
4548
static gdb_packet_s BMD_ALIGN_DEF(8) packet_buffer;
4649

50+
static inline gdb_packet_s *gdb_full_packet_buffer(void)
51+
{
52+
return &packet_buffer;
53+
}
54+
4755
char *gdb_packet_buffer(void)
4856
{
4957
/* Return the static packet data buffer */
5058
return packet_buffer.data;
5159
}
60+
#endif /* EXTERNAL_PACKET_BUFFER */
5261

5362
/* https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html */
5463
void gdb_set_noackmode(bool enable)
@@ -167,18 +176,19 @@ gdb_packet_s *gdb_packet_receive(void)
167176
{
168177
packet_state_e state = PACKET_IDLE; /* State of the packet capture */
169178
uint8_t rx_checksum = 0;
179+
gdb_packet_s *packet = gdb_full_packet_buffer();
170180

171181
while (true) {
172182
const char rx_char = gdb_if_getchar();
173183

174184
switch (state) {
175185
case PACKET_IDLE:
176-
packet_buffer.data[0U] = rx_char;
186+
packet->data[0U] = rx_char;
177187
if (rx_char == GDB_PACKET_START) {
178188
/* Start of GDB packet */
179189
state = PACKET_GDB_CAPTURE;
180-
packet_buffer.size = 0;
181-
packet_buffer.notification = false;
190+
packet->size = 0;
191+
packet->notification = false;
182192
}
183193
#if CONFIG_BMDA == 0
184194
else if (rx_char == REMOTE_SOM) {
@@ -187,22 +197,22 @@ gdb_packet_s *gdb_packet_receive(void)
187197
* Let consume_remote_packet handle this
188198
* returns PACKET_IDLE or PACKET_GDB_CAPTURE if it detects the start of a GDB packet
189199
*/
190-
state = consume_remote_packet(packet_buffer.data, GDB_PACKET_BUFFER_SIZE);
191-
packet_buffer.size = 0;
200+
state = consume_remote_packet(packet->data, GDB_PACKET_BUFFER_SIZE);
201+
packet->size = 0;
192202
}
193203
#endif
194204
/* EOT (end of transmission) - connection was closed */
195205
else if (rx_char == '\x04') {
196-
packet_buffer.data[1U] = '\0'; /* Null terminate */
197-
packet_buffer.size = 1U;
198-
return &packet_buffer;
206+
packet->data[1U] = '\0'; /* Null terminate */
207+
packet->size = 1U;
208+
return packet;
199209
}
200210
break;
201211

202212
case PACKET_GDB_CAPTURE:
203213
if (rx_char == GDB_PACKET_START) {
204214
/* Restart GDB packet capture */
205-
packet_buffer.size = 0;
215+
packet->size = 0;
206216
break;
207217
}
208218
if (rx_char == GDB_PACKET_END) {
@@ -219,12 +229,12 @@ gdb_packet_s *gdb_packet_receive(void)
219229
state = PACKET_GDB_ESCAPE;
220230
else
221231
/* Add to packet buffer */
222-
packet_buffer.data[packet_buffer.size++] = rx_char;
232+
packet->data[packet->size++] = rx_char;
223233
break;
224234

225235
case PACKET_GDB_ESCAPE:
226236
/* Resolve escaped char */
227-
packet_buffer.data[packet_buffer.size++] = rx_char ^ GDB_PACKET_ESCAPE_XOR;
237+
packet->data[packet->size++] = rx_char ^ GDB_PACKET_ESCAPE_XOR;
228238

229239
/* Return to normal packet capture */
230240
state = PACKET_GDB_CAPTURE;
@@ -245,7 +255,7 @@ gdb_packet_s *gdb_packet_receive(void)
245255
rx_checksum |= unhex_digit(rx_char); /* BITWISE OR lower nibble with upper nibble */
246256

247257
/* (N)Acknowledge packet */
248-
const bool checksum_ok = gdb_packet_checksum(&packet_buffer) == rx_checksum;
258+
const bool checksum_ok = gdb_packet_checksum(packet) == rx_checksum;
249259
gdb_if_putchar(checksum_ok ? GDB_PACKET_ACK : GDB_PACKET_NACK, true);
250260
if (!checksum_ok) {
251261
/* Checksum error, restart packet capture */
@@ -255,23 +265,23 @@ gdb_packet_s *gdb_packet_receive(void)
255265
}
256266

257267
/* Null terminate packet */
258-
packet_buffer.data[packet_buffer.size] = '\0';
268+
packet->data[packet->size] = '\0';
259269

260270
#ifndef DEBUG_GDB_IS_NOOP
261271
/* Log packet for debugging */
262-
gdb_packet_debug(__func__, &packet_buffer);
272+
gdb_packet_debug(__func__, packet);
263273
#endif
264274

265275
/* Return captured packet */
266-
return &packet_buffer;
276+
return packet;
267277

268278
default:
269279
/* Something is not right, restart packet capture */
270280
state = PACKET_IDLE;
271281
break;
272282
}
273283

274-
if (packet_buffer.size >= GDB_PACKET_BUFFER_SIZE)
284+
if (packet->size >= GDB_PACKET_BUFFER_SIZE)
275285
/* Buffer overflow, restart packet capture */
276286
state = PACKET_IDLE;
277287
}
@@ -332,13 +342,15 @@ void gdb_packet_send(const gdb_packet_s *const packet)
332342

333343
void gdb_put_packet(const char *preamble, size_t preamble_size, const char *data, size_t data_size, bool hex_data)
334344
{
345+
gdb_packet_s *packet = gdb_full_packet_buffer();
346+
335347
/*
336348
* Create a packet using the internal packet buffer
337349
* This destroys the previous packet in the buffer
338350
* any packets obtained from gdb_packet_receive() will be invalidated
339351
*/
340-
packet_buffer.notification = false;
341-
packet_buffer.size = 0;
352+
packet->notification = false;
353+
packet->size = 0;
342354

343355
/*
344356
* Copy the preamble and data into the packet buffer, limited by the buffer size
@@ -350,8 +362,8 @@ void gdb_put_packet(const char *preamble, size_t preamble_size, const char *data
350362
*/
351363
if (preamble != NULL && preamble_size > 0) {
352364
preamble_size = MIN(preamble_size, GDB_PACKET_BUFFER_SIZE);
353-
memcpy(packet_buffer.data, preamble, preamble_size);
354-
packet_buffer.size = preamble_size;
365+
memcpy(packet->data, preamble, preamble_size);
366+
packet->size = preamble_size;
355367
}
356368

357369
/* Add the data to the packet buffer and transform it if needed */
@@ -361,29 +373,30 @@ void gdb_put_packet(const char *preamble, size_t preamble_size, const char *data
361373
data_size *= 2U;
362374

363375
/* Limit the data size to the remaining space in the packet buffer */
364-
const size_t remaining_size = GDB_PACKET_BUFFER_SIZE - packet_buffer.size;
376+
const size_t remaining_size = GDB_PACKET_BUFFER_SIZE - packet->size;
365377
data_size = MIN(data_size, remaining_size);
366378

367379
/* Copy the data into the packet buffer */
368380
if (hex_data)
369-
hexify(packet_buffer.data + packet_buffer.size, data, data_size / 2U);
381+
hexify(packet->data + packet->size, data, data_size / 2U);
370382
else
371-
memcpy(packet_buffer.data + packet_buffer.size, data, data_size);
372-
packet_buffer.size += data_size;
383+
memcpy(packet->data + packet->size, data, data_size);
384+
packet->size += data_size;
373385
}
374386

375387
/* Transmit the packet */
376-
gdb_packet_send(&packet_buffer);
388+
gdb_packet_send(packet);
377389
}
378390

379391
void gdb_putpacket_str_f(const char *const fmt, ...)
380392
{
393+
gdb_packet_s *packet = gdb_full_packet_buffer();
381394
/*
382395
* Create a packet using the internal packet buffer
383396
* This destroys the previous packet in the buffer
384397
* any packets obtained from gdb_packet_receive() will be invalidated
385398
*/
386-
packet_buffer.notification = false;
399+
packet->notification = false;
387400

388401
/*
389402
* Format the string directly into the packet buffer
@@ -394,30 +407,31 @@ void gdb_putpacket_str_f(const char *const fmt, ...)
394407
*/
395408
va_list ap;
396409
va_start(ap, fmt);
397-
vsnprintf(packet_buffer.data, sizeof(packet_buffer.data), fmt, ap);
410+
vsnprintf(packet->data, sizeof(packet->data), fmt, ap);
398411
va_end(ap);
399412

400413
/* Get the size of the formatted string */
401-
packet_buffer.size = strnlen(packet_buffer.data, GDB_PACKET_BUFFER_SIZE);
414+
packet->size = strnlen(packet->data, GDB_PACKET_BUFFER_SIZE);
402415

403416
/* Transmit the packet */
404-
gdb_packet_send(&packet_buffer);
417+
gdb_packet_send(packet);
405418
}
406419

407420
void gdb_put_notification_str(const char *const str)
408421
{
422+
gdb_packet_s *packet = gdb_full_packet_buffer();
409423
/*
410424
* Create a packet using the internal packet buffer
411425
* This destroys the previous packet in the buffer
412426
* any packets obtained from gdb_packet_receive() will be invalidated
413427
*/
414-
packet_buffer.notification = true;
428+
packet->notification = true;
415429

416-
packet_buffer.size = strnlen(str, GDB_PACKET_BUFFER_SIZE);
417-
memcpy(packet_buffer.data, str, packet_buffer.size);
430+
packet->size = strnlen(str, GDB_PACKET_BUFFER_SIZE);
431+
memcpy(packet->data, str, packet->size);
418432

419433
/* Transmit the packet */
420-
gdb_packet_send(&packet_buffer);
434+
gdb_packet_send(packet);
421435
}
422436

423437
void gdb_out(const char *const str)

0 commit comments

Comments
 (0)