Skip to content

Commit 1c19ad6

Browse files
committed
GdbServerConnection.cc: do not call sprintf in a loop
1 parent 035e5e8 commit 1c19ad6

1 file changed

Lines changed: 38 additions & 34 deletions

File tree

src/GdbServerConnection.cc

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,34 @@ void GdbServerConnection::write_binary_packet(const char* pfx, const uint8_t* da
275275
return write_packet_bytes(buf.data(), buf_num_bytes);
276276
}
277277

278-
static string string_to_hex(const string& s) {
279-
stringstream sstr;
280-
for (char ch : s) {
281-
char buf[16];
282-
sprintf(buf, "%02x", ch);
283-
sstr << buf;
278+
static void parser_assert(bool cond) {
279+
if (!cond) {
280+
fputs("Failed to parse debugger request\n", stderr);
281+
DEBUG_ASSERT(false);
282+
exit(2);
283+
}
284+
}
285+
286+
/**
287+
* For the first |input_len| bytes in |input|, append two characters to |buf| as if
288+
* snprintf("%02x") would, then write a zero terminator.
289+
*/
290+
static void write_hex_string(const uint8_t* input, size_t input_len,
291+
char* buf, size_t buf_len) {
292+
static constexpr char hex_string_table[] = "0123456789abcdef";
293+
parser_assert(buf_len >= 2 * input_len + 1);
294+
for (size_t i = 0; i < input_len; ++i) {
295+
buf[2 * i + 0] = hex_string_table[input[i] >> 4];
296+
buf[2 * i + 1] = hex_string_table[input[i] & 0xf];
284297
}
285-
return sstr.str();
298+
buf[2 * input_len] = '\0';
299+
}
300+
301+
static string string_to_hex(const string& s) {
302+
string output;
303+
output.resize(2 * s.size());
304+
write_hex_string(reinterpret_cast<const uint8_t*>(s.data()), s.size(), output.data(), output.size() + 1);
305+
return output;
286306
}
287307

288308
void GdbServerConnection::write_hex_bytes_packet(const char* prefix,
@@ -296,25 +316,14 @@ void GdbServerConnection::write_hex_bytes_packet(const char* prefix,
296316
vector<char> buf;
297317
buf.resize(pfx_num_chars + 2 * len + 1);
298318
memcpy(buf.data(), prefix, pfx_num_chars);
299-
for (size_t i = 0; i < len; ++i) {
300-
unsigned long b = bytes[i];
301-
snprintf(&buf.data()[pfx_num_chars + 2 * i], 3, "%02lx", b);
302-
}
319+
write_hex_string(bytes, len, buf.data() + pfx_num_chars, buf.size() - pfx_num_chars);
303320
write_packet(buf.data());
304321
}
305322

306323
void GdbServerConnection::write_hex_bytes_packet(const uint8_t* bytes, size_t len) {
307324
write_hex_bytes_packet("", bytes, len);
308325
}
309326

310-
static void parser_assert(bool cond) {
311-
if (!cond) {
312-
fputs("Failed to parse debugger request\n", stderr);
313-
DEBUG_ASSERT(false);
314-
exit(2);
315-
}
316-
}
317-
318327
static string decode_ascii_encoded_hex_str(const char* encoded) {
319328
ssize_t enc_len = strlen(encoded);
320329
parser_assert(enc_len % 2 == 0);
@@ -615,7 +624,7 @@ bool GdbServerConnection::xfer(const char* name, char* args) {
615624

616625
/**
617626
* Format |value| into |buf| in the manner gdb expects. |buf| must
618-
* point at a buffer with at least |1 + 2*DBG_MAX_REG_SIZE| bytes
627+
* point at a buffer with at least |1 + 2*GdbServerRegisterValue::MAX_SIZE| bytes
619628
* available. Fewer bytes than that may be written, but |buf| is
620629
* guaranteed to be null-terminated.
621630
*/
@@ -625,9 +634,7 @@ static size_t print_reg_value(const GdbServerRegisterValue& reg, char* buf) {
625634
/* gdb wants the register value in native endianness.
626635
* reg.value read in native endianness is exactly that.
627636
*/
628-
for (size_t i = 0; i < reg.size; ++i) {
629-
snprintf(&buf[2 * i], 3, "%02lx", (unsigned long)reg.value[i]);
630-
}
637+
write_hex_string(reg.value, reg.size, buf, 1 + 2*GdbServerRegisterValue::MAX_SIZE);
631638
} else {
632639
for (size_t i = 0; i < reg.size; ++i) {
633640
strcpy(&buf[2 * i], "xx");
@@ -1322,17 +1329,14 @@ bool GdbServerConnection::process_vpacket(char* payload) {
13221329
}
13231330

13241331
static string to_string(const vector<uint8_t>& bytes, size_t max_len) {
1325-
stringstream ss;
1326-
for (size_t i = 0; i < bytes.size(); ++i) {
1327-
if (i >= max_len) {
1328-
ss << "...";
1329-
break;
1330-
}
1331-
char buf[3];
1332-
sprintf(buf, "%02x", bytes[i]);
1333-
ss << buf;
1334-
}
1335-
return ss.str();
1332+
string output;
1333+
size_t num_bytes = std::min(max_len, bytes.size());
1334+
output.resize(2 * num_bytes);
1335+
write_hex_string(bytes.data(), num_bytes, output.data(), output.size() + 1);
1336+
if (bytes.size() > max_len) {
1337+
output += "...";
1338+
}
1339+
return output;
13361340
}
13371341

13381342
bool GdbServerConnection::process_packet() {

0 commit comments

Comments
 (0)